1 /*
2  * Copyright (c) 2022 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 ECMASCRIPT_COMPILER_ASSEMBLER_AARCH64_CONSTANTS_H
17 #define ECMASCRIPT_COMPILER_ASSEMBLER_AARCH64_CONSTANTS_H
18 namespace panda::ecmascript::aarch64 {
19 enum RegisterId : uint8_t {
20     X0, X1, X2, X3, X4, X5, X6, X7,
21     X8, X9, X10, X11, X12, X13, X14, X15,
22     X16, X17, X18, X19, X20, X21, X22, X23,
23     X24, X25, X26, X27, X28, X29, X30, SP,
24     Zero = SP,
25     FP = X29,
26     INVALID_REG = 0xFF,
27 };
28 
29 enum RegisterType {
30     W = 0,
31     X = 1,
32 };
33 
34 static const int RegXSize = 64;
35 static const int RegWSize = 32;
36 
37 enum VectorRegisterId : uint8_t {
38     v0, v1, v2, v3, v4, v5, v6, v7,
39     v8, v9, v10, v11, v12, v13, v14, v15,
40     v16, v17, v18, v19, v20, v21, v22, v23,
41     v24, v25, v26, v27, v28, v29, v30, v31,
42     INVALID_VREG = 0xFF,
43 };
44 
45 enum Extend : uint8_t {
46     NO_EXTEND = 0xFF,
47     UXTB = 0,   /* zero extend to byte */
48     UXTH = 1,   /* zero extend to half word */
49     UXTW = 2,   /* zero extend to word */
50     UXTX = 3,   /* zero extend to 64bit */
51     SXTB = 4,   /* sign extend to byte */
52     SXTH = 5,   /* sign extend to half word */
53     SXTW = 6,   /* sign extend to word */
54     SXTX = 7,   /* sign extend to 64bit */
55 };
56 
57 enum Shift : uint8_t {
58     NO_SHIFT = 0xFF,
59     LSL = 0x0,
60     LSR = 0x1,
61     ASR = 0x2,
62     ROR = 0x3,
63     MSL = 0x4,
64 };
65 
66 enum Scale {
67     B = 0,
68     H = 1,
69     S = 2,
70     D = 3,
71     Q = 4,
72 };
73 
74 enum Condition {
75     EQ = 0,
76     NE = 1,
77     HS = 2,
78     CS = HS,
79     LO = 3,
80     CC = LO,
81     MI = 4,
82     PL = 5,
83     VS = 6,
84     VC = 7,
85     HI = 8,
86     LS = 9,
87     GE = 10,
88     LT = 11,
89     GT = 12,
90     LE = 13,
91     AL = 14,
92     NV = 15,
93 };
94 
95 enum MoveOpCode {
96     MOVN = 0x12800000,
97     MOVZ = 0X52800000,
98     MOVK = 0x72800000,
99 };
100 
101 enum AddSubOpCode {
102     ADD_Imm     = 0x11000000,
103     ADD_Shift   = 0x0b000000,
104     ADD_Extend  = 0x0b200000,
105     SUB_Extend  = 0x4b200000,
106     SUB_Imm     = 0x51000000,
107     SUB_Shift   = 0x4b000000,
108 };
109 
110 enum BitwiseOpCode {
111     AND_Imm      = 0x12000000,
112     AND_Shift    = 0x0a000000,
113     ANDS_Imm     = 0x72000000,
114     ANDS_Shift   = 0x6a000000,
115     ORR_Imm      = 0x32000000,
116     ORR_Shift    = 0x2a000000,
117 };
118 
119 // branch code
120 enum BranchOpCode {
121     BranchFMask = 0x7C000000,
122     BranchCondFMask = 0xFE000000,
123     BranchCompareFMask = 0x7E000000,
124     BranchTestFMask = 0x7E000000,
125     Branch      = 0x14000000,
126     BranchCond  = 0x54000000,
127     BCCond      = 0x54000010,
128     BR          = 0xd61f0000,
129     CBNZ        = 0x35000000,
130     CBZ         = 0x34000000,
131     TBZ         = 0x36000000,
132     TBNZ        = 0x37000000,
133 };
134 
135 // brk code
136 enum BrkOpCode {
137     BRKImm      = 0xd4200000,
138 };
139 
140 // call code
141 enum CallOpCode {
142     BL  = 0x94000000,
143     BLR = 0xd63f0000,
144 };
145 
146 // compare code
147 enum CompareCode {
148     CMP_Extend  = 0x6d20000f,
149     CMP_Imm     = 0x7100000f,
150     CMP_Shift   = 0x6d00000f,
151     CSEL        = 0x1a800000,
152     CSET        = 0x1a9f07e0,
153 };
154 
155 // memory code
156 enum LoadStorePairOpCode {
157     LDP_Post     = 0x28c00000,
158     LDP_Pre      = 0x29c00000,
159     LDP_Offset   = 0x29400000,
160     LDP_V_Post   = 0x2cc00000,
161     LDP_V_Pre    = 0x2dc00000,
162     LDP_V_Offset = 0x2d400000,
163     STP_Post     = 0x28800000,
164     STP_Pre      = 0x29800000,
165     STP_Offset   = 0x29000000,
166     STP_V_Post   = 0x2c800000,
167     STP_V_Pre    = 0x2d800000,
168     STP_V_Offset = 0x2d00000,
169 };
170 
171 enum LoadStoreOpCode {
172     LDR_Post     = 0xb8400400,
173     LDR_Pre      = 0xb8400c00,
174     LDR_Offset   = 0xb9400000,
175     LDRB_Post    = 0x38400400,
176     LDRB_Pre     = 0x38400c00,
177     LDRB_Offset  = 0x39400000,
178     LDRH_Post    = 0x78400400,
179     LDRH_Pre     = 0x78400c00,
180     LDRH_Offset  = 0x79400000,
181     STR_Post     = 0xb8000400,
182     STR_Pre      = 0xb8000c00,
183     STR_Offset   = 0xb9000000,
184     LDR_Register = 0xb8600800,
185     LDRB_Register = 0x38600800,
186     LDRH_Register = 0x78600800,
187     LDUR_Offset   = 0xb8400000,
188     STUR_Offset   = 0xb8000000,
189 };
190 
191 enum  AddrMode {
192     OFFSET,
193     PREINDEX,
194     POSTINDEX
195 };
196 
197 enum LogicShiftOpCode {
198     LSL_Reg = 0x1AC02000,
199     LSR_Reg = 0x1AC02400,
200     UBFM    = 0x53000000,
201     BFM     = 0xB3400000,
202 };
203 
204 enum NopOpCode {
205     Nop = 0xd503201f,
206 };
207 
208 enum RetOpCode {
209     Ret = 0xd65f0000,
210 };
211 
212 #define COMMON_REGISTER_FIELD_LIST(V)   \
213     V(COMMON_REG, Rd, 4, 0)             \
214     V(COMMON_REG, Rn, 9, 5)             \
215     V(COMMON_REG, Rm, 20, 16)           \
216     V(COMMON_REG, Rt, 4, 0)             \
217     V(COMMON_REG, Rt2, 14, 10)          \
218     V(COMMON_REG, Sf, 31, 31)
219 
220 /* Aarch64 Instruction MOVZ Field Defines
221     |31 30 29 28|27 26 25 24|23 22 21 20 |        |15 14     |11 10 9  |      5 4|       0|
222     |sf| 1 0 | 1  0 0  1  0  1|  hw |                    imm16                 |    Rd    |
223    Aarch64 Instruction MOVN Field Defines
224     |31 30 29 28|27 26 25 24|23 22 21 20 |        |15 14     |11 10 9  |      5 4|       0|
225     |sf| 0 0 | 1  0 0  1  0  1|  hw |                    imm16                 |    Rd    |
226    Aarch64 Instruction MOVK Field Defines
227     |31 30 29 28|27 26 25 24|23 22 21 20 |        |15 14     |11 10 9  |      5 4|       0|
228     |sf| 1 1 | 1  0 0  1  0  1|  hw |                    imm16                 |    Rd    |
229 */
230 #define MOV_WIDE_FIELD_LIST(V)   \
231     V(MOV_WIDE, Imm16, 20, 5)    \
232     V(MOV_WIDE, Hw, 22, 21)
233 
234 /* Aarch64 Instruction AddImm Field Defines
235     |31 30 29 28|27 26 25 24|23 22 21 20 |        |15 14     |11 10 9  |      5 4|       0|
236     |sf| 1 S | 1  0  0  0  0  1|sh|             imm12              |    Rn     |    Rd    |
237    Aarch64 Instruction AddShift Field Defines
238     |31 30 29 28|27 26 25 24|23 22 21 20 |      16|15 14     |11 10 9  |      5 4|       0|
239     |sf| 0 S | 0  1  0  1  1|shift| 0|    rm      |     imm6       |    Rn     |    Rd    |
240    Aarch64 Instruction AddExtend Field Defines
241     |31 30 29 28|27 26 25 24|23 22 21 20 |      16|15     13 12 |11 10 9  |      5 4|       0|
242     |sf| 0 S | 0  1  0  1  1|0  0 | 1|    rm      | option  |  imm3   |    Rn     |    Rd    |
243 */
244 #define ADD_SUB_FIELD_LIST(V)           \
245     V(ADD_SUB, S, 29, 29)               \
246     V(ADD_SUB, Sh, 22, 22)              \
247     V(ADD_SUB, Imm12, 21, 10)           \
248     V(ADD_SUB, Shift, 23, 22)           \
249     V(ADD_SUB, ShiftAmount, 15, 10)     \
250     V(ADD_SUB, ExtendOption, 15, 13)    \
251     V(ADD_SUB, ExtendShift, 12, 10)
252 
253 /*
254    Aarch64 Instruction OrrImm Field Defines
255     |31 30 29 28|27 26 25 24|23 22 21 20 |       16|15 14     |11 10 9  |      5 4|       0|
256     |sf| 0 1 | 1  0  0  1  0  0|N|       immr      |      imms      |    Rn     |    Rd    |
257    Aarch64 Instruction ORRShift Field Defines
258     |31 30 29 28|27 26 25 24|23 22 21 20 |      16|15 14     |11 10 9  |      5 4|       0|
259     |sf| 0 1 | 0  1  0  1  0|shift| 0|    rm      |     imm6       |    Rn     |    Rd    |
260 */
261 #define BITWISE_OP_FIELD_LIST(V)            \
262     V(BITWISE_OP, N, 22, 22)                \
263     V(BITWISE_OP, Immr, 21, 16)             \
264     V(BITWISE_OP, Shift, 23, 22)            \
265     V(BITWISE_OP, Imms, 15, 10)             \
266     V(BITWISE_OP, ShiftAmount, 15, 10)
267 
268 /*
269    Aarch64 Instruction CMP Instruction is aliase of Subs
270    Aarch64 Instruction CSEL Field Defines
271     |31 30 29 28|27 26 25 24|23 22 21 20 |       16|15 14   12 |11 10 9  |      5 4|       0|
272     |sf| 0  0| 1  1  0  1  0  1 0  0 |     rm      |    cond   | 0  0|    Rn     |    Rd    |
273    Aarch64 Instruction CSET Field Defines
274     |31 30 29 28|27 26 25 24|23 22 21 20|        16|15 14     |11 10 9  |    5 4|       0|
275     |sf| 0  0| 1  1  0  1  0|1  0  0| 1  1  1  1  1|   cond   | 0 1| 1 1 1 1 1|    Rd    |
276 */
277 #define COMPARE_OP_FIELD_LIST(V)   \
278     V(CSEL, Cond, 15, 12)          \
279 
280 /* Aarch64 Instruction LDR Field Defines
281     |31 30 29 28|27 26 25 24|23 22 21 20|        |15      12|11 10 9  |      5 4|       0|
282     |1  x | 1  0 1 |0 |0  0 | 0 1 | 0|          imm9        | 0 1  |    Rn    |     Rt   |
283 */
284 #define LDR_AND_STR_FIELD_LIST(V)   \
285     V(LDR_STR, Size, 31, 30)        \
286     V(LDR_STR, Opc, 23, 22)         \
287     V(LDR_STR, Imm9, 20, 12)        \
288     V(LDR_STR, Imm12, 21, 10)       \
289     V(LDR_STR, Extend, 15, 13)      \
290     V(LDR_STR, S, 12, 12)
291 
292 
293 /* Aarch64 Instruction LDP Field Defines
294     |31 30 29 28|27 26 25 24|23 22 21   |        |15 14     |11 10 9  |      5 4|       0|
295     |x  0 | 1  0 1 |0 |0  0  1| 1|      imm7        |    Rt2      |    Rn     |     Rt   |
296 */
297 #define LDP_AND_STP_FIELD_LIST(V)   \
298     V(LDP_STP, Opc, 31, 30)         \
299     V(LDP_STP, Imm7, 21, 15)
300 
301 
302 /* Aarch64 Instruction B Field Defines
303     |31 30 29 28|27 26 25 24|23 22 21   |        |15 14     |11 10 9  |      5 4|       0|
304     |x  0 | 1  0 1 |0 |0  0  1| 1|      imm7        |    Rt2      |    Rn     |     Rt   |
305 */
306 
307 #define BRANCH_FIELD_LIST(V)        \
308     V(BRANCH, Imm26, 25, 0)         \
309     V(BRANCH, Imm19, 23, 5)         \
310     V(BRANCH, Imm14, 18, 5)         \
311     V(BRANCH, B5, 31, 31)           \
312     V(BRANCH, B40, 23, 19)
313 
314 /* Aarch64 Instruction BRK Field Defines
315     |31 30 29 28|27 26 25 24|23 22 21   |        |15 14     |11 10 9  |      5 4|       0|
316     |1  1 | 0  1  0  0  0  0| 0  0  1|                 imm16                  |0 0 0 0  0|
317 */
318 #define BRK_FIELD_LIST(V)        \
319     V(BRK, Imm16, 20, 5)
320 
321 #define DECL_FIELDS_IN_INSTRUCTION(INSTNAME, FIELD_NAME, HIGHBITS, LOWBITS) \
322 static const uint32_t INSTNAME##_##FIELD_NAME##_HIGHBITS = HIGHBITS;  \
323 static const uint32_t INSTNAME##_##FIELD_NAME##_LOWBITS = LOWBITS;    \
324 static const uint32_t INSTNAME##_##FIELD_NAME##_WIDTH = ((HIGHBITS - LOWBITS) + 1); \
325 static const uint32_t INSTNAME##_##FIELD_NAME##_MASK = (((1 << INSTNAME##_##FIELD_NAME##_WIDTH) - 1) << LOWBITS);
326 
327 #define DECL_INSTRUCTION_FIELDS(V)  \
328     COMMON_REGISTER_FIELD_LIST(V)   \
329     LDP_AND_STP_FIELD_LIST(V)       \
330     LDR_AND_STR_FIELD_LIST(V)       \
331     MOV_WIDE_FIELD_LIST(V)          \
332     BITWISE_OP_FIELD_LIST(V)        \
333     ADD_SUB_FIELD_LIST(V)           \
334     COMPARE_OP_FIELD_LIST(V)        \
335     BRANCH_FIELD_LIST(V)            \
336     BRK_FIELD_LIST(V)
337 
338 DECL_INSTRUCTION_FIELDS(DECL_FIELDS_IN_INSTRUCTION)
339 #undef DECL_INSTRUCTION_FIELDS
340 };  // namespace panda::ecmascript::aarch64
341 #endif