< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Print this page




  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP
  27 #define CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP
  28 
  29 #include "asm/assembler.hpp"
  30 #include "oops/compressedOops.hpp"





  31 
  32 // MacroAssembler extends Assembler by frequently used macros.
  33 //
  34 // Instructions for which a 'better' code sequence exists depending
  35 // on arguments should also go in here.
  36 
  37 class MacroAssembler: public Assembler {
  38   friend class LIR_Assembler;
  39 
  40  public:
  41   using Assembler::mov;
  42   using Assembler::movi;
  43 
  44  protected:
  45 
  46   // Support for VM calls
  47   //
  48   // This is the base routine called by the different versions of call_VM_leaf. The interpreter
  49   // may customize this version by overriding it for its purposes (e.g., to save/restore
  50   // additional registers when doing a VM call).


 568     mrs(0b011, 0b0000, 0b0000, 0b001, reg);
 569   }
 570 
 571   // idiv variant which deals with MINLONG as dividend and -1 as divisor
 572   int corrected_idivl(Register result, Register ra, Register rb,
 573                       bool want_remainder, Register tmp = rscratch1);
 574   int corrected_idivq(Register result, Register ra, Register rb,
 575                       bool want_remainder, Register tmp = rscratch1);
 576 
 577   // Support for NULL-checks
 578   //
 579   // Generates code that causes a NULL OS exception if the content of reg is NULL.
 580   // If the accessed location is M[reg + offset] and the offset is known, provide the
 581   // offset. No explicit code generation is needed if the offset is within a certain
 582   // range (0 <= offset <= page_size).
 583 
 584   virtual void null_check(Register reg, int offset = -1);
 585   static bool needs_explicit_null_check(intptr_t offset);
 586   static bool uses_implicit_null_check(void* address);
 587 










 588   static address target_addr_for_insn(address insn_addr, unsigned insn);
 589   static address target_addr_for_insn(address insn_addr) {
 590     unsigned insn = *(unsigned*)insn_addr;
 591     return target_addr_for_insn(insn_addr, insn);
 592   }
 593 
 594   // Required platform-specific helpers for Label::patch_instructions.
 595   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
 596   static int pd_patch_instruction_size(address branch, address target);
 597   static void pd_patch_instruction(address branch, address target, const char* file = NULL, int line = 0) {
 598     pd_patch_instruction_size(branch, target);
 599   }
 600   static address pd_call_destination(address branch) {
 601     return target_addr_for_insn(branch);
 602   }
 603 #ifndef PRODUCT
 604   static void pd_print_patched_instruction(address branch);
 605 #endif
 606 
 607   static int patch_oop(address insn_addr, address o);


 772   void set_last_Java_frame(Register last_java_sp,
 773                            Register last_java_fp,
 774                            Register last_java_pc,
 775                            Register scratch);
 776 
 777   void reset_last_Java_frame(Register thread);
 778 
 779   // thread in the default location (rthread)
 780   void reset_last_Java_frame(bool clear_fp);
 781 
 782   // Stores
 783   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
 784   void store_check(Register obj, Address dst);   // same as above, dst is exact store location (reg. is destroyed)
 785 
 786   void resolve_jobject(Register value, Register thread, Register tmp);
 787 
 788   // C 'boolean' to Java boolean: x == 0 ? 0 : 1
 789   void c2bool(Register x);
 790 
 791   // oop manipulations



 792   void load_klass(Register dst, Register src);
 793   void store_klass(Register dst, Register src);
 794   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 795 
 796   void resolve_oop_handle(Register result, Register tmp = r5);
 797   void load_mirror(Register dst, Register method, Register tmp = r5);
 798 
 799   void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
 800                       Register tmp1, Register tmp_thread);
 801 
 802   void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
 803                        Register tmp1, Register tmp_thread);
 804 
 805   // Resolves obj for access. Result is placed in the same register.
 806   // All other registers are preserved.
 807   void resolve(DecoratorSet decorators, Register obj);
 808 
 809   void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
 810                      Register thread_tmp = noreg, DecoratorSet decorators = 0);
 811 
 812   void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
 813                               Register thread_tmp = noreg, DecoratorSet decorators = 0);
 814   void store_heap_oop(Address dst, Register src, Register tmp1 = noreg,
 815                       Register tmp_thread = noreg, DecoratorSet decorators = 0);
 816 
 817   // currently unimplemented
 818   // Used for storing NULL. All other oop constants should be
 819   // stored using routines that take a jobject.
 820   void store_heap_oop_null(Address dst);
 821 
 822   void load_prototype_header(Register dst, Register src);
 823 
 824   void store_klass_gap(Register dst, Register src);
 825 
 826   // This dummy is to prevent a call to store_heap_oop from
 827   // converting a zero (like NULL) into a Register by giving
 828   // the compiler two choices it can't resolve
 829 
 830   void store_heap_oop(Address dst, void* dummy);
 831 
 832   void encode_heap_oop(Register d, Register s);
 833   void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
 834   void decode_heap_oop(Register d, Register s);
 835   void decode_heap_oop(Register r) { decode_heap_oop(r, r); }


