< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Print this page

 438 
 439   WRAP(madd) WRAP(msub) WRAP(maddw) WRAP(msubw)
 440   WRAP(smaddl) WRAP(smsubl) WRAP(umaddl) WRAP(umsubl)
 441 #undef WRAP
 442 
 443 
 444   // macro assembly operations needed for aarch64
 445 
 446   // first two private routines for loading 32 bit or 64 bit constants
 447 private:
 448 
 449   void mov_immediate64(Register dst, uint64_t imm64);
 450   void mov_immediate32(Register dst, uint32_t imm32);
 451 
 452   int push(unsigned int bitset, Register stack);
 453   int pop(unsigned int bitset, Register stack);
 454 
 455   int push_fp(unsigned int bitset, Register stack);
 456   int pop_fp(unsigned int bitset, Register stack);
 457 



 458   void mov(Register dst, Address a);
 459 
 460 public:
 461   void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
 462   void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
 463 
 464   void push_fp(FloatRegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
 465   void pop_fp(FloatRegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
 466 
 467   static RegSet call_clobbered_registers();
 468 



 469   // Push and pop everything that might be clobbered by a native
 470   // runtime call except rscratch1 and rscratch2.  (They are always
 471   // scratch, so we don't have to protect them.)  Only save the lower
 472   // 64 bits of each vector register. Additonal registers can be excluded
 473   // in a passed RegSet.
 474   void push_call_clobbered_registers_except(RegSet exclude);
 475   void pop_call_clobbered_registers_except(RegSet exclude);
 476 
 477   void push_call_clobbered_registers() {
 478     push_call_clobbered_registers_except(RegSet());
 479   }
 480   void pop_call_clobbered_registers() {
 481     pop_call_clobbered_registers_except(RegSet());
 482   }
 483 
 484 
 485   // now mov instructions for loading absolute addresses and 32 or
 486   // 64 bit integers
 487 
 488   inline void mov(Register dst, address addr)             { mov_immediate64(dst, (uint64_t)addr); }

 848   void encode_heap_oop_not_null(Register r);
 849   void decode_heap_oop_not_null(Register r);
 850   void encode_heap_oop_not_null(Register dst, Register src);
 851   void decode_heap_oop_not_null(Register dst, Register src);
 852 
 853   void set_narrow_oop(Register dst, jobject obj);
 854 
 855   void encode_klass_not_null(Register r);
 856   void decode_klass_not_null(Register r);
 857   void encode_klass_not_null(Register dst, Register src);
 858   void decode_klass_not_null(Register dst, Register src);
 859 
 860   void set_narrow_klass(Register dst, Klass* k);
 861 
 862   // if heap base register is used - reinit it with the correct value
 863   void reinit_heapbase();
 864 
 865   DEBUG_ONLY(void verify_heapbase(const char* msg);)
 866 
 867   void push_CPU_state(bool save_vectors = false, bool use_sve = false,
 868                       int sve_vector_size_in_bytes = 0);
 869   void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
 870                       int sve_vector_size_in_bytes = 0);
 871 
 872   // Round up to a power of two
 873   void round_to(Register reg, int modulus);
 874 
 875   // allocation
 876   void eden_allocate(
 877     Register obj,                      // result: pointer to object after successful allocation
 878     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
 879     int      con_size_in_bytes,        // object size in bytes if   known at compile time
 880     Register t1,                       // temp register
 881     Label&   slow_case                 // continuation point if fast allocation fails
 882   );
 883   void tlab_allocate(
 884     Register obj,                      // result: pointer to object after successful allocation
 885     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
 886     int      con_size_in_bytes,        // object size in bytes if   known at compile time
 887     Register t1,                       // temp register
 888     Register t2,                       // temp register
 889     Label&   slow_case                 // continuation point if fast allocation fails
 890   );

1348   // Check whether two loads/stores can be merged into ldp/stp.
1349   bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
1350 
1351   // Merge current load/store with previous load/store into ldp/stp.
1352   void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1353 
1354   // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
1355   bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1356 
1357 public:
1358   void spill(Register Rx, bool is64, int offset) {
1359     if (is64) {
1360       str(Rx, spill_address(8, offset));
1361     } else {
1362       strw(Rx, spill_address(4, offset));
1363     }
1364   }
1365   void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1366     str(Vx, T, spill_address(1 << (int)T, offset));
1367   }

1368   void spill_sve_vector(FloatRegister Zx, int offset, int vector_reg_size_in_bytes) {
1369     sve_str(Zx, sve_spill_address(vector_reg_size_in_bytes, offset));
1370   }




1371   void unspill(Register Rx, bool is64, int offset) {
1372     if (is64) {
1373       ldr(Rx, spill_address(8, offset));
1374     } else {
1375       ldrw(Rx, spill_address(4, offset));
1376     }
1377   }
1378   void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1379     ldr(Vx, T, spill_address(1 << (int)T, offset));
1380   }

1381   void unspill_sve_vector(FloatRegister Zx, int offset, int vector_reg_size_in_bytes) {
1382     sve_ldr(Zx, sve_spill_address(vector_reg_size_in_bytes, offset));
1383   }




