< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Print this page
8248238: Adding Windows support to OpenJDK on AArch64

Summary: LP64 vs LLP64 changes to add Windows support

Contributed-by: Monica Beckwith <monica.beckwith@microsoft.com>, Ludovic Henry <luhenry@microsoft.com>
Reviewed-by:
8248238: Adding Windows support to OpenJDK on AArch64

Summary: Adding Windows support for AArch64

Contributed-by: Ludovic Henry <luhenry@microsoft.com>, Monica Beckwith <monica.beckwith@microsoft.com>
Reviewed-by:


 175   void membar(Membar_mask_bits order_constraint);
 176 
 177   using Assembler::ldr;
 178   using Assembler::str;
 179   using Assembler::ldrw;
 180   using Assembler::strw;
 181 
 182   void ldr(Register Rx, const Address &adr);
 183   void ldrw(Register Rw, const Address &adr);
 184   void str(Register Rx, const Address &adr);
 185   void strw(Register Rx, const Address &adr);
 186 
 187   // Frame creation and destruction shared between JITs.
 188   void build_frame(int framesize);
 189   void remove_frame(int framesize);
 190 
 191   virtual void _call_Unimplemented(address call_site) {
 192     mov(rscratch2, call_site);
 193   }
 194 



 195 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)

 196 
 197   // aliases defined in AARCH64 spec
 198 
 199   template<class T>
 200   inline void cmpw(Register Rd, T imm)  { subsw(zr, Rd, imm); }
 201 
 202   inline void cmp(Register Rd, unsigned char imm8)  { subs(zr, Rd, imm8); }
 203   inline void cmp(Register Rd, unsigned imm) __attribute__ ((deprecated));
 204 
 205   inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
 206   inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); }
 207 
 208   void cset(Register Rd, Assembler::Condition cond) {
 209     csinc(Rd, zr, zr, ~cond);
 210   }
 211   void csetw(Register Rd, Assembler::Condition cond) {
 212     csincw(Rd, zr, zr, ~cond);
 213   }
 214 
 215   void cneg(Register Rd, Register Rn, Assembler::Condition cond) {
 216     csneg(Rd, Rn, Rn, ~cond);
 217   }
 218   void cnegw(Register Rd, Register Rn, Assembler::Condition cond) {
 219     csnegw(Rd, Rn, Rn, ~cond);
 220   }
 221 
 222   inline void movw(Register Rd, Register Rn) {
 223     if (Rd == sp || Rn == sp) {


 439     umaddl(Rd, Rn, Rm, zr);
 440   }
 441 
 442 #define WRAP(INSN)                                                            \
 443   void INSN(Register Rd, Register Rn, Register Rm, Register Ra) {             \
 444     if ((VM_Version::features() & VM_Version::CPU_A53MAC) && Ra != zr)        \
 445       nop();                                                                  \
 446     Assembler::INSN(Rd, Rn, Rm, Ra);                                          \
 447   }
 448 
 449   WRAP(madd) WRAP(msub) WRAP(maddw) WRAP(msubw)
 450   WRAP(smaddl) WRAP(smsubl) WRAP(umaddl) WRAP(umsubl)
 451 #undef WRAP
 452 
 453 
 454   // macro assembly operations needed for aarch64
 455 
 456   // first two private routines for loading 32 bit or 64 bit constants
 457 private:
 458 
 459   void mov_immediate64(Register dst, u_int64_t imm64);
 460   void mov_immediate32(Register dst, u_int32_t imm32);
 461 
 462   int push(unsigned int bitset, Register stack);
 463   int pop(unsigned int bitset, Register stack);
 464 
 465   int push_fp(unsigned int bitset, Register stack);
 466   int pop_fp(unsigned int bitset, Register stack);
 467 
 468   void mov(Register dst, Address a);
 469 
 470 public:
 471   void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
 472   void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
 473 
 474   void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
 475   void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
 476 
 477   // Push and pop everything that might be clobbered by a native
 478   // runtime call except rscratch1 and rscratch2.  (They are always
 479   // scratch, so we don't have to protect them.)  Only save the lower
 480   // 64 bits of each vector register.
 481   void push_call_clobbered_registers();
 482   void pop_call_clobbered_registers();
 483 
 484   // now mov instructions for loading absolute addresses and 32 or
 485   // 64 bit integers
 486 
 487   inline void mov(Register dst, address addr)
 488   {
 489     mov_immediate64(dst, (u_int64_t)addr);
 490   }
 491 
 492   inline void mov(Register dst, u_int64_t imm64)
 493   {
 494     mov_immediate64(dst, imm64);
 495   }
 496 
 497   inline void movw(Register dst, u_int32_t imm32)
 498   {
 499     mov_immediate32(dst, imm32);
 500   }
 501 
 502   inline void mov(Register dst, long l)
 503   {
 504     mov(dst, (u_int64_t)l);
 505   }
 506 
 507   inline void mov(Register dst, int i)
 508   {
 509     mov(dst, (long)i);
 510   }
 511 
 512   void mov(Register dst, RegisterOrConstant src) {
 513     if (src.is_register())
 514       mov(dst, src.as_register());
 515     else
 516       mov(dst, src.as_constant());
 517   }
 518 
 519   void movptr(Register r, uintptr_t imm64);
 520 
 521   void mov(FloatRegister Vd, SIMD_Arrangement T, u_int32_t imm32);
 522 
 523   void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
 524     orr(Vd, T, Vn, Vn);
 525   }
 526 
 527 public:
 528 
 529   // Generalized Test Bit And Branch, including a "far" variety which
 530   // spans more than 32KiB.
 531   void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) {
 532     assert(cond == EQ || cond == NE, "must be");
 533 
 534     if (far)
 535       cond = ~cond;
 536 
 537     void (Assembler::* branch)(Register Rt, int bitpos, Label &L);
 538     if (cond == Assembler::EQ)
 539       branch = &Assembler::tbz;
 540     else
 541       branch = &Assembler::tbnz;
 542 
 543     if (far) {
 544       Label L;
 545       (this->*branch)(Rt, bitpos, L);
 546       b(dest);
 547       bind(L);
 548     } else {
 549       (this->*branch)(Rt, bitpos, dest);
 550     }
 551   }
 552 
 553   // macro instructions for accessing and updating floating point
 554   // status register
 555   //
 556   // FPSR : op1 == 011
 557   //        CRn == 0100
 558   //        CRm == 0100
 559   //        op2 == 001
 560 
 561   inline void get_fpsr(Register reg)
 562   {
 563     mrs(0b11, 0b0100, 0b0100, 0b001, reg);


1153              enum shift_kind kind, unsigned shift = 0) {                \
1154     Assembler::INSN(Rd, Rn, Rm, kind, shift);                           \
1155   }                                                                     \
1156                                                                         \
1157   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1158     Assembler::INSN(Rd, Rn, Rm);                                        \
1159   }                                                                     \
1160                                                                         \
1161   void INSN(Register Rd, Register Rn, Register Rm,                      \
1162            ext::operation option, int amount = 0) {                     \
1163     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1164   }
1165 
1166   WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1167 
1168   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1169   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1170   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1171   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1172 
1173   void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
1174 
1175   void tableswitch(Register index, jint lowbound, jint highbound,
1176                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1177     adr(rscratch1, jumptable);
1178     subsw(rscratch2, index, lowbound);
1179     subsw(zr, rscratch2, highbound - lowbound);
1180     br(Assembler::HS, jumptable_end);
1181     add(rscratch1, rscratch1, rscratch2,
1182         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1183     br(rscratch1);
1184   }
1185 
1186   // Form an address from base + offset in Rd.  Rd may or may not
1187   // actually be used: you must use the Address that is returned.  It
1188   // is up to you to ensure that the shift provided matches the size
1189   // of your data.
1190   Address form_address(Register Rd, Register base, long byte_offset, int shift);
1191 
1192   // Return true iff an address is within the 48-bit AArch64 address
1193   // space.
1194   bool is_valid_AArch64_address(address a) {
1195     return ((uint64_t)a >> 48) == 0;
1196   }
1197 
1198   // Load the base of the cardtable byte map into reg.
1199   void load_byte_map_base(Register reg);
1200 
1201   // Prolog generator routines to support switch between x86 code and
1202   // generated ARM code
1203 
1204   // routine to generate an x86 prolog for a stub function which
1205   // bootstraps into the generated ARM code which directly follows the
1206   // stub
1207   //
1208 
1209   public:
1210 
1211   void ldr_constant(Register dest, const Address &const_addr) {
1212     if (NearCpool) {
1213       ldr(dest, const_addr);
1214     } else {
1215       unsigned long offset;
1216       adrp(dest, InternalAddress(const_addr.target()), offset);
1217       ldr(dest, Address(dest, offset));
1218     }
1219   }
1220 
1221   address read_polling_page(Register r, relocInfo::relocType rtype);
1222   void get_polling_page(Register dest, relocInfo::relocType rtype);
1223   address fetch_and_read_polling_page(Register r, relocInfo::relocType rtype);
1224 
1225   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1226   void update_byte_crc32(Register crc, Register val, Register table);
1227   void update_word_crc32(Register crc, Register v, Register tmp,
1228         Register table0, Register table1, Register table2, Register table3,
1229         bool upper = false);
1230 
1231   void has_negatives(Register ary1, Register len, Register result);
1232 
1233   void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1234                      Register tmp1, Register tmp2, Register tmp3, int elem_size);
1235 
1236   void string_equals(Register a1, Register a2, Register result, Register cnt1,
1237                      int elem_size);
1238 
1239   void fill_words(Register base, Register cnt, Register value);
1240   void zero_words(Register base, u_int64_t cnt);
1241   void zero_words(Register ptr, Register cnt);
1242   void zero_dcache_blocks(Register base, Register cnt);
1243 
1244   static const int zero_words_block_size;
1245 
1246   void byte_array_inflate(Register src, Register dst, Register len,
1247                           FloatRegister vtmp1, FloatRegister vtmp2,
1248                           FloatRegister vtmp3, Register tmp4);
1249 
1250   void char_array_compress(Register src, Register dst, Register len,
1251                            FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1252                            FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1253                            Register result);
1254 
1255   void encode_iso_array(Register src, Register dst,
1256                         Register len, Register result,
1257                         FloatRegister Vtmp1, FloatRegister Vtmp2,
1258                         FloatRegister Vtmp3, FloatRegister Vtmp4);
1259   void fast_log(FloatRegister vtmp0, FloatRegister vtmp1, FloatRegister vtmp2,
1260                 FloatRegister vtmp3, FloatRegister vtmp4, FloatRegister vtmp5,


1293         Register tmp3);
1294 public:
1295   void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1296                        Register zlen, Register tmp1, Register tmp2, Register tmp3,
1297                        Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1298   void mul_add(Register out, Register in, Register offs, Register len, Register k);
1299   // ISB may be needed because of a safepoint
1300   void maybe_isb() { isb(); }
1301 
1302 private:
1303   // Return the effective address r + (r1 << ext) + offset.
1304   // Uses rscratch2.
1305   Address offsetted_address(Register r, Register r1, Address::extend ext,
1306                             int offset, int size);
1307 
1308 private:
1309   // Returns an address on the stack which is reachable with a ldr/str of size
1310   // Uses rscratch2 if the address is not directly reachable
1311   Address spill_address(int size, int offset, Register tmp=rscratch2);
1312 
1313   bool merge_alignment_check(Register base, size_t size, long cur_offset, long prev_offset) const;
1314 
1315   // Check whether two loads/stores can be merged into ldp/stp.
1316   bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
1317 
1318   // Merge current load/store with previous load/store into ldp/stp.
1319   void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1320 
1321   // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
1322   bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1323 
1324 public:
1325   void spill(Register Rx, bool is64, int offset) {
1326     if (is64) {
1327       str(Rx, spill_address(8, offset));
1328     } else {
1329       strw(Rx, spill_address(4, offset));
1330     }
1331   }
1332   void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1333     str(Vx, T, spill_address(1 << (int)T, offset));




 175   void membar(Membar_mask_bits order_constraint);
 176 
 177   using Assembler::ldr;
 178   using Assembler::str;
 179   using Assembler::ldrw;
 180   using Assembler::strw;
 181 
 182   void ldr(Register Rx, const Address &adr);
 183   void ldrw(Register Rw, const Address &adr);
 184   void str(Register Rx, const Address &adr);
 185   void strw(Register Rx, const Address &adr);
 186 
 187   // Frame creation and destruction shared between JITs.
 188   void build_frame(int framesize);
 189   void remove_frame(int framesize);
 190 
 191   virtual void _call_Unimplemented(address call_site) {
 192     mov(rscratch2, call_site);
 193   }
 194 
 195 #ifdef _WIN64
 196 #define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
 197 #else
 198 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
 199 #endif
 200 
 201   // aliases defined in AARCH64 spec
 202 
 203   template<class T>
 204   inline void cmpw(Register Rd, T imm)  { subsw(zr, Rd, imm); }
 205 
 206   inline void cmp(Register Rd, unsigned char imm8)  { subs(zr, Rd, imm8); }
 207   inline DEPRECATED void cmp(Register Rd, unsigned imm);
 208 
 209   inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); }
 210   inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); }
 211 
 212   void cset(Register Rd, Assembler::Condition cond) {
 213     csinc(Rd, zr, zr, ~cond);
 214   }
 215   void csetw(Register Rd, Assembler::Condition cond) {
 216     csincw(Rd, zr, zr, ~cond);
 217   }
 218 
 219   void cneg(Register Rd, Register Rn, Assembler::Condition cond) {
 220     csneg(Rd, Rn, Rn, ~cond);
 221   }
 222   void cnegw(Register Rd, Register Rn, Assembler::Condition cond) {
 223     csnegw(Rd, Rn, Rn, ~cond);
 224   }
 225 
 226   inline void movw(Register Rd, Register Rn) {
 227     if (Rd == sp || Rn == sp) {


 443     umaddl(Rd, Rn, Rm, zr);
 444   }
 445 
 446 #define WRAP(INSN)                                                            \
 447   void INSN(Register Rd, Register Rn, Register Rm, Register Ra) {             \
 448     if ((VM_Version::features() & VM_Version::CPU_A53MAC) && Ra != zr)        \
 449       nop();                                                                  \
 450     Assembler::INSN(Rd, Rn, Rm, Ra);                                          \
 451   }
 452 
 453   WRAP(madd) WRAP(msub) WRAP(maddw) WRAP(msubw)
 454   WRAP(smaddl) WRAP(smsubl) WRAP(umaddl) WRAP(umsubl)
 455 #undef WRAP
 456 
 457 
 458   // macro assembly operations needed for aarch64
 459 
 460   // first two private routines for loading 32 bit or 64 bit constants
 461 private:
 462 
 463   void mov_immediate64(Register dst, uint64_t imm64);
 464   void mov_immediate32(Register dst, uint32_t imm32);
 465 
 466   int push(unsigned int bitset, Register stack);
 467   int pop(unsigned int bitset, Register stack);
 468 
 469   int push_fp(unsigned int bitset, Register stack);
 470   int pop_fp(unsigned int bitset, Register stack);
 471 
 472   void mov(Register dst, Address a);
 473 
 474 public:
 475   void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
 476   void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
 477 
 478   void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
 479   void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
 480 
 481   // Push and pop everything that might be clobbered by a native
 482   // runtime call except rscratch1 and rscratch2.  (They are always
 483   // scratch, so we don't have to protect them.)  Only save the lower
 484   // 64 bits of each vector register.
 485   void push_call_clobbered_registers();
 486   void pop_call_clobbered_registers();
 487 
 488   // now mov instructions for loading absolute addresses and 32 or
 489   // 64 bit integers
 490 
 491   inline void mov(Register dst, address addr)
 492   {
 493     mov_immediate64(dst, (uint64_t)addr);
 494   }
 495 
 496   inline void mov(Register dst, uint64_t imm64)
 497   {
 498     mov_immediate64(dst, imm64);
 499   }
 500 
 501   inline void movw(Register dst, uint32_t imm32)
 502   {
 503     mov_immediate32(dst, imm32);
 504   }
 505 
 506   inline void mov(Register dst, int64_t l)
 507   {
 508     mov(dst, (uint64_t)l);
 509   }
 510 
 511   inline void mov(Register dst, int i)
 512   {
 513     mov(dst, (int64_t)i);
 514   }
 515 
 516   void mov(Register dst, RegisterOrConstant src) {
 517     if (src.is_register())
 518       mov(dst, src.as_register());
 519     else
 520       mov(dst, src.as_constant());
 521   }
 522 
 523   void movptr(Register r, uintptr_t imm64);
 524 
 525   void mov(FloatRegister Vd, SIMD_Arrangement T, uint32_t imm32);
 526 
 527   void mov(FloatRegister Vd, SIMD_Arrangement T, FloatRegister Vn) {
 528     orr(Vd, T, Vn, Vn);
 529   }
 530 
 531 public:
 532 
 533   // Generalized Test Bit And Branch, including a "far" variety which
 534   // spans more than 32KiB.
 535   void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool isfar = false) {
 536     assert(cond == EQ || cond == NE, "must be");
 537 
 538     if (isfar)
 539       cond = ~cond;
 540 
 541     void (Assembler::* branch)(Register Rt, int bitpos, Label &L);
 542     if (cond == Assembler::EQ)
 543       branch = &Assembler::tbz;
 544     else
 545       branch = &Assembler::tbnz;
 546 
 547     if (isfar) {
 548       Label L;
 549       (this->*branch)(Rt, bitpos, L);
 550       b(dest);
 551       bind(L);
 552     } else {
 553       (this->*branch)(Rt, bitpos, dest);
 554     }
 555   }
 556 
 557   // macro instructions for accessing and updating floating point
 558   // status register
 559   //
 560   // FPSR : op1 == 011
 561   //        CRn == 0100
 562   //        CRm == 0100
 563   //        op2 == 001
 564 
 565   inline void get_fpsr(Register reg)
 566   {
 567     mrs(0b11, 0b0100, 0b0100, 0b001, reg);


1157              enum shift_kind kind, unsigned shift = 0) {                \
1158     Assembler::INSN(Rd, Rn, Rm, kind, shift);                           \
1159   }                                                                     \
1160                                                                         \
1161   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1162     Assembler::INSN(Rd, Rn, Rm);                                        \
1163   }                                                                     \
1164                                                                         \
1165   void INSN(Register Rd, Register Rn, Register Rm,                      \
1166            ext::operation option, int amount = 0) {                     \
1167     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1168   }
1169 
1170   WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1171 
1172   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1173   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1174   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1175   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1176 
1177   void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1178 
1179   void tableswitch(Register index, jint lowbound, jint highbound,
1180                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1181     adr(rscratch1, jumptable);
1182     subsw(rscratch2, index, lowbound);
1183     subsw(zr, rscratch2, highbound - lowbound);
1184     br(Assembler::HS, jumptable_end);
1185     add(rscratch1, rscratch1, rscratch2,
1186         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1187     br(rscratch1);
1188   }
1189 
1190   // Form an address from base + offset in Rd.  Rd may or may not
1191   // actually be used: you must use the Address that is returned.  It
1192   // is up to you to ensure that the shift provided matches the size
1193   // of your data.
1194   Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1195 
1196   // Return true iff an address is within the 48-bit AArch64 address
1197   // space.
1198   bool is_valid_AArch64_address(address a) {
1199     return ((uint64_t)a >> 48) == 0;
1200   }
1201 
1202   // Load the base of the cardtable byte map into reg.
1203   void load_byte_map_base(Register reg);
1204 
1205   // Prolog generator routines to support switch between x86 code and
1206   // generated ARM code
1207 
1208   // routine to generate an x86 prolog for a stub function which
1209   // bootstraps into the generated ARM code which directly follows the
1210   // stub
1211   //
1212 
1213   public:
1214 
1215   void ldr_constant(Register dest, const Address &const_addr) {
1216     if (NearCpool) {
1217       ldr(dest, const_addr);
1218     } else {
1219       uint64_t offset;
1220       adrp(dest, InternalAddress(const_addr.target()), offset);
1221       ldr(dest, Address(dest, offset));
1222     }
1223   }
1224 
1225   address read_polling_page(Register r, relocInfo::relocType rtype);
1226   void get_polling_page(Register dest, relocInfo::relocType rtype);
1227   address fetch_and_read_polling_page(Register r, relocInfo::relocType rtype);
1228 
1229   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1230   void update_byte_crc32(Register crc, Register val, Register table);
1231   void update_word_crc32(Register crc, Register v, Register tmp,
1232         Register table0, Register table1, Register table2, Register table3,
1233         bool upper = false);
1234 
1235   void has_negatives(Register ary1, Register len, Register result);
1236 
1237   void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1238                      Register tmp1, Register tmp2, Register tmp3, int elem_size);
1239 
1240   void string_equals(Register a1, Register a2, Register result, Register cnt1,
1241                      int elem_size);
1242 
1243   void fill_words(Register base, Register cnt, Register value);
1244   void zero_words(Register base, uint64_t cnt);
1245   void zero_words(Register ptr, Register cnt);
1246   void zero_dcache_blocks(Register base, Register cnt);
1247 
1248   static const int zero_words_block_size;
1249 
1250   void byte_array_inflate(Register src, Register dst, Register len,
1251                           FloatRegister vtmp1, FloatRegister vtmp2,
1252                           FloatRegister vtmp3, Register tmp4);
1253 
1254   void char_array_compress(Register src, Register dst, Register len,
1255                            FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1256                            FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1257                            Register result);
1258 
1259   void encode_iso_array(Register src, Register dst,
1260                         Register len, Register result,
1261                         FloatRegister Vtmp1, FloatRegister Vtmp2,
1262                         FloatRegister Vtmp3, FloatRegister Vtmp4);
1263   void fast_log(FloatRegister vtmp0, FloatRegister vtmp1, FloatRegister vtmp2,
1264                 FloatRegister vtmp3, FloatRegister vtmp4, FloatRegister vtmp5,


1297         Register tmp3);
1298 public:
1299   void multiply_to_len(Register x, Register xlen, Register y, Register ylen, Register z,
1300                        Register zlen, Register tmp1, Register tmp2, Register tmp3,
1301                        Register tmp4, Register tmp5, Register tmp6, Register tmp7);
1302   void mul_add(Register out, Register in, Register offs, Register len, Register k);
1303   // ISB may be needed because of a safepoint
1304   void maybe_isb() { isb(); }
1305 
1306 private:
1307   // Return the effective address r + (r1 << ext) + offset.
1308   // Uses rscratch2.
1309   Address offsetted_address(Register r, Register r1, Address::extend ext,
1310                             int offset, int size);
1311 
1312 private:
1313   // Returns an address on the stack which is reachable with a ldr/str of size
1314   // Uses rscratch2 if the address is not directly reachable
1315   Address spill_address(int size, int offset, Register tmp=rscratch2);
1316 
1317   bool merge_alignment_check(Register base, size_t size, int64_t cur_offset, int64_t prev_offset) const;
1318 
1319   // Check whether two loads/stores can be merged into ldp/stp.
1320   bool ldst_can_merge(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store) const;
1321 
1322   // Merge current load/store with previous load/store into ldp/stp.
1323   void merge_ldst(Register rx, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1324 
1325   // Try to merge two loads/stores into ldp/stp. If success, returns true else false.
1326   bool try_merge_ldst(Register rt, const Address &adr, size_t cur_size_in_bytes, bool is_store);
1327 
1328 public:
1329   void spill(Register Rx, bool is64, int offset) {
1330     if (is64) {
1331       str(Rx, spill_address(8, offset));
1332     } else {
1333       strw(Rx, spill_address(4, offset));
1334     }
1335   }
1336   void spill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1337     str(Vx, T, spill_address(1 << (int)T, offset));


< prev index next >