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