< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Print this page

   1 /*
   2  * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  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.inline.hpp"
  30 #include "code/vmreg.hpp"
  31 #include "metaprogramming/enableIf.hpp"
  32 #include "oops/compressedOops.hpp"
  33 #include "oops/compressedKlass.hpp"
  34 #include "runtime/vm_version.hpp"

  35 #include "utilities/powerOfTwo.hpp"




  36 
  37 class OopMap;
  38 
  39 // MacroAssembler extends Assembler by frequently used macros.
  40 //
  41 // Instructions for which a 'better' code sequence exists depending
  42 // on arguments should also go in here.
  43 
  44 class MacroAssembler: public Assembler {
  45   friend class LIR_Assembler;
  46 
  47  public:
  48   using Assembler::mov;
  49   using Assembler::movi;
  50 
  51  protected:
  52 
  53   // Support for VM calls
  54   //
  55   // This is the base routine called by the different versions of call_VM_leaf. The interpreter

 632     msr(0b011, 0b0100, 0b0010, 0b000, reg);
 633   }
 634 
 635   // idiv variant which deals with MINLONG as dividend and -1 as divisor
 636   int corrected_idivl(Register result, Register ra, Register rb,
 637                       bool want_remainder, Register tmp = rscratch1);
 638   int corrected_idivq(Register result, Register ra, Register rb,
 639                       bool want_remainder, Register tmp = rscratch1);
 640 
 641   // Support for null-checks
 642   //
 643   // Generates code that causes a null OS exception if the content of reg is null.
 644   // If the accessed location is M[reg + offset] and the offset is known, provide the
 645   // offset. No explicit code generation is needed if the offset is within a certain
 646   // range (0 <= offset <= page_size).
 647 
 648   virtual void null_check(Register reg, int offset = -1);
 649   static bool needs_explicit_null_check(intptr_t offset);
 650   static bool uses_implicit_null_check(void* address);
 651 























 652   static address target_addr_for_insn(address insn_addr, unsigned insn);
 653   static address target_addr_for_insn_or_null(address insn_addr, unsigned insn);
 654   static address target_addr_for_insn(address insn_addr) {
 655     unsigned insn = *(unsigned*)insn_addr;
 656     return target_addr_for_insn(insn_addr, insn);
 657   }
 658   static address target_addr_for_insn_or_null(address insn_addr) {
 659     unsigned insn = *(unsigned*)insn_addr;
 660     return target_addr_for_insn_or_null(insn_addr, insn);
 661   }
 662 
 663   // Required platform-specific helpers for Label::patch_instructions.
 664   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
 665   static int pd_patch_instruction_size(address branch, address target);
 666   static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
 667     pd_patch_instruction_size(branch, target);
 668   }
 669   static address pd_call_destination(address branch) {
 670     return target_addr_for_insn(branch);
 671   }

 869 
 870   void reset_last_Java_frame(Register thread);
 871 
 872   // thread in the default location (rthread)
 873   void reset_last_Java_frame(bool clear_fp);
 874 
 875   // Stores
 876   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
 877   void store_check(Register obj, Address dst);   // same as above, dst is exact store location (reg. is destroyed)
 878 
 879   void resolve_jobject(Register value, Register tmp1, Register tmp2);
 880   void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
 881 
 882   // C 'boolean' to Java boolean: x == 0 ? 0 : 1
 883   void c2bool(Register x);
 884 
 885   void load_method_holder_cld(Register rresult, Register rmethod);
 886   void load_method_holder(Register holder, Register method);
 887 
 888   // oop manipulations


 889   void load_narrow_klass_compact(Register dst, Register src);
 890   void load_klass(Register dst, Register src);
 891   void store_klass(Register dst, Register src);
 892   void cmp_klass(Register obj, Register klass, Register tmp);
 893   void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
 894 
 895   void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
 896   void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
 897   void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
 898 
 899   void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
 900                       Register tmp1, Register tmp2);
 901 
 902   void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
 903                        Register tmp1, Register tmp2, Register tmp3);
 904 









 905   void load_heap_oop(Register dst, Address src, Register tmp1,
 906                      Register tmp2, DecoratorSet decorators = 0);
 907 
 908   void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
 909                               Register tmp2, DecoratorSet decorators = 0);
 910   void store_heap_oop(Address dst, Register val, Register tmp1,
 911                       Register tmp2, Register tmp3, DecoratorSet decorators = 0);
 912 
 913   // currently unimplemented
 914   // Used for storing null. All other oop constants should be
 915   // stored using routines that take a jobject.
 916   void store_heap_oop_null(Address dst);
 917 


 918   void store_klass_gap(Register dst, Register src);
 919 
 920   // This dummy is to prevent a call to store_heap_oop from
 921   // converting a zero (like null) into a Register by giving
 922   // the compiler two choices it can't resolve
 923 
 924   void store_heap_oop(Address dst, void* dummy);
 925 
 926   void encode_heap_oop(Register d, Register s);
 927   void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
 928   void decode_heap_oop(Register d, Register s);
 929   void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
 930   void encode_heap_oop_not_null(Register r);
 931   void decode_heap_oop_not_null(Register r);
 932   void encode_heap_oop_not_null(Register dst, Register src);
 933   void decode_heap_oop_not_null(Register dst, Register src);
 934 
 935   void set_narrow_oop(Register dst, jobject obj);
 936 
 937   void encode_klass_not_null(Register r);

 948 
 949   void push_CPU_state(bool save_vectors = false, bool use_sve = false,
 950                       int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 951   void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
 952                      int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 953 
 954   void push_cont_fastpath(Register java_thread = rthread);
 955   void pop_cont_fastpath(Register java_thread = rthread);
 956 
 957   void inc_held_monitor_count(Register tmp);
 958   void dec_held_monitor_count(Register tmp);
 959 
 960   // Round up to a power of two
 961   void round_to(Register reg, int modulus);
 962 
 963   // java.lang.Math::round intrinsics
 964   void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
 965   void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
 966 
 967   // allocation









 968   void tlab_allocate(
 969     Register obj,                      // result: pointer to object after successful allocation
 970     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
 971     int      con_size_in_bytes,        // object size in bytes if   known at compile time
 972     Register t1,                       // temp register
 973     Register t2,                       // temp register
 974     Label&   slow_case                 // continuation point if fast allocation fails
 975   );
 976   void verify_tlab();
 977 





 978   // interface method calling
 979   void lookup_interface_method(Register recv_klass,
 980                                Register intf_klass,
 981                                RegisterOrConstant itable_index,
 982                                Register method_result,
 983                                Register scan_temp,
 984                                Label& no_such_interface,
 985                    bool return_method = true);
 986 
 987   void lookup_interface_method_stub(Register recv_klass,
 988                                     Register holder_klass,
 989                                     Register resolved_klass,
 990                                     Register method_result,
 991                                     Register temp_reg,
 992                                     Register temp_reg2,
 993                                     int itable_index,
 994                                     Label& L_no_such_interface);
 995 
 996   // virtual method calling
 997   // n.b. x86 allows RegisterOrConstant for vtable_index

1419   }                                                                     \
1420                                                                         \
1421   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1422     Assembler::INSN(Rd, Rn, Rm);                                        \
1423   }                                                                     \
1424                                                                         \
1425   void INSN(Register Rd, Register Rn, Register Rm,                      \
1426            ext::operation option, int amount = 0) {                     \
1427     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1428   }
1429 
1430   WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1431 
1432   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1433   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1434   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1435   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1436 
1437   void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1438 


















1439   void tableswitch(Register index, jint lowbound, jint highbound,
1440                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1441     adr(rscratch1, jumptable);
1442     subsw(rscratch2, index, lowbound);
1443     subsw(zr, rscratch2, highbound - lowbound);
1444     br(Assembler::HS, jumptable_end);
1445     add(rscratch1, rscratch1, rscratch2,
1446         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1447     br(rscratch1);
1448   }
1449 
1450   // Form an address from base + offset in Rd.  Rd may or may not
1451   // actually be used: you must use the Address that is returned.  It
1452   // is up to you to ensure that the shift provided matches the size
1453   // of your data.
1454   Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1455 
1456   // Return true iff an address is within the 48-bit AArch64 address
1457   // space.
1458   bool is_valid_AArch64_address(address a) {

1500 #define ARRAYS_HASHCODE_REGISTERS \
1501   do {                      \
1502     assert(result == r0  && \
1503            ary    == r1  && \
1504            cnt    == r2  && \
1505            vdata0 == v3  && \
1506            vdata1 == v2  && \
1507            vdata2 == v1  && \
1508            vdata3 == v0  && \
1509            vmul0  == v4  && \
1510            vmul1  == v5  && \
1511            vmul2  == v6  && \
1512            vmul3  == v7  && \
1513            vpow   == v12 && \
1514            vpowm  == v13, "registers must match aarch64.ad"); \
1515   } while (0)
1516 
1517   void string_equals(Register a1, Register a2, Register result, Register cnt1);
1518 
1519   void fill_words(Register base, Register cnt, Register value);


1520   address zero_words(Register base, uint64_t cnt);
1521   address zero_words(Register ptr, Register cnt);
1522   void zero_dcache_blocks(Register base, Register cnt);
1523 
1524   static const int zero_words_block_size;
1525 
1526   address byte_array_inflate(Register src, Register dst, Register len,
1527                              FloatRegister vtmp1, FloatRegister vtmp2,
1528                              FloatRegister vtmp3, Register tmp4);
1529 
1530   void char_array_compress(Register src, Register dst, Register len,
1531                            Register res,
1532                            FloatRegister vtmp0, FloatRegister vtmp1,
1533                            FloatRegister vtmp2, FloatRegister vtmp3,
1534                            FloatRegister vtmp4, FloatRegister vtmp5);
1535 
1536   void encode_iso_array(Register src, Register dst,
1537                         Register len, Register res, bool ascii,
1538                         FloatRegister vtmp0, FloatRegister vtmp1,
1539                         FloatRegister vtmp2, FloatRegister vtmp3,

   1 /*
   2  * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, 2024, Red Hat Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  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.inline.hpp"
  30 #include "code/vmreg.hpp"
  31 #include "metaprogramming/enableIf.hpp"
  32 #include "oops/compressedOops.hpp"
  33 #include "oops/compressedKlass.hpp"
  34 #include "runtime/vm_version.hpp"
  35 #include "utilities/macros.hpp"
  36 #include "utilities/powerOfTwo.hpp"
  37 #include "runtime/signature.hpp"
  38 
  39 
  40 class ciInlineKlass;
  41 
  42 class OopMap;
  43 
  44 // MacroAssembler extends Assembler by frequently used macros.
  45 //
  46 // Instructions for which a 'better' code sequence exists depending
  47 // on arguments should also go in here.
  48 
  49 class MacroAssembler: public Assembler {
  50   friend class LIR_Assembler;
  51 
  52  public:
  53   using Assembler::mov;
  54   using Assembler::movi;
  55 
  56  protected:
  57 
  58   // Support for VM calls
  59   //
  60   // This is the base routine called by the different versions of call_VM_leaf. The interpreter

 637     msr(0b011, 0b0100, 0b0010, 0b000, reg);
 638   }
 639 
 640   // idiv variant which deals with MINLONG as dividend and -1 as divisor
 641   int corrected_idivl(Register result, Register ra, Register rb,
 642                       bool want_remainder, Register tmp = rscratch1);
 643   int corrected_idivq(Register result, Register ra, Register rb,
 644                       bool want_remainder, Register tmp = rscratch1);
 645 
 646   // Support for null-checks
 647   //
 648   // Generates code that causes a null OS exception if the content of reg is null.
 649   // If the accessed location is M[reg + offset] and the offset is known, provide the
 650   // offset. No explicit code generation is needed if the offset is within a certain
 651   // range (0 <= offset <= page_size).
 652 
 653   virtual void null_check(Register reg, int offset = -1);
 654   static bool needs_explicit_null_check(intptr_t offset);
 655   static bool uses_implicit_null_check(void* address);
 656 
 657   // markWord tests, kills markWord reg
 658   void test_markword_is_inline_type(Register markword, Label& is_inline_type);
 659 
 660   // inlineKlass queries, kills temp_reg
 661   void test_klass_is_inline_type(Register klass, Register temp_reg, Label& is_inline_type);
 662   void test_oop_is_not_inline_type(Register object, Register tmp, Label& not_inline_type);
 663 
 664   void test_field_is_null_free_inline_type(Register flags, Register temp_reg, Label& is_null_free);
 665   void test_field_is_not_null_free_inline_type(Register flags, Register temp_reg, Label& not_null_free);
 666   void test_field_is_flat(Register flags, Register temp_reg, Label& is_flat);
 667   void test_field_has_null_marker(Register flags, Register temp_reg, Label& has_null_marker);
 668 
 669   // Check oops for special arrays, i.e. flat arrays and/or null-free arrays
 670   void test_oop_prototype_bit(Register oop, Register temp_reg, int32_t test_bit, bool jmp_set, Label& jmp_label);
 671   void test_flat_array_oop(Register klass, Register temp_reg, Label& is_flat_array);
 672   void test_non_flat_array_oop(Register oop, Register temp_reg, Label&is_non_flat_array);
 673   void test_null_free_array_oop(Register oop, Register temp_reg, Label& is_null_free_array);
 674   void test_non_null_free_array_oop(Register oop, Register temp_reg, Label&is_non_null_free_array);
 675 
 676   // Check array klass layout helper for flat or null-free arrays...
 677   void test_flat_array_layout(Register lh, Label& is_flat_array);
 678   void test_non_flat_array_layout(Register lh, Label& is_non_flat_array);
 679 
 680   static address target_addr_for_insn(address insn_addr, unsigned insn);
 681   static address target_addr_for_insn_or_null(address insn_addr, unsigned insn);
 682   static address target_addr_for_insn(address insn_addr) {
 683     unsigned insn = *(unsigned*)insn_addr;
 684     return target_addr_for_insn(insn_addr, insn);
 685   }
 686   static address target_addr_for_insn_or_null(address insn_addr) {
 687     unsigned insn = *(unsigned*)insn_addr;
 688     return target_addr_for_insn_or_null(insn_addr, insn);
 689   }
 690 
 691   // Required platform-specific helpers for Label::patch_instructions.
 692   // They _shadow_ the declarations in AbstractAssembler, which are undefined.
 693   static int pd_patch_instruction_size(address branch, address target);
 694   static void pd_patch_instruction(address branch, address target, const char* file = nullptr, int line = 0) {
 695     pd_patch_instruction_size(branch, target);
 696   }
 697   static address pd_call_destination(address branch) {
 698     return target_addr_for_insn(branch);
 699   }

 897 
 898   void reset_last_Java_frame(Register thread);
 899 
 900   // thread in the default location (rthread)
 901   void reset_last_Java_frame(bool clear_fp);
 902 
 903   // Stores
 904   void store_check(Register obj);                // store check for obj - register is destroyed afterwards
 905   void store_check(Register obj, Address dst);   // same as above, dst is exact store location (reg. is destroyed)
 906 
 907   void resolve_jobject(Register value, Register tmp1, Register tmp2);
 908   void resolve_global_jobject(Register value, Register tmp1, Register tmp2);
 909 
 910   // C 'boolean' to Java boolean: x == 0 ? 0 : 1
 911   void c2bool(Register x);
 912 
 913   void load_method_holder_cld(Register rresult, Register rmethod);
 914   void load_method_holder(Register holder, Register method);
 915 
 916   // oop manipulations
 917   void load_metadata(Register dst, Register src);
 918 
 919   void load_narrow_klass_compact(Register dst, Register src);
 920   void load_klass(Register dst, Register src);
 921   void store_klass(Register dst, Register src);
 922   void cmp_klass(Register obj, Register klass, Register tmp);
 923   void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
 924 
 925   void resolve_weak_handle(Register result, Register tmp1, Register tmp2);
 926   void resolve_oop_handle(Register result, Register tmp1, Register tmp2);
 927   void load_mirror(Register dst, Register method, Register tmp1, Register tmp2);
 928 
 929   void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
 930                       Register tmp1, Register tmp2);
 931 
 932   void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
 933                        Register tmp1, Register tmp2, Register tmp3);
 934 
 935   void flat_field_copy(DecoratorSet decorators, Register src, Register dst, Register inline_layout_info);
 936 
 937   // inline type data payload offsets...
 938   void payload_offset(Register inline_klass, Register offset);
 939   void payload_address(Register oop, Register data, Register inline_klass);
 940   // get data payload ptr a flat value array at index, kills rcx and index
 941   void data_for_value_array_index(Register array, Register array_klass,
 942                                   Register index, Register data);
 943 
 944   void load_heap_oop(Register dst, Address src, Register tmp1,
 945                      Register tmp2, DecoratorSet decorators = 0);
 946 
 947   void load_heap_oop_not_null(Register dst, Address src, Register tmp1,
 948                               Register tmp2, DecoratorSet decorators = 0);
 949   void store_heap_oop(Address dst, Register val, Register tmp1,
 950                       Register tmp2, Register tmp3, DecoratorSet decorators = 0);
 951 
 952   // currently unimplemented
 953   // Used for storing null. All other oop constants should be
 954   // stored using routines that take a jobject.
 955   void store_heap_oop_null(Address dst);
 956 
 957   void load_prototype_header(Register dst, Register src);
 958 
 959   void store_klass_gap(Register dst, Register src);
 960 
 961   // This dummy is to prevent a call to store_heap_oop from
 962   // converting a zero (like null) into a Register by giving
 963   // the compiler two choices it can't resolve
 964 
 965   void store_heap_oop(Address dst, void* dummy);
 966 
 967   void encode_heap_oop(Register d, Register s);
 968   void encode_heap_oop(Register r) { encode_heap_oop(r, r); }
 969   void decode_heap_oop(Register d, Register s);
 970   void decode_heap_oop(Register r) { decode_heap_oop(r, r); }
 971   void encode_heap_oop_not_null(Register r);
 972   void decode_heap_oop_not_null(Register r);
 973   void encode_heap_oop_not_null(Register dst, Register src);
 974   void decode_heap_oop_not_null(Register dst, Register src);
 975 
 976   void set_narrow_oop(Register dst, jobject obj);
 977 
 978   void encode_klass_not_null(Register r);

 989 
 990   void push_CPU_state(bool save_vectors = false, bool use_sve = false,
 991                       int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 992   void pop_CPU_state(bool restore_vectors = false, bool use_sve = false,
 993                      int sve_vector_size_in_bytes = 0, int total_predicate_in_bytes = 0);
 994 
 995   void push_cont_fastpath(Register java_thread = rthread);
 996   void pop_cont_fastpath(Register java_thread = rthread);
 997 
 998   void inc_held_monitor_count(Register tmp);
 999   void dec_held_monitor_count(Register tmp);
1000 
1001   // Round up to a power of two
1002   void round_to(Register reg, int modulus);
1003 
1004   // java.lang.Math::round intrinsics
1005   void java_round_double(Register dst, FloatRegister src, FloatRegister ftmp);
1006   void java_round_float(Register dst, FloatRegister src, FloatRegister ftmp);
1007 
1008   // allocation
1009 
1010   // Object / value buffer allocation...
1011   // Allocate instance of klass, assumes klass initialized by caller
1012   // new_obj prefers to be rax
1013   // Kills t1 and t2, perserves klass, return allocation in new_obj (rsi on LP64)
1014   void allocate_instance(Register klass, Register new_obj,
1015                          Register t1, Register t2,
1016                          bool clear_fields, Label& alloc_failed);
1017 
1018   void tlab_allocate(
1019     Register obj,                      // result: pointer to object after successful allocation
1020     Register var_size_in_bytes,        // object size in bytes if unknown at compile time; invalid otherwise
1021     int      con_size_in_bytes,        // object size in bytes if   known at compile time
1022     Register t1,                       // temp register
1023     Register t2,                       // temp register
1024     Label&   slow_case                 // continuation point if fast allocation fails
1025   );
1026   void verify_tlab();
1027 
1028   // For field "index" within "klass", return inline_klass ...
1029   void get_inline_type_field_klass(Register klass, Register index, Register inline_klass);
1030   void inline_layout_info(Register holder_klass, Register index, Register layout_info);
1031 
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

1474   }                                                                     \
1475                                                                         \
1476   void INSN(Register Rd, Register Rn, Register Rm) {                    \
1477     Assembler::INSN(Rd, Rn, Rm);                                        \
1478   }                                                                     \
1479                                                                         \
1480   void INSN(Register Rd, Register Rn, Register Rm,                      \
1481            ext::operation option, int amount = 0) {                     \
1482     Assembler::INSN(Rd, Rn, Rm, option, amount);                        \
1483   }
1484 
1485   WRAP(adds, false) WRAP(addsw, true) WRAP(subs, false) WRAP(subsw, true)
1486 
1487   void add(Register Rd, Register Rn, RegisterOrConstant increment);
1488   void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1489   void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1490   void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1491 
1492   void adrp(Register reg1, const Address &dest, uint64_t &byte_offset);
1493 
1494   void verified_entry(Compile* C, int sp_inc);
1495 
1496   // Inline type specific methods
1497   #include "asm/macroAssembler_common.hpp"
1498 
1499   int store_inline_type_fields_to_buf(ciInlineKlass* vk, bool from_interpreter = true);
1500   bool move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[]);
1501   bool unpack_inline_helper(const GrowableArray<SigEntry>* sig, int& sig_index,
1502                             VMReg from, int& from_index, VMRegPair* to, int to_count, int& to_index,
1503                             RegState reg_state[]);
1504   bool pack_inline_helper(const GrowableArray<SigEntry>* sig, int& sig_index, int vtarg_index,
1505                           VMRegPair* from, int from_count, int& from_index, VMReg to,
1506                           RegState reg_state[], Register val_array);
1507   int extend_stack_for_inline_args(int args_on_stack);
1508   void remove_frame(int initial_framesize, bool needs_stack_repair);
1509   VMReg spill_reg_for(VMReg reg);
1510   void save_stack_increment(int sp_inc, int frame_size);
1511 
1512   void tableswitch(Register index, jint lowbound, jint highbound,
1513                    Label &jumptable, Label &jumptable_end, int stride = 1) {
1514     adr(rscratch1, jumptable);
1515     subsw(rscratch2, index, lowbound);
1516     subsw(zr, rscratch2, highbound - lowbound);
1517     br(Assembler::HS, jumptable_end);
1518     add(rscratch1, rscratch1, rscratch2,
1519         ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1520     br(rscratch1);
1521   }
1522 
1523   // Form an address from base + offset in Rd.  Rd may or may not
1524   // actually be used: you must use the Address that is returned.  It
1525   // is up to you to ensure that the shift provided matches the size
1526   // of your data.
1527   Address form_address(Register Rd, Register base, int64_t byte_offset, int shift);
1528 
1529   // Return true iff an address is within the 48-bit AArch64 address
1530   // space.
1531   bool is_valid_AArch64_address(address a) {

1573 #define ARRAYS_HASHCODE_REGISTERS \
1574   do {                      \
1575     assert(result == r0  && \
1576            ary    == r1  && \
1577            cnt    == r2  && \
1578            vdata0 == v3  && \
1579            vdata1 == v2  && \
1580            vdata2 == v1  && \
1581            vdata3 == v0  && \
1582            vmul0  == v4  && \
1583            vmul1  == v5  && \
1584            vmul2  == v6  && \
1585            vmul3  == v7  && \
1586            vpow   == v12 && \
1587            vpowm  == v13, "registers must match aarch64.ad"); \
1588   } while (0)
1589 
1590   void string_equals(Register a1, Register a2, Register result, Register cnt1);
1591 
1592   void fill_words(Register base, Register cnt, Register value);
1593   void fill_words(Register base, uint64_t cnt, Register value);
1594 
1595   address zero_words(Register base, uint64_t cnt);
1596   address zero_words(Register ptr, Register cnt);
1597   void zero_dcache_blocks(Register base, Register cnt);
1598 
1599   static const int zero_words_block_size;
1600 
1601   address byte_array_inflate(Register src, Register dst, Register len,
1602                              FloatRegister vtmp1, FloatRegister vtmp2,
1603                              FloatRegister vtmp3, Register tmp4);
1604 
1605   void char_array_compress(Register src, Register dst, Register len,
1606                            Register res,
1607                            FloatRegister vtmp0, FloatRegister vtmp1,
1608                            FloatRegister vtmp2, FloatRegister vtmp3,
1609                            FloatRegister vtmp4, FloatRegister vtmp5);
1610 
1611   void encode_iso_array(Register src, Register dst,
1612                         Register len, Register res, bool ascii,
1613                         FloatRegister vtmp0, FloatRegister vtmp1,
1614                         FloatRegister vtmp2, FloatRegister vtmp3,
< prev index next >