1384   void spill_copy128(int src_offset, int dst_offset,
1385                      Register tmp1=rscratch1, Register tmp2=rscratch2) {
1386     if (src_offset < 512 && (src_offset & 7) == 0 &&
1387         dst_offset < 512 && (dst_offset & 7) == 0) {
1388       ldp(tmp1, tmp2, Address(sp, src_offset));
1389       stp(tmp1, tmp2, Address(sp, dst_offset));
1390     } else {
1391       unspill(tmp1, true, src_offset);
1392       spill(tmp1, true, dst_offset);
1393       unspill(tmp1, true, src_offset+8);
1394       spill(tmp1, true, dst_offset+8);
1395     }
1396   }
1397   void spill_copy_sve_vector_stack_to_stack(int src_offset, int dst_offset,
1398                                             int sve_vec_reg_size_in_bytes) {
1399     assert(sve_vec_reg_size_in_bytes % 16 == 0, "unexpected sve vector reg size");
1400     for (int i = 0; i < sve_vec_reg_size_in_bytes / 16; i++) {
1401       spill_copy128(src_offset, dst_offset);
1402       src_offset += 16;
1403       dst_offset += 16;
1404     }
1405   }






1406   void cache_wb(Address line);
1407   void cache_wbsync(bool is_pre);
1408 
1409 private:
1410   // Check the current thread doesn't need a cross modify fence.
1411   void verify_cross_modify_fence_not_required() PRODUCT_RETURN;
1412 
1413 };
1414 
1415 #ifdef ASSERT
1416 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1417 #endif
1418 
1419 /**
1420  * class SkipIfEqual:
1421  *
1422  * Instantiating this class will result in assembly code being output that will
1423  * jump around any code emitted between the creation of the instance and it's
1424  * automatic destruction at the end of a scope block, depending on the value of
1425  * the flag passed to the constructor, which will be checked at run-time.

 438 
 439   WRAP(madd) WRAP(msub) WRAP(maddw) WRAP(msubw)
 440   WRAP(smaddl) WRAP(smsubl) WRAP(umaddl) WRAP(umsubl)
 441 #undef WRAP
 442 
 443 
 444   // macro assembly operations needed for aarch64
 445 
 446   // first two private routines for loading 32 bit or 64 bit constants
 447 private:
 448 
 449   void mov_immediate64(Register dst, uint64_t imm64);
 450   void mov_immediate32(Register dst, uint32_t imm32);
 451 
 452   int push(unsigned int bitset, Register stack);
 453   int pop(unsigned int bitset, Register stack);
 454 
 455   int push_fp(unsigned int bitset, Register stack);
 456   int pop_fp(unsigned int bitset, Register stack);
 457 
 458   int push_p(unsigned int bitset, Register stack);
 459   int pop_p(unsigned int bitset, Register stack);
 460 
 461   void mov(Register dst, Address a);
 462 
 463 public:
 464   void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
 465   void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
 466 
 467   void push_fp(FloatRegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
 468   void pop_fp(FloatRegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
 469 
 470   static RegSet call_clobbered_registers();
 471 
 472   void push_p(PRegSet regs, Register stack) { if (regs.bits()) push_p(regs.bits(), stack); }
 473   void pop_p(PRegSet regs, Register stack) { if (regs.bits()) pop_p(regs.bits(), stack); }
 474 
 475   // Push and pop everything that might be clobbered by a native
 476   // runtime call except rscratch1 and rscratch2.  (They are always
 477   // scratch, so we don't have to protect them.)  Only save the lower
 478   // 64 bits of each vector register. Additonal registers can be excluded
 479   // in a passed RegSet.
 480   void push_call_clobbered_registers_except(RegSet exclude);
 481   void pop_call_clobbered_registers_except(RegSet exclude);
 482 
 483   void push_call_clobbered_registers() {
 484     push_call_clobbered_registers_except(RegSet());
 485   }
 486   void pop_call_clobbered_registers() {
 487     pop_call_clobbered_registers_except(RegSet());
 488   }
 489 
 490 
 491   // now mov instructions for loading absolute addresses and 32 or
 492   // 64 bit integers
 493 
 494   inline void mov(Register dst, address addr)             { mov_immediate64(dst, (uint64_t)addr); }

 854   void encode_heap_oop_not_null(Register r);
 855   void decode_heap_oop_not_null(Register r);
 856   void encode_heap_oop_not_null(Register dst, Register src);
 857   void decode_heap_oop_not_null(Register dst, Register src);
 858 
 859   void set_narrow_oop(Register dst, jobject obj);
 860 
 861   void encode_klass_not_null(Register r);
 862   void decode_klass_not_null(Register r);
 863   void encode_klass_not_null(Register dst, Register src);
 864   void decode_klass_not_null(Register dst, Register src);
 865 
 866   void set_narrow_klass(Register dst, Klass* k);
 867 
 868   // if heap base register is used - reinit it with the correct value
 869   void reinit_heapbase();
 870 
 871   DEBUG_ONLY(void verify_heapbase(const char* msg);)
 872 
 873   void push_CPU_state(bool save_vectors = false, bool use_sve = false,
 874                       int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 875   void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
 876                      int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 877 
 878   // Round up to a power of two
 879   void round_to(Register reg, int modulus);
 880 
 881   // allocation
 882   void eden_allocate(
 883     Register obj,                      // result: pointer to object after successful allocation
 884     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
 885     int      con_size_in_bytes,        // object size in bytes if   known at compile time
 886     Register t1,                       // temp register
 887     Label&   slow_case                 // continuation point if fast allocation fails
 888   );
 889   void tlab_allocate(
 890     Register obj,                      // result: pointer to object after successful allocation
 891     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
 892     int      con_size_in_bytes,        // object size in bytes if   known at compile time
 893     Register t1,                       // temp register
 894     Register t2,                       // temp register
 895     Label&   slow_case                 // continuation point if fast allocation fails
 896   );

1354   // Check whether two loads/stores can be merged into ldp/stp.
1355   bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
1356 
1357   // Merge current load/store with previous load/store into ldp/stp.
1358   void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1359 
1360   // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
1361   bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1362 
1363 public:
1364   void spill(Register Rx, bool is64, int offset) {
1365     if (is64) {
1366       str(Rx, spill_address(8, offset));
1367     } else {
1368       strw(Rx, spill_address(4, offset));
1369     }
1370   }
1371   void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1372     str(Vx, T, spill_address(1 << (int)T, offset));
1373   }
1374 
1375   void spill_sve_vector(FloatRegister Zx, int offset, int vector_reg_size_in_bytes) {
1376     sve_str(Zx, sve_spill_address(vector_reg_size_in_bytes, offset));
1377   }
1378   void spill_sve_predicate(PRegister pr, int offset, int predicate_reg_size_in_bytes) {
1379     sve_str(pr, sve_spill_address(predicate_reg_size_in_bytes, offset));
1380   }
1381 
1382   void unspill(Register Rx, bool is64, int offset) {
1383     if (is64) {
1384       ldr(Rx, spill_address(8, offset));
1385     } else {
1386       ldrw(Rx, spill_address(4, offset));
1387     }
1388   }
1389   void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1390     ldr(Vx, T, spill_address(1 << (int)T, offset));
1391   }
1392 
1393   void unspill_sve_vector(FloatRegister Zx, int offset, int vector_reg_size_in_bytes) {
1394     sve_ldr(Zx, sve_spill_address(vector_reg_size_in_bytes, offset));
1395   }
1396   void unspill_sve_predicate(PRegister pr, int offset, int predicate_reg_size_in_bytes) {
1397     sve_ldr(pr, sve_spill_address(predicate_reg_size_in_bytes, offset));
1398   }
1399 
1400   void spill_copy128(int src_offset, int dst_offset,
1401                      Register tmp1=rscratch1, Register tmp2=rscratch2) {
1402     if (src_offset < 512 && (src_offset & 7) == 0 &&
1403         dst_offset < 512 && (dst_offset & 7) == 0) {
1404       ldp(tmp1, tmp2, Address(sp, src_offset));
1405       stp(tmp1, tmp2, Address(sp, dst_offset));
1406     } else {
1407       unspill(tmp1, true, src_offset);
1408       spill(tmp1, true, dst_offset);
1409       unspill(tmp1, true, src_offset+8);
1410       spill(tmp1, true, dst_offset+8);
1411     }
1412   }
1413   void spill_copy_sve_vector_stack_to_stack(int src_offset, int dst_offset,
1414                                             int sve_vec_reg_size_in_bytes) {
1415     assert(sve_vec_reg_size_in_bytes % 16 == 0, "unexpected sve vector reg size");
1416     for (int i = 0; i < sve_vec_reg_size_in_bytes / 16; i++) {
1417       spill_copy128(src_offset, dst_offset);
1418       src_offset += 16;
1419       dst_offset += 16;
1420     }
1421   }
1422   void spill_copy_sve_predicate_stack_to_stack(int src_offset, int dst_offset,
1423                                                int sve_predicate_reg_size_in_bytes) {
1424     sve_ldr(ptrue, sve_spill_address(sve_predicate_reg_size_in_bytes, src_offset));
1425     sve_str(ptrue, sve_spill_address(sve_predicate_reg_size_in_bytes, dst_offset));
1426     reinitialize_ptrue();
1427   }
1428   void cache_wb(Address line);
1429   void cache_wbsync(bool is_pre);
1430 
1431 private:
1432   // Check the current thread doesn't need a cross modify fence.
1433   void verify_cross_modify_fence_not_required() PRODUCT_RETURN;
1434 
1435 };
1436 
1437 #ifdef ASSERT
1438 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1439 #endif
1440 
1441 /**
1442  * class SkipIfEqual:
1443  *
1444  * Instantiating this class will result in assembly code being output that will
1445  * jump around any code emitted between the creation of the instance and it's
1446  * automatic destruction at the end of a scope block, depending on the value of
1447  * the flag passed to the constructor, which will be checked at run-time.
< prev index next >