1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef MAPLE_IR_INCLUDE_OPCODES_H
17 #define MAPLE_IR_INCLUDE_OPCODES_H
18 #include "types_def.h"
19 #include "mpl_logging.h"
20
21 namespace maple {
22 enum Opcode : uint8 {
23 OP_undef,
24 #define OPCODE(STR, YY, ZZ, SS) OP_##STR,
25 #include "opcodes.def"
26 #undef OPCODE
27 OP_last,
28 };
29
30 #define CASE_OP_ASSERT_NONNULL \
31 case OP_assertnonnull: \
32 case OP_assignassertnonnull: \
33 case OP_callassertnonnull: \
34 case OP_returnassertnonnull:
35
36 #define CASE_OP_ASSERT_BOUNDARY \
37 case OP_assertge: \
38 case OP_assertlt: \
39 case OP_calcassertge: \
40 case OP_calcassertlt: \
41 case OP_callassertle: \
42 case OP_returnassertle: \
43 case OP_assignassertle:
44
IsDAssign(Opcode code)45 inline constexpr bool IsDAssign(Opcode code)
46 {
47 return (code == OP_dassign || code == OP_maydassign);
48 }
49
IsCallAssigned(Opcode code)50 inline constexpr bool IsCallAssigned(Opcode code)
51 {
52 return (code == OP_callassigned || code == OP_virtualcallassigned || code == OP_virtualicallassigned ||
53 code == OP_superclasscallassigned || code == OP_interfacecallassigned ||
54 code == OP_interfaceicallassigned || code == OP_customcallassigned || code == OP_polymorphiccallassigned ||
55 code == OP_icallassigned || code == OP_icallprotoassigned || code == OP_intrinsiccallassigned ||
56 code == OP_xintrinsiccallassigned || code == OP_intrinsiccallwithtypeassigned);
57 }
58
IsBranch(Opcode opcode)59 inline constexpr bool IsBranch(Opcode opcode)
60 {
61 return (opcode == OP_goto || opcode == OP_brtrue || opcode == OP_brfalse || opcode == OP_switch ||
62 opcode == OP_igoto);
63 }
64
IsLogicalShift(Opcode opcode)65 inline constexpr bool IsLogicalShift(Opcode opcode)
66 {
67 return (opcode == OP_lshr || opcode == OP_shl);
68 }
69
IsCommutative(Opcode opcode)70 constexpr bool IsCommutative(Opcode opcode)
71 {
72 switch (opcode) {
73 case OP_add:
74 case OP_mul:
75 case OP_max:
76 case OP_min:
77 case OP_band:
78 case OP_bior:
79 case OP_bxor:
80 case OP_eq:
81 case OP_ne:
82 case OP_land:
83 case OP_lior:
84 return true;
85 default:
86 return false;
87 }
88 }
89
IsStmtMustRequire(Opcode opcode)90 constexpr bool IsStmtMustRequire(Opcode opcode)
91 {
92 switch (opcode) {
93 case OP_jstry:
94 case OP_throw:
95 case OP_try:
96 case OP_catch:
97 case OP_jscatch:
98 case OP_finally:
99 case OP_endtry:
100 case OP_cleanuptry:
101 case OP_gosub:
102 case OP_retsub:
103 case OP_return:
104 case OP_call:
105 case OP_virtualcall:
106 case OP_virtualicall:
107 case OP_superclasscall:
108 case OP_interfacecall:
109 case OP_interfaceicall:
110 case OP_customcall:
111 case OP_polymorphiccall:
112 case OP_callassigned:
113 case OP_virtualcallassigned:
114 case OP_virtualicallassigned:
115 case OP_superclasscallassigned:
116 case OP_interfacecallassigned:
117 case OP_interfaceicallassigned:
118 case OP_customcallassigned:
119 case OP_polymorphiccallassigned:
120 case OP_icall:
121 case OP_icallassigned:
122 case OP_icallproto:
123 case OP_icallprotoassigned:
124 case OP_intrinsiccall:
125 case OP_xintrinsiccall:
126 case OP_intrinsiccallassigned:
127 case OP_xintrinsiccallassigned:
128 case OP_intrinsiccallwithtype:
129 case OP_intrinsiccallwithtypeassigned:
130 case OP_asm:
131 case OP_syncenter:
132 case OP_syncexit:
133 case OP_membaracquire:
134 case OP_membarrelease:
135 case OP_membarstoreload:
136 case OP_membarstorestore:
137 CASE_OP_ASSERT_NONNULL
138 CASE_OP_ASSERT_BOUNDARY
139 case OP_free:
140 case OP_incref:
141 case OP_decref:
142 case OP_decrefreset: {
143 return true;
144 }
145 default:
146 return false;
147 }
148 }
149
150 // the result of these op is actually u1(may be set as other type, but its return value can only be zero or one)
151 // different from kOpcodeInfo.IsCompare(op) : cmp/cmpg/cmpl have no reverse op, and may return -1/0/1
IsCompareHasReverseOp(Opcode op)152 constexpr bool IsCompareHasReverseOp(Opcode op)
153 {
154 if (op == OP_eq || op == OP_ne || op == OP_ge || op == OP_gt || op == OP_le || op == OP_lt) {
155 return true;
156 }
157 return false;
158 }
159
GetSwapCmpOp(Opcode op)160 constexpr Opcode GetSwapCmpOp(Opcode op)
161 {
162 switch (op) {
163 case OP_eq:
164 return OP_eq;
165 case OP_ne:
166 return OP_ne;
167 case OP_ge:
168 return OP_le;
169 case OP_gt:
170 return OP_lt;
171 case OP_le:
172 return OP_ge;
173 case OP_lt:
174 return OP_gt;
175 default:
176 CHECK_FATAL(false, "can't swap op");
177 return op;
178 }
179 }
180
GetReverseCmpOp(Opcode op)181 constexpr Opcode GetReverseCmpOp(Opcode op)
182 {
183 switch (op) {
184 case OP_eq:
185 return OP_ne;
186 case OP_ne:
187 return OP_eq;
188 case OP_ge:
189 return OP_lt;
190 case OP_gt:
191 return OP_le;
192 case OP_le:
193 return OP_gt;
194 case OP_lt:
195 return OP_ge;
196 default:
197 CHECK_FATAL(false, "opcode has no reverse op");
198 return op;
199 }
200 }
201
IsSupportedOpForCopyInPhasesLoopUnrollAndVRP(Opcode op)202 constexpr bool IsSupportedOpForCopyInPhasesLoopUnrollAndVRP(Opcode op)
203 {
204 switch (op) {
205 case OP_igoto:
206 case OP_switch:
207 case OP_comment:
208 case OP_goto:
209 case OP_dassign:
210 case OP_regassign:
211 case OP_membarrelease:
212 case OP_brfalse:
213 case OP_brtrue:
214 case OP_maydassign:
215 case OP_iassign:
216 CASE_OP_ASSERT_NONNULL
217 CASE_OP_ASSERT_BOUNDARY
218 case OP_membaracquire:
219 case OP_call:
220 case OP_callassigned:
221 case OP_virtualcallassigned:
222 case OP_virtualicallassigned:
223 case OP_interfaceicallassigned:
224 case OP_intrinsiccall:
225 case OP_intrinsiccallassigned:
226 case OP_intrinsiccallwithtype:
227 case OP_membarstorestore:
228 case OP_membarstoreload: {
229 return true;
230 }
231 default:
232 return false;
233 }
234 }
235 } // namespace maple
236 #endif // MAPLE_IR_INCLUDE_OPCODES_H
237