1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. 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_RISCV_C2_MACROASSEMBLER_RISCV_HPP 27 #define CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP 28 29 // C2_MacroAssembler contains high-level macros for C2 30 31 private: 32 // Return true if the phase output is in the scratch emit size mode. 33 virtual bool in_scratch_emit_size() override; 34 35 void element_compare(Register r1, Register r2, 36 Register result, Register cnt, 37 Register tmp1, Register tmp2, 38 VectorRegister vr1, VectorRegister vr2, 39 VectorRegister vrs, 40 bool is_latin, Label& DONE, Assembler::LMUL lmul); 41 42 void compress_bits_v(Register dst, Register src, Register mask, bool is_long); 43 void expand_bits_v(Register dst, Register src, Register mask, bool is_long); 44 45 public: 46 // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. 47 void fast_lock(Register object, Register box, 48 Register tmp1, Register tmp2, Register tmp3, Register tmp4); 49 void fast_unlock(Register object, Register box, Register tmp1, Register tmp2); 50 51 // Code used by cmpFastLockLightweight and cmpFastUnlockLightweight mach instructions in .ad file. 52 void fast_lock_lightweight(Register object, Register box, 53 Register tmp1, Register tmp2, Register tmp3, Register tmp4); 54 void fast_unlock_lightweight(Register object, Register box, 55 Register tmp1, Register tmp2, Register tmp3); 56 57 void string_compare(Register str1, Register str2, 58 Register cnt1, Register cnt2, Register result, 59 Register tmp1, Register tmp2, Register tmp3, 60 int ae); 61 62 void string_indexof_char_short(Register str1, Register cnt1, 63 Register ch, Register result, 64 bool isL); 65 66 void string_indexof_char(Register str1, Register cnt1, 67 Register ch, Register result, 68 Register tmp1, Register tmp2, 69 Register tmp3, Register tmp4, 70 bool isL); 71 72 void string_indexof(Register str1, Register str2, 73 Register cnt1, Register cnt2, 74 Register tmp1, Register tmp2, 75 Register tmp3, Register tmp4, 76 Register tmp5, Register tmp6, 77 Register result, int ae); 78 79 void string_indexof_linearscan(Register haystack, Register needle, 80 Register haystack_len, Register needle_len, 81 Register tmp1, Register tmp2, 82 Register tmp3, Register tmp4, 83 int needle_con_cnt, Register result, int ae); 84 85 void arrays_equals(Register r1, Register r2, 86 Register tmp1, Register tmp2, Register tmp3, 87 Register result, int elem_size); 88 89 void arrays_hashcode(Register ary, Register cnt, Register result, 90 Register tmp1, Register tmp2, 91 Register tmp3, Register tmp4, 92 Register tmp5, Register tmp6, 93 BasicType eltype); 94 95 // helper function for arrays_hashcode 96 int arrays_hashcode_elsize(BasicType eltype); 97 void arrays_hashcode_elload(Register dst, Address src, BasicType eltype); 98 99 void string_equals(Register r1, Register r2, 100 Register result, Register cnt1); 101 102 // refer to conditional_branches and float_conditional_branches 103 static const int bool_test_bits = 3; 104 static const int neg_cond_bits = 2; 105 static const int unsigned_branch_mask = 1 << bool_test_bits; 106 static const int double_branch_mask = 1 << bool_test_bits; 107 108 // cmp 109 void cmp_branch(int cmpFlag, 110 Register op1, Register op2, 111 Label& label, bool is_far = false); 112 113 void float_cmp_branch(int cmpFlag, 114 FloatRegister op1, FloatRegister op2, 115 Label& label, bool is_far = false); 116 117 void enc_cmpUEqNeLeGt_imm0_branch(int cmpFlag, Register op, 118 Label& L, bool is_far = false); 119 120 void enc_cmpEqNe_imm0_branch(int cmpFlag, Register op, 121 Label& L, bool is_far = false); 122 123 void enc_cmove(int cmpFlag, 124 Register op1, Register op2, 125 Register dst, Register src); 126 127 void spill(Register r, bool is64, int offset) { 128 is64 ? sd(r, Address(sp, offset)) 129 : sw(r, Address(sp, offset)); 130 } 131 132 void spill(FloatRegister f, bool is64, int offset) { 133 is64 ? fsd(f, Address(sp, offset)) 134 : fsw(f, Address(sp, offset)); 135 } 136 137 void spill(VectorRegister v, int offset) { 138 add(t0, sp, offset); 139 vs1r_v(v, t0); 140 } 141 142 void unspill(Register r, bool is64, int offset) { 143 is64 ? ld(r, Address(sp, offset)) 144 : lw(r, Address(sp, offset)); 145 } 146 147 void unspillu(Register r, bool is64, int offset) { 148 is64 ? ld(r, Address(sp, offset)) 149 : lwu(r, Address(sp, offset)); 150 } 151 152 void unspill(FloatRegister f, bool is64, int offset) { 153 is64 ? fld(f, Address(sp, offset)) 154 : flw(f, Address(sp, offset)); 155 } 156 157 void unspill(VectorRegister v, int offset) { 158 add(t0, sp, offset); 159 vl1r_v(v, t0); 160 } 161 162 void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, uint vector_length_in_bytes) { 163 assert(vector_length_in_bytes % 16 == 0, "unexpected vector reg size"); 164 for (int i = 0; i < (int)vector_length_in_bytes / 8; i++) { 165 unspill(t0, true, src_offset + (i * 8)); 166 spill(t0, true, dst_offset + (i * 8)); 167 } 168 } 169 170 void minmax_fp(FloatRegister dst, 171 FloatRegister src1, FloatRegister src2, 172 bool is_double, bool is_min); 173 174 void round_double_mode(FloatRegister dst, FloatRegister src, int round_mode, 175 Register tmp1, Register tmp2, Register tmp3); 176 177 void signum_fp(FloatRegister dst, FloatRegister one, bool is_double); 178 179 void float16_to_float(FloatRegister dst, Register src, Register tmp); 180 void float_to_float16(Register dst, FloatRegister src, FloatRegister ftmp, Register xtmp); 181 182 void signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen); 183 184 185 // intrinsic methods implemented by rvv instructions 186 187 // compress bits, i.e. j.l.Integer/Long::compress. 188 void compress_bits_i_v(Register dst, Register src, Register mask); 189 void compress_bits_l_v(Register dst, Register src, Register mask); 190 // expand bits, i.e. j.l.Integer/Long::expand. 191 void expand_bits_i_v(Register dst, Register src, Register mask); 192 void expand_bits_l_v(Register dst, Register src, Register mask); 193 194 void java_round_float_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length); 195 void java_round_double_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length); 196 197 void float16_to_float_v(VectorRegister dst, VectorRegister src, uint vector_length); 198 void float_to_float16_v(VectorRegister dst, VectorRegister src, VectorRegister vtmp, Register tmp, uint vector_length); 199 200 void string_equals_v(Register r1, Register r2, 201 Register result, Register cnt1); 202 203 void arrays_equals_v(Register r1, Register r2, 204 Register result, Register cnt1, 205 int elem_size); 206 207 void string_compare_v(Register str1, Register str2, 208 Register cnt1, Register cnt2, 209 Register result, 210 Register tmp1, Register tmp2, 211 int encForm); 212 213 void clear_array_v(Register base, Register cnt); 214 215 void byte_array_inflate_v(Register src, Register dst, 216 Register len, Register tmp); 217 218 void char_array_compress_v(Register src, Register dst, 219 Register len, Register result, 220 Register tmp); 221 222 void encode_iso_array_v(Register src, Register dst, 223 Register len, Register result, 224 Register tmp, bool ascii); 225 226 void count_positives_v(Register ary, Register len, 227 Register result, Register tmp); 228 229 void string_indexof_char_v(Register str1, Register cnt1, 230 Register ch, Register result, 231 Register tmp1, Register tmp2, 232 bool isL); 233 234 void minmax_fp_v(VectorRegister dst, 235 VectorRegister src1, VectorRegister src2, 236 BasicType bt, bool is_min, uint vector_length); 237 238 void minmax_fp_masked_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, 239 VectorRegister vmask, VectorRegister tmp1, VectorRegister tmp2, 240 BasicType bt, bool is_min, uint vector_length); 241 242 void reduce_minmax_fp_v(FloatRegister dst, 243 FloatRegister src1, VectorRegister src2, 244 VectorRegister tmp1, VectorRegister tmp2, 245 bool is_double, bool is_min, uint vector_length, 246 VectorMask vm = Assembler::unmasked); 247 248 void reduce_integral_v(Register dst, Register src1, 249 VectorRegister src2, VectorRegister tmp, 250 int opc, BasicType bt, uint vector_length, 251 VectorMask vm = Assembler::unmasked); 252 253 void vsetvli_helper(BasicType bt, uint vector_length, LMUL vlmul = Assembler::m1, Register tmp = t0); 254 255 void compare_integral_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, int cond, 256 BasicType bt, uint vector_length, VectorMask vm = Assembler::unmasked); 257 258 void compare_fp_v(VectorRegister dst, VectorRegister src1, VectorRegister src2, int cond, 259 BasicType bt, uint vector_length, VectorMask vm = Assembler::unmasked); 260 261 void spill_vmask(VectorRegister v, int offset); 262 263 void unspill_vmask(VectorRegister v, int offset); 264 265 void spill_copy_vmask_stack_to_stack(int src_offset, int dst_offset, uint vector_length_in_bytes) { 266 assert(vector_length_in_bytes % 4 == 0, "unexpected vector mask reg size"); 267 for (int i = 0; i < (int)vector_length_in_bytes / 4; i++) { 268 unspill(t0, false, src_offset + (i * 4)); 269 spill(t0, false, dst_offset + (i * 4)); 270 } 271 } 272 273 void integer_extend_v(VectorRegister dst, BasicType dst_bt, uint vector_length, 274 VectorRegister src, BasicType src_bt, bool is_signed); 275 276 void integer_narrow_v(VectorRegister dst, BasicType dst_bt, uint vector_length, 277 VectorRegister src, BasicType src_bt); 278 279 void vfcvt_rtz_x_f_v_safe(VectorRegister dst, VectorRegister src); 280 281 void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); 282 void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); 283 284 #endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP