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