1126   }                                                                     \
1127                                                                         \
1128   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1129     Assembler::INSN(Rd, Rn, Rm);                                        \
1130   }                                                                     \
1131                                                                         \
1132   void INSN(Register Rd, Register Rn, Register Rm,                      \
1133            ext::operation option, int amount = 0) {                     \
1134     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1135   }
1136 
1137   WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1138 
1139   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1140   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1141   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1142   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1143 
1144   void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
1145 































1146   void tableswitch(Register index, jint lowbound, jint highbound,
1147                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1148     adr(rscratch1, jumptable);
1149     subsw(rscratch2, index, lowbound);
1150     subsw(zr, rscratch2, highbound - lowbound);
1151     br(Assembler::HS, jumptable_end);
1152     add(rscratch1, rscratch1, rscratch2,
1153         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1154     br(rscratch1);
1155   }
1156 
1157   // Form an address from base + offset in Rd.  Rd may or may not
1158   // actually be used: you must use the Address that is returned.  It
1159   // is up to you to ensure that the shift provided matches the size
1160   // of your data.
1161   Address form_address(Register Rd, Register base, long byte_offset, int shift);
1162 
1163   // Return true iff an address is within the 48-bit AArch64 address
1164   // space.
1165   bool is_valid_AArch64_address(address a) {


1218   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1219   void update_byte_crc32(Register crc, Register val, Register table);
1220   void update_word_crc32(Register crc, Register v, Register tmp,
1221         Register table0, Register table1, Register table2, Register table3,
1222         bool upper = false);
1223 
1224   void string_compare(Register str1, Register str2,
1225                       Register cnt1, Register cnt2, Register result,
1226                       Register tmp1, Register tmp2, FloatRegister vtmp1,
1227                       FloatRegister vtmp2, FloatRegister vtmp3, int ae);
1228 
1229   void has_negatives(Register ary1, Register len, Register result);
1230 
1231   void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1232                      Register tmp1, Register tmp2, Register tmp3, int elem_size);
1233 
1234   void string_equals(Register a1, Register a2, Register result, Register cnt1,
1235                      int elem_size);
1236 
1237   void fill_words(Register base, Register cnt, Register value);


1238   void zero_words(Register base, u_int64_t cnt);
1239   void zero_words(Register ptr, Register cnt);
1240   void zero_dcache_blocks(Register base, Register cnt);
1241 
1242   static const int zero_words_block_size;
1243 
1244   void byte_array_inflate(Register src, Register dst, Register len,
1245                           FloatRegister vtmp1, FloatRegister vtmp2,
1246                           FloatRegister vtmp3, Register tmp4);
1247 
1248   void char_array_compress(Register src, Register dst, Register len,
1249                            FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1250                            FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1251                            Register result);
1252 
1253   void encode_iso_array(Register src, Register dst,
1254                         Register len, Register result,
1255                         FloatRegister Vtmp1, FloatRegister Vtmp2,
1256                         FloatRegister Vtmp3, FloatRegister Vtmp4);
1257   void string_indexof(Register str1, Register str2,


1345     } else {
1346       ldrw(Rx, spill_address(4, offset));
1347     }
1348   }
1349   void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1350     ldr(Vx, T, spill_address(1 << (int)T, offset));
1351   }
1352   void spill_copy128(int src_offset, int dst_offset,
1353                      Register tmp1=rscratch1, Register tmp2=rscratch2) {
1354     if (src_offset < 512 && (src_offset & 7) == 0 &&
1355         dst_offset < 512 && (dst_offset & 7) == 0) {
1356       ldp(tmp1, tmp2, Address(sp, src_offset));
1357       stp(tmp1, tmp2, Address(sp, dst_offset));
1358     } else {
1359       unspill(tmp1, true, src_offset);
1360       spill(tmp1, true, dst_offset);
1361       unspill(tmp1, true, src_offset+8);
1362       spill(tmp1, true, dst_offset+8);
1363     }
1364   }



