Mercurial > hg > graal-jvmci-8
comparison src/cpu/sparc/vm/assembler_sparc.hpp @ 727:6b2273dd6fa9
6822110: Add AddressLiteral class on SPARC
Summary: The Address class on SPARC currently handles both, addresses and address literals, what makes the Address class more complicated than it has to be.
Reviewed-by: never, kvn
author | twisti |
---|---|
date | Tue, 21 Apr 2009 11:16:30 -0700 |
parents | e5b0439ef4ae |
children | 62001a362ce9 |
comparison
equal
deleted
inserted
replaced
725:928912ce8438 | 727:6b2273dd6fa9 |
---|---|
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 |
493 } | 521 } |
494 | 522 |
495 // When applied to a register-based argument, give the corresponding address | 523 // When applied to a register-based argument, give the corresponding address |
496 // into the 6-word area "into which callee may store register arguments" | 524 // into the 6-word area "into which callee may store register arguments" |
497 // (This is a different place than the corresponding register-save area location.) | 525 // (This is a different place than the corresponding register-save area location.) |
498 Address address_in_frame() const { | 526 Address address_in_frame() const; |
499 return Address( is_in() ? Address::extra_in_argument | |
500 : Address::extra_out_argument, | |
501 _number ); | |
502 } | |
503 | 527 |
504 // debugging | 528 // debugging |
505 const char* name() const; | 529 const char* name() const; |
506 | 530 |
507 friend class Assembler; | 531 friend class Assembler; |
519 static int patched_branch(int dest_pos, int inst, int inst_pos); | 543 static int patched_branch(int dest_pos, int inst, int inst_pos); |
520 static int branch_destination(int inst, int pos); | 544 static int branch_destination(int inst, int pos); |
521 | 545 |
522 | 546 |
523 friend class AbstractAssembler; | 547 friend class AbstractAssembler; |
548 friend class AddressLiteral; | |
524 | 549 |
525 // code patchers need various routines like inv_wdisp() | 550 // code patchers need various routines like inv_wdisp() |
526 friend class NativeInstruction; | 551 friend class NativeInstruction; |
527 friend class NativeGeneralJump; | 552 friend class NativeGeneralJump; |
528 friend class Relocation; | 553 friend class Relocation; |
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); |
2408 | 2450 |
2409 // Helper functions for statistics gathering. | 2451 // Helper functions for statistics gathering. |
2410 // Conditionally (non-atomically) increments passed counter address, preserving condition codes. | 2452 // Conditionally (non-atomically) increments passed counter address, preserving condition codes. |
2411 void cond_inc(Condition cond, address counter_addr, Register Rtemp1, Register Rtemp2); | 2453 void cond_inc(Condition cond, address counter_addr, Register Rtemp1, Register Rtemp2); |
2412 // Unconditional increment. | 2454 // Unconditional increment. |
2413 void inc_counter(address counter_addr, Register Rtemp1, Register Rtemp2); | 2455 void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2); |
2456 void inc_counter(int* counter_addr, Register Rtmp1, Register Rtmp2); | |
2414 | 2457 |
2415 #undef VIRTUAL | 2458 #undef VIRTUAL |
2416 | 2459 |
2417 }; | 2460 }; |
2418 | 2461 |