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_VM_MACROASSEMBLER_AARCH64_HPP
27 #define CPU_AARCH64_VM_MACROASSEMBLER_AARCH64_HPP
28
29 #include "asm/assembler.hpp"
30
31 // MacroAssembler extends Assembler by frequently used macros.
32 //
33 // Instructions for which a 'better' code sequence exists depending
34 // on arguments should also go in here.
35
36 class MacroAssembler: public Assembler {
37 friend class LIR_Assembler;
38
39 public:
40 using Assembler::mov;
41 using Assembler::movi;
42
43 protected:
44
45 // Support for VM calls
46 //
47 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
48 // may customize this version by overriding it for its purposes (e.g., to save/restore
49 // additional registers when doing a VM call).
567 mrs(0b011, 0b0000, 0b0000, 0b001, reg);
568 }
569
570 // idiv variant which deals with MINLONG as dividend and -1 as divisor
571 int corrected_idivl(Register result, Register ra, Register rb,
572 bool want_remainder, Register tmp = rscratch1);
573 int corrected_idivq(Register result, Register ra, Register rb,
574 bool want_remainder, Register tmp = rscratch1);
575
576 // Support for NULL-checks
577 //
578 // Generates code that causes a NULL OS exception if the content of reg is NULL.
579 // If the accessed location is M[reg + offset] and the offset is known, provide the
580 // offset. No explicit code generation is needed if the offset is within a certain
581 // range (0 <= offset <= page_size).
582
583 virtual void null_check(Register reg, int offset = -1);
584 static bool needs_explicit_null_check(intptr_t offset);
585 static bool uses_implicit_null_check(void* address);
586
587 static address target_addr_for_insn(address insn_addr, unsigned insn);
588 static address target_addr_for_insn(address insn_addr) {
589 unsigned insn = *(unsigned*)insn_addr;
590 return target_addr_for_insn(insn_addr, insn);
591 }
592
593 // Required platform-specific helpers for Label::patch_instructions.
594 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
595 static int pd_patch_instruction_size(address branch, address target);
596 static void pd_patch_instruction(address branch, address target, const char* file = NULL, int line = 0) {
597 pd_patch_instruction_size(branch, target);
598 }
599 static address pd_call_destination(address branch) {
600 return target_addr_for_insn(branch);
601 }
602 #ifndef PRODUCT
603 static void pd_print_patched_instruction(address branch);
604 #endif
605
606 static int patch_oop(address insn_addr, address o);
1123 Assembler::INSN(Rd, Rn, Rm, kind, shift); \
1124 } \
1125 \
1126 void INSN(Register Rd, Register Rn, Register Rm) { \
1127 Assembler::INSN(Rd, Rn, Rm); \
1128 } \
1129 \
1130 void INSN(Register Rd, Register Rn, Register Rm, \
1131 ext::operation option, int amount = 0) { \
1132 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1133 }
1134
1135 WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1136
1137 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1138 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1139 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1140 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1141
1142 void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
1143
1144 void tableswitch(Register index, jint lowbound, jint highbound,
1145 Label &jumptable, Label &jumptable_end, int stride = 1) {
1146 adr(rscratch1, jumptable);
1147 subsw(rscratch2, index, lowbound);
1148 subsw(zr, rscratch2, highbound - lowbound);
1149 br(Assembler::HS, jumptable_end);
1150 add(rscratch1, rscratch1, rscratch2,
1151 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1152 br(rscratch1);
1153 }
1154
1155 // Form an address from base + offset in Rd. Rd may or may not
1156 // actually be used: you must use the Address that is returned. It
1157 // is up to you to ensure that the shift provided matches the size
1158 // of your data.
1159 Address form_address(Register Rd, Register base, long byte_offset, int shift);
1160
1161 // Return true iff an address is within the 48-bit AArch64 address
1162 // space.
|
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_VM_MACROASSEMBLER_AARCH64_HPP
27 #define CPU_AARCH64_VM_MACROASSEMBLER_AARCH64_HPP
28
29 #include "asm/assembler.hpp"
30 #include "runtime/signature.hpp"
31
32
33 // MacroAssembler extends Assembler by frequently used macros.
34 //
35 // Instructions for which a 'better' code sequence exists depending
36 // on arguments should also go in here.
37
38 class MacroAssembler: public Assembler {
39 friend class LIR_Assembler;
40
41 public:
42 using Assembler::mov;
43 using Assembler::movi;
44
45 protected:
46
47 // Support for VM calls
48 //
49 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
50 // may customize this version by overriding it for its purposes (e.g., to save/restore
51 // additional registers when doing a VM call).
569 mrs(0b011, 0b0000, 0b0000, 0b001, reg);
570 }
571
572 // idiv variant which deals with MINLONG as dividend and -1 as divisor
573 int corrected_idivl(Register result, Register ra, Register rb,
574 bool want_remainder, Register tmp = rscratch1);
575 int corrected_idivq(Register result, Register ra, Register rb,
576 bool want_remainder, Register tmp = rscratch1);
577
578 // Support for NULL-checks
579 //
580 // Generates code that causes a NULL OS exception if the content of reg is NULL.
581 // If the accessed location is M[reg + offset] and the offset is known, provide the
582 // offset. No explicit code generation is needed if the offset is within a certain
583 // range (0 <= offset <= page_size).
584
585 virtual void null_check(Register reg, int offset = -1);
586 static bool needs_explicit_null_check(intptr_t offset);
587 static bool uses_implicit_null_check(void* address);
588
589 void test_klass_is_value(Register klass, Register temp_reg, Label& is_value);
590
591 void test_field_is_flattenable(Register flags, Register temp_reg, Label& is_flattenable);
592 void test_field_is_not_flattenable(Register flags, Register temp_reg, Label& notFlattenable);
593 void test_field_is_flattened(Register flags, Register temp_reg, Label& is_flattened);
594
595 // Check klass/oops is flat value type array (oop->_klass->_layout_helper & vt_bit)
596 void test_flat_array_klass(Register klass, Register temp_reg, Label& is_flat_array);
597 void test_flat_array_oop(Register oop, Register temp_reg, Label& is_flat_array);
598
599
600
601 static address target_addr_for_insn(address insn_addr, unsigned insn);
602 static address target_addr_for_insn(address insn_addr) {
603 unsigned insn = *(unsigned*)insn_addr;
604 return target_addr_for_insn(insn_addr, insn);
605 }
606
607 // Required platform-specific helpers for Label::patch_instructions.
608 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
609 static int pd_patch_instruction_size(address branch, address target);
610 static void pd_patch_instruction(address branch, address target, const char* file = NULL, int line = 0) {
611 pd_patch_instruction_size(branch, target);
612 }
613 static address pd_call_destination(address branch) {
614 return target_addr_for_insn(branch);
615 }
616 #ifndef PRODUCT
617 static void pd_print_patched_instruction(address branch);
618 #endif
619
620 static int patch_oop(address insn_addr, address o);
1137 Assembler::INSN(Rd, Rn, Rm, kind, shift); \
1138 } \
1139 \
1140 void INSN(Register Rd, Register Rn, Register Rm) { \
1141 Assembler::INSN(Rd, Rn, Rm); \
1142 } \
1143 \
1144 void INSN(Register Rd, Register Rn, Register Rm, \
1145 ext::operation option, int amount = 0) { \
1146 Assembler::INSN(Rd, Rn, Rm, option, amount); \
1147 }
1148
1149 WRAP(adds) WRAP(addsw) WRAP(subs) WRAP(subsw)
1150
1151 void add(Register Rd, Register Rn, RegisterOrConstant increment);
1152 void addw(Register Rd, Register Rn, RegisterOrConstant increment);
1153 void sub(Register Rd, Register Rn, RegisterOrConstant decrement);
1154 void subw(Register Rd, Register Rn, RegisterOrConstant decrement);
1155
1156 void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
1157
1158 // Support for MachVVEPNode
1159 void unpack_value_args(Compile* C);
1160
1161 void tableswitch(Register index, jint lowbound, jint highbound,
1162 Label &jumptable, Label &jumptable_end, int stride = 1) {
1163 adr(rscratch1, jumptable);
1164 subsw(rscratch2, index, lowbound);
1165 subsw(zr, rscratch2, highbound - lowbound);
1166 br(Assembler::HS, jumptable_end);
1167 add(rscratch1, rscratch1, rscratch2,
1168 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1169 br(rscratch1);
1170 }
1171
1172 // Form an address from base + offset in Rd. Rd may or may not
1173 // actually be used: you must use the Address that is returned. It
1174 // is up to you to ensure that the shift provided matches the size
1175 // of your data.
1176 Address form_address(Register Rd, Register base, long byte_offset, int shift);
1177
1178 // Return true iff an address is within the 48-bit AArch64 address
1179 // space.
|