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 void element_compare(Register r1, Register r2, 33 Register result, Register cnt, 34 Register tmp1, Register tmp2, 35 VectorRegister vr1, VectorRegister vr2, 36 VectorRegister vrs, 37 bool is_latin, Label& DONE); 38 public: 39 40 void string_compare(Register str1, Register str2, 41 Register cnt1, Register cnt2, Register result, 42 Register tmp1, Register tmp2, Register tmp3, 43 int ae); 44 45 void string_indexof_char_short(Register str1, Register cnt1, 46 Register ch, Register result, 47 bool isL); 48 49 void string_indexof_char(Register str1, Register cnt1, 50 Register ch, Register result, 51 Register tmp1, Register tmp2, 52 Register tmp3, Register tmp4, 53 bool isL); 54 55 void string_indexof(Register str1, Register str2, 56 Register cnt1, Register cnt2, 57 Register tmp1, Register tmp2, 58 Register tmp3, Register tmp4, 59 Register tmp5, Register tmp6, 60 Register result, int ae); 61 62 void string_indexof_linearscan(Register haystack, Register needle, 63 Register haystack_len, Register needle_len, 64 Register tmp1, Register tmp2, 65 Register tmp3, Register tmp4, 66 int needle_con_cnt, Register result, int ae); 67 68 void arrays_equals(Register r1, Register r2, 69 Register tmp3, Register tmp4, 70 Register tmp5, Register tmp6, 71 Register result, Register cnt1, 72 int elem_size); 73 74 void string_equals(Register r1, Register r2, 75 Register result, Register cnt1, 76 int elem_size); 77 78 // refer to conditional_branches and float_conditional_branches 79 static const int bool_test_bits = 3; 80 static const int neg_cond_bits = 2; 81 static const int unsigned_branch_mask = 1 << bool_test_bits; 82 static const int double_branch_mask = 1 << bool_test_bits; 83 84 // cmp 85 void cmp_branch(int cmpFlag, 86 Register op1, Register op2, 87 Label& label, bool is_far = false); 88 89 void float_cmp_branch(int cmpFlag, 90 FloatRegister op1, FloatRegister op2, 91 Label& label, bool is_far = false); 92 93 void enc_cmpUEqNeLeGt_imm0_branch(int cmpFlag, Register op, 94 Label& L, bool is_far = false); 95 96 void enc_cmpEqNe_imm0_branch(int cmpFlag, Register op, 97 Label& L, bool is_far = false); 98 99 void enc_cmove(int cmpFlag, 100 Register op1, Register op2, 101 Register dst, Register src); 102 103 void spill(Register r, bool is64, int offset) { 104 is64 ? sd(r, Address(sp, offset)) 105 : sw(r, Address(sp, offset)); 106 } 107 108 void spill(FloatRegister f, bool is64, int offset) { 109 is64 ? fsd(f, Address(sp, offset)) 110 : fsw(f, Address(sp, offset)); 111 } 112 113 void spill(VectorRegister v, int offset) { 114 add(t0, sp, offset); 115 vs1r_v(v, t0); 116 } 117 118 void unspill(Register r, bool is64, int offset) { 119 is64 ? ld(r, Address(sp, offset)) 120 : lw(r, Address(sp, offset)); 121 } 122 123 void unspillu(Register r, bool is64, int offset) { 124 is64 ? ld(r, Address(sp, offset)) 125 : lwu(r, Address(sp, offset)); 126 } 127 128 void unspill(FloatRegister f, bool is64, int offset) { 129 is64 ? fld(f, Address(sp, offset)) 130 : flw(f, Address(sp, offset)); 131 } 132 133 void unspill(VectorRegister v, int offset) { 134 add(t0, sp, offset); 135 vl1r_v(v, t0); 136 } 137 138 void spill_copy_vector_stack_to_stack(int src_offset, int dst_offset, int vec_reg_size_in_bytes) { 139 assert(vec_reg_size_in_bytes % 16 == 0, "unexpected vector reg size"); 140 unspill(v0, src_offset); 141 spill(v0, dst_offset); 142 } 143 144 void minmax_FD(FloatRegister dst, 145 FloatRegister src1, FloatRegister src2, 146 bool is_double, bool is_min); 147 148 // intrinsic methods implemented by rvv instructions 149 void string_equals_v(Register r1, Register r2, 150 Register result, Register cnt1, 151 int elem_size); 152 153 void arrays_equals_v(Register r1, Register r2, 154 Register result, Register cnt1, 155 int elem_size); 156 157 void string_compare_v(Register str1, Register str2, 158 Register cnt1, Register cnt2, 159 Register result, 160 Register tmp1, Register tmp2, 161 int encForm); 162 163 void clear_array_v(Register base, Register cnt); 164 165 void byte_array_inflate_v(Register src, Register dst, 166 Register len, Register tmp); 167 168 void char_array_compress_v(Register src, Register dst, 169 Register len, Register result, 170 Register tmp); 171 172 void encode_iso_array_v(Register src, Register dst, 173 Register len, Register result, 174 Register tmp); 175 176 void has_negatives_v(Register ary, Register len, 177 Register result, Register tmp); 178 179 void string_indexof_char_v(Register str1, Register cnt1, 180 Register ch, Register result, 181 Register tmp1, Register tmp2, 182 bool isL); 183 184 void minmax_FD_v(VectorRegister dst, 185 VectorRegister src1, VectorRegister src2, 186 bool is_double, bool is_min); 187 188 void reduce_minmax_FD_v(FloatRegister dst, 189 FloatRegister src1, VectorRegister src2, 190 VectorRegister tmp1, VectorRegister tmp2, 191 bool is_double, bool is_min); 192 193 #endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP