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.inline.hpp"
30 #include "code/aotCodeCache.hpp"
31 #include "code/vmreg.hpp"
32 #include "metaprogramming/enableIf.hpp"
33 #include "oops/compressedOops.hpp"
34 #include "oops/compressedKlass.hpp"
35 #include "runtime/atomicAccess.hpp"
36 #include "runtime/vm_version.hpp"
37 #include "utilities/globalDefinitions.hpp"
38 #include "utilities/powerOfTwo.hpp"
39
40 class OopMap;
41 struct GtestFriendToMacroAssembler;
42
43 // MacroAssembler extends Assembler by frequently used macros.
44 //
45 // Instructions for which a 'better' code sequence exists depending
46 // on arguments should also go in here.
47
48 class MacroAssembler: public Assembler {
49 friend class LIR_Assembler;
50 friend struct GtestFriendToMacroAssembler;
51
52 public:
53 using Assembler::mov;
54 using Assembler::movi;
55
56 protected:
57
58 // Support for VM calls
174
175 void bind(Label& L) {
176 Assembler::bind(L);
177 code()->clear_last_merge_candidate();
178 code()->set_last_label(pc());
179 }
180
181 void membar(Membar_mask_bits order_constraint);
182
183 using Assembler::ldr;
184 using Assembler::str;
185 using Assembler::ldrw;
186 using Assembler::strw;
187
188 void ldr(Register Rx, const Address &adr);
189 void ldrw(Register Rw, const Address &adr);
190 void str(Register Rx, const Address &adr);
191 void strw(Register Rx, const Address &adr);
192
193 // Frame creation and destruction shared between JITs.
194 void build_frame(int framesize);
195 void remove_frame(int framesize);
196
197 virtual void _call_Unimplemented(address call_site) {
198 mov(rscratch2, call_site);
199 }
200
201 // Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__
202 // Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention."
203 // https://reviews.llvm.org/D3311
204
205 #ifdef _WIN64
206 #define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
207 #else
208 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
209 #endif
210
211 // aliases defined in AARCH64 spec
212
213 template<class T>
214 inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
693 mrs(0b011, 0b1110, 0b0000, 0b110, reg);
694 }
695
696 // idiv variant which deals with MINLONG as dividend and -1 as divisor
697 int corrected_idivl(Register result, Register ra, Register rb,
698 bool want_remainder, Register tmp = rscratch1);
699 int corrected_idivq(Register result, Register ra, Register rb,
700 bool want_remainder, Register tmp = rscratch1);
701
702 // Support for null-checks
703 //
704 // Generates code that causes a null OS exception if the content of reg is null.
705 // If the accessed location is M[reg + offset] and the offset is known, provide the
706 // offset. No explicit code generation is needed if the offset is within a certain
707 // range (0 <= offset <= page_size).
708
709 virtual void null_check(Register reg, int offset = -1);
710 static bool needs_explicit_null_check(intptr_t offset);
711 static bool uses_implicit_null_check(void* address);
712
713 static address target_addr_for_insn(address insn_addr);
714
715 // Required platform-specific helpers for Label::patch_instructions.
716 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
717 static int pd_patch_instruction_size(address branch, address target);
718 static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
719 pd_patch_instruction_size(branch, target);
720 }
721 static address pd_call_destination(address branch) {
722 return target_addr_for_insn(branch);
723 }
724 #ifndef PRODUCT
725 static void pd_print_patched_instruction(address branch);
726 #endif
727
728 static int patch_oop(address insn_addr, address o);
729
730 // Return whether code is emitted to a scratch blob.
731 virtual bool in_scratch_emit_size() {
732 return false;
919 void set_last_Java_frame(Register last_java_sp,
920 Register last_java_fp,
921 Register last_java_pc,
922 Register scratch);
923
924 void reset_last_Java_frame(Register thread);
925
926 // thread in the default location (rthread)
927 void reset_last_Java_frame(bool clear_fp);
928
929 void resolve_jobject(Register value, Register tmp1, Register tmp2);
930 void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
931
932 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
933 void c2bool(Register x);
934
935 void load_method_holder_cld(Register rresult, Register rmethod);
936 void load_method_holder(Register holder, Register method);
937
938 // oop manipulations
939 void load_narrow_klass_compact(Register dst, Register src);
940 void load_narrow_klass(Register dst, Register src);
941 void load_klass(Register dst, Register src, Register tmp);
942 void store_klass(Register dst, Register src, Register tmp);
943 void cmp_klass(Register obj, Register klass, Register tmp, Register tmp2);
944 void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
945
946 void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
947 void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
948 void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
949
950 void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
951 Register tmp1, Register tmp2);
952
953 void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
954 Register tmp1, Register tmp2, Register tmp3);
955
956 void load_heap_oop(Register dst, Address src, Register tmp1,
957 Register tmp2, DecoratorSet decorators = 0);
958
959 void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
960 Register tmp2, DecoratorSet decorators = 0);
961 void store_heap_oop(Address dst, Register val, Register tmp1,
962 Register tmp2, Register tmp3, DecoratorSet decorators = 0);
963
964 // currently unimplemented
965 // Used for storing null. All other oop constants should be
966 // stored using routines that take a jobject.
967 void store_heap_oop_null(Address dst);
968
969 void store_klass_gap(Register dst, Register src);
970
971 // This dummy is to prevent a call to store_heap_oop from
972 // converting a zero (like null) into a Register by giving
973 // the compiler two choices it can't resolve
974
975 void store_heap_oop(Address dst, void* dummy);
976
977 void encode_heap_oop(Register d, Register s);
978 void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
979 void decode_heap_oop(Register d, Register s);
980 void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
981 void encode_heap_oop_not_null(Register r);
982 void decode_heap_oop_not_null(Register r);
983 void encode_heap_oop_not_null(Register dst, Register src);
984 void decode_heap_oop_not_null(Register dst, Register src);
985
986 void set_narrow_oop(Register dst, jobject obj);
987
988 void encode_klass_not_null(Register dst, Register src, Register tmp);
994 void reinit_heapbase();
995
996 DEBUG_ONLY(void verify_heapbase(const char* msg);)
997
998 void push_CPU_state(bool save_vectors = false, bool use_sve = false,
999 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1000 void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
1001 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1002
1003 void push_cont_fastpath(Register java_thread = rthread);
1004 void pop_cont_fastpath(Register java_thread = rthread);
1005
1006 // Round up to a power of two
1007 void round_to(Register reg, int modulus);
1008
1009 // java.lang.Math::round intrinsics
1010 void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
1011 void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
1012
1013 // allocation
1014 void tlab_allocate(
1015 Register obj, // result: pointer to object after successful allocation
1016 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
1017 int con_size_in_bytes, // object size in bytes if known at compile time
1018 Register t1, // temp register
1019 Register t2, // temp register
1020 Label& slow_case // continuation point if fast allocation fails
1021 );
1022 void verify_tlab();
1023
1024 // interface method calling
1025 void lookup_interface_method(Register recv_klass,
1026 Register intf_klass,
1027 RegisterOrConstant itable_index,
1028 Register method_result,
1029 Register scan_temp,
1030 Label& no_such_interface,
1031 bool return_method = true);
1032
1033 void lookup_interface_method_stub(Register recv_klass,
1034 Register holder_klass,
1035 Register resolved_klass,
1036 Register method_result,
1037 Register temp_reg,
1038 Register temp_reg2,
1039 int itable_index,
1040 Label& L_no_such_interface);
1041
1042 // virtual method calling
1043 // n.b. x86 allows RegisterOrConstant for vtable_index
1467 } \
1468 \
1469 void INSN(Register Rd, Register Rn, Register Rm) { \
1470 Assembler::INSN(Rd, Rn, Rm); \
1471 } \
1472 \
1473 void INSN(Register Rd, Register Rn, Register Rm, \
1474 ext::operation option, int amount = 0) { \
1475 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1476 }
1477
1478 WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1479
1480 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1481 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1482 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1483 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1484
1485 void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1486
1487 void tableswitch(Register index, jint lowbound, jint highbound,
1488 Label &jumptable, Label &jumptable_end, int stride = 1) {
1489 adr(rscratch1, jumptable);
1490 subsw(rscratch2, index, lowbound);
1491 subsw(zr, rscratch2, highbound - lowbound);
1492 br(Assembler::HS, jumptable_end);
1493 add(rscratch1, rscratch1, rscratch2,
1494 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1495 br(rscratch1);
1496 }
1497
1498 // Form an address from base + offset in Rd. Rd may or may not
1499 // actually be used: you must use the Address that is returned. It
1500 // is up to you to ensure that the shift provided matches the size
1501 // of your data.
1502 Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1503
1504 // Return true iff an address is within the 48-bit AArch64 address
1505 // space.
1506 bool is_valid_AArch64_address(address a) {
1541 #define ARRAYS_HASHCODE_REGISTERS \
1542 do { \
1543 assert(result == r0 && \
1544 ary == r1 && \
1545 cnt == r2 && \
1546 vdata0 == v3 && \
1547 vdata1 == v2 && \
1548 vdata2 == v1 && \
1549 vdata3 == v0 && \
1550 vmul0 == v4 && \
1551 vmul1 == v5 && \
1552 vmul2 == v6 && \
1553 vmul3 == v7 && \
1554 vpow == v12 && \
1555 vpowm == v13, "registers must match aarch64.ad"); \
1556 } while (0)
1557
1558 void string_equals(Register a1, Register a2, Register result, Register cnt1);
1559
1560 void fill_words(Register base, Register cnt, Register value);
1561 address zero_words(Register base, uint64_t cnt);
1562 address zero_words(Register ptr, Register cnt);
1563 void zero_dcache_blocks(Register base, Register cnt);
1564
1565 static const int zero_words_block_size;
1566
1567 address byte_array_inflate(Register src, Register dst, Register len,
1568 FloatRegister vtmp1, FloatRegister vtmp2,
1569 FloatRegister vtmp3, Register tmp4);
1570
1571 void char_array_compress(Register src, Register dst, Register len,
1572 Register res,
1573 FloatRegister vtmp0, FloatRegister vtmp1,
1574 FloatRegister vtmp2, FloatRegister vtmp3,
1575 FloatRegister vtmp4, FloatRegister vtmp5);
1576
1577 void encode_iso_array(Register src, Register dst,
1578 Register len, Register res, bool ascii,
1579 FloatRegister vtmp0, FloatRegister vtmp1,
1580 FloatRegister vtmp2, FloatRegister vtmp3,
|
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.inline.hpp"
30 #include "code/aotCodeCache.hpp"
31 #include "code/vmreg.hpp"
32 #include "metaprogramming/enableIf.hpp"
33 #include "oops/compressedOops.hpp"
34 #include "oops/compressedKlass.hpp"
35 #include "runtime/atomicAccess.hpp"
36 #include "runtime/vm_version.hpp"
37 #include "utilities/globalDefinitions.hpp"
38 #include "utilities/macros.hpp"
39 #include "utilities/powerOfTwo.hpp"
40 #include "runtime/signature.hpp"
41
42
43 class ciInlineKlass;
44
45 class OopMap;
46 struct GtestFriendToMacroAssembler;
47
48 // MacroAssembler extends Assembler by frequently used macros.
49 //
50 // Instructions for which a 'better' code sequence exists depending
51 // on arguments should also go in here.
52
53 class MacroAssembler: public Assembler {
54 friend class LIR_Assembler;
55 friend struct GtestFriendToMacroAssembler;
56
57 public:
58 using Assembler::mov;
59 using Assembler::movi;
60
61 protected:
62
63 // Support for VM calls
179
180 void bind(Label& L) {
181 Assembler::bind(L);
182 code()->clear_last_merge_candidate();
183 code()->set_last_label(pc());
184 }
185
186 void membar(Membar_mask_bits order_constraint);
187
188 using Assembler::ldr;
189 using Assembler::str;
190 using Assembler::ldrw;
191 using Assembler::strw;
192
193 void ldr(Register Rx, const Address &adr);
194 void ldrw(Register Rw, const Address &adr);
195 void str(Register Rx, const Address &adr);
196 void strw(Register Rx, const Address &adr);
197
198 // Frame creation and destruction shared between JITs.
199 DEBUG_ONLY(void build_frame(int framesize);)
200 void build_frame(int framesize DEBUG_ONLY(COMMA bool zap_rfp_lr_spills));
201 void remove_frame(int framesize);
202
203 virtual void _call_Unimplemented(address call_site) {
204 mov(rscratch2, call_site);
205 }
206
207 // Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__
208 // Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention."
209 // https://reviews.llvm.org/D3311
210
211 #ifdef _WIN64
212 #define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
213 #else
214 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
215 #endif
216
217 // aliases defined in AARCH64 spec
218
219 template<class T>
220 inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
699 mrs(0b011, 0b1110, 0b0000, 0b110, reg);
700 }
701
702 // idiv variant which deals with MINLONG as dividend and -1 as divisor
703 int corrected_idivl(Register result, Register ra, Register rb,
704 bool want_remainder, Register tmp = rscratch1);
705 int corrected_idivq(Register result, Register ra, Register rb,
706 bool want_remainder, Register tmp = rscratch1);
707
708 // Support for null-checks
709 //
710 // Generates code that causes a null OS exception if the content of reg is null.
711 // If the accessed location is M[reg + offset] and the offset is known, provide the
712 // offset. No explicit code generation is needed if the offset is within a certain
713 // range (0 <= offset <= page_size).
714
715 virtual void null_check(Register reg, int offset = -1);
716 static bool needs_explicit_null_check(intptr_t offset);
717 static bool uses_implicit_null_check(void* address);
718
719 // markWord tests, kills markWord reg
720 void test_markword_is_inline_type(Register markword, Label& is_inline_type);
721
722 // inlineKlass queries, kills temp_reg
723 void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type, bool can_be_null = true);
724
725 void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
726 void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
727 void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
728
729 // Check oops for special arrays, i.e. flat arrays and/or null-free arrays
730 void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
731 void test_flat_array_oop(Register klass, Register temp_reg, Label& is_flat_array);
732 void test_non_flat_array_oop(Register oop, Register temp_reg, Label&is_non_flat_array);
733 void test_null_free_array_oop(Register oop, Register temp_reg, Label& is_null_free_array);
734 void test_non_null_free_array_oop(Register oop, Register temp_reg, Label&is_non_null_free_array);
735
736 // Check array klass layout helper for flat or null-free arrays...
737 void test_flat_array_layout(Register lh, Label& is_flat_array);
738
739 static address target_addr_for_insn(address insn_addr);
740
741 // Required platform-specific helpers for Label::patch_instructions.
742 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
743 static int pd_patch_instruction_size(address branch, address target);
744 static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
745 pd_patch_instruction_size(branch, target);
746 }
747 static address pd_call_destination(address branch) {
748 return target_addr_for_insn(branch);
749 }
750 #ifndef PRODUCT
751 static void pd_print_patched_instruction(address branch);
752 #endif
753
754 static int patch_oop(address insn_addr, address o);
755
756 // Return whether code is emitted to a scratch blob.
757 virtual bool in_scratch_emit_size() {
758 return false;
945 void set_last_Java_frame(Register last_java_sp,
946 Register last_java_fp,
947 Register last_java_pc,
948 Register scratch);
949
950 void reset_last_Java_frame(Register thread);
951
952 // thread in the default location (rthread)
953 void reset_last_Java_frame(bool clear_fp);
954
955 void resolve_jobject(Register value, Register tmp1, Register tmp2);
956 void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
957
958 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
959 void c2bool(Register x);
960
961 void load_method_holder_cld(Register rresult, Register rmethod);
962 void load_method_holder(Register holder, Register method);
963
964 // oop manipulations
965 void load_metadata(Register dst, Register src);
966
967 void load_narrow_klass_compact(Register dst, Register src);
968 void load_narrow_klass(Register dst, Register src);
969 void load_klass(Register dst, Register src, Register tmp);
970 void store_klass(Register dst, Register src, Register tmp);
971 void cmp_klass(Register obj, Register klass, Register tmp, Register tmp2);
972 void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
973
974 void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
975 void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
976 void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
977
978 void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
979 Register tmp1, Register tmp2);
980
981 void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
982 Register tmp1, Register tmp2, Register tmp3);
983
984 void flat_field_copy(DecoratorSet decorators, Register src, Register dst, Register inline_layout_info);
985
986 // inline type data payload offsets...
987 void payload_offset(Register inline_klass, Register offset);
988 void payload_address(Register oop, Register data, Register inline_klass);
989
990 void load_heap_oop(Register dst, Address src, Register tmp1,
991 Register tmp2, DecoratorSet decorators = 0);
992
993 void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
994 Register tmp2, DecoratorSet decorators = 0);
995 void store_heap_oop(Address dst, Register val, Register tmp1,
996 Register tmp2, Register tmp3, DecoratorSet decorators = 0);
997
998 // currently unimplemented
999 // Used for storing null. All other oop constants should be
1000 // stored using routines that take a jobject.
1001 void store_heap_oop_null(Address dst);
1002
1003 void load_prototype_header(Register dst, Register src);
1004
1005 void store_klass_gap(Register dst, Register src);
1006
1007 // This dummy is to prevent a call to store_heap_oop from
1008 // converting a zero (like null) into a Register by giving
1009 // the compiler two choices it can't resolve
1010
1011 void store_heap_oop(Address dst, void* dummy);
1012
1013 void encode_heap_oop(Register d, Register s);
1014 void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
1015 void decode_heap_oop(Register d, Register s);
1016 void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
1017 void encode_heap_oop_not_null(Register r);
1018 void decode_heap_oop_not_null(Register r);
1019 void encode_heap_oop_not_null(Register dst, Register src);
1020 void decode_heap_oop_not_null(Register dst, Register src);
1021
1022 void set_narrow_oop(Register dst, jobject obj);
1023
1024 void encode_klass_not_null(Register dst, Register src, Register tmp);
1030 void reinit_heapbase();
1031
1032 DEBUG_ONLY(void verify_heapbase(const char* msg);)
1033
1034 void push_CPU_state(bool save_vectors = false, bool use_sve = false,
1035 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1036 void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
1037 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1038
1039 void push_cont_fastpath(Register java_thread = rthread);
1040 void pop_cont_fastpath(Register java_thread = rthread);
1041
1042 // Round up to a power of two
1043 void round_to(Register reg, int modulus);
1044
1045 // java.lang.Math::round intrinsics
1046 void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
1047 void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
1048
1049 // allocation
1050
1051 void tlab_allocate(
1052 Register obj, // result: pointer to object after successful allocation
1053 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
1054 int con_size_in_bytes, // object size in bytes if known at compile time
1055 Register t1, // temp register
1056 Register t2, // temp register
1057 Label& slow_case // continuation point if fast allocation fails
1058 );
1059 void verify_tlab();
1060
1061 void inline_layout_info(Register holder_klass, Register index, Register layout_info);
1062
1063 // interface method calling
1064 void lookup_interface_method(Register recv_klass,
1065 Register intf_klass,
1066 RegisterOrConstant itable_index,
1067 Register method_result,
1068 Register scan_temp,
1069 Label& no_such_interface,
1070 bool return_method = true);
1071
1072 void lookup_interface_method_stub(Register recv_klass,
1073 Register holder_klass,
1074 Register resolved_klass,
1075 Register method_result,
1076 Register temp_reg,
1077 Register temp_reg2,
1078 int itable_index,
1079 Label& L_no_such_interface);
1080
1081 // virtual method calling
1082 // n.b. x86 allows RegisterOrConstant for vtable_index
1506 } \
1507 \
1508 void INSN(Register Rd, Register Rn, Register Rm) { \
1509 Assembler::INSN(Rd, Rn, Rm); \
1510 } \
1511 \
1512 void INSN(Register Rd, Register Rn, Register Rm, \
1513 ext::operation option, int amount = 0) { \
1514 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1515 }
1516
1517 WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1518
1519 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1520 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1521 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1522 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1523
1524 void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1525
1526 void verified_entry(Compile* C, int sp_inc);
1527
1528 // Inline type specific methods
1529 #include "asm/macroAssembler_common.hpp"
1530
1531 void save_stack_increment(int sp_inc, int frame_size);
1532
1533 void tableswitch(Register index, jint lowbound, jint highbound,
1534 Label &jumptable, Label &jumptable_end, int stride = 1) {
1535 adr(rscratch1, jumptable);
1536 subsw(rscratch2, index, lowbound);
1537 subsw(zr, rscratch2, highbound - lowbound);
1538 br(Assembler::HS, jumptable_end);
1539 add(rscratch1, rscratch1, rscratch2,
1540 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1541 br(rscratch1);
1542 }
1543
1544 // Form an address from base + offset in Rd. Rd may or may not
1545 // actually be used: you must use the Address that is returned. It
1546 // is up to you to ensure that the shift provided matches the size
1547 // of your data.
1548 Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1549
1550 // Return true iff an address is within the 48-bit AArch64 address
1551 // space.
1552 bool is_valid_AArch64_address(address a) {
1587 #define ARRAYS_HASHCODE_REGISTERS \
1588 do { \
1589 assert(result == r0 && \
1590 ary == r1 && \
1591 cnt == r2 && \
1592 vdata0 == v3 && \
1593 vdata1 == v2 && \
1594 vdata2 == v1 && \
1595 vdata3 == v0 && \
1596 vmul0 == v4 && \
1597 vmul1 == v5 && \
1598 vmul2 == v6 && \
1599 vmul3 == v7 && \
1600 vpow == v12 && \
1601 vpowm == v13, "registers must match aarch64.ad"); \
1602 } while (0)
1603
1604 void string_equals(Register a1, Register a2, Register result, Register cnt1);
1605
1606 void fill_words(Register base, Register cnt, Register value);
1607 void fill_words(Register base, uint64_t cnt, Register value);
1608
1609 address zero_words(Register base, uint64_t cnt);
1610 address zero_words(Register ptr, Register cnt);
1611 void zero_dcache_blocks(Register base, Register cnt);
1612
1613 static const int zero_words_block_size;
1614
1615 address byte_array_inflate(Register src, Register dst, Register len,
1616 FloatRegister vtmp1, FloatRegister vtmp2,
1617 FloatRegister vtmp3, Register tmp4);
1618
1619 void char_array_compress(Register src, Register dst, Register len,
1620 Register res,
1621 FloatRegister vtmp0, FloatRegister vtmp1,
1622 FloatRegister vtmp2, FloatRegister vtmp3,
1623 FloatRegister vtmp4, FloatRegister vtmp5);
1624
1625 void encode_iso_array(Register src, Register dst,
1626 Register len, Register res, bool ascii,
1627 FloatRegister vtmp0, FloatRegister vtmp1,
1628 FloatRegister vtmp2, FloatRegister vtmp3,
|