1 /*
2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #ifndef CPU_X86_C2_MACROASSEMBLER_X86_HPP
26 #define CPU_X86_C2_MACROASSEMBLER_X86_HPP
27 
28 // C2_MacroAssembler contains high-level macros for C2
29 
30 public:
31   // special instructions for EVEX
32   void setvectmask(Register dst, Register src);
33   void restorevectmask();
34 
35   // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file.
36   // See full desription in macroAssembler_x86.cpp.
37   void fast_lock(Register obj, Register box, Register tmp,
38                  Register scr, Register cx1, Register cx2,
39                  BiasedLockingCounters* counters,
40                  RTMLockingCounters* rtm_counters,
41                  RTMLockingCounters* stack_rtm_counters,
42                  Metadata* method_data,
43                  bool use_rtm, bool profile_rtm);
44   void fast_unlock(Register obj, Register box, Register tmp, bool use_rtm);
45 
46 #if INCLUDE_RTM_OPT
47   void rtm_counters_update(Register abort_status, Register rtm_counters);
48   void branch_on_random_using_rdtsc(Register tmp, Register scr, int count, Label& brLabel);
49   void rtm_abort_ratio_calculation(Register tmp, Register rtm_counters_reg,
50                                    RTMLockingCounters* rtm_counters,
51                                    Metadata* method_data);
52   void rtm_profiling(Register abort_status_Reg, Register rtm_counters_Reg,
53                      RTMLockingCounters* rtm_counters, Metadata* method_data, bool profile_rtm);
54   void rtm_retry_lock_on_abort(Register retry_count, Register abort_status, Label& retryLabel);
55   void rtm_retry_lock_on_busy(Register retry_count, Register box, Register tmp, Register scr, Label& retryLabel);
56   void rtm_stack_locking(Register obj, Register tmp, Register scr,
57                          Register retry_on_abort_count,
58                          RTMLockingCounters* stack_rtm_counters,
59                          Metadata* method_data, bool profile_rtm,
60                          Label& DONE_LABEL, Label& IsInflated);
61   void rtm_inflated_locking(Register obj, Register box, Register tmp,
62                             Register scr, Register retry_on_busy_count,
63                             Register retry_on_abort_count,
64                             RTMLockingCounters* rtm_counters,
65                             Metadata* method_data, bool profile_rtm,
66                             Label& DONE_LABEL);
67 #endif
68 
69   // Generic instructions support for use in .ad files C2 code generation
70   void vabsnegd(int opcode, XMMRegister dst, XMMRegister src, Register scr);
71   void vabsnegd(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr);
72   void vabsnegf(int opcode, XMMRegister dst, XMMRegister src, Register scr);
73   void vabsnegf(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr);
74   void vextendbw(bool sign, XMMRegister dst, XMMRegister src, int vector_len);
75   void vextendbw(bool sign, XMMRegister dst, XMMRegister src);
76   void vshiftd(int opcode, XMMRegister dst, XMMRegister src);
77   void vshiftd(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
78   void vshiftw(int opcode, XMMRegister dst, XMMRegister src);
79   void vshiftw(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
80   void vshiftq(int opcode, XMMRegister dst, XMMRegister src);
81   void vshiftq(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
82 
83   // Reductions for vectors of ints, longs, floats, and doubles.
84 
85   // dst = src1 + reduce(op, src2) using vtmp as temps
86   void reduceI(int opcode, int vlen, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
87 #ifdef _LP64
88   void reduceL(int opcode, int vlen, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
89 #endif // _LP64
90 
91   // dst = reduce(op, src2) using vtmp as temps
92   void reduce_fp(int opcode, int vlen,
93                  XMMRegister dst, XMMRegister src,
94                  XMMRegister vtmp1, XMMRegister vtmp2 = xnoreg);
95  private:
96   void reduceF(int opcode, int vlen, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
97   void reduceD(int opcode, int vlen, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
98 
99   void reduce2I (int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
100   void reduce4I (int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
101   void reduce8I (int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
102   void reduce16I(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
103 
104 #ifdef _LP64
105   void reduce2L(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
106   void reduce4L(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
107   void reduce8L(int opcode, Register dst, Register src1, XMMRegister src2, XMMRegister vtmp1, XMMRegister vtmp2);
108 #endif // _LP64
109 
110   void reduce2F (int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp);
111   void reduce4F (int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp);
112   void reduce8F (int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
113   void reduce16F(int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
114 
115   void reduce2D(int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp);
116   void reduce4D(int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
117   void reduce8D(int opcode, XMMRegister dst, XMMRegister src, XMMRegister vtmp1, XMMRegister vtmp2);
118 
119   void reduce_operation_128(int opcode, XMMRegister dst, XMMRegister src);
120   void reduce_operation_256(int opcode, XMMRegister dst, XMMRegister src1, XMMRegister src2);
121 
122  public:
123 
124   void string_indexof_char(Register str1, Register cnt1, Register ch, Register result,
125                            XMMRegister vec1, XMMRegister vec2, XMMRegister vec3, Register tmp);
126 
127   // IndexOf strings.
128   // Small strings are loaded through stack if they cross page boundary.
129   void string_indexof(Register str1, Register str2,
130                       Register cnt1, Register cnt2,
131                       int int_cnt2,  Register result,
132                       XMMRegister vec, Register tmp,
133                       int ae);
134 
135   // IndexOf for constant substrings with size >= 8 elements
136   // which don't need to be loaded through stack.
137   void string_indexofC8(Register str1, Register str2,
138                       Register cnt1, Register cnt2,
139                       int int_cnt2,  Register result,
140                       XMMRegister vec, Register tmp,
141                       int ae);
142 
143     // Smallest code: we don't need to load through stack,
144     // check string tail.
145 
146   // helper function for string_compare
147   void load_next_elements(Register elem1, Register elem2, Register str1, Register str2,
148                           Address::ScaleFactor scale, Address::ScaleFactor scale1,
149                           Address::ScaleFactor scale2, Register index, int ae);
150   // Compare strings.
151   void string_compare(Register str1, Register str2,
152                       Register cnt1, Register cnt2, Register result,
153                       XMMRegister vec1, int ae);
154 
155   // Search for Non-ASCII character (Negative byte value) in a byte array,
156   // return true if it has any and false otherwise.
157   void has_negatives(Register ary1, Register len,
158                      Register result, Register tmp1,
159                      XMMRegister vec1, XMMRegister vec2);
160 
161   // Compare char[] or byte[] arrays.
162   void arrays_equals(bool is_array_equ, Register ary1, Register ary2,
163                      Register limit, Register result, Register chr,
164                      XMMRegister vec1, XMMRegister vec2, bool is_char);
165 
166 #endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP
167