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.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/vm_version.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/powerOfTwo.hpp"
38
39 class OopMap;
40
41 // MacroAssembler extends Assembler by frequently used macros.
42 //
43 // Instructions for which a 'better' code sequence exists depending
44 // on arguments should also go in here.
45
46 class MacroAssembler: public Assembler {
47 friend class LIR_Assembler;
48
49 public:
50 using Assembler::mov;
51 using Assembler::movi;
52
53 protected:
54
55 // Support for VM calls
56 //
57 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
168
169 void bind(Label& L) {
170 Assembler::bind(L);
171 code()->clear_last_merge_candidate();
172 code()->set_last_label(pc());
173 }
174
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 // Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__
196 // Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention."
197 // https://reviews.llvm.org/D3311
198
199 #ifdef _WIN64
200 #define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__)
201 #else
202 #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__)
203 #endif
204
205 // aliases defined in AARCH64 spec
206
207 template<class T>
208 inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); }
660 mrs(0b011, 0b1110, 0b0000, 0b110, reg);
661 }
662
663 // idiv variant which deals with MINLONG as dividend and -1 as divisor
664 int corrected_idivl(Register result, Register ra, Register rb,
665 bool want_remainder, Register tmp = rscratch1);
666 int corrected_idivq(Register result, Register ra, Register rb,
667 bool want_remainder, Register tmp = rscratch1);
668
669 // Support for null-checks
670 //
671 // Generates code that causes a null OS exception if the content of reg is null.
672 // If the accessed location is M[reg + offset] and the offset is known, provide the
673 // offset. No explicit code generation is needed if the offset is within a certain
674 // range (0 <= offset <= page_size).
675
676 virtual void null_check(Register reg, int offset = -1);
677 static bool needs_explicit_null_check(intptr_t offset);
678 static bool uses_implicit_null_check(void* address);
679
680 static address target_addr_for_insn(address insn_addr);
681
682 // Required platform-specific helpers for Label::patch_instructions.
683 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
684 static int pd_patch_instruction_size(address branch, address target);
685 static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
686 pd_patch_instruction_size(branch, target);
687 }
688 static address pd_call_destination(address branch) {
689 return target_addr_for_insn(branch);
690 }
691 #ifndef PRODUCT
692 static void pd_print_patched_instruction(address branch);
693 #endif
694
695 static int patch_oop(address insn_addr, address o);
696
697 // Return whether code is emitted to a scratch blob.
698 virtual bool in_scratch_emit_size() {
699 return false;
886 void set_last_Java_frame(Register last_java_sp,
887 Register last_java_fp,
888 Register last_java_pc,
889 Register scratch);
890
891 void reset_last_Java_frame(Register thread);
892
893 // thread in the default location (rthread)
894 void reset_last_Java_frame(bool clear_fp);
895
896 void resolve_jobject(Register value, Register tmp1, Register tmp2);
897 void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
898
899 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
900 void c2bool(Register x);
901
902 void load_method_holder_cld(Register rresult, Register rmethod);
903 void load_method_holder(Register holder, Register method);
904
905 // oop manipulations
906 void load_narrow_klass_compact(Register dst, Register src);
907 void load_klass(Register dst, Register src);
908 void store_klass(Register dst, Register src);
909 void cmp_klass(Register obj, Register klass, Register tmp);
910 void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
911
912 void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
913 void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
914 void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
915
916 void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
917 Register tmp1, Register tmp2);
918
919 void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
920 Register tmp1, Register tmp2, Register tmp3);
921
922 void load_heap_oop(Register dst, Address src, Register tmp1,
923 Register tmp2, DecoratorSet decorators = 0);
924
925 void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
926 Register tmp2, DecoratorSet decorators = 0);
927 void store_heap_oop(Address dst, Register val, Register tmp1,
928 Register tmp2, Register tmp3, DecoratorSet decorators = 0);
929
930 // currently unimplemented
931 // Used for storing null. All other oop constants should be
932 // stored using routines that take a jobject.
933 void store_heap_oop_null(Address dst);
934
935 void store_klass_gap(Register dst, Register src);
936
937 // This dummy is to prevent a call to store_heap_oop from
938 // converting a zero (like null) into a Register by giving
939 // the compiler two choices it can't resolve
940
941 void store_heap_oop(Address dst, void* dummy);
942
943 void encode_heap_oop(Register d, Register s);
944 void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
945 void decode_heap_oop(Register d, Register s);
946 void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
947 void encode_heap_oop_not_null(Register r);
948 void decode_heap_oop_not_null(Register r);
949 void encode_heap_oop_not_null(Register dst, Register src);
950 void decode_heap_oop_not_null(Register dst, Register src);
951
952 void set_narrow_oop(Register dst, jobject obj);
953
954 void decode_klass_not_null_for_aot(Register dst, Register src);
964 void reinit_heapbase();
965
966 DEBUG_ONLY(void verify_heapbase(const char* msg);)
967
968 void push_CPU_state(bool save_vectors = false, bool use_sve = false,
969 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
970 void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
971 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
972
973 void push_cont_fastpath(Register java_thread = rthread);
974 void pop_cont_fastpath(Register java_thread = rthread);
975
976 // Round up to a power of two
977 void round_to(Register reg, int modulus);
978
979 // java.lang.Math::round intrinsics
980 void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
981 void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
982
983 // allocation
984 void tlab_allocate(
985 Register obj, // result: pointer to object after successful allocation
986 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
987 int con_size_in_bytes, // object size in bytes if known at compile time
988 Register t1, // temp register
989 Register t2, // temp register
990 Label& slow_case // continuation point if fast allocation fails
991 );
992 void verify_tlab();
993
994 // interface method calling
995 void lookup_interface_method(Register recv_klass,
996 Register intf_klass,
997 RegisterOrConstant itable_index,
998 Register method_result,
999 Register scan_temp,
1000 Label& no_such_interface,
1001 bool return_method = true);
1002
1003 void lookup_interface_method_stub(Register recv_klass,
1004 Register holder_klass,
1005 Register resolved_klass,
1006 Register method_result,
1007 Register temp_reg,
1008 Register temp_reg2,
1009 int itable_index,
1010 Label& L_no_such_interface);
1011
1012 // virtual method calling
1013 // n.b. x86 allows RegisterOrConstant for vtable_index
1431 } \
1432 \
1433 void INSN(Register Rd, Register Rn, Register Rm) { \
1434 Assembler::INSN(Rd, Rn, Rm); \
1435 } \
1436 \
1437 void INSN(Register Rd, Register Rn, Register Rm, \
1438 ext::operation option, int amount = 0) { \
1439 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1440 }
1441
1442 WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1443
1444 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1445 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1446 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1447 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1448
1449 void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1450
1451 void tableswitch(Register index, jint lowbound, jint highbound,
1452 Label &jumptable, Label &jumptable_end, int stride = 1) {
1453 adr(rscratch1, jumptable);
1454 subsw(rscratch2, index, lowbound);
1455 subsw(zr, rscratch2, highbound - lowbound);
1456 br(Assembler::HS, jumptable_end);
1457 add(rscratch1, rscratch1, rscratch2,
1458 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1459 br(rscratch1);
1460 }
1461
1462 // Form an address from base + offset in Rd. Rd may or may not
1463 // actually be used: you must use the Address that is returned. It
1464 // is up to you to ensure that the shift provided matches the size
1465 // of your data.
1466 Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1467
1468 // Return true iff an address is within the 48-bit AArch64 address
1469 // space.
1470 bool is_valid_AArch64_address(address a) {
1505 #define ARRAYS_HASHCODE_REGISTERS \
1506 do { \
1507 assert(result == r0 && \
1508 ary == r1 && \
1509 cnt == r2 && \
1510 vdata0 == v3 && \
1511 vdata1 == v2 && \
1512 vdata2 == v1 && \
1513 vdata3 == v0 && \
1514 vmul0 == v4 && \
1515 vmul1 == v5 && \
1516 vmul2 == v6 && \
1517 vmul3 == v7 && \
1518 vpow == v12 && \
1519 vpowm == v13, "registers must match aarch64.ad"); \
1520 } while (0)
1521
1522 void string_equals(Register a1, Register a2, Register result, Register cnt1);
1523
1524 void fill_words(Register base, Register cnt, Register value);
1525 address zero_words(Register base, uint64_t cnt);
1526 address zero_words(Register ptr, Register cnt);
1527 void zero_dcache_blocks(Register base, Register cnt);
1528
1529 static const int zero_words_block_size;
1530
1531 address byte_array_inflate(Register src, Register dst, Register len,
1532 FloatRegister vtmp1, FloatRegister vtmp2,
1533 FloatRegister vtmp3, Register tmp4);
1534
1535 void char_array_compress(Register src, Register dst, Register len,
1536 Register res,
1537 FloatRegister vtmp0, FloatRegister vtmp1,
1538 FloatRegister vtmp2, FloatRegister vtmp3,
1539 FloatRegister vtmp4, FloatRegister vtmp5);
1540
1541 void encode_iso_array(Register src, Register dst,
1542 Register len, Register res, bool ascii,
1543 FloatRegister vtmp0, FloatRegister vtmp1,
1544 FloatRegister vtmp2, FloatRegister vtmp3,
|
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.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/vm_version.hpp"
36 #include "utilities/globalDefinitions.hpp"
37 #include "utilities/macros.hpp"
38 #include "utilities/powerOfTwo.hpp"
39 #include "runtime/signature.hpp"
40
41
42 class ciInlineKlass;
43
44 class OopMap;
45
46 // MacroAssembler extends Assembler by frequently used macros.
47 //
48 // Instructions for which a 'better' code sequence exists depending
49 // on arguments should also go in here.
50
51 class MacroAssembler: public Assembler {
52 friend class LIR_Assembler;
53
54 public:
55 using Assembler::mov;
56 using Assembler::movi;
57
58 protected:
59
60 // Support for VM calls
61 //
62 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
173
174 void bind(Label& L) {
175 Assembler::bind(L);
176 code()->clear_last_merge_candidate();
177 code()->set_last_label(pc());
178 }
179
180 void membar(Membar_mask_bits order_constraint);
181
182 using Assembler::ldr;
183 using Assembler::str;
184 using Assembler::ldrw;
185 using Assembler::strw;
186
187 void ldr(Register Rx, const Address &adr);
188 void ldrw(Register Rw, const Address &adr);
189 void str(Register Rx, const Address &adr);
190 void strw(Register Rx, const Address &adr);
191
192 // Frame creation and destruction shared between JITs.
193 DEBUG_ONLY(void build_frame(int framesize);)
194 void build_frame(int framesize DEBUG_ONLY(COMMA bool zap_rfp_lr_spills));
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); }
666 mrs(0b011, 0b1110, 0b0000, 0b110, reg);
667 }
668
669 // idiv variant which deals with MINLONG as dividend and -1 as divisor
670 int corrected_idivl(Register result, Register ra, Register rb,
671 bool want_remainder, Register tmp = rscratch1);
672 int corrected_idivq(Register result, Register ra, Register rb,
673 bool want_remainder, Register tmp = rscratch1);
674
675 // Support for null-checks
676 //
677 // Generates code that causes a null OS exception if the content of reg is null.
678 // If the accessed location is M[reg + offset] and the offset is known, provide the
679 // offset. No explicit code generation is needed if the offset is within a certain
680 // range (0 <= offset <= page_size).
681
682 virtual void null_check(Register reg, int offset = -1);
683 static bool needs_explicit_null_check(intptr_t offset);
684 static bool uses_implicit_null_check(void* address);
685
686 // markWord tests, kills markWord reg
687 void test_markword_is_inline_type(Register markword, Label& is_inline_type);
688
689 // inlineKlass queries, kills temp_reg
690 void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type, bool can_be_null = true);
691
692 void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
693 void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
694 void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
695
696 // Check oops for special arrays, i.e. flat arrays and/or null-free arrays
697 void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
698 void test_flat_array_oop(Register klass, Register temp_reg, Label& is_flat_array);
699 void test_non_flat_array_oop(Register oop, Register temp_reg, Label&is_non_flat_array);
700 void test_null_free_array_oop(Register oop, Register temp_reg, Label& is_null_free_array);
701 void test_non_null_free_array_oop(Register oop, Register temp_reg, Label&is_non_null_free_array);
702
703 // Check array klass layout helper for flat or null-free arrays...
704 void test_flat_array_layout(Register lh, Label& is_flat_array);
705
706 static address target_addr_for_insn(address insn_addr);
707
708 // Required platform-specific helpers for Label::patch_instructions.
709 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
710 static int pd_patch_instruction_size(address branch, address target);
711 static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
712 pd_patch_instruction_size(branch, target);
713 }
714 static address pd_call_destination(address branch) {
715 return target_addr_for_insn(branch);
716 }
717 #ifndef PRODUCT
718 static void pd_print_patched_instruction(address branch);
719 #endif
720
721 static int patch_oop(address insn_addr, address o);
722
723 // Return whether code is emitted to a scratch blob.
724 virtual bool in_scratch_emit_size() {
725 return false;
912 void set_last_Java_frame(Register last_java_sp,
913 Register last_java_fp,
914 Register last_java_pc,
915 Register scratch);
916
917 void reset_last_Java_frame(Register thread);
918
919 // thread in the default location (rthread)
920 void reset_last_Java_frame(bool clear_fp);
921
922 void resolve_jobject(Register value, Register tmp1, Register tmp2);
923 void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
924
925 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
926 void c2bool(Register x);
927
928 void load_method_holder_cld(Register rresult, Register rmethod);
929 void load_method_holder(Register holder, Register method);
930
931 // oop manipulations
932 void load_metadata(Register dst, Register src);
933
934 void load_narrow_klass_compact(Register dst, Register src);
935 void load_klass(Register dst, Register src);
936 void store_klass(Register dst, Register src);
937 void cmp_klass(Register obj, Register klass, Register tmp);
938 void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
939
940 void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
941 void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
942 void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
943
944 void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
945 Register tmp1, Register tmp2);
946
947 void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
948 Register tmp1, Register tmp2, Register tmp3);
949
950 void flat_field_copy(DecoratorSet decorators, Register src, Register dst, Register inline_layout_info);
951
952 // inline type data payload offsets...
953 void payload_offset(Register inline_klass, Register offset);
954 void payload_address(Register oop, Register data, Register inline_klass);
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 load_prototype_header(Register dst, Register src);
970
971 void store_klass_gap(Register dst, Register src);
972
973 // This dummy is to prevent a call to store_heap_oop from
974 // converting a zero (like null) into a Register by giving
975 // the compiler two choices it can't resolve
976
977 void store_heap_oop(Address dst, void* dummy);
978
979 void encode_heap_oop(Register d, Register s);
980 void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
981 void decode_heap_oop(Register d, Register s);
982 void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
983 void encode_heap_oop_not_null(Register r);
984 void decode_heap_oop_not_null(Register r);
985 void encode_heap_oop_not_null(Register dst, Register src);
986 void decode_heap_oop_not_null(Register dst, Register src);
987
988 void set_narrow_oop(Register dst, jobject obj);
989
990 void decode_klass_not_null_for_aot(Register dst, Register src);
1000 void reinit_heapbase();
1001
1002 DEBUG_ONLY(void verify_heapbase(const char* msg);)
1003
1004 void push_CPU_state(bool save_vectors = false, bool use_sve = false,
1005 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1006 void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
1007 int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
1008
1009 void push_cont_fastpath(Register java_thread = rthread);
1010 void pop_cont_fastpath(Register java_thread = rthread);
1011
1012 // Round up to a power of two
1013 void round_to(Register reg, int modulus);
1014
1015 // java.lang.Math::round intrinsics
1016 void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
1017 void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
1018
1019 // allocation
1020
1021 void tlab_allocate(
1022 Register obj, // result: pointer to object after successful allocation
1023 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
1024 int con_size_in_bytes, // object size in bytes if known at compile time
1025 Register t1, // temp register
1026 Register t2, // temp register
1027 Label& slow_case // continuation point if fast allocation fails
1028 );
1029 void verify_tlab();
1030
1031 void inline_layout_info(Register holder_klass, Register index, Register layout_info);
1032
1033 // interface method calling
1034 void lookup_interface_method(Register recv_klass,
1035 Register intf_klass,
1036 RegisterOrConstant itable_index,
1037 Register method_result,
1038 Register scan_temp,
1039 Label& no_such_interface,
1040 bool return_method = true);
1041
1042 void lookup_interface_method_stub(Register recv_klass,
1043 Register holder_klass,
1044 Register resolved_klass,
1045 Register method_result,
1046 Register temp_reg,
1047 Register temp_reg2,
1048 int itable_index,
1049 Label& L_no_such_interface);
1050
1051 // virtual method calling
1052 // n.b. x86 allows RegisterOrConstant for vtable_index
1470 } \
1471 \
1472 void INSN(Register Rd, Register Rn, Register Rm) { \
1473 Assembler::INSN(Rd, Rn, Rm); \
1474 } \
1475 \
1476 void INSN(Register Rd, Register Rn, Register Rm, \
1477 ext::operation option, int amount = 0) { \
1478 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1479 }
1480
1481 WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1482
1483 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1484 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1485 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1486 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1487
1488 void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1489
1490 void verified_entry(Compile* C, int sp_inc);
1491
1492 // Inline type specific methods
1493 #include "asm/macroAssembler_common.hpp"
1494
1495 void save_stack_increment(int sp_inc, int frame_size);
1496
1497 void tableswitch(Register index, jint lowbound, jint highbound,
1498 Label &jumptable, Label &jumptable_end, int stride = 1) {
1499 adr(rscratch1, jumptable);
1500 subsw(rscratch2, index, lowbound);
1501 subsw(zr, rscratch2, highbound - lowbound);
1502 br(Assembler::HS, jumptable_end);
1503 add(rscratch1, rscratch1, rscratch2,
1504 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1505 br(rscratch1);
1506 }
1507
1508 // Form an address from base + offset in Rd. Rd may or may not
1509 // actually be used: you must use the Address that is returned. It
1510 // is up to you to ensure that the shift provided matches the size
1511 // of your data.
1512 Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1513
1514 // Return true iff an address is within the 48-bit AArch64 address
1515 // space.
1516 bool is_valid_AArch64_address(address a) {
1551 #define ARRAYS_HASHCODE_REGISTERS \
1552 do { \
1553 assert(result == r0 && \
1554 ary == r1 && \
1555 cnt == r2 && \
1556 vdata0 == v3 && \
1557 vdata1 == v2 && \
1558 vdata2 == v1 && \
1559 vdata3 == v0 && \
1560 vmul0 == v4 && \
1561 vmul1 == v5 && \
1562 vmul2 == v6 && \
1563 vmul3 == v7 && \
1564 vpow == v12 && \
1565 vpowm == v13, "registers must match aarch64.ad"); \
1566 } while (0)
1567
1568 void string_equals(Register a1, Register a2, Register result, Register cnt1);
1569
1570 void fill_words(Register base, Register cnt, Register value);
1571 void fill_words(Register base, uint64_t cnt, Register value);
1572
1573 address zero_words(Register base, uint64_t cnt);
1574 address zero_words(Register ptr, Register cnt);
1575 void zero_dcache_blocks(Register base, Register cnt);
1576
1577 static const int zero_words_block_size;
1578
1579 address byte_array_inflate(Register src, Register dst, Register len,
1580 FloatRegister vtmp1, FloatRegister vtmp2,
1581 FloatRegister vtmp3, Register tmp4);
1582
1583 void char_array_compress(Register src, Register dst, Register len,
1584 Register res,
1585 FloatRegister vtmp0, FloatRegister vtmp1,
1586 FloatRegister vtmp2, FloatRegister vtmp3,
1587 FloatRegister vtmp4, FloatRegister vtmp5);
1588
1589 void encode_iso_array(Register src, Register dst,
1590 Register len, Register res, bool ascii,
1591 FloatRegister vtmp0, FloatRegister vtmp1,
1592 FloatRegister vtmp2, FloatRegister vtmp3,
|