272 // Note: A register location is represented via a Register, not |
272 // Note: A register location is represented via a Register, not |
273 // via an address for efficiency & simplicity reasons. |
273 // via an address for efficiency & simplicity reasons. |
274 |
274 |
275 class Address VALUE_OBJ_CLASS_SPEC { |
275 class Address VALUE_OBJ_CLASS_SPEC { |
276 private: |
276 private: |
277 Register _base; |
277 Register _base; // Base register. |
278 #ifdef _LP64 |
278 RegisterOrConstant _index_or_disp; // Index register or constant displacement. |
279 int _hi32; // bits 63::32 |
279 RelocationHolder _rspec; |
280 int _low32; // bits 31::0 |
280 |
281 #endif |
281 public: |
282 int _hi; |
282 Address() : _base(noreg), _index_or_disp(noreg) {} |
283 int _disp; |
283 |
284 RelocationHolder _rspec; |
284 Address(Register base, RegisterOrConstant index_or_disp) |
285 |
285 : _base(base), |
286 RelocationHolder rspec_from_rtype(relocInfo::relocType rt, address a = NULL) { |
286 _index_or_disp(index_or_disp) { |
287 switch (rt) { |
287 } |
|
288 |
|
289 Address(Register base, Register index) |
|
290 : _base(base), |
|
291 _index_or_disp(index) { |
|
292 } |
|
293 |
|
294 Address(Register base, int disp) |
|
295 : _base(base), |
|
296 _index_or_disp(disp) { |
|
297 } |
|
298 |
|
299 #ifdef ASSERT |
|
300 // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
|
301 Address(Register base, ByteSize disp) |
|
302 : _base(base), |
|
303 _index_or_disp(in_bytes(disp)) { |
|
304 } |
|
305 #endif |
|
306 |
|
307 // accessors |
|
308 Register base() const { return _base; } |
|
309 Register index() const { return _index_or_disp.as_register(); } |
|
310 int disp() const { return _index_or_disp.as_constant(); } |
|
311 |
|
312 bool has_index() const { return _index_or_disp.is_register(); } |
|
313 bool has_disp() const { return _index_or_disp.is_constant(); } |
|
314 |
|
315 const relocInfo::relocType rtype() { return _rspec.type(); } |
|
316 const RelocationHolder& rspec() { return _rspec; } |
|
317 |
|
318 RelocationHolder rspec(int offset) const { |
|
319 return offset == 0 ? _rspec : _rspec.plus(offset); |
|
320 } |
|
321 |
|
322 inline bool is_simm13(int offset = 0); // check disp+offset for overflow |
|
323 |
|
324 Address plus_disp(int plusdisp) const { // bump disp by a small amount |
|
325 assert(_index_or_disp.is_constant(), "must have a displacement"); |
|
326 Address a(base(), disp() + plusdisp); |
|
327 return a; |
|
328 } |
|
329 |
|
330 Address after_save() const { |
|
331 Address a = (*this); |
|
332 a._base = a._base->after_save(); |
|
333 return a; |
|
334 } |
|
335 |
|
336 Address after_restore() const { |
|
337 Address a = (*this); |
|
338 a._base = a._base->after_restore(); |
|
339 return a; |
|
340 } |
|
341 |
|
342 // Convert the raw encoding form into the form expected by the |
|
343 // constructor for Address. |
|
344 static Address make_raw(int base, int index, int scale, int disp, bool disp_is_oop); |
|
345 |
|
346 friend class Assembler; |
|
347 }; |
|
348 |
|
349 |
|
350 class AddressLiteral VALUE_OBJ_CLASS_SPEC { |
|
351 private: |
|
352 address _address; |
|
353 RelocationHolder _rspec; |
|
354 |
|
355 RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) { |
|
356 switch (rtype) { |
288 case relocInfo::external_word_type: |
357 case relocInfo::external_word_type: |
289 return external_word_Relocation::spec(a); |
358 return external_word_Relocation::spec(addr); |
290 case relocInfo::internal_word_type: |
359 case relocInfo::internal_word_type: |
291 return internal_word_Relocation::spec(a); |
360 return internal_word_Relocation::spec(addr); |
292 #ifdef _LP64 |
361 #ifdef _LP64 |
293 case relocInfo::opt_virtual_call_type: |
362 case relocInfo::opt_virtual_call_type: |
294 return opt_virtual_call_Relocation::spec(); |
363 return opt_virtual_call_Relocation::spec(); |
295 case relocInfo::static_call_type: |
364 case relocInfo::static_call_type: |
296 return static_call_Relocation::spec(); |
365 return static_call_Relocation::spec(); |
303 ShouldNotReachHere(); |
372 ShouldNotReachHere(); |
304 return RelocationHolder(); |
373 return RelocationHolder(); |
305 } |
374 } |
306 } |
375 } |
307 |
376 |
|
377 protected: |
|
378 // creation |
|
379 AddressLiteral() : _address(NULL), _rspec(NULL) {} |
|
380 |
308 public: |
381 public: |
309 Address(Register b, address a, relocInfo::relocType rt = relocInfo::none) |
382 AddressLiteral(address addr, RelocationHolder const& rspec) |
310 : _rspec(rspec_from_rtype(rt, a)) |
383 : _address(addr), |
311 { |
384 _rspec(rspec) {} |
312 _base = b; |
385 |
|
386 // Some constructors to avoid casting at the call site. |
|
387 AddressLiteral(jobject obj, RelocationHolder const& rspec) |
|
388 : _address((address) obj), |
|
389 _rspec(rspec) {} |
|
390 |
|
391 AddressLiteral(intptr_t value, RelocationHolder const& rspec) |
|
392 : _address((address) value), |
|
393 _rspec(rspec) {} |
|
394 |
|
395 AddressLiteral(address addr, relocInfo::relocType rtype = relocInfo::none) |
|
396 : _address((address) addr), |
|
397 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
398 |
|
399 // Some constructors to avoid casting at the call site. |
|
400 AddressLiteral(address* addr, relocInfo::relocType rtype = relocInfo::none) |
|
401 : _address((address) addr), |
|
402 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
403 |
|
404 AddressLiteral(bool* addr, relocInfo::relocType rtype = relocInfo::none) |
|
405 : _address((address) addr), |
|
406 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
407 |
|
408 AddressLiteral(const bool* addr, relocInfo::relocType rtype = relocInfo::none) |
|
409 : _address((address) addr), |
|
410 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
411 |
|
412 AddressLiteral(signed char* addr, relocInfo::relocType rtype = relocInfo::none) |
|
413 : _address((address) addr), |
|
414 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
415 |
|
416 AddressLiteral(int* addr, relocInfo::relocType rtype = relocInfo::none) |
|
417 : _address((address) addr), |
|
418 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
419 |
|
420 AddressLiteral(intptr_t addr, relocInfo::relocType rtype = relocInfo::none) |
|
421 : _address((address) addr), |
|
422 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
|
423 |
313 #ifdef _LP64 |
424 #ifdef _LP64 |
314 _hi32 = (intptr_t)a >> 32; // top 32 bits in 64 bit word |
425 // 32-bit complains about a multiple declaration for int*. |
315 _low32 = (intptr_t)a & ~0; // low 32 bits in 64 bit word |
426 AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none) |
316 #endif |
427 : _address((address) addr), |
317 _hi = (intptr_t)a & ~0x3ff; // top 22 bits in low word |
428 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
318 _disp = (intptr_t)a & 0x3ff; // bottom 10 bits |
429 #endif |
319 } |
430 |
320 |
431 AddressLiteral(oop addr, relocInfo::relocType rtype = relocInfo::none) |
321 Address(Register b, address a, RelocationHolder const& rspec) |
432 : _address((address) addr), |
322 : _rspec(rspec) |
433 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
323 { |
434 |
324 _base = b; |
435 AddressLiteral(float* addr, relocInfo::relocType rtype = relocInfo::none) |
325 #ifdef _LP64 |
436 : _address((address) addr), |
326 _hi32 = (intptr_t)a >> 32; // top 32 bits in 64 bit word |
437 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
327 _low32 = (intptr_t)a & ~0; // low 32 bits in 64 bit word |
438 |
328 #endif |
439 AddressLiteral(double* addr, relocInfo::relocType rtype = relocInfo::none) |
329 _hi = (intptr_t)a & ~0x3ff; // top 22 bits |
440 : _address((address) addr), |
330 _disp = (intptr_t)a & 0x3ff; // bottom 10 bits |
441 _rspec(rspec_from_rtype(rtype, (address) addr)) {} |
331 } |
442 |
332 |
443 intptr_t value() const { return (intptr_t) _address; } |
333 Address(Register b, intptr_t h, intptr_t d, RelocationHolder const& rspec = RelocationHolder()) |
444 int low10() const; |
334 : _rspec(rspec) |
445 |
335 { |
446 const relocInfo::relocType rtype() const { return _rspec.type(); } |
336 _base = b; |
447 const RelocationHolder& rspec() const { return _rspec; } |
337 #ifdef _LP64 |
448 |
338 // [RGV] Put in Assert to force me to check usage of this constructor |
449 RelocationHolder rspec(int offset) const { |
339 assert( h == 0, "Check usage of this constructor" ); |
|
340 _hi32 = h; |
|
341 _low32 = d; |
|
342 _hi = h; |
|
343 _disp = d; |
|
344 #else |
|
345 _hi = h; |
|
346 _disp = d; |
|
347 #endif |
|
348 } |
|
349 |
|
350 Address() |
|
351 : _rspec(RelocationHolder()) |
|
352 { |
|
353 _base = G0; |
|
354 #ifdef _LP64 |
|
355 _hi32 = 0; |
|
356 _low32 = 0; |
|
357 #endif |
|
358 _hi = 0; |
|
359 _disp = 0; |
|
360 } |
|
361 |
|
362 // fancier constructors |
|
363 |
|
364 enum addr_type { |
|
365 extra_in_argument, // in the In registers |
|
366 extra_out_argument // in the Outs |
|
367 }; |
|
368 |
|
369 Address( addr_type, int ); |
|
370 |
|
371 // accessors |
|
372 |
|
373 Register base() const { return _base; } |
|
374 #ifdef _LP64 |
|
375 int hi32() const { return _hi32; } |
|
376 int low32() const { return _low32; } |
|
377 #endif |
|
378 int hi() const { return _hi; } |
|
379 int disp() const { return _disp; } |
|
380 #ifdef _LP64 |
|
381 intptr_t value() const { return ((intptr_t)_hi32 << 32) | |
|
382 (intptr_t)(uint32_t)_low32; } |
|
383 #else |
|
384 int value() const { return _hi | _disp; } |
|
385 #endif |
|
386 const relocInfo::relocType rtype() { return _rspec.type(); } |
|
387 const RelocationHolder& rspec() { return _rspec; } |
|
388 |
|
389 RelocationHolder rspec(int offset) const { |
|
390 return offset == 0 ? _rspec : _rspec.plus(offset); |
450 return offset == 0 ? _rspec : _rspec.plus(offset); |
391 } |
451 } |
392 |
|
393 inline bool is_simm13(int offset = 0); // check disp+offset for overflow |
|
394 |
|
395 Address plus_disp(int disp) const { // bump disp by a small amount |
|
396 Address a = (*this); |
|
397 a._disp += disp; |
|
398 return a; |
|
399 } |
|
400 |
|
401 Address split_disp() const { // deal with disp overflow |
|
402 Address a = (*this); |
|
403 int hi_disp = _disp & ~0x3ff; |
|
404 if (hi_disp != 0) { |
|
405 a._disp -= hi_disp; |
|
406 a._hi += hi_disp; |
|
407 } |
|
408 return a; |
|
409 } |
|
410 |
|
411 Address after_save() const { |
|
412 Address a = (*this); |
|
413 a._base = a._base->after_save(); |
|
414 return a; |
|
415 } |
|
416 |
|
417 Address after_restore() const { |
|
418 Address a = (*this); |
|
419 a._base = a._base->after_restore(); |
|
420 return a; |
|
421 } |
|
422 |
|
423 friend class Assembler; |
|
424 }; |
452 }; |
425 |
453 |
426 |
454 |
427 inline Address RegisterImpl::address_in_saved_window() const { |
455 inline Address RegisterImpl::address_in_saved_window() const { |
428 return (Address(SP, 0, (sp_offset_in_saved_window() * wordSize) + STACK_BIAS)); |
456 return (Address(SP, (sp_offset_in_saved_window() * wordSize) + STACK_BIAS)); |
429 } |
457 } |
430 |
458 |
431 |
459 |
432 |
460 |
433 // Argument is an abstraction used to represent an outgoing |
461 // Argument is an abstraction used to represent an outgoing |
1091 public: |
1116 public: |
1092 // instructions, refer to page numbers in the SPARC Architecture Manual, V9 |
1117 // instructions, refer to page numbers in the SPARC Architecture Manual, V9 |
1093 |
1118 |
1094 // pp 135 (addc was addx in v8) |
1119 // pp 135 (addc was addx in v8) |
1095 |
1120 |
1096 inline void add( Register s1, Register s2, Register d ); |
1121 inline void add(Register s1, Register s2, Register d ); |
1097 inline void add( Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none); |
1122 inline void add(Register s1, int simm13a, Register d, relocInfo::relocType rtype = relocInfo::none); |
1098 inline void add( Register s1, int simm13a, Register d, RelocationHolder const& rspec); |
1123 inline void add(Register s1, int simm13a, Register d, RelocationHolder const& rspec); |
1099 inline void add( Register s1, RegisterOrConstant s2, Register d, int offset = 0); |
1124 inline void add(Register s1, RegisterOrConstant s2, Register d, int offset = 0); |
1100 inline void add( const Address& a, Register d, int offset = 0); |
1125 inline void add(const Address& a, Register d, int offset = 0) { add( a.base(), a.disp() + offset, d, a.rspec(offset)); } |
1101 |
1126 |
1102 void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } |
1127 void addcc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } |
1103 void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } |
1128 void addcc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } |
1104 void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } |
1129 void addc( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } |
1105 void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } |
1130 void addc( Register s1, int simm13a, Register d ) { emit_long( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } |
1250 // pp 170 |
1275 // pp 170 |
1251 |
1276 |
1252 void jmpl( Register s1, Register s2, Register d ); |
1277 void jmpl( Register s1, Register s2, Register d ); |
1253 void jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec = RelocationHolder() ); |
1278 void jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec = RelocationHolder() ); |
1254 |
1279 |
1255 inline void jmpl( Address& a, Register d, int offset = 0); |
|
1256 |
|
1257 // 171 |
1280 // 171 |
1258 |
1281 |
1259 inline void ldf( FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d ); |
1282 inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d); |
1260 inline void ldf( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ); |
1283 inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder()); |
1261 |
1284 |
1262 inline void ldf( FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset = 0); |
1285 inline void ldf(FloatRegisterImpl::Width w, const Address& a, FloatRegister d, int offset = 0); |
1263 |
1286 |
1264 |
1287 |
1265 inline void ldfsr( Register s1, Register s2 ); |
1288 inline void ldfsr( Register s1, Register s2 ); |
1266 inline void ldfsr( Register s1, int simm13a); |
1289 inline void ldfsr( Register s1, int simm13a); |
1267 inline void ldxfsr( Register s1, Register s2 ); |
1290 inline void ldxfsr( Register s1, Register s2 ); |
1301 inline void ld( Register s1, Register s2, Register d ); |
1324 inline void ld( Register s1, Register s2, Register d ); |
1302 inline void ld( Register s1, int simm13a, Register d); |
1325 inline void ld( Register s1, int simm13a, Register d); |
1303 inline void ldd( Register s1, Register s2, Register d ); |
1326 inline void ldd( Register s1, Register s2, Register d ); |
1304 inline void ldd( Register s1, int simm13a, Register d); |
1327 inline void ldd( Register s1, int simm13a, Register d); |
1305 |
1328 |
1306 inline void ldsb( const Address& a, Register d, int offset = 0 ); |
1329 #ifdef ASSERT |
1307 inline void ldsh( const Address& a, Register d, int offset = 0 ); |
1330 // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
1308 inline void ldsw( const Address& a, Register d, int offset = 0 ); |
1331 inline void ld( Register s1, ByteSize simm13a, Register d); |
1309 inline void ldub( const Address& a, Register d, int offset = 0 ); |
1332 #endif |
1310 inline void lduh( const Address& a, Register d, int offset = 0 ); |
1333 |
1311 inline void lduw( const Address& a, Register d, int offset = 0 ); |
1334 inline void ldsb(const Address& a, Register d, int offset = 0); |
1312 inline void ldx( const Address& a, Register d, int offset = 0 ); |
1335 inline void ldsh(const Address& a, Register d, int offset = 0); |
1313 inline void ld( const Address& a, Register d, int offset = 0 ); |
1336 inline void ldsw(const Address& a, Register d, int offset = 0); |
1314 inline void ldd( const Address& a, Register d, int offset = 0 ); |
1337 inline void ldub(const Address& a, Register d, int offset = 0); |
|
1338 inline void lduh(const Address& a, Register d, int offset = 0); |
|
1339 inline void lduw(const Address& a, Register d, int offset = 0); |
|
1340 inline void ldx( const Address& a, Register d, int offset = 0); |
|
1341 inline void ld( const Address& a, Register d, int offset = 0); |
|
1342 inline void ldd( const Address& a, Register d, int offset = 0); |
1315 |
1343 |
1316 inline void ldub( Register s1, RegisterOrConstant s2, Register d ); |
1344 inline void ldub( Register s1, RegisterOrConstant s2, Register d ); |
1317 inline void ldsb( Register s1, RegisterOrConstant s2, Register d ); |
1345 inline void ldsb( Register s1, RegisterOrConstant s2, Register d ); |
1318 inline void lduh( Register s1, RegisterOrConstant s2, Register d ); |
1346 inline void lduh( Register s1, RegisterOrConstant s2, Register d ); |
1319 inline void ldsh( Register s1, RegisterOrConstant s2, Register d ); |
1347 inline void ldsh( Register s1, RegisterOrConstant s2, Register d ); |
1534 inline void stx( Register d, Register s1, Register s2 ); |
1562 inline void stx( Register d, Register s1, Register s2 ); |
1535 inline void stx( Register d, Register s1, int simm13a); |
1563 inline void stx( Register d, Register s1, int simm13a); |
1536 inline void std( Register d, Register s1, Register s2 ); |
1564 inline void std( Register d, Register s1, Register s2 ); |
1537 inline void std( Register d, Register s1, int simm13a); |
1565 inline void std( Register d, Register s1, int simm13a); |
1538 |
1566 |
|
1567 #ifdef ASSERT |
|
1568 // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
|
1569 inline void st( Register d, Register s1, ByteSize simm13a); |
|
1570 #endif |
|
1571 |
1539 inline void stb( Register d, const Address& a, int offset = 0 ); |
1572 inline void stb( Register d, const Address& a, int offset = 0 ); |
1540 inline void sth( Register d, const Address& a, int offset = 0 ); |
1573 inline void sth( Register d, const Address& a, int offset = 0 ); |
1541 inline void stw( Register d, const Address& a, int offset = 0 ); |
1574 inline void stw( Register d, const Address& a, int offset = 0 ); |
1542 inline void stx( Register d, const Address& a, int offset = 0 ); |
1575 inline void stx( Register d, const Address& a, int offset = 0 ); |
1543 inline void st( Register d, const Address& a, int offset = 0 ); |
1576 inline void st( Register d, const Address& a, int offset = 0 ); |
1682 // Instructions for which a 'better' code sequence exists depending |
1715 // Instructions for which a 'better' code sequence exists depending |
1683 // on arguments should also go in here. |
1716 // on arguments should also go in here. |
1684 |
1717 |
1685 #define JMP2(r1, r2) jmp(r1, r2, __FILE__, __LINE__) |
1718 #define JMP2(r1, r2) jmp(r1, r2, __FILE__, __LINE__) |
1686 #define JMP(r1, off) jmp(r1, off, __FILE__, __LINE__) |
1719 #define JMP(r1, off) jmp(r1, off, __FILE__, __LINE__) |
1687 #define JUMP(a, off) jump(a, off, __FILE__, __LINE__) |
1720 #define JUMP(a, temp, off) jump(a, temp, off, __FILE__, __LINE__) |
1688 #define JUMPL(a, d, off) jumpl(a, d, off, __FILE__, __LINE__) |
1721 #define JUMPL(a, temp, d, off) jumpl(a, temp, d, off, __FILE__, __LINE__) |
1689 |
1722 |
1690 |
1723 |
1691 class MacroAssembler: public Assembler { |
1724 class MacroAssembler: public Assembler { |
1692 protected: |
1725 protected: |
1693 // Support for VM calls |
1726 // Support for VM calls |
1828 #ifndef PRODUCT |
1861 #ifndef PRODUCT |
1829 static void pd_print_patched_instruction(address branch); |
1862 static void pd_print_patched_instruction(address branch); |
1830 #endif |
1863 #endif |
1831 |
1864 |
1832 // sethi Macro handles optimizations and relocations |
1865 // sethi Macro handles optimizations and relocations |
1833 void sethi( Address& a, bool ForceRelocatable = false ); |
1866 private: |
1834 void sethi( intptr_t imm22a, Register d, bool ForceRelocatable = false, RelocationHolder const& rspec = RelocationHolder()); |
1867 void internal_sethi(const AddressLiteral& addrlit, Register d, bool ForceRelocatable); |
|
1868 public: |
|
1869 void sethi(const AddressLiteral& addrlit, Register d); |
|
1870 void patchable_sethi(const AddressLiteral& addrlit, Register d); |
1835 |
1871 |
1836 // compute the size of a sethi/set |
1872 // compute the size of a sethi/set |
1837 static int size_of_sethi( address a, bool worst_case = false ); |
1873 static int size_of_sethi( address a, bool worst_case = false ); |
1838 static int worst_case_size_of_set(); |
1874 static int worst_case_size_of_set(); |
1839 |
1875 |
1840 // set may be either setsw or setuw (high 32 bits may be zero or sign) |
1876 // set may be either setsw or setuw (high 32 bits may be zero or sign) |
1841 void set( intptr_t value, Register d, RelocationHolder const& rspec = RelocationHolder() ); |
1877 private: |
1842 void setsw( int value, Register d, RelocationHolder const& rspec = RelocationHolder() ); |
1878 void internal_set(const AddressLiteral& al, Register d, bool ForceRelocatable); |
1843 void set64( jlong value, Register d, Register tmp); |
1879 public: |
|
1880 void set(const AddressLiteral& addrlit, Register d); |
|
1881 void set(intptr_t value, Register d); |
|
1882 void set(address addr, Register d, RelocationHolder const& rspec); |
|
1883 void patchable_set(const AddressLiteral& addrlit, Register d); |
|
1884 void patchable_set(intptr_t value, Register d); |
|
1885 void set64(jlong value, Register d, Register tmp); |
1844 |
1886 |
1845 // sign-extend 32 to 64 |
1887 // sign-extend 32 to 64 |
1846 inline void signx( Register s, Register d ) { sra( s, G0, d); } |
1888 inline void signx( Register s, Register d ) { sra( s, G0, d); } |
1847 inline void signx( Register d ) { sra( d, G0, d); } |
1889 inline void signx( Register d ) { sra( d, G0, d); } |
1848 |
1890 |
1928 } |
1970 } |
1929 |
1971 |
1930 inline void mov( int simm13a, Register d) { or3( G0, simm13a, d); } |
1972 inline void mov( int simm13a, Register d) { or3( G0, simm13a, d); } |
1931 |
1973 |
1932 // address pseudos: make these names unlike instruction names to avoid confusion |
1974 // address pseudos: make these names unlike instruction names to avoid confusion |
1933 inline void split_disp( Address& a, Register temp ); |
|
1934 inline intptr_t load_pc_address( Register reg, int bytes_to_skip ); |
1975 inline intptr_t load_pc_address( Register reg, int bytes_to_skip ); |
1935 inline void load_address( Address& a, int offset = 0 ); |
1976 inline void load_contents(AddressLiteral& addrlit, Register d, int offset = 0); |
1936 inline void load_contents( Address& a, Register d, int offset = 0 ); |
1977 inline void load_ptr_contents(AddressLiteral& addrlit, Register d, int offset = 0); |
1937 inline void load_ptr_contents( Address& a, Register d, int offset = 0 ); |
1978 inline void store_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0); |
1938 inline void store_contents( Register s, Address& a, int offset = 0 ); |
1979 inline void store_ptr_contents(Register s, AddressLiteral& addrlit, Register temp, int offset = 0); |
1939 inline void store_ptr_contents( Register s, Address& a, int offset = 0 ); |
1980 inline void jumpl_to(AddressLiteral& addrlit, Register temp, Register d, int offset = 0); |
1940 inline void jumpl_to( Address& a, Register d, int offset = 0 ); |
1981 inline void jump_to(AddressLiteral& addrlit, Register temp, int offset = 0); |
1941 inline void jump_to( Address& a, int offset = 0 ); |
1982 inline void jump_indirect_to(Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0); |
1942 inline void jump_indirect_to( Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0 ); |
|
1943 |
1983 |
1944 // ring buffer traceable jumps |
1984 // ring buffer traceable jumps |
1945 |
1985 |
1946 void jmp2( Register r1, Register r2, const char* file, int line ); |
1986 void jmp2( Register r1, Register r2, const char* file, int line ); |
1947 void jmp ( Register r1, int offset, const char* file, int line ); |
1987 void jmp ( Register r1, int offset, const char* file, int line ); |
1948 |
1988 |
1949 void jumpl( Address& a, Register d, int offset, const char* file, int line ); |
1989 void jumpl(AddressLiteral& addrlit, Register temp, Register d, int offset, const char* file, int line); |
1950 void jump ( Address& a, int offset, const char* file, int line ); |
1990 void jump (AddressLiteral& addrlit, Register temp, int offset, const char* file, int line); |
1951 |
1991 |
1952 |
1992 |
1953 // argument pseudos: |
1993 // argument pseudos: |
1954 |
1994 |
1955 inline void load_argument( Argument& a, Register d ); |
1995 inline void load_argument( Argument& a, Register d ); |
1970 // -------------------------------------------------- |
2010 // -------------------------------------------------- |
1971 |
2011 |
1972 // Functions for isolating 64 bit loads for LP64 |
2012 // Functions for isolating 64 bit loads for LP64 |
1973 // ld_ptr will perform ld for 32 bit VM's and ldx for 64 bit VM's |
2013 // ld_ptr will perform ld for 32 bit VM's and ldx for 64 bit VM's |
1974 // st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's |
2014 // st_ptr will perform st for 32 bit VM's and stx for 64 bit VM's |
1975 inline void ld_ptr( Register s1, Register s2, Register d ); |
2015 inline void ld_ptr(Register s1, Register s2, Register d); |
1976 inline void ld_ptr( Register s1, int simm13a, Register d); |
2016 inline void ld_ptr(Register s1, int simm13a, Register d); |
1977 inline void ld_ptr( Register s1, RegisterOrConstant s2, Register d ); |
2017 inline void ld_ptr(Register s1, RegisterOrConstant s2, Register d); |
1978 inline void ld_ptr( const Address& a, Register d, int offset = 0 ); |
2018 inline void ld_ptr(const Address& a, Register d, int offset = 0); |
1979 inline void st_ptr( Register d, Register s1, Register s2 ); |
2019 inline void st_ptr(Register d, Register s1, Register s2); |
1980 inline void st_ptr( Register d, Register s1, int simm13a); |
2020 inline void st_ptr(Register d, Register s1, int simm13a); |
1981 inline void st_ptr( Register d, Register s1, RegisterOrConstant s2 ); |
2021 inline void st_ptr(Register d, Register s1, RegisterOrConstant s2); |
1982 inline void st_ptr( Register d, const Address& a, int offset = 0 ); |
2022 inline void st_ptr(Register d, const Address& a, int offset = 0); |
|
2023 |
|
2024 #ifdef ASSERT |
|
2025 // ByteSize is only a class when ASSERT is defined, otherwise it's an int. |
|
2026 inline void ld_ptr(Register s1, ByteSize simm13a, Register d); |
|
2027 inline void st_ptr(Register d, Register s1, ByteSize simm13a); |
|
2028 #endif |
1983 |
2029 |
1984 // ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's |
2030 // ld_long will perform ld for 32 bit VM's and ldx for 64 bit VM's |
1985 // st_long will perform st for 32 bit VM's and stx for 64 bit VM's |
2031 // st_long will perform st for 32 bit VM's and stx for 64 bit VM's |
1986 inline void ld_long( Register s1, Register s2, Register d ); |
2032 inline void ld_long(Register s1, Register s2, Register d); |
1987 inline void ld_long( Register s1, int simm13a, Register d ); |
2033 inline void ld_long(Register s1, int simm13a, Register d); |
1988 inline void ld_long( Register s1, RegisterOrConstant s2, Register d ); |
2034 inline void ld_long(Register s1, RegisterOrConstant s2, Register d); |
1989 inline void ld_long( const Address& a, Register d, int offset = 0 ); |
2035 inline void ld_long(const Address& a, Register d, int offset = 0); |
1990 inline void st_long( Register d, Register s1, Register s2 ); |
2036 inline void st_long(Register d, Register s1, Register s2); |
1991 inline void st_long( Register d, Register s1, int simm13a ); |
2037 inline void st_long(Register d, Register s1, int simm13a); |
1992 inline void st_long( Register d, Register s1, RegisterOrConstant s2 ); |
2038 inline void st_long(Register d, Register s1, RegisterOrConstant s2); |
1993 inline void st_long( Register d, const Address& a, int offset = 0 ); |
2039 inline void st_long(Register d, const Address& a, int offset = 0); |
1994 |
|
1995 // Loading values by size and signed-ness |
|
1996 void load_sized_value(Register s1, RegisterOrConstant s2, Register d, |
|
1997 int size_in_bytes, bool is_signed); |
|
1998 |
2040 |
1999 // Helpers for address formation. |
2041 // Helpers for address formation. |
2000 // They update the dest in place, whether it is a register or constant. |
2042 // They update the dest in place, whether it is a register or constant. |
2001 // They emit no code at all if src is a constant zero. |
2043 // They emit no code at all if src is a constant zero. |
2002 // If dest is a constant and src is a register, the temp argument |
2044 // If dest is a constant and src is a register, the temp argument |
2047 |
2089 |
2048 // Manipulation of C++ bools |
2090 // Manipulation of C++ bools |
2049 // These are idioms to flag the need for care with accessing bools but on |
2091 // These are idioms to flag the need for care with accessing bools but on |
2050 // this platform we assume byte size |
2092 // this platform we assume byte size |
2051 |
2093 |
2052 inline void stbool( Register d, const Address& a, int offset = 0 ) { stb(d, a, offset); } |
2094 inline void stbool(Register d, const Address& a) { stb(d, a); } |
2053 inline void ldbool( const Address& a, Register d, int offset = 0 ) { ldsb( a, d, offset ); } |
2095 inline void ldbool(const Address& a, Register d) { ldsb(a, d); } |
2054 inline void tstbool( Register s ) { tst(s); } |
2096 inline void tstbool( Register s ) { tst(s); } |
2055 inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } |
2097 inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } |
2056 |
2098 |
2057 // klass oop manipulations if compressed |
2099 // klass oop manipulations if compressed |
2058 void load_klass(Register src_oop, Register klass); |
2100 void load_klass(Register src_oop, Register klass); |
2059 void store_klass(Register klass, Register dst_oop); |
2101 void store_klass(Register klass, Register dst_oop); |
2060 void store_klass_gap(Register s, Register dst_oop); |
2102 void store_klass_gap(Register s, Register dst_oop); |
2061 |
2103 |
2062 // oop manipulations |
2104 // oop manipulations |
2063 void load_heap_oop(const Address& s, Register d, int offset = 0); |
2105 void load_heap_oop(const Address& s, Register d); |
2064 void load_heap_oop(Register s1, Register s2, Register d); |
2106 void load_heap_oop(Register s1, Register s2, Register d); |
2065 void load_heap_oop(Register s1, int simm13a, Register d); |
2107 void load_heap_oop(Register s1, int simm13a, Register d); |
2066 void store_heap_oop(Register d, Register s1, Register s2); |
2108 void store_heap_oop(Register d, Register s1, Register s2); |
2067 void store_heap_oop(Register d, Register s1, int simm13a); |
2109 void store_heap_oop(Register d, Register s1, int simm13a); |
2068 void store_heap_oop(Register d, const Address& a, int offset = 0); |
2110 void store_heap_oop(Register d, const Address& a, int offset = 0); |
2188 void unimplemented(const char* what = "") { char* b = new char[1024]; sprintf(b, "unimplemented: %s", what); stop(b); } |
2230 void unimplemented(const char* what = "") { char* b = new char[1024]; sprintf(b, "unimplemented: %s", what); stop(b); } |
2189 void should_not_reach_here() { stop("should not reach here"); } |
2231 void should_not_reach_here() { stop("should not reach here"); } |
2190 void print_CPU_state(); |
2232 void print_CPU_state(); |
2191 |
2233 |
2192 // oops in code |
2234 // oops in code |
2193 Address allocate_oop_address( jobject obj, Register d ); // allocate_index |
2235 AddressLiteral allocate_oop_address(jobject obj); // allocate_index |
2194 Address constant_oop_address( jobject obj, Register d ); // find_index |
2236 AddressLiteral constant_oop_address(jobject obj); // find_index |
2195 inline void set_oop ( jobject obj, Register d ); // uses allocate_oop_address |
2237 inline void set_oop (jobject obj, Register d); // uses allocate_oop_address |
2196 inline void set_oop_constant( jobject obj, Register d ); // uses constant_oop_address |
2238 inline void set_oop_constant (jobject obj, Register d); // uses constant_oop_address |
2197 inline void set_oop ( Address obj_addr ); // same as load_address |
2239 inline void set_oop (AddressLiteral& obj_addr, Register d); // same as load_address |
2198 |
2240 |
2199 void set_narrow_oop( jobject obj, Register d ); |
2241 void set_narrow_oop( jobject obj, Register d ); |
2200 |
2242 |
2201 // nop padding |
2243 // nop padding |
2202 void align(int modulus); |
2244 void align(int modulus); |