1365 };
1366 
1367 #ifdef ASSERT
1368 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1369 #endif
1370 
1371 /**
1372  * class SkipIfEqual:
1373  *
1374  * Instantiating this class will result in assembly code being output that will
1375  * jump around any code emitted between the creation of the instance and it's
1376  * automatic destruction at the end of a scope block, depending on the value of
1377  * the flag passed to the constructor, which will be checked at run-time.
1378  */
1379 class SkipIfEqual {
1380  private:
1381   MacroAssembler* _masm;
1382   Label _label;
1383 
1384  public:


  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP
  27 #define CPU_AARCH64_MACROASSEMBLER_AARCH64_HPP
  28 
  29 #include "asm/assembler.hpp"
  30 #include "oops/compressedOops.hpp"
  31 #include "utilities/macros.hpp"
  32 #include "runtime/signature.hpp"
  33 
  34 
  35 class ciValueKlass;
  36 
  37 // MacroAssembler extends Assembler by frequently used macros.
  38 //
  39 // Instructions for which a 'better' code sequence exists depending
  40 // on arguments should also go in here.
  41 
  42 class MacroAssembler: public Assembler {
  43   friend class LIR_Assembler;
  44 
  45  public:
  46   using Assembler::mov;
  47   using Assembler::movi;
  48 
  49  protected:
  50 
  51   // Support for VM calls
  52   //
  53   // This is the base routine called by the different versions of call_VM_leaf. The interpreter
  54   // may customize this version by overriding it for its purposes (e.g., to save/restore
  55   // additional registers when doing a VM call).


 573     mrs(0b011, 0b0000, 0b0000, 0b001, reg);
 574   }
 575 
 576   // idiv variant which deals with MINLONG as dividend and -1 as divisor
 577   int corrected_idivl(Register result, Register ra, Register rb,
 578                       bool want_remainder, Register tmp = rscratch1);
 579   int corrected_idivq(Register result, Register ra, Register rb,
 580                       bool want_remainder, Register tmp = rscratch1);
 581 
 582   // Support for NULL-checks
 583   //
 584   // Generates code that causes a NULL OS exception if the content of reg is NULL.
 585   // If the accessed location is M[reg + offset] and the offset is known, provide the
 586   // offset. No explicit code generation is needed if the offset is within a certain
 587   // range (0 <= offset <= page_size).
 588 
 589   virtual void null_check(Register reg, int offset = -1);
 590   static bool needs_explicit_null_check(intptr_t offset);
 591   static bool uses_implicit_null_check(void* address);
 592 
 593   void test_klass_is_value(Register klass, Register temp_reg, Label& is_value);
 594 
 595   void test_field_is_flattenable(Register flags, Register temp_reg, Label& is_flattenable);
 596   void test_field_is_not_flattenable(Register flags, Register temp_reg, Label& notFlattenable);
 597   void test_field_is_flattened(Register flags, Register temp_reg, Label& is_flattened);
 598 
 599   // Check klass/oops is flat value type array (oop->_klass->_layout_helper & vt_bit)
 600   void test_flattened_array_oop(Register klass, Register temp_reg, Label& is_flattened_array);
 601   void test_null_free_array_oop(Register oop, Register temp_reg, Label& is_null_free_array);
 602 
 603   static address target_addr_for_insn(address insn_addr, unsigned insn);
 604   static address target_addr_for_insn(address insn_addr) {
 605     unsigned insn = *(unsigned*)insn_addr;
 606     return target_addr_for_insn(insn_addr, insn);
 607   }
 608 
 609   // Required platform-specific helpers for Label::patch_instructions.
 610   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
 611   static int pd_patch_instruction_size(address branch, address target);
 612   static void pd_patch_instruction(address branch, address target, const char* file = NULL, int line = 0) {
 613     pd_patch_instruction_size(branch, target);
 614   }
 615   static address pd_call_destination(address branch) {
 616     return target_addr_for_insn(branch);
 617   }
 618 #ifndef PRODUCT
 619   static void pd_print_patched_instruction(address branch);
 620 #endif
 621 
 622   static int patch_oop(address insn_addr, address o);


 787   void set_last_Java_frame(Register last_java_sp,
 788                            Register last_java_fp,
 789                            Register last_java_pc,
 790                            Register scratch);
 791 
 792   void reset_last_Java_frame(Register thread);
 793 
 794   // thread in the default location (rthread)
 795   void reset_last_Java_frame(bool clear_fp);
 796 
 797   // Stores
 798   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
 799   void store_check(Register obj, Address dst);   // same as above, dst is exact store location (reg. is destroyed)
 800 
 801   void resolve_jobject(Register value, Register thread, Register tmp);
 802 
 803   // C 'boolean' to Java boolean: x == 0 ? 0 : 1
 804   void c2bool(Register x);
 805 
 806   // oop manipulations
 807   void load_metadata(Register dst, Register src);
 808   void load_storage_props(Register dst, Register src);
 809 
 810   void load_klass(Register dst, Register src);
 811   void store_klass(Register dst, Register src);
 812   void cmp_klass(Register oop, Register trial_klass, Register tmp);
 813 
 814   void resolve_oop_handle(Register result, Register tmp = r5);
 815   void load_mirror(Register dst, Register method, Register tmp = r5);
 816 
 817   void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
 818                       Register tmp1, Register tmp_thread);
 819 
 820   void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register src,
 821                        Register tmp1, Register tmp_thread, Register tmp3 = noreg);
 822 
 823   // Resolves obj for access. Result is placed in the same register.
 824   // All other registers are preserved.
 825   void resolve(DecoratorSet decorators, Register obj);
 826 
 827   void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
 828                      Register thread_tmp = noreg, DecoratorSet decorators = 0);
 829 
 830   void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
 831                               Register thread_tmp = noreg, DecoratorSet decorators = 0);
 832   void store_heap_oop(Address dst, Register src, Register tmp1 = noreg,
 833                       Register tmp_thread = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0);
 834 
 835   // currently unimplemented
 836   // Used for storing NULL. All other oop constants should be
 837   // stored using routines that take a jobject.
 838   void store_heap_oop_null(Address dst);
 839 
 840   void load_prototype_header(Register dst, Register src);
 841 
 842   void store_klass_gap(Register dst, Register src);
 843 
 844   // This dummy is to prevent a call to store_heap_oop from
 845   // converting a zero (like NULL) into a Register by giving
 846   // the compiler two choices it can't resolve
 847 
 848   void store_heap_oop(Address dst, void* dummy);
 849 
 850   void encode_heap_oop(Register d, Register s);
 851   void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
 852   void decode_heap_oop(Register d, Register s);
 853   void decode_heap_oop(Register r) { decode_heap_oop(r, r); }


