src/cpu/x86/vm/assembler_x86.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-dvm Sdiff src/cpu/x86/vm

src/cpu/x86/vm/assembler_x86.hpp

Print this page
rev 522 : [mq]: meth.patch


 118 REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3);
 119 REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4);
 120 REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5);
 121 REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6);
 122 REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7);
 123 
 124 REGISTER_DECLARATION(Register, rscratch1, r10);  // volatile
 125 REGISTER_DECLARATION(Register, rscratch2, r11);  // volatile
 126 
 127 REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved
 128 REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved
 129 
 130 #else
 131 // rscratch1 will apear in 32bit code that is dead but of course must compile
 132 // Using noreg ensures if the dead code is incorrectly live and executed it
 133 // will cause an assertion failure
 134 #define rscratch1 noreg
 135 
 136 #endif // _LP64
 137 





















 138 // Address is an abstraction used to represent a memory location
 139 // using any of the amd64 addressing modes with one object.
 140 //
 141 // Note: A register location is represented via a Register, not
 142 //       via an address for efficiency & simplicity reasons.
 143 
 144 class ArrayAddress;
 145 
 146 class Address VALUE_OBJ_CLASS_SPEC {
 147  public:
 148   enum ScaleFactor {
 149     no_scale = -1,
 150     times_1  =  0,
 151     times_2  =  1,
 152     times_4  =  2,
 153     times_8  =  3,
 154     times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
 155   };
 156 








 157  private:
 158   Register         _base;
 159   Register         _index;
 160   ScaleFactor      _scale;
 161   int              _disp;
 162   RelocationHolder _rspec;
 163 
 164   // Easily misused constructors make them private
 165   // %%% can we make these go away?
 166   NOT_LP64(Address(address loc, RelocationHolder spec);)
 167   Address(int disp, address loc, relocInfo::relocType rtype);
 168   Address(int disp, address loc, RelocationHolder spec);
 169 
 170  public:
 171 
 172  int disp() { return _disp; }
 173   // creation
 174   Address()
 175     : _base(noreg),
 176       _index(noreg),


 180 
 181   // No default displacement otherwise Register can be implicitly
 182   // converted to 0(Register) which is quite a different animal.
 183 
 184   Address(Register base, int disp)
 185     : _base(base),
 186       _index(noreg),
 187       _scale(no_scale),
 188       _disp(disp) {
 189   }
 190 
 191   Address(Register base, Register index, ScaleFactor scale, int disp = 0)
 192     : _base (base),
 193       _index(index),
 194       _scale(scale),
 195       _disp (disp) {
 196     assert(!index->is_valid() == (scale == Address::no_scale),
 197            "inconsistent address");
 198   }
 199 
















 200   // The following two overloads are used in connection with the
 201   // ByteSize type (see sizes.hpp).  They simplify the use of
 202   // ByteSize'd arguments in assembly code. Note that their equivalent
 203   // for the optimized build are the member functions with int disp
 204   // argument since ByteSize is mapped to an int type in that case.
 205   //
 206   // Note: DO NOT introduce similar overloaded functions for WordSize
 207   // arguments as in the optimized mode, both ByteSize and WordSize
 208   // are mapped to the same type and thus the compiler cannot make a
 209   // distinction anymore (=> compiler errors).
 210 
 211 #ifdef ASSERT
 212   Address(Register base, ByteSize disp)
 213     : _base(base),
 214       _index(noreg),
 215       _scale(no_scale),
 216       _disp(in_bytes(disp)) {
 217   }
 218 
 219   Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
 220     : _base(base),
 221       _index(index),
 222       _scale(scale),
 223       _disp(in_bytes(disp)) {
 224     assert(!index->is_valid() == (scale == Address::no_scale),
 225            "inconsistent address");
 226   }











 227 #endif // ASSERT
 228 
 229   // accessors
 230   bool        uses(Register reg) const { return _base == reg || _index == reg; }
 231   Register    base()             const { return _base;  }
 232   Register    index()            const { return _index; }
 233   ScaleFactor scale()            const { return _scale; }
 234   int         disp()             const { return _disp;  }
 235 
 236   // Convert the raw encoding form into the form expected by the constructor for
 237   // Address.  An index of 4 (rsp) corresponds to having no index, so convert
 238   // that to noreg for the Address constructor.
 239   static Address make_raw(int base, int index, int scale, int disp);
 240 
 241   static Address make_array(ArrayAddress);
 242 








 243 
 244  private:
 245   bool base_needs_rex() const {
 246     return _base != noreg && _base->encoding() >= 8;
 247   }
 248 
 249   bool index_needs_rex() const {
 250     return _index != noreg &&_index->encoding() >= 8;
 251   }
 252 
 253   relocInfo::relocType reloc() const { return _rspec.type(); }
 254 
 255   friend class Assembler;
 256   friend class MacroAssembler;
 257   friend class LIR_Assembler; // base/index/scale/disp
 258 };
 259 
 260 //
 261 // AddressLiteral has been split out from Address because operands of this type
 262 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out


