hotspot/src/share/vm/asm/assembler.hpp
changeset 14626 0cf4eccf130f
parent 14625 b02f361c324e
child 14631 526804361522
equal deleted inserted replaced
14625:b02f361c324e 14626:0cf4eccf130f
    23  */
    23  */
    24 
    24 
    25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP
    25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP
    26 #define SHARE_VM_ASM_ASSEMBLER_HPP
    26 #define SHARE_VM_ASM_ASSEMBLER_HPP
    27 
    27 
       
    28 #include "asm/codeBuffer.hpp"
    28 #include "code/oopRecorder.hpp"
    29 #include "code/oopRecorder.hpp"
    29 #include "code/relocInfo.hpp"
    30 #include "code/relocInfo.hpp"
    30 #include "memory/allocation.hpp"
    31 #include "memory/allocation.hpp"
    31 #include "utilities/debug.hpp"
    32 #include "utilities/debug.hpp"
    32 #include "utilities/growableArray.hpp"
    33 #include "utilities/growableArray.hpp"
    33 #include "utilities/top.hpp"
    34 #include "utilities/top.hpp"
       
    35 
    34 #ifdef TARGET_ARCH_x86
    36 #ifdef TARGET_ARCH_x86
    35 # include "register_x86.hpp"
    37 # include "register_x86.hpp"
    36 # include "vm_version_x86.hpp"
    38 # include "vm_version_x86.hpp"
    37 #endif
    39 #endif
    38 #ifdef TARGET_ARCH_sparc
    40 #ifdef TARGET_ARCH_sparc
    52 # include "vm_version_ppc.hpp"
    54 # include "vm_version_ppc.hpp"
    53 #endif
    55 #endif
    54 
    56 
    55 // This file contains platform-independent assembler declarations.
    57 // This file contains platform-independent assembler declarations.
    56 
    58 
    57 class CodeBuffer;
       
    58 class MacroAssembler;
    59 class MacroAssembler;
    59 class AbstractAssembler;
    60 class AbstractAssembler;
    60 class Label;
    61 class Label;
    61 
    62 
    62 /**
    63 /**
   120   void bind_loc(int loc) {
   121   void bind_loc(int loc) {
   121     assert(loc >= 0, "illegal locator");
   122     assert(loc >= 0, "illegal locator");
   122     assert(_loc == -1, "already bound");
   123     assert(_loc == -1, "already bound");
   123     _loc = loc;
   124     _loc = loc;
   124   }
   125   }
   125   void bind_loc(int pos, int sect);  // = bind_loc(locator(pos, sect))
   126   void bind_loc(int pos, int sect) { bind_loc(CodeBuffer::locator(pos, sect)); }
   126 
   127 
   127 #ifndef PRODUCT
   128 #ifndef PRODUCT
   128   // Iterates over all unresolved instructions for printing
   129   // Iterates over all unresolved instructions for printing
   129   void print_instructions(MacroAssembler* masm) const;
   130   void print_instructions(MacroAssembler* masm) const;
   130 #endif // PRODUCT
   131 #endif // PRODUCT
   135    */
   136    */
   136   int loc() const {
   137   int loc() const {
   137     assert(_loc >= 0, "unbound label");
   138     assert(_loc >= 0, "unbound label");
   138     return _loc;
   139     return _loc;
   139   }
   140   }
   140   int loc_pos() const;   // == locator_pos(loc())
   141   int loc_pos()  const { return CodeBuffer::locator_pos(loc()); }
   141   int loc_sect() const;  // == locator_sect(loc())
   142   int loc_sect() const { return CodeBuffer::locator_sect(loc()); }
   142 
   143 
   143   bool is_bound() const    { return _loc >=  0; }
   144   bool is_bound() const    { return _loc >=  0; }
   144   bool is_unbound() const  { return _loc == -1 && _patch_index > 0; }
   145   bool is_unbound() const  { return _loc == -1 && _patch_index > 0; }
   145   bool is_unused() const   { return _loc == -1 && _patch_index == 0; }
   146   bool is_unused() const   { return _loc == -1 && _patch_index == 0; }
   146 
   147 
   202  protected:
   203  protected:
   203   CodeSection* _code_section;          // section within the code buffer
   204   CodeSection* _code_section;          // section within the code buffer
   204   OopRecorder* _oop_recorder;          // support for relocInfo::oop_type
   205   OopRecorder* _oop_recorder;          // support for relocInfo::oop_type
   205 
   206 
   206   // Code emission & accessing
   207   // Code emission & accessing
   207   inline address addr_at(int pos) const;
   208   address addr_at(int pos) const { return code_section()->start() + pos; }
       
   209 
   208 
   210 
   209   // This routine is called with a label is used for an address.
   211   // This routine is called with a label is used for an address.
   210   // Labels and displacements truck in offsets, but target must return a PC.
   212   // Labels and displacements truck in offsets, but target must return a PC.
   211   address target(Label& L);            // return _code_section->target(L)
   213   address target(Label& L)             { return code_section()->target(L, pc()); }
   212 
   214 
   213   bool is8bit(int x) const             { return -0x80 <= x && x < 0x80; }
   215   bool is8bit(int x) const             { return -0x80 <= x && x < 0x80; }
   214   bool isByte(int x) const             { return 0 <= x && x < 0x100; }
   216   bool isByte(int x) const             { return 0 <= x && x < 0x100; }
   215   bool isShiftCount(int x) const       { return 0 <= x && x < 32; }
   217   bool isShiftCount(int x) const       { return 0 <= x && x < 32; }
   216 
   218 
       
   219   void emit_int8(   int8_t  x) { code_section()->emit_int8(   x); }
       
   220   void emit_int16(  int16_t x) { code_section()->emit_int16(  x); }
       
   221   void emit_int32(  int32_t x) { code_section()->emit_int32(  x); }
       
   222   void emit_int64(  int64_t x) { code_section()->emit_int64(  x); }
       
   223 
       
   224   void emit_float(  jfloat  x) { code_section()->emit_float(  x); }
       
   225   void emit_double( jdouble x) { code_section()->emit_double( x); }
       
   226   void emit_address(address x) { code_section()->emit_address(x); }
       
   227 
   217   void emit_byte(int x)  { emit_int8 (x); }  // deprecated
   228   void emit_byte(int x)  { emit_int8 (x); }  // deprecated
   218   void emit_word(int x)  { emit_int16(x); }  // deprecated
   229   void emit_word(int x)  { emit_int16(x); }  // deprecated
   219   void emit_long(jint x) { emit_int32(x); }  // deprecated
   230   void emit_long(jint x) { emit_int32(x); }  // deprecated
   220 
       
   221   inline void emit_int8(  int8_t  x);
       
   222   inline void emit_int16( int16_t x);
       
   223   inline void emit_int32( int32_t x);
       
   224   inline void emit_int64( int64_t x);
       
   225 
       
   226   inline void emit_float( jfloat  x);
       
   227   inline void emit_double(jdouble x);
       
   228   inline void emit_address(address x);
       
   229 
   231 
   230   // Instruction boundaries (required when emitting relocatable values).
   232   // Instruction boundaries (required when emitting relocatable values).
   231   class InstructionMark: public StackObj {
   233   class InstructionMark: public StackObj {
   232    private:
   234    private:
   233     AbstractAssembler* _assm;
   235     AbstractAssembler* _assm;
   240     ~InstructionMark() {
   242     ~InstructionMark() {
   241       _assm->clear_inst_mark();
   243       _assm->clear_inst_mark();
   242     }
   244     }
   243   };
   245   };
   244   friend class InstructionMark;
   246   friend class InstructionMark;
   245   #ifdef ASSERT
   247 #ifdef ASSERT
   246   // Make it return true on platforms which need to verify
   248   // Make it return true on platforms which need to verify
   247   // instruction boundaries for some operations.
   249   // instruction boundaries for some operations.
   248   inline static bool pd_check_instruction_mark();
   250   inline static bool pd_check_instruction_mark();
   249 
   251 
   250   // Add delta to short branch distance to verify that it still fit into imm8.
   252   // Add delta to short branch distance to verify that it still fit into imm8.
   265     }
   267     }
   266     ~ShortBranchVerifier() {
   268     ~ShortBranchVerifier() {
   267       _assm->clear_short_branch_delta();
   269       _assm->clear_short_branch_delta();
   268     }
   270     }
   269   };
   271   };
   270   #else
   272 #else
   271   // Dummy in product.
   273   // Dummy in product.
   272   class ShortBranchVerifier: public StackObj {
   274   class ShortBranchVerifier: public StackObj {
   273    public:
   275    public:
   274     ShortBranchVerifier(AbstractAssembler* assm) {}
   276     ShortBranchVerifier(AbstractAssembler* assm) {}
   275   };
   277   };
   276   #endif
   278 #endif
   277 
   279 
   278   // Label functions
   280   // Label functions
   279   void print(Label& L);
   281   void print(Label& L);
   280 
   282 
   281  public:
   283  public:
   309   static bool is_simm26(intptr_t x) { return is_simm(x, 26); }
   311   static bool is_simm26(intptr_t x) { return is_simm(x, 26); }
   310   static bool is_simm32(intptr_t x) { return is_simm(x, 32); }
   312   static bool is_simm32(intptr_t x) { return is_simm(x, 32); }
   311 
   313 
   312   // Accessors
   314   // Accessors
   313   CodeSection*  code_section() const   { return _code_section; }
   315   CodeSection*  code_section() const   { return _code_section; }
   314   inline CodeBuffer*   code() const;
   316   CodeBuffer*   code()         const   { return code_section()->outer(); }
   315   inline int           sect() const;
   317   int           sect()         const   { return code_section()->index(); }
   316   inline address       pc() const;
   318   address       pc()           const   { return code_section()->end();   }
   317   inline int           offset() const;
   319   int           offset()       const   { return code_section()->size();  }
   318   inline int           locator() const;       // CodeBuffer::locator(offset(), sect())
   320   int           locator()      const   { return CodeBuffer::locator(offset(), sect()); }
   319 
   321 
   320   OopRecorder*  oop_recorder() const   { return _oop_recorder; }
   322   OopRecorder*  oop_recorder() const   { return _oop_recorder; }
   321   void      set_oop_recorder(OopRecorder* r) { _oop_recorder = r; }
   323   void      set_oop_recorder(OopRecorder* r) { _oop_recorder = r; }
   322 
   324 
   323   address  inst_mark() const;
   325   address       inst_mark() const { return code_section()->mark();       }
   324   void set_inst_mark();
   326   void      set_inst_mark()       {        code_section()->set_mark();   }
   325   void clear_inst_mark();
   327   void    clear_inst_mark()       {        code_section()->clear_mark(); }
   326 
   328 
   327   // Constants in code
   329   // Constants in code
   328   void a_byte(int x);
   330   void a_byte(int x);
   329   void a_long(jint x);
   331   void a_long(jint x);
   330   void relocate(RelocationHolder const& rspec, int format = 0);
   332   void relocate(RelocationHolder const& rspec, int format = 0) {
       
   333     assert(!pd_check_instruction_mark()
       
   334         || inst_mark() == NULL || inst_mark() == code_section()->end(),
       
   335         "call relocate() between instructions");
       
   336     code_section()->relocate(code_section()->end(), rspec, format);
       
   337   }
   331   void relocate(   relocInfo::relocType rtype, int format = 0) {
   338   void relocate(   relocInfo::relocType rtype, int format = 0) {
   332     if (rtype != relocInfo::none)
   339     code_section()->relocate(code_section()->end(), rtype, format);
   333       relocate(Relocation::spec_simple(rtype), format);
       
   334   }
   340   }
   335 
   341 
   336   static int code_fill_byte();         // used to pad out odd-sized code buffers
   342   static int code_fill_byte();         // used to pad out odd-sized code buffers
   337 
   343 
   338   // Associate a comment with the current offset.  It will be printed
   344   // Associate a comment with the current offset.  It will be printed