1144   }                                                                     \
1145                                                                         \
1146   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1147     Assembler::INSN(Rd, Rn, Rm);                                        \
1148   }                                                                     \
1149                                                                         \
1150   void INSN(Register Rd, Register Rn, Register Rm,                      \
1151            ext::operation option, int amount = 0) {                     \
1152     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1153   }
1154 
1155   WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1156 
1157   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1158   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1159   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1160   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1161 
1162   void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
1163 
1164 
1165   enum RegState {
1166      reg_readonly,
1167      reg_writable,
1168      reg_written
1169   };
1170 
1171   void verified_entry(Compile* C, int sp_inc);
1172 
1173   int store_value_type_fields_to_buf(ciValueKlass* vk, bool from_interpreter = true);
1174 
1175 // Unpack all value type arguments passed as oops 
1176   void unpack_value_args(Compile* C, bool receiver_only);
1177   bool move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[], int ret_off, int extra_stack_offset);
1178   bool unpack_value_helper(const GrowableArray<SigEntry>* sig, int& sig_index, VMReg from, VMRegPair* regs_to, int& to_index,
1179                            RegState reg_state[], int ret_off, int extra_stack_offset);
1180   bool pack_value_helper(const GrowableArray<SigEntry>* sig, int& sig_index, int vtarg_index,
1181                          VMReg to, VMRegPair* regs_from, int regs_from_count, int& from_index, RegState reg_state[],
1182                          int ret_off, int extra_stack_offset);
1183   void restore_stack(Compile* C);
1184 
1185   int shuffle_value_args(bool is_packing, bool receiver_only, int extra_stack_offset,
1186                          BasicType* sig_bt, const GrowableArray<SigEntry>* sig_cc,
1187                          int args_passed, int args_on_stack, VMRegPair* regs,
1188                          int args_passed_to, int args_on_stack_to, VMRegPair* regs_to);
1189   bool shuffle_value_args_spill(bool is_packing,  const GrowableArray<SigEntry>* sig_cc, int sig_cc_index,
1190                                 VMRegPair* regs_from, int from_index, int regs_from_count,
1191                                 RegState* reg_state, int sp_inc, int extra_stack_offset);
1192   VMReg spill_reg_for(VMReg reg);
1193 
1194 
1195   void tableswitch(Register index, jint lowbound, jint highbound,
1196                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1197     adr(rscratch1, jumptable);
1198     subsw(rscratch2, index, lowbound);
1199     subsw(zr, rscratch2, highbound - lowbound);
1200     br(Assembler::HS, jumptable_end);
1201     add(rscratch1, rscratch1, rscratch2,
1202         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1203     br(rscratch1);
1204   }
1205 
1206   // Form an address from base + offset in Rd.  Rd may or may not
1207   // actually be used: you must use the Address that is returned.  It
1208   // is up to you to ensure that the shift provided matches the size
1209   // of your data.
1210   Address form_address(Register Rd, Register base, long byte_offset, int shift);
1211 
1212   // Return true iff an address is within the 48-bit AArch64 address
1213   // space.
1214   bool is_valid_AArch64_address(address a) {


1267   // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1268   void update_byte_crc32(Register crc, Register val, Register table);
1269   void update_word_crc32(Register crc, Register v, Register tmp,
1270         Register table0, Register table1, Register table2, Register table3,
1271         bool upper = false);
1272 
1273   void string_compare(Register str1, Register str2,
1274                       Register cnt1, Register cnt2, Register result,
1275                       Register tmp1, Register tmp2, FloatRegister vtmp1,
1276                       FloatRegister vtmp2, FloatRegister vtmp3, int ae);
1277 
1278   void has_negatives(Register ary1, Register len, Register result);
1279 
1280   void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1281                      Register tmp1, Register tmp2, Register tmp3, int elem_size);
1282 
1283   void string_equals(Register a1, Register a2, Register result, Register cnt1,
1284                      int elem_size);
1285 
1286   void fill_words(Register base, Register cnt, Register value);
1287   void fill_words(Register base, u_int64_t cnt, Register value);
1288 
1289   void zero_words(Register base, u_int64_t cnt);
1290   void zero_words(Register ptr, Register cnt);
1291   void zero_dcache_blocks(Register base, Register cnt);
1292 
1293   static const int zero_words_block_size;
1294 
1295   void byte_array_inflate(Register src, Register dst, Register len,
1296                           FloatRegister vtmp1, FloatRegister vtmp2,
1297                           FloatRegister vtmp3, Register tmp4);
1298 
1299   void char_array_compress(Register src, Register dst, Register len,
1300                            FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1301                            FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1302                            Register result);
1303 
1304   void encode_iso_array(Register src, Register dst,
1305                         Register len, Register result,
1306                         FloatRegister Vtmp1, FloatRegister Vtmp2,
1307                         FloatRegister Vtmp3, FloatRegister Vtmp4);
1308   void string_indexof(Register str1, Register str2,


1396     } else {
1397       ldrw(Rx, spill_address(4, offset));
1398     }
1399   }
1400   void unspill(FloatRegister Vx, SIMD_RegVariant T, int offset) {
1401     ldr(Vx, T, spill_address(1 << (int)T, offset));
1402   }
1403   void spill_copy128(int src_offset, int dst_offset,
1404                      Register tmp1=rscratch1, Register tmp2=rscratch2) {
1405     if (src_offset < 512 && (src_offset & 7) == 0 &&
1406         dst_offset < 512 && (dst_offset & 7) == 0) {
1407       ldp(tmp1, tmp2, Address(sp, src_offset));
1408       stp(tmp1, tmp2, Address(sp, dst_offset));
1409     } else {
1410       unspill(tmp1, true, src_offset);
1411       spill(tmp1, true, dst_offset);
1412       unspill(tmp1, true, src_offset+8);
1413       spill(tmp1, true, dst_offset+8);
1414     }
1415   }
1416 
1417   #include "asm/macroAssembler_common.hpp"
1418 
1419 };
1420 
1421 #ifdef ASSERT
1422 inline bool AbstractAssembler::pd_check_instruction_mark() { return false; }
1423 #endif
1424 
1425 /**
1426  * class SkipIfEqual:
1427  *
1428  * Instantiating this class will result in assembly code being output that will
1429  * jump around any code emitted between the creation of the instance and it's
1430  * automatic destruction at the end of a scope block, depending on the value of
1431  * the flag passed to the constructor, which will be checked at run-time.
1432  */
1433 class SkipIfEqual {
1434  private:
1435   MacroAssembler* _masm;
1436   Label _label;
1437 
1438  public:
< prev index next >