1387   // Required platform-specific helpers for Label::patch_instructions.
1388   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
1389   void pd_patch_instruction(address branch, address target);
1390 #ifndef PRODUCT
1391   static void pd_print_patched_instruction(address branch);
1392 #endif
1393 
1394   // The following 4 methods return the offset of the appropriate move instruction
1395 
1396   // Support for fast byte/word loading with zero extension (depending on particular CPU)
1397   int load_unsigned_byte(Register dst, Address src);
1398   int load_unsigned_word(Register dst, Address src);
1399 
1400   // Support for fast byte/word loading with sign extension (depending on particular CPU)
1401   int load_signed_byte(Register dst, Address src);
1402   int load_signed_word(Register dst, Address src);
1403 
1404   // Support for sign-extension (hi:lo = extend_sign(lo))
1405   void extend_sign(Register hi, Register lo);
1406 



1407   // Support for inc/dec with optimal instruction selection depending on value
1408 
1409   void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
1410   void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; }
1411 
1412   void decrementl(Address dst, int value = 1);
1413   void decrementl(Register reg, int value = 1);
1414 
1415   void decrementq(Register reg, int value = 1);
1416   void decrementq(Address dst, int value = 1);
1417 
1418   void incrementl(Address dst, int value = 1);
1419   void incrementl(Register reg, int value = 1);
1420 
1421   void incrementq(Register reg, int value = 1);
1422   void incrementq(Address dst, int value = 1);
1423 
1424 
1425   // Support optimal SSE move instructions.
1426   void movflt(XMMRegister dst, XMMRegister src) {


1704   void pop_callee_saved_registers();
1705 
1706   // allocation
1707   void eden_allocate(
1708     Register obj,                      // result: pointer to object after successful allocation
1709     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
1710     int      con_size_in_bytes,        // object size in bytes if   known at compile time
1711     Register t1,                       // temp register
1712     Label&   slow_case                 // continuation point if fast allocation fails
1713   );
1714   void tlab_allocate(
1715     Register obj,                      // result: pointer to object after successful allocation
1716     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
1717     int      con_size_in_bytes,        // object size in bytes if   known at compile time
1718     Register t1,                       // temp register
1719     Register t2,                       // temp register
1720     Label&   slow_case                 // continuation point if fast allocation fails
1721   );
1722   void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
1723 

































1724   //----
1725   void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
1726 
1727   // Debugging
1728 
1729   // only if +VerifyOops
1730   void verify_oop(Register reg, const char* s = "broken oop");
1731   void verify_oop_addr(Address addr, const char * s = "broken oop addr");
1732 
1733   // only if +VerifyFPU
1734   void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
1735 
1736   // prints msg, dumps registers and stops execution
1737   void stop(const char* msg);
1738 
1739   // prints msg and continues
1740   void warn(const char* msg);
1741 
1742   static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
1743   static void debug64(char* msg, int64_t pc, int64_t regs[]);




 118 REGISTER_DECLARATION(XMMRegister, j_farg3, xmm3);
 119 REGISTER_DECLARATION(XMMRegister, j_farg4, xmm4);
 120 REGISTER_DECLARATION(XMMRegister, j_farg5, xmm5);
 121 REGISTER_DECLARATION(XMMRegister, j_farg6, xmm6);
 122 REGISTER_DECLARATION(XMMRegister, j_farg7, xmm7);
 123 
 124 REGISTER_DECLARATION(Register, rscratch1, r10);  // volatile
 125 REGISTER_DECLARATION(Register, rscratch2, r11);  // volatile
 126 
 127 REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved
 128 REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved
 129 
 130 #else
 131 // rscratch1 will apear in 32bit code that is dead but of course must compile
 132 // Using noreg ensures if the dead code is incorrectly live and executed it
 133 // will cause an assertion failure
 134 #define rscratch1 noreg
 135 
 136 #endif // _LP64
 137 
 138 // A union type for code which has to assemble both constant and non-constant operands.
 139 class RegisterConstant VALUE_OBJ_CLASS_SPEC {
 140  private:
 141   Register _r;
 142   intptr_t _c;
 143 
 144  public:
 145   RegisterConstant(): _r(noreg), _c(0) {}
 146   RegisterConstant(Register r): _r(r), _c(0) {}
 147   RegisterConstant(intptr_t c): _r(noreg), _c(c) {}
 148 
 149   Register as_register() const { assert(is_register(),""); return _r; }
 150   intptr_t as_constant() const { assert(is_constant(),""); return _c; }
 151 
 152   Register register_or_noreg() const { return _r; }
 153   intptr_t constant_or_zero() const  { return _c; }
 154 
 155   bool is_register() const { return _r != noreg; }
 156   bool is_constant() const { return _r == noreg; }
 157 };
 158 
 159 // Address is an abstraction used to represent a memory location
 160 // using any of the amd64 addressing modes with one object.
 161 //
 162 // Note: A register location is represented via a Register, not
 163 //       via an address for efficiency & simplicity reasons.
 164 
 165 class ArrayAddress;
 166 
 167 class Address VALUE_OBJ_CLASS_SPEC {
 168  public:
 169   enum ScaleFactor {
 170     no_scale = -1,
 171     times_1  =  0,
 172     times_2  =  1,
 173     times_4  =  2,
 174     times_8  =  3,
 175     times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
 176   };
 177 
 178   static ScaleFactor times(int size) {
 179     assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
 180     if (size == 8)  return times_8;
 181     if (size == 4)  return times_4;
 182     if (size == 2)  return times_2;
 183     return times_1;
 184   }
 185 
 186  private:
 187   Register         _base;
 188   Register         _index;
 189   ScaleFactor      _scale;
 190   int              _disp;
 191   RelocationHolder _rspec;
 192 
 193   // Easily misused constructors make them private
 194   // %%% can we make these go away?
 195   NOT_LP64(Address(address loc, RelocationHolder spec);)
 196   Address(int disp, address loc, relocInfo::relocType rtype);
 197   Address(int disp, address loc, RelocationHolder spec);
 198 
 199  public:
 200 
 201  int disp() { return _disp; }
 202   // creation
 203   Address()
 204     : _base(noreg),
 205       _index(noreg),


 209 
 210   // No default displacement otherwise Register can be implicitly
 211   // converted to 0(Register) which is quite a different animal.
 212 
 213   Address(Register base, int disp)
 214     : _base(base),
 215       _index(noreg),
 216       _scale(no_scale),
 217       _disp(disp) {
 218   }
 219 
 220   Address(Register base, Register index, ScaleFactor scale, int disp = 0)
 221     : _base (base),
 222       _index(index),
 223       _scale(scale),
 224       _disp (disp) {
 225     assert(!index->is_valid() == (scale == Address::no_scale),
 226            "inconsistent address");
 227   }
 228 
 229   Address(Register base, RegisterConstant index, ScaleFactor scale = times_1, int disp = 0)
 230     : _base (base),
 231       _index(index.register_or_noreg()),
 232       _scale(scale),
 233       _disp (disp + (index.constant_or_zero() * scale_size(scale))) {
 234     if (!index.is_register())  scale = Address::no_scale;
 235     assert(!_index->is_valid() == (scale == Address::no_scale),
 236            "inconsistent address");
 237   }
 238 
 239   Address plus_disp(int disp) {
 240     Address result = (*this);
 241     result._disp += disp;
 242     return result;
 243   }
 244 
 245   // The following two overloads are used in connection with the
 246   // ByteSize type (see sizes.hpp).  They simplify the use of
 247   // ByteSize'd arguments in assembly code. Note that their equivalent
 248   // for the optimized build are the member functions with int disp
 249   // argument since ByteSize is mapped to an int type in that case.
 250   //
 251   // Note: DO NOT introduce similar overloaded functions for WordSize
 252   // arguments as in the optimized mode, both ByteSize and WordSize
 253   // are mapped to the same type and thus the compiler cannot make a
 254   // distinction anymore (=> compiler errors).
 255 
 256 #ifdef ASSERT
 257   Address(Register base, ByteSize disp)
 258     : _base(base),
 259       _index(noreg),
 260       _scale(no_scale),
 261       _disp(in_bytes(disp)) {
 262   }
 263 
 264   Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
 265     : _base(base),
 266       _index(index),
 267       _scale(scale),
 268       _disp(in_bytes(disp)) {
 269     assert(!index->is_valid() == (scale == Address::no_scale),
 270            "inconsistent address");
 271   }
 272 
 273   Address(Register base, RegisterConstant index, ScaleFactor scale, ByteSize disp)
 274     : _base (base),
 275       _index(index.register_or_noreg()),
 276       _scale(scale),
 277       _disp (in_bytes(disp) + (index.constant_or_zero() * scale_size(scale))) {
 278     if (!index.is_register())  scale = Address::no_scale;
 279     assert(!_index->is_valid() == (scale == Address::no_scale),
 280            "inconsistent address");
 281   }
 282 
 283 #endif // ASSERT
 284 
 285   // accessors
 286   bool        uses(Register reg) const { return _base == reg || _index == reg; }
 287   Register    base()             const { return _base;  }
 288   Register    index()            const { return _index; }
 289   ScaleFactor scale()            const { return _scale; }
 290   int         disp()             const { return _disp;  }
 291 
 292   // Convert the raw encoding form into the form expected by the constructor for
 293   // Address.  An index of 4 (rsp) corresponds to having no index, so convert
 294   // that to noreg for the Address constructor.
 295   static Address make_raw(int base, int index, int scale, int disp);
 296 
 297   static Address make_array(ArrayAddress);
 298 
 299   static int scale_size(ScaleFactor scale) {
 300     assert(scale != no_scale, "");
 301     assert(((1 << (int)times_1) == 1 &&
 302             (1 << (int)times_2) == 2 &&
 303             (1 << (int)times_4) == 4 &&
 304             (1 << (int)times_8) == 8), "");
 305     return (1 << (int)scale);
 306   }
 307 
 308  private:
 309   bool base_needs_rex() const {
 310     return _base != noreg && _base->encoding() >= 8;
 311   }
 312 
 313   bool index_needs_rex() const {
 314     return _index != noreg &&_index->encoding() >= 8;
 315   }
 316 
 317   relocInfo::relocType reloc() const { return _rspec.type(); }
 318 
 319   friend class Assembler;
 320   friend class MacroAssembler;
 321   friend class LIR_Assembler; // base/index/scale/disp
 322 };
 323 
 324 //
 325 // AddressLiteral has been split out from Address because operands of this type
 326 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out


1451   // Required platform-specific helpers for Label::patch_instructions.
1452   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
1453   void pd_patch_instruction(address branch, address target);
1454 #ifndef PRODUCT
1455   static void pd_print_patched_instruction(address branch);
1456 #endif
1457 
1458   // The following 4 methods return the offset of the appropriate move instruction
1459 
1460   // Support for fast byte/word loading with zero extension (depending on particular CPU)
1461   int load_unsigned_byte(Register dst, Address src);
1462   int load_unsigned_word(Register dst, Address src);
1463 
1464   // Support for fast byte/word loading with sign extension (depending on particular CPU)
1465   int load_signed_byte(Register dst, Address src);
1466   int load_signed_word(Register dst, Address src);
1467 
1468   // Support for sign-extension (hi:lo = extend_sign(lo))
1469   void extend_sign(Register hi, Register lo);
1470 
1471   // Loading values by size and signed-ness
1472   void load_sized_value(Register dst, Address src, int size_in_bytes, bool is_signed);
1473 
1474   // Support for inc/dec with optimal instruction selection depending on value
1475 
1476   void increment(Register reg, int value = 1) { LP64_ONLY(incrementq(reg, value)) NOT_LP64(incrementl(reg, value)) ; }
1477   void decrement(Register reg, int value = 1) { LP64_ONLY(decrementq(reg, value)) NOT_LP64(decrementl(reg, value)) ; }
1478 
1479   void decrementl(Address dst, int value = 1);
1480   void decrementl(Register reg, int value = 1);
1481 
1482   void decrementq(Register reg, int value = 1);
1483   void decrementq(Address dst, int value = 1);
1484 
1485   void incrementl(Address dst, int value = 1);
1486   void incrementl(Register reg, int value = 1);
1487 
1488   void incrementq(Register reg, int value = 1);
1489   void incrementq(Address dst, int value = 1);
1490 
1491 
1492   // Support optimal SSE move instructions.
1493   void movflt(XMMRegister dst, XMMRegister src) {


1771   void pop_callee_saved_registers();
1772 
1773   // allocation
1774   void eden_allocate(
1775     Register obj,                      // result: pointer to object after successful allocation
1776     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
1777     int      con_size_in_bytes,        // object size in bytes if   known at compile time
1778     Register t1,                       // temp register
1779     Label&   slow_case                 // continuation point if fast allocation fails
1780   );
1781   void tlab_allocate(
1782     Register obj,                      // result: pointer to object after successful allocation
1783     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
1784     int      con_size_in_bytes,        // object size in bytes if   known at compile time
1785     Register t1,                       // temp register
1786     Register t2,                       // temp register
1787     Label&   slow_case                 // continuation point if fast allocation fails
1788   );
1789   void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
1790 
1791   // small bootstrap problems
1792   RegisterConstant delayed_value(intptr_t* delayed_value_addr, Register tmp);
1793   RegisterConstant delayed_value(int(*value_fn)(), Register tmp) {
1794     return delayed_value(delayed_value_addr(value_fn), tmp);
1795   }
1796   RegisterConstant delayed_value(address(*value_fn)(), Register tmp) {
1797     return delayed_value((intptr_t*) delayed_value_addr(value_fn), tmp);
1798   }
1799 
1800   // interface method calling
1801   void lookup_interface_method(Register recv_klass,
1802                                Register intf_klass,
1803                                RegisterConstant itable_index,
1804                                Register method_result,
1805                                Register scan_temp,
1806                                Label& no_such_interface);
1807 
1808   // method handles (JSR 292)
1809   void check_method_handle_type(Register mtype_reg, Register mh_reg,
1810                                 Register temp_reg,
1811                                 Label& wrong_method_type);
1812   void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
1813                                   Register temp_reg);
1814   void jump_to_method_handle_entry(Register mh_reg, Register temp_reg);
1815   Address argument_address(RegisterConstant arg_slot, int extra_slot_offset = 0);
1816 
1817 
1818   // klass type checking (falls through on failure)
1819   void check_klass_subtype(Register sub_klass,
1820                            Register super_klass,
1821                            Register temp_reg,
1822                            Label& L_success);
1823 
1824   //----
1825   void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
1826 
1827   // Debugging
1828 
1829   // only if +VerifyOops
1830   void verify_oop(Register reg, const char* s = "broken oop");
1831   void verify_oop_addr(Address addr, const char * s = "broken oop addr");
1832 
1833   // only if +VerifyFPU
1834   void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
1835 
1836   // prints msg, dumps registers and stops execution
1837   void stop(const char* msg);
1838 
1839   // prints msg and continues
1840   void warn(const char* msg);
1841 
1842   static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
1843   static void debug64(char* msg, int64_t pc, int64_t regs[]);


src/cpu/x86/vm/assembler_x86.hpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File