• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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