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
18namespace panda::ecmascript::aarch64 {
19enum 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
29enum RegisterType {
30    W = 0,
31    X = 1,
32};
33
34static const int RegXSize = 64;
35static const int RegWSize = 32;
36
37enum 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
45enum 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
57enum Shift : uint8_t {
58    NO_SHIFT = 0xFF,
59    LSL = 0x0,
60    LSR = 0x1,
61    ASR = 0x2,
62    ROR = 0x3,
63    MSL = 0x4,
64};
65
66enum Scale {
67    B = 0,
68    H = 1,
69    S = 2,
70    D = 3,
71    Q = 4,
72};
73
74enum 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
95enum MoveOpCode {
96    MOVN = 0x12800000,
97    MOVZ = 0X52800000,
98    MOVK = 0x72800000,
99};
100
101enum 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
110enum 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
120enum 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
136enum BrkOpCode {
137    BRKImm      = 0xd4200000,
138};
139
140// call code
141enum CallOpCode {
142    BL  = 0x94000000,
143    BLR = 0xd63f0000,
144};
145
146// compare code
147enum CompareCode {
148    CMP_Extend  = 0x6d20000f,
149    CMP_Imm     = 0x7100000f,
150    CMP_Shift   = 0x6d00000f,
151    CSEL        = 0x1a800000,
152    CSET        = 0x1a9f07e0,
153};
154
155// memory code
156enum 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
171enum 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
191enum  AddrMode {
192    OFFSET,
193    PREINDEX,
194    POSTINDEX
195};
196
197enum LogicShiftOpCode {
198    LSL_Reg = 0x1AC02000,
199    LSR_Reg = 0x1AC02400,
200    UBFM    = 0x53000000,
201    BFM     = 0xB3400000,
202};
203
204enum NopOpCode {
205    Nop = 0xd503201f,
206};
207
208enum 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) \
322static const uint32_t INSTNAME##_##FIELD_NAME##_HIGHBITS = HIGHBITS;  \
323static const uint32_t INSTNAME##_##FIELD_NAME##_LOWBITS = LOWBITS;    \
324static const uint32_t INSTNAME##_##FIELD_NAME##_WIDTH = ((HIGHBITS - LOWBITS) + 1); \
325static 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
338DECL_INSTRUCTION_FIELDS(DECL_FIELDS_IN_INSTRUCTION)
339#undef DECL_INSTRUCTION_FIELDS
340};  // namespace panda::ecmascript::aarch64
341#endif