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.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);
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.
1163 bool is_valid_AArch64_address(address a) {
1216 // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1217 void update_byte_crc32(Register crc, Register val, Register table);
1218 void update_word_crc32(Register crc, Register v, Register tmp,
1219 Register table0, Register table1, Register table2, Register table3,
1220 bool upper = false);
1221
1222 void string_compare(Register str1, Register str2,
1223 Register cnt1, Register cnt2, Register result,
1224 Register tmp1, Register tmp2, FloatRegister vtmp1,
1225 FloatRegister vtmp2, FloatRegister vtmp3, int ae);
1226
1227 void has_negatives(Register ary1, Register len, Register result);
1228
1229 void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1230 Register tmp1, Register tmp2, Register tmp3, int elem_size);
1231
1232 void string_equals(Register a1, Register a2, Register result, Register cnt1,
1233 int elem_size);
1234
1235 void fill_words(Register base, Register cnt, Register value);
1236 void zero_words(Register base, u_int64_t cnt);
1237 void zero_words(Register ptr, Register cnt);
1238 void zero_dcache_blocks(Register base, Register cnt);
1239
1240 static const int zero_words_block_size;
1241
1242 void byte_array_inflate(Register src, Register dst, Register len,
1243 FloatRegister vtmp1, FloatRegister vtmp2,
1244 FloatRegister vtmp3, Register tmp4);
1245
1246 void char_array_compress(Register src, Register dst, Register len,
1247 FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1248 FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1249 Register result);
1250
1251 void encode_iso_array(Register src, Register dst,
1252 Register len, Register result,
1253 FloatRegister Vtmp1, FloatRegister Vtmp2,
1254 FloatRegister Vtmp3, FloatRegister Vtmp4);
1255 void string_indexof(Register str1, Register str2,
|
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.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);
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
1159 enum RegState {
1160 reg_readonly,
1161 reg_writable,
1162 reg_written
1163 };
1164
1165 // Unpack all value type arguments passed as oops
1166 void unpack_value_args(Compile* C, bool receiver_only);
1167 bool move_helper(VMReg from, VMReg to, BasicType bt, RegState reg_state[], int ret_off);
1168 bool unpack_value_helper(const GrowableArray<SigEntry>* sig, int& sig_index, VMReg from, VMRegPair* regs_to, int& to_index, RegState reg_state[], int ret_off);
1169 void verified_entry(Compile* C, int sp_inc);
1170
1171 void tableswitch(Register index, jint lowbound, jint highbound,
1172 Label &jumptable, Label &jumptable_end, int stride = 1) {
1173 adr(rscratch1, jumptable);
1174 subsw(rscratch2, index, lowbound);
1175 subsw(zr, rscratch2, highbound - lowbound);
1176 br(Assembler::HS, jumptable_end);
1177 add(rscratch1, rscratch1, rscratch2,
1178 ext::sxtw, exact_log2(stride * Assembler::instruction_size));
1179 br(rscratch1);
1180 }
1181
1182 // Form an address from base + offset in Rd. Rd may or may not
1183 // actually be used: you must use the Address that is returned. It
1184 // is up to you to ensure that the shift provided matches the size
1185 // of your data.
1186 Address form_address(Register Rd, Register base, long byte_offset, int shift);
1187
1188 // Return true iff an address is within the 48-bit AArch64 address
1189 // space.
1190 bool is_valid_AArch64_address(address a) {
1243 // CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
1244 void update_byte_crc32(Register crc, Register val, Register table);
1245 void update_word_crc32(Register crc, Register v, Register tmp,
1246 Register table0, Register table1, Register table2, Register table3,
1247 bool upper = false);
1248
1249 void string_compare(Register str1, Register str2,
1250 Register cnt1, Register cnt2, Register result,
1251 Register tmp1, Register tmp2, FloatRegister vtmp1,
1252 FloatRegister vtmp2, FloatRegister vtmp3, int ae);
1253
1254 void has_negatives(Register ary1, Register len, Register result);
1255
1256 void arrays_equals(Register a1, Register a2, Register result, Register cnt1,
1257 Register tmp1, Register tmp2, Register tmp3, int elem_size);
1258
1259 void string_equals(Register a1, Register a2, Register result, Register cnt1,
1260 int elem_size);
1261
1262 void fill_words(Register base, Register cnt, Register value);
1263 void fill_words(Register base, u_int64_t cnt, Register value);
1264
1265 void zero_words(Register base, u_int64_t cnt);
1266 void zero_words(Register ptr, Register cnt);
1267 void zero_dcache_blocks(Register base, Register cnt);
1268
1269 static const int zero_words_block_size;
1270
1271 void byte_array_inflate(Register src, Register dst, Register len,
1272 FloatRegister vtmp1, FloatRegister vtmp2,
1273 FloatRegister vtmp3, Register tmp4);
1274
1275 void char_array_compress(Register src, Register dst, Register len,
1276 FloatRegister tmp1Reg, FloatRegister tmp2Reg,
1277 FloatRegister tmp3Reg, FloatRegister tmp4Reg,
1278 Register result);
1279
1280 void encode_iso_array(Register src, Register dst,
1281 Register len, Register result,
1282 FloatRegister Vtmp1, FloatRegister Vtmp2,
1283 FloatRegister Vtmp3, FloatRegister Vtmp4);
1284 void string_indexof(Register str1, Register str2,
|