]> Git Repo - qemu.git/blob - tcg/aarch64/tcg-target.inc.c
tcg: Support arbitrary size + alignment
[qemu.git] / tcg / aarch64 / tcg-target.inc.c
1 /*
2  * Initial TCG Implementation for aarch64
3  *
4  * Copyright (c) 2013 Huawei Technologies Duesseldorf GmbH
5  * Written by Claudio Fontana
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or
8  * (at your option) any later version.
9  *
10  * See the COPYING file in the top-level directory for details.
11  */
12
13 #include "tcg-be-ldst.h"
14 #include "qemu/bitops.h"
15
16 /* We're going to re-use TCGType in setting of the SF bit, which controls
17    the size of the operation performed.  If we know the values match, it
18    makes things much cleaner.  */
19 QEMU_BUILD_BUG_ON(TCG_TYPE_I32 != 0 || TCG_TYPE_I64 != 1);
20
21 #ifdef CONFIG_DEBUG_TCG
22 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
23     "%x0", "%x1", "%x2", "%x3", "%x4", "%x5", "%x6", "%x7",
24     "%x8", "%x9", "%x10", "%x11", "%x12", "%x13", "%x14", "%x15",
25     "%x16", "%x17", "%x18", "%x19", "%x20", "%x21", "%x22", "%x23",
26     "%x24", "%x25", "%x26", "%x27", "%x28", "%fp", "%x30", "%sp",
27 };
28 #endif /* CONFIG_DEBUG_TCG */
29
30 static const int tcg_target_reg_alloc_order[] = {
31     TCG_REG_X20, TCG_REG_X21, TCG_REG_X22, TCG_REG_X23,
32     TCG_REG_X24, TCG_REG_X25, TCG_REG_X26, TCG_REG_X27,
33     TCG_REG_X28, /* we will reserve this for guest_base if configured */
34
35     TCG_REG_X8, TCG_REG_X9, TCG_REG_X10, TCG_REG_X11,
36     TCG_REG_X12, TCG_REG_X13, TCG_REG_X14, TCG_REG_X15,
37     TCG_REG_X16, TCG_REG_X17,
38
39     TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
40     TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7,
41
42     /* X18 reserved by system */
43     /* X19 reserved for AREG0 */
44     /* X29 reserved as fp */
45     /* X30 reserved as temporary */
46 };
47
48 static const int tcg_target_call_iarg_regs[8] = {
49     TCG_REG_X0, TCG_REG_X1, TCG_REG_X2, TCG_REG_X3,
50     TCG_REG_X4, TCG_REG_X5, TCG_REG_X6, TCG_REG_X7
51 };
52 static const int tcg_target_call_oarg_regs[1] = {
53     TCG_REG_X0
54 };
55
56 #define TCG_REG_TMP TCG_REG_X30
57
58 #ifndef CONFIG_SOFTMMU
59 /* Note that XZR cannot be encoded in the address base register slot,
60    as that actaully encodes SP.  So if we need to zero-extend the guest
61    address, via the address index register slot, we need to load even
62    a zero guest base into a register.  */
63 #define USE_GUEST_BASE     (guest_base != 0 || TARGET_LONG_BITS == 32)
64 #define TCG_REG_GUEST_BASE TCG_REG_X28
65 #endif
66
67 static inline void reloc_pc26(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
68 {
69     ptrdiff_t offset = target - code_ptr;
70     tcg_debug_assert(offset == sextract64(offset, 0, 26));
71     /* read instruction, mask away previous PC_REL26 parameter contents,
72        set the proper offset, then write back the instruction. */
73     *code_ptr = deposit32(*code_ptr, 0, 26, offset);
74 }
75
76 static inline void reloc_pc26_atomic(tcg_insn_unit *code_ptr,
77                                      tcg_insn_unit *target)
78 {
79     ptrdiff_t offset = target - code_ptr;
80     tcg_insn_unit insn;
81     tcg_debug_assert(offset == sextract64(offset, 0, 26));
82     /* read instruction, mask away previous PC_REL26 parameter contents,
83        set the proper offset, then write back the instruction. */
84     insn = atomic_read(code_ptr);
85     atomic_set(code_ptr, deposit32(insn, 0, 26, offset));
86 }
87
88 static inline void reloc_pc19(tcg_insn_unit *code_ptr, tcg_insn_unit *target)
89 {
90     ptrdiff_t offset = target - code_ptr;
91     tcg_debug_assert(offset == sextract64(offset, 0, 19));
92     *code_ptr = deposit32(*code_ptr, 5, 19, offset);
93 }
94
95 static inline void patch_reloc(tcg_insn_unit *code_ptr, int type,
96                                intptr_t value, intptr_t addend)
97 {
98     tcg_debug_assert(addend == 0);
99     switch (type) {
100     case R_AARCH64_JUMP26:
101     case R_AARCH64_CALL26:
102         reloc_pc26(code_ptr, (tcg_insn_unit *)value);
103         break;
104     case R_AARCH64_CONDBR19:
105         reloc_pc19(code_ptr, (tcg_insn_unit *)value);
106         break;
107     default:
108         tcg_abort();
109     }
110 }
111
112 #define TCG_CT_CONST_AIMM 0x100
113 #define TCG_CT_CONST_LIMM 0x200
114 #define TCG_CT_CONST_ZERO 0x400
115 #define TCG_CT_CONST_MONE 0x800
116
117 /* parse target specific constraints */
118 static int target_parse_constraint(TCGArgConstraint *ct,
119                                    const char **pct_str)
120 {
121     const char *ct_str = *pct_str;
122
123     switch (ct_str[0]) {
124     case 'r':
125         ct->ct |= TCG_CT_REG;
126         tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1);
127         break;
128     case 'l': /* qemu_ld / qemu_st address, data_reg */
129         ct->ct |= TCG_CT_REG;
130         tcg_regset_set32(ct->u.regs, 0, (1ULL << TCG_TARGET_NB_REGS) - 1);
131 #ifdef CONFIG_SOFTMMU
132         /* x0 and x1 will be overwritten when reading the tlb entry,
133            and x2, and x3 for helper args, better to avoid using them. */
134         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X0);
135         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X1);
136         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X2);
137         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
138 #endif
139         break;
140     case 'A': /* Valid for arithmetic immediate (positive or negative).  */
141         ct->ct |= TCG_CT_CONST_AIMM;
142         break;
143     case 'L': /* Valid for logical immediate.  */
144         ct->ct |= TCG_CT_CONST_LIMM;
145         break;
146     case 'M': /* minus one */
147         ct->ct |= TCG_CT_CONST_MONE;
148         break;
149     case 'Z': /* zero */
150         ct->ct |= TCG_CT_CONST_ZERO;
151         break;
152     default:
153         return -1;
154     }
155
156     ct_str++;
157     *pct_str = ct_str;
158     return 0;
159 }
160
161 static inline bool is_aimm(uint64_t val)
162 {
163     return (val & ~0xfff) == 0 || (val & ~0xfff000) == 0;
164 }
165
166 static inline bool is_limm(uint64_t val)
167 {
168     /* Taking a simplified view of the logical immediates for now, ignoring
169        the replication that can happen across the field.  Match bit patterns
170        of the forms
171            0....01....1
172            0..01..10..0
173        and their inverses.  */
174
175     /* Make things easier below, by testing the form with msb clear. */
176     if ((int64_t)val < 0) {
177         val = ~val;
178     }
179     if (val == 0) {
180         return false;
181     }
182     val += val & -val;
183     return (val & (val - 1)) == 0;
184 }
185
186 static int tcg_target_const_match(tcg_target_long val, TCGType type,
187                                   const TCGArgConstraint *arg_ct)
188 {
189     int ct = arg_ct->ct;
190
191     if (ct & TCG_CT_CONST) {
192         return 1;
193     }
194     if (type == TCG_TYPE_I32) {
195         val = (int32_t)val;
196     }
197     if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
198         return 1;
199     }
200     if ((ct & TCG_CT_CONST_LIMM) && is_limm(val)) {
201         return 1;
202     }
203     if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
204         return 1;
205     }
206     if ((ct & TCG_CT_CONST_MONE) && val == -1) {
207         return 1;
208     }
209
210     return 0;
211 }
212
213 enum aarch64_cond_code {
214     COND_EQ = 0x0,
215     COND_NE = 0x1,
216     COND_CS = 0x2,     /* Unsigned greater or equal */
217     COND_HS = COND_CS, /* ALIAS greater or equal */
218     COND_CC = 0x3,     /* Unsigned less than */
219     COND_LO = COND_CC, /* ALIAS Lower */
220     COND_MI = 0x4,     /* Negative */
221     COND_PL = 0x5,     /* Zero or greater */
222     COND_VS = 0x6,     /* Overflow */
223     COND_VC = 0x7,     /* No overflow */
224     COND_HI = 0x8,     /* Unsigned greater than */
225     COND_LS = 0x9,     /* Unsigned less or equal */
226     COND_GE = 0xa,
227     COND_LT = 0xb,
228     COND_GT = 0xc,
229     COND_LE = 0xd,
230     COND_AL = 0xe,
231     COND_NV = 0xf, /* behaves like COND_AL here */
232 };
233
234 static const enum aarch64_cond_code tcg_cond_to_aarch64[] = {
235     [TCG_COND_EQ] = COND_EQ,
236     [TCG_COND_NE] = COND_NE,
237     [TCG_COND_LT] = COND_LT,
238     [TCG_COND_GE] = COND_GE,
239     [TCG_COND_LE] = COND_LE,
240     [TCG_COND_GT] = COND_GT,
241     /* unsigned */
242     [TCG_COND_LTU] = COND_LO,
243     [TCG_COND_GTU] = COND_HI,
244     [TCG_COND_GEU] = COND_HS,
245     [TCG_COND_LEU] = COND_LS,
246 };
247
248 typedef enum {
249     LDST_ST = 0,    /* store */
250     LDST_LD = 1,    /* load */
251     LDST_LD_S_X = 2,  /* load and sign-extend into Xt */
252     LDST_LD_S_W = 3,  /* load and sign-extend into Wt */
253 } AArch64LdstType;
254
255 /* We encode the format of the insn into the beginning of the name, so that
256    we can have the preprocessor help "typecheck" the insn vs the output
257    function.  Arm didn't provide us with nice names for the formats, so we
258    use the section number of the architecture reference manual in which the
259    instruction group is described.  */
260 typedef enum {
261     /* Compare and branch (immediate).  */
262     I3201_CBZ       = 0x34000000,
263     I3201_CBNZ      = 0x35000000,
264
265     /* Conditional branch (immediate).  */
266     I3202_B_C       = 0x54000000,
267
268     /* Unconditional branch (immediate).  */
269     I3206_B         = 0x14000000,
270     I3206_BL        = 0x94000000,
271
272     /* Unconditional branch (register).  */
273     I3207_BR        = 0xd61f0000,
274     I3207_BLR       = 0xd63f0000,
275     I3207_RET       = 0xd65f0000,
276
277     /* Load/store register.  Described here as 3.3.12, but the helper
278        that emits them can transform to 3.3.10 or 3.3.13.  */
279     I3312_STRB      = 0x38000000 | LDST_ST << 22 | MO_8 << 30,
280     I3312_STRH      = 0x38000000 | LDST_ST << 22 | MO_16 << 30,
281     I3312_STRW      = 0x38000000 | LDST_ST << 22 | MO_32 << 30,
282     I3312_STRX      = 0x38000000 | LDST_ST << 22 | MO_64 << 30,
283
284     I3312_LDRB      = 0x38000000 | LDST_LD << 22 | MO_8 << 30,
285     I3312_LDRH      = 0x38000000 | LDST_LD << 22 | MO_16 << 30,
286     I3312_LDRW      = 0x38000000 | LDST_LD << 22 | MO_32 << 30,
287     I3312_LDRX      = 0x38000000 | LDST_LD << 22 | MO_64 << 30,
288
289     I3312_LDRSBW    = 0x38000000 | LDST_LD_S_W << 22 | MO_8 << 30,
290     I3312_LDRSHW    = 0x38000000 | LDST_LD_S_W << 22 | MO_16 << 30,
291
292     I3312_LDRSBX    = 0x38000000 | LDST_LD_S_X << 22 | MO_8 << 30,
293     I3312_LDRSHX    = 0x38000000 | LDST_LD_S_X << 22 | MO_16 << 30,
294     I3312_LDRSWX    = 0x38000000 | LDST_LD_S_X << 22 | MO_32 << 30,
295
296     I3312_TO_I3310  = 0x00200800,
297     I3312_TO_I3313  = 0x01000000,
298
299     /* Load/store register pair instructions.  */
300     I3314_LDP       = 0x28400000,
301     I3314_STP       = 0x28000000,
302
303     /* Add/subtract immediate instructions.  */
304     I3401_ADDI      = 0x11000000,
305     I3401_ADDSI     = 0x31000000,
306     I3401_SUBI      = 0x51000000,
307     I3401_SUBSI     = 0x71000000,
308
309     /* Bitfield instructions.  */
310     I3402_BFM       = 0x33000000,
311     I3402_SBFM      = 0x13000000,
312     I3402_UBFM      = 0x53000000,
313
314     /* Extract instruction.  */
315     I3403_EXTR      = 0x13800000,
316
317     /* Logical immediate instructions.  */
318     I3404_ANDI      = 0x12000000,
319     I3404_ORRI      = 0x32000000,
320     I3404_EORI      = 0x52000000,
321
322     /* Move wide immediate instructions.  */
323     I3405_MOVN      = 0x12800000,
324     I3405_MOVZ      = 0x52800000,
325     I3405_MOVK      = 0x72800000,
326
327     /* PC relative addressing instructions.  */
328     I3406_ADR       = 0x10000000,
329     I3406_ADRP      = 0x90000000,
330
331     /* Add/subtract shifted register instructions (without a shift).  */
332     I3502_ADD       = 0x0b000000,
333     I3502_ADDS      = 0x2b000000,
334     I3502_SUB       = 0x4b000000,
335     I3502_SUBS      = 0x6b000000,
336
337     /* Add/subtract shifted register instructions (with a shift).  */
338     I3502S_ADD_LSL  = I3502_ADD,
339
340     /* Add/subtract with carry instructions.  */
341     I3503_ADC       = 0x1a000000,
342     I3503_SBC       = 0x5a000000,
343
344     /* Conditional select instructions.  */
345     I3506_CSEL      = 0x1a800000,
346     I3506_CSINC     = 0x1a800400,
347
348     /* Data-processing (1 source) instructions.  */
349     I3507_REV16     = 0x5ac00400,
350     I3507_REV32     = 0x5ac00800,
351     I3507_REV64     = 0x5ac00c00,
352
353     /* Data-processing (2 source) instructions.  */
354     I3508_LSLV      = 0x1ac02000,
355     I3508_LSRV      = 0x1ac02400,
356     I3508_ASRV      = 0x1ac02800,
357     I3508_RORV      = 0x1ac02c00,
358     I3508_SMULH     = 0x9b407c00,
359     I3508_UMULH     = 0x9bc07c00,
360     I3508_UDIV      = 0x1ac00800,
361     I3508_SDIV      = 0x1ac00c00,
362
363     /* Data-processing (3 source) instructions.  */
364     I3509_MADD      = 0x1b000000,
365     I3509_MSUB      = 0x1b008000,
366
367     /* Logical shifted register instructions (without a shift).  */
368     I3510_AND       = 0x0a000000,
369     I3510_BIC       = 0x0a200000,
370     I3510_ORR       = 0x2a000000,
371     I3510_ORN       = 0x2a200000,
372     I3510_EOR       = 0x4a000000,
373     I3510_EON       = 0x4a200000,
374     I3510_ANDS      = 0x6a000000,
375 } AArch64Insn;
376
377 static inline uint32_t tcg_in32(TCGContext *s)
378 {
379     uint32_t v = *(uint32_t *)s->code_ptr;
380     return v;
381 }
382
383 /* Emit an opcode with "type-checking" of the format.  */
384 #define tcg_out_insn(S, FMT, OP, ...) \
385     glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
386
387 static void tcg_out_insn_3201(TCGContext *s, AArch64Insn insn, TCGType ext,
388                               TCGReg rt, int imm19)
389 {
390     tcg_out32(s, insn | ext << 31 | (imm19 & 0x7ffff) << 5 | rt);
391 }
392
393 static void tcg_out_insn_3202(TCGContext *s, AArch64Insn insn,
394                               TCGCond c, int imm19)
395 {
396     tcg_out32(s, insn | tcg_cond_to_aarch64[c] | (imm19 & 0x7ffff) << 5);
397 }
398
399 static void tcg_out_insn_3206(TCGContext *s, AArch64Insn insn, int imm26)
400 {
401     tcg_out32(s, insn | (imm26 & 0x03ffffff));
402 }
403
404 static void tcg_out_insn_3207(TCGContext *s, AArch64Insn insn, TCGReg rn)
405 {
406     tcg_out32(s, insn | rn << 5);
407 }
408
409 static void tcg_out_insn_3314(TCGContext *s, AArch64Insn insn,
410                               TCGReg r1, TCGReg r2, TCGReg rn,
411                               tcg_target_long ofs, bool pre, bool w)
412 {
413     insn |= 1u << 31; /* ext */
414     insn |= pre << 24;
415     insn |= w << 23;
416
417     tcg_debug_assert(ofs >= -0x200 && ofs < 0x200 && (ofs & 7) == 0);
418     insn |= (ofs & (0x7f << 3)) << (15 - 3);
419
420     tcg_out32(s, insn | r2 << 10 | rn << 5 | r1);
421 }
422
423 static void tcg_out_insn_3401(TCGContext *s, AArch64Insn insn, TCGType ext,
424                               TCGReg rd, TCGReg rn, uint64_t aimm)
425 {
426     if (aimm > 0xfff) {
427         tcg_debug_assert((aimm & 0xfff) == 0);
428         aimm >>= 12;
429         tcg_debug_assert(aimm <= 0xfff);
430         aimm |= 1 << 12;  /* apply LSL 12 */
431     }
432     tcg_out32(s, insn | ext << 31 | aimm << 10 | rn << 5 | rd);
433 }
434
435 /* This function can be used for both 3.4.2 (Bitfield) and 3.4.4
436    (Logical immediate).  Both insn groups have N, IMMR and IMMS fields
437    that feed the DecodeBitMasks pseudo function.  */
438 static void tcg_out_insn_3402(TCGContext *s, AArch64Insn insn, TCGType ext,
439                               TCGReg rd, TCGReg rn, int n, int immr, int imms)
440 {
441     tcg_out32(s, insn | ext << 31 | n << 22 | immr << 16 | imms << 10
442               | rn << 5 | rd);
443 }
444
445 #define tcg_out_insn_3404  tcg_out_insn_3402
446
447 static void tcg_out_insn_3403(TCGContext *s, AArch64Insn insn, TCGType ext,
448                               TCGReg rd, TCGReg rn, TCGReg rm, int imms)
449 {
450     tcg_out32(s, insn | ext << 31 | ext << 22 | rm << 16 | imms << 10
451               | rn << 5 | rd);
452 }
453
454 /* This function is used for the Move (wide immediate) instruction group.
455    Note that SHIFT is a full shift count, not the 2 bit HW field. */
456 static void tcg_out_insn_3405(TCGContext *s, AArch64Insn insn, TCGType ext,
457                               TCGReg rd, uint16_t half, unsigned shift)
458 {
459     tcg_debug_assert((shift & ~0x30) == 0);
460     tcg_out32(s, insn | ext << 31 | shift << (21 - 4) | half << 5 | rd);
461 }
462
463 static void tcg_out_insn_3406(TCGContext *s, AArch64Insn insn,
464                               TCGReg rd, int64_t disp)
465 {
466     tcg_out32(s, insn | (disp & 3) << 29 | (disp & 0x1ffffc) << (5 - 2) | rd);
467 }
468
469 /* This function is for both 3.5.2 (Add/Subtract shifted register), for
470    the rare occasion when we actually want to supply a shift amount.  */
471 static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
472                                       TCGType ext, TCGReg rd, TCGReg rn,
473                                       TCGReg rm, int imm6)
474 {
475     tcg_out32(s, insn | ext << 31 | rm << 16 | imm6 << 10 | rn << 5 | rd);
476 }
477
478 /* This function is for 3.5.2 (Add/subtract shifted register),
479    and 3.5.10 (Logical shifted register), for the vast majorty of cases
480    when we don't want to apply a shift.  Thus it can also be used for
481    3.5.3 (Add/subtract with carry) and 3.5.8 (Data processing 2 source).  */
482 static void tcg_out_insn_3502(TCGContext *s, AArch64Insn insn, TCGType ext,
483                               TCGReg rd, TCGReg rn, TCGReg rm)
484 {
485     tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd);
486 }
487
488 #define tcg_out_insn_3503  tcg_out_insn_3502
489 #define tcg_out_insn_3508  tcg_out_insn_3502
490 #define tcg_out_insn_3510  tcg_out_insn_3502
491
492 static void tcg_out_insn_3506(TCGContext *s, AArch64Insn insn, TCGType ext,
493                               TCGReg rd, TCGReg rn, TCGReg rm, TCGCond c)
494 {
495     tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd
496               | tcg_cond_to_aarch64[c] << 12);
497 }
498
499 static void tcg_out_insn_3507(TCGContext *s, AArch64Insn insn, TCGType ext,
500                               TCGReg rd, TCGReg rn)
501 {
502     tcg_out32(s, insn | ext << 31 | rn << 5 | rd);
503 }
504
505 static void tcg_out_insn_3509(TCGContext *s, AArch64Insn insn, TCGType ext,
506                               TCGReg rd, TCGReg rn, TCGReg rm, TCGReg ra)
507 {
508     tcg_out32(s, insn | ext << 31 | rm << 16 | ra << 10 | rn << 5 | rd);
509 }
510
511 static void tcg_out_insn_3310(TCGContext *s, AArch64Insn insn,
512                               TCGReg rd, TCGReg base, TCGType ext,
513                               TCGReg regoff)
514 {
515     /* Note the AArch64Insn constants above are for C3.3.12.  Adjust.  */
516     tcg_out32(s, insn | I3312_TO_I3310 | regoff << 16 |
517               0x4000 | ext << 13 | base << 5 | rd);
518 }
519
520 static void tcg_out_insn_3312(TCGContext *s, AArch64Insn insn,
521                               TCGReg rd, TCGReg rn, intptr_t offset)
522 {
523     tcg_out32(s, insn | (offset & 0x1ff) << 12 | rn << 5 | rd);
524 }
525
526 static void tcg_out_insn_3313(TCGContext *s, AArch64Insn insn,
527                               TCGReg rd, TCGReg rn, uintptr_t scaled_uimm)
528 {
529     /* Note the AArch64Insn constants above are for C3.3.12.  Adjust.  */
530     tcg_out32(s, insn | I3312_TO_I3313 | scaled_uimm << 10 | rn << 5 | rd);
531 }
532
533 /* Register to register move using ORR (shifted register with no shift). */
534 static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rm)
535 {
536     tcg_out_insn(s, 3510, ORR, ext, rd, TCG_REG_XZR, rm);
537 }
538
539 /* Register to register move using ADDI (move to/from SP).  */
540 static void tcg_out_movr_sp(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn)
541 {
542     tcg_out_insn(s, 3401, ADDI, ext, rd, rn, 0);
543 }
544
545 /* This function is used for the Logical (immediate) instruction group.
546    The value of LIMM must satisfy IS_LIMM.  See the comment above about
547    only supporting simplified logical immediates.  */
548 static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext,
549                              TCGReg rd, TCGReg rn, uint64_t limm)
550 {
551     unsigned h, l, r, c;
552
553     tcg_debug_assert(is_limm(limm));
554
555     h = clz64(limm);
556     l = ctz64(limm);
557     if (l == 0) {
558         r = 0;                  /* form 0....01....1 */
559         c = ctz64(~limm) - 1;
560         if (h == 0) {
561             r = clz64(~limm);   /* form 1..10..01..1 */
562             c += r;
563         }
564     } else {
565         r = 64 - l;             /* form 1....10....0 or 0..01..10..0 */
566         c = r - h - 1;
567     }
568     if (ext == TCG_TYPE_I32) {
569         r &= 31;
570         c &= 31;
571     }
572
573     tcg_out_insn_3404(s, insn, ext, rd, rn, ext, r, c);
574 }
575
576 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
577                          tcg_target_long value)
578 {
579     AArch64Insn insn;
580     int i, wantinv, shift;
581     tcg_target_long svalue = value;
582     tcg_target_long ivalue = ~value;
583     tcg_target_long imask;
584
585     /* For 32-bit values, discard potential garbage in value.  For 64-bit
586        values within [2**31, 2**32-1], we can create smaller sequences by
587        interpreting this as a negative 32-bit number, while ensuring that
588        the high 32 bits are cleared by setting SF=0.  */
589     if (type == TCG_TYPE_I32 || (value & ~0xffffffffull) == 0) {
590         svalue = (int32_t)value;
591         value = (uint32_t)value;
592         ivalue = (uint32_t)ivalue;
593         type = TCG_TYPE_I32;
594     }
595
596     /* Speed things up by handling the common case of small positive
597        and negative values specially.  */
598     if ((value & ~0xffffull) == 0) {
599         tcg_out_insn(s, 3405, MOVZ, type, rd, value, 0);
600         return;
601     } else if ((ivalue & ~0xffffull) == 0) {
602         tcg_out_insn(s, 3405, MOVN, type, rd, ivalue, 0);
603         return;
604     }
605
606     /* Check for bitfield immediates.  For the benefit of 32-bit quantities,
607        use the sign-extended value.  That lets us match rotated values such
608        as 0xff0000ff with the same 64-bit logic matching 0xffffffffff0000ff. */
609     if (is_limm(svalue)) {
610         tcg_out_logicali(s, I3404_ORRI, type, rd, TCG_REG_XZR, svalue);
611         return;
612     }
613
614     /* Look for host pointer values within 4G of the PC.  This happens
615        often when loading pointers to QEMU's own data structures.  */
616     if (type == TCG_TYPE_I64) {
617         tcg_target_long disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12);
618         if (disp == sextract64(disp, 0, 21)) {
619             tcg_out_insn(s, 3406, ADRP, rd, disp);
620             if (value & 0xfff) {
621                 tcg_out_insn(s, 3401, ADDI, type, rd, rd, value & 0xfff);
622             }
623             return;
624         }
625     }
626
627     /* Would it take fewer insns to begin with MOVN?  For the value and its
628        inverse, count the number of 16-bit lanes that are 0.  */
629     for (i = wantinv = imask = 0; i < 64; i += 16) {
630         tcg_target_long mask = 0xffffull << i;
631         if ((value & mask) == 0) {
632             wantinv -= 1;
633         }
634         if ((ivalue & mask) == 0) {
635             wantinv += 1;
636             imask |= mask;
637         }
638     }
639
640     /* If we had more 0xffff than 0x0000, invert VALUE and use MOVN.  */
641     insn = I3405_MOVZ;
642     if (wantinv > 0) {
643         value = ivalue;
644         insn = I3405_MOVN;
645     }
646
647     /* Find the lowest lane that is not 0x0000.  */
648     shift = ctz64(value) & (63 & -16);
649     tcg_out_insn_3405(s, insn, type, rd, value >> shift, shift);
650
651     if (wantinv > 0) {
652         /* Re-invert the value, so MOVK sees non-inverted bits.  */
653         value = ~value;
654         /* Clear out all the 0xffff lanes.  */
655         value ^= imask;
656     }
657     /* Clear out the lane that we just set.  */
658     value &= ~(0xffffUL << shift);
659
660     /* Iterate until all lanes have been set, and thus cleared from VALUE.  */
661     while (value) {
662         shift = ctz64(value) & (63 & -16);
663         tcg_out_insn(s, 3405, MOVK, type, rd, value >> shift, shift);
664         value &= ~(0xffffUL << shift);
665     }
666 }
667
668 /* Define something more legible for general use.  */
669 #define tcg_out_ldst_r  tcg_out_insn_3310
670
671 static void tcg_out_ldst(TCGContext *s, AArch64Insn insn,
672                          TCGReg rd, TCGReg rn, intptr_t offset)
673 {
674     TCGMemOp size = (uint32_t)insn >> 30;
675
676     /* If the offset is naturally aligned and in range, then we can
677        use the scaled uimm12 encoding */
678     if (offset >= 0 && !(offset & ((1 << size) - 1))) {
679         uintptr_t scaled_uimm = offset >> size;
680         if (scaled_uimm <= 0xfff) {
681             tcg_out_insn_3313(s, insn, rd, rn, scaled_uimm);
682             return;
683         }
684     }
685
686     /* Small signed offsets can use the unscaled encoding.  */
687     if (offset >= -256 && offset < 256) {
688         tcg_out_insn_3312(s, insn, rd, rn, offset);
689         return;
690     }
691
692     /* Worst-case scenario, move offset to temp register, use reg offset.  */
693     tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset);
694     tcg_out_ldst_r(s, insn, rd, rn, TCG_TYPE_I64, TCG_REG_TMP);
695 }
696
697 static inline void tcg_out_mov(TCGContext *s,
698                                TCGType type, TCGReg ret, TCGReg arg)
699 {
700     if (ret != arg) {
701         tcg_out_movr(s, type, ret, arg);
702     }
703 }
704
705 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
706                               TCGReg arg1, intptr_t arg2)
707 {
708     tcg_out_ldst(s, type == TCG_TYPE_I32 ? I3312_LDRW : I3312_LDRX,
709                  arg, arg1, arg2);
710 }
711
712 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
713                               TCGReg arg1, intptr_t arg2)
714 {
715     tcg_out_ldst(s, type == TCG_TYPE_I32 ? I3312_STRW : I3312_STRX,
716                  arg, arg1, arg2);
717 }
718
719 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
720                                TCGReg base, intptr_t ofs)
721 {
722     if (val == 0) {
723         tcg_out_st(s, type, TCG_REG_XZR, base, ofs);
724         return true;
725     }
726     return false;
727 }
728
729 static inline void tcg_out_bfm(TCGContext *s, TCGType ext, TCGReg rd,
730                                TCGReg rn, unsigned int a, unsigned int b)
731 {
732     tcg_out_insn(s, 3402, BFM, ext, rd, rn, ext, a, b);
733 }
734
735 static inline void tcg_out_ubfm(TCGContext *s, TCGType ext, TCGReg rd,
736                                 TCGReg rn, unsigned int a, unsigned int b)
737 {
738     tcg_out_insn(s, 3402, UBFM, ext, rd, rn, ext, a, b);
739 }
740
741 static inline void tcg_out_sbfm(TCGContext *s, TCGType ext, TCGReg rd,
742                                 TCGReg rn, unsigned int a, unsigned int b)
743 {
744     tcg_out_insn(s, 3402, SBFM, ext, rd, rn, ext, a, b);
745 }
746
747 static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd,
748                                 TCGReg rn, TCGReg rm, unsigned int a)
749 {
750     tcg_out_insn(s, 3403, EXTR, ext, rd, rn, rm, a);
751 }
752
753 static inline void tcg_out_shl(TCGContext *s, TCGType ext,
754                                TCGReg rd, TCGReg rn, unsigned int m)
755 {
756     int bits = ext ? 64 : 32;
757     int max = bits - 1;
758     tcg_out_ubfm(s, ext, rd, rn, bits - (m & max), max - (m & max));
759 }
760
761 static inline void tcg_out_shr(TCGContext *s, TCGType ext,
762                                TCGReg rd, TCGReg rn, unsigned int m)
763 {
764     int max = ext ? 63 : 31;
765     tcg_out_ubfm(s, ext, rd, rn, m & max, max);
766 }
767
768 static inline void tcg_out_sar(TCGContext *s, TCGType ext,
769                                TCGReg rd, TCGReg rn, unsigned int m)
770 {
771     int max = ext ? 63 : 31;
772     tcg_out_sbfm(s, ext, rd, rn, m & max, max);
773 }
774
775 static inline void tcg_out_rotr(TCGContext *s, TCGType ext,
776                                 TCGReg rd, TCGReg rn, unsigned int m)
777 {
778     int max = ext ? 63 : 31;
779     tcg_out_extr(s, ext, rd, rn, rn, m & max);
780 }
781
782 static inline void tcg_out_rotl(TCGContext *s, TCGType ext,
783                                 TCGReg rd, TCGReg rn, unsigned int m)
784 {
785     int bits = ext ? 64 : 32;
786     int max = bits - 1;
787     tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max));
788 }
789
790 static inline void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd,
791                                TCGReg rn, unsigned lsb, unsigned width)
792 {
793     unsigned size = ext ? 64 : 32;
794     unsigned a = (size - lsb) & (size - 1);
795     unsigned b = width - 1;
796     tcg_out_bfm(s, ext, rd, rn, a, b);
797 }
798
799 static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
800                         tcg_target_long b, bool const_b)
801 {
802     if (const_b) {
803         /* Using CMP or CMN aliases.  */
804         if (b >= 0) {
805             tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
806         } else {
807             tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
808         }
809     } else {
810         /* Using CMP alias SUBS wzr, Wn, Wm */
811         tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
812     }
813 }
814
815 static inline void tcg_out_goto(TCGContext *s, tcg_insn_unit *target)
816 {
817     ptrdiff_t offset = target - s->code_ptr;
818     tcg_debug_assert(offset == sextract64(offset, 0, 26));
819     tcg_out_insn(s, 3206, B, offset);
820 }
821
822 static inline void tcg_out_goto_noaddr(TCGContext *s)
823 {
824     /* We pay attention here to not modify the branch target by reading from
825        the buffer. This ensure that caches and memory are kept coherent during
826        retranslation.  Mask away possible garbage in the high bits for the
827        first translation, while keeping the offset bits for retranslation. */
828     uint32_t old = tcg_in32(s);
829     tcg_out_insn(s, 3206, B, old);
830 }
831
832 static inline void tcg_out_goto_cond_noaddr(TCGContext *s, TCGCond c)
833 {
834     /* See comments in tcg_out_goto_noaddr.  */
835     uint32_t old = tcg_in32(s) >> 5;
836     tcg_out_insn(s, 3202, B_C, c, old);
837 }
838
839 static inline void tcg_out_callr(TCGContext *s, TCGReg reg)
840 {
841     tcg_out_insn(s, 3207, BLR, reg);
842 }
843
844 static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
845 {
846     ptrdiff_t offset = target - s->code_ptr;
847     if (offset == sextract64(offset, 0, 26)) {
848         tcg_out_insn(s, 3206, BL, offset);
849     } else {
850         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, (intptr_t)target);
851         tcg_out_callr(s, TCG_REG_TMP);
852     }
853 }
854
855 void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
856 {
857     tcg_insn_unit *code_ptr = (tcg_insn_unit *)jmp_addr;
858     tcg_insn_unit *target = (tcg_insn_unit *)addr;
859
860     reloc_pc26_atomic(code_ptr, target);
861     flush_icache_range(jmp_addr, jmp_addr + 4);
862 }
863
864 static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)
865 {
866     if (!l->has_value) {
867         tcg_out_reloc(s, s->code_ptr, R_AARCH64_JUMP26, l, 0);
868         tcg_out_goto_noaddr(s);
869     } else {
870         tcg_out_goto(s, l->u.value_ptr);
871     }
872 }
873
874 static void tcg_out_brcond(TCGContext *s, TCGMemOp ext, TCGCond c, TCGArg a,
875                            TCGArg b, bool b_const, TCGLabel *l)
876 {
877     intptr_t offset;
878     bool need_cmp;
879
880     if (b_const && b == 0 && (c == TCG_COND_EQ || c == TCG_COND_NE)) {
881         need_cmp = false;
882     } else {
883         need_cmp = true;
884         tcg_out_cmp(s, ext, a, b, b_const);
885     }
886
887     if (!l->has_value) {
888         tcg_out_reloc(s, s->code_ptr, R_AARCH64_CONDBR19, l, 0);
889         offset = tcg_in32(s) >> 5;
890     } else {
891         offset = l->u.value_ptr - s->code_ptr;
892         tcg_debug_assert(offset == sextract64(offset, 0, 19));
893     }
894
895     if (need_cmp) {
896         tcg_out_insn(s, 3202, B_C, c, offset);
897     } else if (c == TCG_COND_EQ) {
898         tcg_out_insn(s, 3201, CBZ, ext, a, offset);
899     } else {
900         tcg_out_insn(s, 3201, CBNZ, ext, a, offset);
901     }
902 }
903
904 static inline void tcg_out_rev64(TCGContext *s, TCGReg rd, TCGReg rn)
905 {
906     tcg_out_insn(s, 3507, REV64, TCG_TYPE_I64, rd, rn);
907 }
908
909 static inline void tcg_out_rev32(TCGContext *s, TCGReg rd, TCGReg rn)
910 {
911     tcg_out_insn(s, 3507, REV32, TCG_TYPE_I32, rd, rn);
912 }
913
914 static inline void tcg_out_rev16(TCGContext *s, TCGReg rd, TCGReg rn)
915 {
916     tcg_out_insn(s, 3507, REV16, TCG_TYPE_I32, rd, rn);
917 }
918
919 static inline void tcg_out_sxt(TCGContext *s, TCGType ext, TCGMemOp s_bits,
920                                TCGReg rd, TCGReg rn)
921 {
922     /* Using ALIASes SXTB, SXTH, SXTW, of SBFM Xd, Xn, #0, #7|15|31 */
923     int bits = (8 << s_bits) - 1;
924     tcg_out_sbfm(s, ext, rd, rn, 0, bits);
925 }
926
927 static inline void tcg_out_uxt(TCGContext *s, TCGMemOp s_bits,
928                                TCGReg rd, TCGReg rn)
929 {
930     /* Using ALIASes UXTB, UXTH of UBFM Wd, Wn, #0, #7|15 */
931     int bits = (8 << s_bits) - 1;
932     tcg_out_ubfm(s, 0, rd, rn, 0, bits);
933 }
934
935 static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
936                             TCGReg rn, int64_t aimm)
937 {
938     if (aimm >= 0) {
939         tcg_out_insn(s, 3401, ADDI, ext, rd, rn, aimm);
940     } else {
941         tcg_out_insn(s, 3401, SUBI, ext, rd, rn, -aimm);
942     }
943 }
944
945 static inline void tcg_out_addsub2(TCGContext *s, int ext, TCGReg rl,
946                                    TCGReg rh, TCGReg al, TCGReg ah,
947                                    tcg_target_long bl, tcg_target_long bh,
948                                    bool const_bl, bool const_bh, bool sub)
949 {
950     TCGReg orig_rl = rl;
951     AArch64Insn insn;
952
953     if (rl == ah || (!const_bh && rl == bh)) {
954         rl = TCG_REG_TMP;
955     }
956
957     if (const_bl) {
958         insn = I3401_ADDSI;
959         if ((bl < 0) ^ sub) {
960             insn = I3401_SUBSI;
961             bl = -bl;
962         }
963         tcg_out_insn_3401(s, insn, ext, rl, al, bl);
964     } else {
965         tcg_out_insn_3502(s, sub ? I3502_SUBS : I3502_ADDS, ext, rl, al, bl);
966     }
967
968     insn = I3503_ADC;
969     if (const_bh) {
970         /* Note that the only two constants we support are 0 and -1, and
971            that SBC = rn + ~rm + c, so adc -1 is sbc 0, and vice-versa.  */
972         if ((bh != 0) ^ sub) {
973             insn = I3503_SBC;
974         }
975         bh = TCG_REG_XZR;
976     } else if (sub) {
977         insn = I3503_SBC;
978     }
979     tcg_out_insn_3503(s, insn, ext, rh, ah, bh);
980
981     tcg_out_mov(s, ext, orig_rl, rl);
982 }
983
984 #ifdef CONFIG_SOFTMMU
985 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
986  *                                     TCGMemOpIdx oi, uintptr_t ra)
987  */
988 static void * const qemu_ld_helpers[16] = {
989     [MO_UB]   = helper_ret_ldub_mmu,
990     [MO_LEUW] = helper_le_lduw_mmu,
991     [MO_LEUL] = helper_le_ldul_mmu,
992     [MO_LEQ]  = helper_le_ldq_mmu,
993     [MO_BEUW] = helper_be_lduw_mmu,
994     [MO_BEUL] = helper_be_ldul_mmu,
995     [MO_BEQ]  = helper_be_ldq_mmu,
996 };
997
998 /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
999  *                                     uintxx_t val, TCGMemOpIdx oi,
1000  *                                     uintptr_t ra)
1001  */
1002 static void * const qemu_st_helpers[16] = {
1003     [MO_UB]   = helper_ret_stb_mmu,
1004     [MO_LEUW] = helper_le_stw_mmu,
1005     [MO_LEUL] = helper_le_stl_mmu,
1006     [MO_LEQ]  = helper_le_stq_mmu,
1007     [MO_BEUW] = helper_be_stw_mmu,
1008     [MO_BEUL] = helper_be_stl_mmu,
1009     [MO_BEQ]  = helper_be_stq_mmu,
1010 };
1011
1012 static inline void tcg_out_adr(TCGContext *s, TCGReg rd, void *target)
1013 {
1014     ptrdiff_t offset = tcg_pcrel_diff(s, target);
1015     tcg_debug_assert(offset == sextract64(offset, 0, 21));
1016     tcg_out_insn(s, 3406, ADR, rd, offset);
1017 }
1018
1019 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1020 {
1021     TCGMemOpIdx oi = lb->oi;
1022     TCGMemOp opc = get_memop(oi);
1023     TCGMemOp size = opc & MO_SIZE;
1024
1025     reloc_pc19(lb->label_ptr[0], s->code_ptr);
1026
1027     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
1028     tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
1029     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, oi);
1030     tcg_out_adr(s, TCG_REG_X3, lb->raddr);
1031     tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1032     if (opc & MO_SIGN) {
1033         tcg_out_sxt(s, lb->type, size, lb->datalo_reg, TCG_REG_X0);
1034     } else {
1035         tcg_out_mov(s, size == MO_64, lb->datalo_reg, TCG_REG_X0);
1036     }
1037
1038     tcg_out_goto(s, lb->raddr);
1039 }
1040
1041 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1042 {
1043     TCGMemOpIdx oi = lb->oi;
1044     TCGMemOp opc = get_memop(oi);
1045     TCGMemOp size = opc & MO_SIZE;
1046
1047     reloc_pc19(lb->label_ptr[0], s->code_ptr);
1048
1049     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
1050     tcg_out_mov(s, TARGET_LONG_BITS == 64, TCG_REG_X1, lb->addrlo_reg);
1051     tcg_out_mov(s, size == MO_64, TCG_REG_X2, lb->datalo_reg);
1052     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, oi);
1053     tcg_out_adr(s, TCG_REG_X4, lb->raddr);
1054     tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1055     tcg_out_goto(s, lb->raddr);
1056 }
1057
1058 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1059                                 TCGType ext, TCGReg data_reg, TCGReg addr_reg,
1060                                 tcg_insn_unit *raddr, tcg_insn_unit *label_ptr)
1061 {
1062     TCGLabelQemuLdst *label = new_ldst_label(s);
1063
1064     label->is_ld = is_ld;
1065     label->oi = oi;
1066     label->type = ext;
1067     label->datalo_reg = data_reg;
1068     label->addrlo_reg = addr_reg;
1069     label->raddr = raddr;
1070     label->label_ptr[0] = label_ptr;
1071 }
1072
1073 /* Load and compare a TLB entry, emitting the conditional jump to the
1074    slow path for the failure case, which will be patched later when finalizing
1075    the slow path. Generated code returns the host addend in X1,
1076    clobbers X0,X2,X3,TMP. */
1077 static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, TCGMemOp opc,
1078                              tcg_insn_unit **label_ptr, int mem_index,
1079                              bool is_read)
1080 {
1081     int tlb_offset = is_read ?
1082         offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1083         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
1084     unsigned a_bits = get_alignment_bits(opc);
1085     unsigned s_bits = opc & MO_SIZE;
1086     unsigned a_mask = (1u << a_bits) - 1;
1087     unsigned s_mask = (1u << s_bits) - 1;
1088     TCGReg base = TCG_AREG0, x3;
1089     uint64_t tlb_mask;
1090
1091     /* For aligned accesses, we check the first byte and include the alignment
1092        bits within the address.  For unaligned access, we check that we don't
1093        cross pages using the address of the last byte of the access.  */
1094     if (a_bits >= s_bits) {
1095         x3 = addr_reg;
1096     } else {
1097         tcg_out_insn(s, 3401, ADDI, TARGET_LONG_BITS == 64,
1098                      TCG_REG_X3, addr_reg, s_mask - a_mask);
1099         x3 = TCG_REG_X3;
1100     }
1101     tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
1102
1103     /* Extract the TLB index from the address into X0.
1104        X0<CPU_TLB_BITS:0> =
1105        addr_reg<TARGET_PAGE_BITS+CPU_TLB_BITS:TARGET_PAGE_BITS> */
1106     tcg_out_ubfm(s, TARGET_LONG_BITS == 64, TCG_REG_X0, addr_reg,
1107                  TARGET_PAGE_BITS, TARGET_PAGE_BITS + CPU_TLB_BITS);
1108
1109     /* Store the page mask part of the address into X3.  */
1110     tcg_out_logicali(s, I3404_ANDI, TARGET_LONG_BITS == 64,
1111                      TCG_REG_X3, x3, tlb_mask);
1112
1113     /* Add any "high bits" from the tlb offset to the env address into X2,
1114        to take advantage of the LSL12 form of the ADDI instruction.
1115        X2 = env + (tlb_offset & 0xfff000) */
1116     if (tlb_offset & 0xfff000) {
1117         tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_X2, base,
1118                      tlb_offset & 0xfff000);
1119         base = TCG_REG_X2;
1120     }
1121
1122     /* Merge the tlb index contribution into X2.
1123        X2 = X2 + (X0 << CPU_TLB_ENTRY_BITS) */
1124     tcg_out_insn(s, 3502S, ADD_LSL, TCG_TYPE_I64, TCG_REG_X2, base,
1125                  TCG_REG_X0, CPU_TLB_ENTRY_BITS);
1126
1127     /* Merge "low bits" from tlb offset, load the tlb comparator into X0.
1128        X0 = load [X2 + (tlb_offset & 0x000fff)] */
1129     tcg_out_ldst(s, TARGET_LONG_BITS == 32 ? I3312_LDRW : I3312_LDRX,
1130                  TCG_REG_X0, TCG_REG_X2, tlb_offset & 0xfff);
1131
1132     /* Load the tlb addend. Do that early to avoid stalling.
1133        X1 = load [X2 + (tlb_offset & 0xfff) + offsetof(addend)] */
1134     tcg_out_ldst(s, I3312_LDRX, TCG_REG_X1, TCG_REG_X2,
1135                  (tlb_offset & 0xfff) + (offsetof(CPUTLBEntry, addend)) -
1136                  (is_read ? offsetof(CPUTLBEntry, addr_read)
1137                   : offsetof(CPUTLBEntry, addr_write)));
1138
1139     /* Perform the address comparison. */
1140     tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3, 0);
1141
1142     /* If not equal, we jump to the slow path. */
1143     *label_ptr = s->code_ptr;
1144     tcg_out_goto_cond_noaddr(s, TCG_COND_NE);
1145 }
1146
1147 #endif /* CONFIG_SOFTMMU */
1148
1149 static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop, TCGType ext,
1150                                    TCGReg data_r, TCGReg addr_r,
1151                                    TCGType otype, TCGReg off_r)
1152 {
1153     const TCGMemOp bswap = memop & MO_BSWAP;
1154
1155     switch (memop & MO_SSIZE) {
1156     case MO_UB:
1157         tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, otype, off_r);
1158         break;
1159     case MO_SB:
1160         tcg_out_ldst_r(s, ext ? I3312_LDRSBX : I3312_LDRSBW,
1161                        data_r, addr_r, otype, off_r);
1162         break;
1163     case MO_UW:
1164         tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r);
1165         if (bswap) {
1166             tcg_out_rev16(s, data_r, data_r);
1167         }
1168         break;
1169     case MO_SW:
1170         if (bswap) {
1171             tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r);
1172             tcg_out_rev16(s, data_r, data_r);
1173             tcg_out_sxt(s, ext, MO_16, data_r, data_r);
1174         } else {
1175             tcg_out_ldst_r(s, (ext ? I3312_LDRSHX : I3312_LDRSHW),
1176                            data_r, addr_r, otype, off_r);
1177         }
1178         break;
1179     case MO_UL:
1180         tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r);
1181         if (bswap) {
1182             tcg_out_rev32(s, data_r, data_r);
1183         }
1184         break;
1185     case MO_SL:
1186         if (bswap) {
1187             tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r);
1188             tcg_out_rev32(s, data_r, data_r);
1189             tcg_out_sxt(s, TCG_TYPE_I64, MO_32, data_r, data_r);
1190         } else {
1191             tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, otype, off_r);
1192         }
1193         break;
1194     case MO_Q:
1195         tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r);
1196         if (bswap) {
1197             tcg_out_rev64(s, data_r, data_r);
1198         }
1199         break;
1200     default:
1201         tcg_abort();
1202     }
1203 }
1204
1205 static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp memop,
1206                                    TCGReg data_r, TCGReg addr_r,
1207                                    TCGType otype, TCGReg off_r)
1208 {
1209     const TCGMemOp bswap = memop & MO_BSWAP;
1210
1211     switch (memop & MO_SIZE) {
1212     case MO_8:
1213         tcg_out_ldst_r(s, I3312_STRB, data_r, addr_r, otype, off_r);
1214         break;
1215     case MO_16:
1216         if (bswap && data_r != TCG_REG_XZR) {
1217             tcg_out_rev16(s, TCG_REG_TMP, data_r);
1218             data_r = TCG_REG_TMP;
1219         }
1220         tcg_out_ldst_r(s, I3312_STRH, data_r, addr_r, otype, off_r);
1221         break;
1222     case MO_32:
1223         if (bswap && data_r != TCG_REG_XZR) {
1224             tcg_out_rev32(s, TCG_REG_TMP, data_r);
1225             data_r = TCG_REG_TMP;
1226         }
1227         tcg_out_ldst_r(s, I3312_STRW, data_r, addr_r, otype, off_r);
1228         break;
1229     case MO_64:
1230         if (bswap && data_r != TCG_REG_XZR) {
1231             tcg_out_rev64(s, TCG_REG_TMP, data_r);
1232             data_r = TCG_REG_TMP;
1233         }
1234         tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, otype, off_r);
1235         break;
1236     default:
1237         tcg_abort();
1238     }
1239 }
1240
1241 static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1242                             TCGMemOpIdx oi, TCGType ext)
1243 {
1244     TCGMemOp memop = get_memop(oi);
1245     const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
1246 #ifdef CONFIG_SOFTMMU
1247     unsigned mem_index = get_mmuidx(oi);
1248     tcg_insn_unit *label_ptr;
1249
1250     tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 1);
1251     tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
1252                            TCG_REG_X1, otype, addr_reg);
1253     add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg,
1254                         s->code_ptr, label_ptr);
1255 #else /* !CONFIG_SOFTMMU */
1256     if (USE_GUEST_BASE) {
1257         tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
1258                                TCG_REG_GUEST_BASE, otype, addr_reg);
1259     } else {
1260         tcg_out_qemu_ld_direct(s, memop, ext, data_reg,
1261                                addr_reg, TCG_TYPE_I64, TCG_REG_XZR);
1262     }
1263 #endif /* CONFIG_SOFTMMU */
1264 }
1265
1266 static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1267                             TCGMemOpIdx oi)
1268 {
1269     TCGMemOp memop = get_memop(oi);
1270     const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32;
1271 #ifdef CONFIG_SOFTMMU
1272     unsigned mem_index = get_mmuidx(oi);
1273     tcg_insn_unit *label_ptr;
1274
1275     tcg_out_tlb_read(s, addr_reg, memop, &label_ptr, mem_index, 0);
1276     tcg_out_qemu_st_direct(s, memop, data_reg,
1277                            TCG_REG_X1, otype, addr_reg);
1278     add_qemu_ldst_label(s, false, oi, (memop & MO_SIZE)== MO_64,
1279                         data_reg, addr_reg, s->code_ptr, label_ptr);
1280 #else /* !CONFIG_SOFTMMU */
1281     if (USE_GUEST_BASE) {
1282         tcg_out_qemu_st_direct(s, memop, data_reg,
1283                                TCG_REG_GUEST_BASE, otype, addr_reg);
1284     } else {
1285         tcg_out_qemu_st_direct(s, memop, data_reg,
1286                                addr_reg, TCG_TYPE_I64, TCG_REG_XZR);
1287     }
1288 #endif /* CONFIG_SOFTMMU */
1289 }
1290
1291 static tcg_insn_unit *tb_ret_addr;
1292
1293 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1294                        const TCGArg args[TCG_MAX_OP_ARGS],
1295                        const int const_args[TCG_MAX_OP_ARGS])
1296 {
1297     /* 99% of the time, we can signal the use of extension registers
1298        by looking to see if the opcode handles 64-bit data.  */
1299     TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0;
1300
1301     /* Hoist the loads of the most common arguments.  */
1302     TCGArg a0 = args[0];
1303     TCGArg a1 = args[1];
1304     TCGArg a2 = args[2];
1305     int c2 = const_args[2];
1306
1307     /* Some operands are defined with "rZ" constraint, a register or
1308        the zero register.  These need not actually test args[I] == 0.  */
1309 #define REG0(I)  (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
1310
1311     switch (opc) {
1312     case INDEX_op_exit_tb:
1313         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
1314         tcg_out_goto(s, tb_ret_addr);
1315         break;
1316
1317     case INDEX_op_goto_tb:
1318 #ifndef USE_DIRECT_JUMP
1319 #error "USE_DIRECT_JUMP required for aarch64"
1320 #endif
1321         /* consistency for USE_DIRECT_JUMP */
1322         tcg_debug_assert(s->tb_jmp_insn_offset != NULL);
1323         s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1324         /* actual branch destination will be patched by
1325            aarch64_tb_set_jmp_target later, beware retranslation. */
1326         tcg_out_goto_noaddr(s);
1327         s->tb_jmp_reset_offset[a0] = tcg_current_code_size(s);
1328         break;
1329
1330     case INDEX_op_br:
1331         tcg_out_goto_label(s, arg_label(a0));
1332         break;
1333
1334     case INDEX_op_ld8u_i32:
1335     case INDEX_op_ld8u_i64:
1336         tcg_out_ldst(s, I3312_LDRB, a0, a1, a2);
1337         break;
1338     case INDEX_op_ld8s_i32:
1339         tcg_out_ldst(s, I3312_LDRSBW, a0, a1, a2);
1340         break;
1341     case INDEX_op_ld8s_i64:
1342         tcg_out_ldst(s, I3312_LDRSBX, a0, a1, a2);
1343         break;
1344     case INDEX_op_ld16u_i32:
1345     case INDEX_op_ld16u_i64:
1346         tcg_out_ldst(s, I3312_LDRH, a0, a1, a2);
1347         break;
1348     case INDEX_op_ld16s_i32:
1349         tcg_out_ldst(s, I3312_LDRSHW, a0, a1, a2);
1350         break;
1351     case INDEX_op_ld16s_i64:
1352         tcg_out_ldst(s, I3312_LDRSHX, a0, a1, a2);
1353         break;
1354     case INDEX_op_ld_i32:
1355     case INDEX_op_ld32u_i64:
1356         tcg_out_ldst(s, I3312_LDRW, a0, a1, a2);
1357         break;
1358     case INDEX_op_ld32s_i64:
1359         tcg_out_ldst(s, I3312_LDRSWX, a0, a1, a2);
1360         break;
1361     case INDEX_op_ld_i64:
1362         tcg_out_ldst(s, I3312_LDRX, a0, a1, a2);
1363         break;
1364
1365     case INDEX_op_st8_i32:
1366     case INDEX_op_st8_i64:
1367         tcg_out_ldst(s, I3312_STRB, REG0(0), a1, a2);
1368         break;
1369     case INDEX_op_st16_i32:
1370     case INDEX_op_st16_i64:
1371         tcg_out_ldst(s, I3312_STRH, REG0(0), a1, a2);
1372         break;
1373     case INDEX_op_st_i32:
1374     case INDEX_op_st32_i64:
1375         tcg_out_ldst(s, I3312_STRW, REG0(0), a1, a2);
1376         break;
1377     case INDEX_op_st_i64:
1378         tcg_out_ldst(s, I3312_STRX, REG0(0), a1, a2);
1379         break;
1380
1381     case INDEX_op_add_i32:
1382         a2 = (int32_t)a2;
1383         /* FALLTHRU */
1384     case INDEX_op_add_i64:
1385         if (c2) {
1386             tcg_out_addsubi(s, ext, a0, a1, a2);
1387         } else {
1388             tcg_out_insn(s, 3502, ADD, ext, a0, a1, a2);
1389         }
1390         break;
1391
1392     case INDEX_op_sub_i32:
1393         a2 = (int32_t)a2;
1394         /* FALLTHRU */
1395     case INDEX_op_sub_i64:
1396         if (c2) {
1397             tcg_out_addsubi(s, ext, a0, a1, -a2);
1398         } else {
1399             tcg_out_insn(s, 3502, SUB, ext, a0, a1, a2);
1400         }
1401         break;
1402
1403     case INDEX_op_neg_i64:
1404     case INDEX_op_neg_i32:
1405         tcg_out_insn(s, 3502, SUB, ext, a0, TCG_REG_XZR, a1);
1406         break;
1407
1408     case INDEX_op_and_i32:
1409         a2 = (int32_t)a2;
1410         /* FALLTHRU */
1411     case INDEX_op_and_i64:
1412         if (c2) {
1413             tcg_out_logicali(s, I3404_ANDI, ext, a0, a1, a2);
1414         } else {
1415             tcg_out_insn(s, 3510, AND, ext, a0, a1, a2);
1416         }
1417         break;
1418
1419     case INDEX_op_andc_i32:
1420         a2 = (int32_t)a2;
1421         /* FALLTHRU */
1422     case INDEX_op_andc_i64:
1423         if (c2) {
1424             tcg_out_logicali(s, I3404_ANDI, ext, a0, a1, ~a2);
1425         } else {
1426             tcg_out_insn(s, 3510, BIC, ext, a0, a1, a2);
1427         }
1428         break;
1429
1430     case INDEX_op_or_i32:
1431         a2 = (int32_t)a2;
1432         /* FALLTHRU */
1433     case INDEX_op_or_i64:
1434         if (c2) {
1435             tcg_out_logicali(s, I3404_ORRI, ext, a0, a1, a2);
1436         } else {
1437             tcg_out_insn(s, 3510, ORR, ext, a0, a1, a2);
1438         }
1439         break;
1440
1441     case INDEX_op_orc_i32:
1442         a2 = (int32_t)a2;
1443         /* FALLTHRU */
1444     case INDEX_op_orc_i64:
1445         if (c2) {
1446             tcg_out_logicali(s, I3404_ORRI, ext, a0, a1, ~a2);
1447         } else {
1448             tcg_out_insn(s, 3510, ORN, ext, a0, a1, a2);
1449         }
1450         break;
1451
1452     case INDEX_op_xor_i32:
1453         a2 = (int32_t)a2;
1454         /* FALLTHRU */
1455     case INDEX_op_xor_i64:
1456         if (c2) {
1457             tcg_out_logicali(s, I3404_EORI, ext, a0, a1, a2);
1458         } else {
1459             tcg_out_insn(s, 3510, EOR, ext, a0, a1, a2);
1460         }
1461         break;
1462
1463     case INDEX_op_eqv_i32:
1464         a2 = (int32_t)a2;
1465         /* FALLTHRU */
1466     case INDEX_op_eqv_i64:
1467         if (c2) {
1468             tcg_out_logicali(s, I3404_EORI, ext, a0, a1, ~a2);
1469         } else {
1470             tcg_out_insn(s, 3510, EON, ext, a0, a1, a2);
1471         }
1472         break;
1473
1474     case INDEX_op_not_i64:
1475     case INDEX_op_not_i32:
1476         tcg_out_insn(s, 3510, ORN, ext, a0, TCG_REG_XZR, a1);
1477         break;
1478
1479     case INDEX_op_mul_i64:
1480     case INDEX_op_mul_i32:
1481         tcg_out_insn(s, 3509, MADD, ext, a0, a1, a2, TCG_REG_XZR);
1482         break;
1483
1484     case INDEX_op_div_i64:
1485     case INDEX_op_div_i32:
1486         tcg_out_insn(s, 3508, SDIV, ext, a0, a1, a2);
1487         break;
1488     case INDEX_op_divu_i64:
1489     case INDEX_op_divu_i32:
1490         tcg_out_insn(s, 3508, UDIV, ext, a0, a1, a2);
1491         break;
1492
1493     case INDEX_op_rem_i64:
1494     case INDEX_op_rem_i32:
1495         tcg_out_insn(s, 3508, SDIV, ext, TCG_REG_TMP, a1, a2);
1496         tcg_out_insn(s, 3509, MSUB, ext, a0, TCG_REG_TMP, a2, a1);
1497         break;
1498     case INDEX_op_remu_i64:
1499     case INDEX_op_remu_i32:
1500         tcg_out_insn(s, 3508, UDIV, ext, TCG_REG_TMP, a1, a2);
1501         tcg_out_insn(s, 3509, MSUB, ext, a0, TCG_REG_TMP, a2, a1);
1502         break;
1503
1504     case INDEX_op_shl_i64:
1505     case INDEX_op_shl_i32:
1506         if (c2) {
1507             tcg_out_shl(s, ext, a0, a1, a2);
1508         } else {
1509             tcg_out_insn(s, 3508, LSLV, ext, a0, a1, a2);
1510         }
1511         break;
1512
1513     case INDEX_op_shr_i64:
1514     case INDEX_op_shr_i32:
1515         if (c2) {
1516             tcg_out_shr(s, ext, a0, a1, a2);
1517         } else {
1518             tcg_out_insn(s, 3508, LSRV, ext, a0, a1, a2);
1519         }
1520         break;
1521
1522     case INDEX_op_sar_i64:
1523     case INDEX_op_sar_i32:
1524         if (c2) {
1525             tcg_out_sar(s, ext, a0, a1, a2);
1526         } else {
1527             tcg_out_insn(s, 3508, ASRV, ext, a0, a1, a2);
1528         }
1529         break;
1530
1531     case INDEX_op_rotr_i64:
1532     case INDEX_op_rotr_i32:
1533         if (c2) {
1534             tcg_out_rotr(s, ext, a0, a1, a2);
1535         } else {
1536             tcg_out_insn(s, 3508, RORV, ext, a0, a1, a2);
1537         }
1538         break;
1539
1540     case INDEX_op_rotl_i64:
1541     case INDEX_op_rotl_i32:
1542         if (c2) {
1543             tcg_out_rotl(s, ext, a0, a1, a2);
1544         } else {
1545             tcg_out_insn(s, 3502, SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2);
1546             tcg_out_insn(s, 3508, RORV, ext, a0, a1, TCG_REG_TMP);
1547         }
1548         break;
1549
1550     case INDEX_op_brcond_i32:
1551         a1 = (int32_t)a1;
1552         /* FALLTHRU */
1553     case INDEX_op_brcond_i64:
1554         tcg_out_brcond(s, ext, a2, a0, a1, const_args[1], arg_label(args[3]));
1555         break;
1556
1557     case INDEX_op_setcond_i32:
1558         a2 = (int32_t)a2;
1559         /* FALLTHRU */
1560     case INDEX_op_setcond_i64:
1561         tcg_out_cmp(s, ext, a1, a2, c2);
1562         /* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond).  */
1563         tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, a0, TCG_REG_XZR,
1564                      TCG_REG_XZR, tcg_invert_cond(args[3]));
1565         break;
1566
1567     case INDEX_op_movcond_i32:
1568         a2 = (int32_t)a2;
1569         /* FALLTHRU */
1570     case INDEX_op_movcond_i64:
1571         tcg_out_cmp(s, ext, a1, a2, c2);
1572         tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
1573         break;
1574
1575     case INDEX_op_qemu_ld_i32:
1576     case INDEX_op_qemu_ld_i64:
1577         tcg_out_qemu_ld(s, a0, a1, a2, ext);
1578         break;
1579     case INDEX_op_qemu_st_i32:
1580     case INDEX_op_qemu_st_i64:
1581         tcg_out_qemu_st(s, REG0(0), a1, a2);
1582         break;
1583
1584     case INDEX_op_bswap64_i64:
1585         tcg_out_rev64(s, a0, a1);
1586         break;
1587     case INDEX_op_bswap32_i64:
1588     case INDEX_op_bswap32_i32:
1589         tcg_out_rev32(s, a0, a1);
1590         break;
1591     case INDEX_op_bswap16_i64:
1592     case INDEX_op_bswap16_i32:
1593         tcg_out_rev16(s, a0, a1);
1594         break;
1595
1596     case INDEX_op_ext8s_i64:
1597     case INDEX_op_ext8s_i32:
1598         tcg_out_sxt(s, ext, MO_8, a0, a1);
1599         break;
1600     case INDEX_op_ext16s_i64:
1601     case INDEX_op_ext16s_i32:
1602         tcg_out_sxt(s, ext, MO_16, a0, a1);
1603         break;
1604     case INDEX_op_ext_i32_i64:
1605     case INDEX_op_ext32s_i64:
1606         tcg_out_sxt(s, TCG_TYPE_I64, MO_32, a0, a1);
1607         break;
1608     case INDEX_op_ext8u_i64:
1609     case INDEX_op_ext8u_i32:
1610         tcg_out_uxt(s, MO_8, a0, a1);
1611         break;
1612     case INDEX_op_ext16u_i64:
1613     case INDEX_op_ext16u_i32:
1614         tcg_out_uxt(s, MO_16, a0, a1);
1615         break;
1616     case INDEX_op_extu_i32_i64:
1617     case INDEX_op_ext32u_i64:
1618         tcg_out_movr(s, TCG_TYPE_I32, a0, a1);
1619         break;
1620
1621     case INDEX_op_deposit_i64:
1622     case INDEX_op_deposit_i32:
1623         tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
1624         break;
1625
1626     case INDEX_op_add2_i32:
1627         tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
1628                         (int32_t)args[4], args[5], const_args[4],
1629                         const_args[5], false);
1630         break;
1631     case INDEX_op_add2_i64:
1632         tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
1633                         args[5], const_args[4], const_args[5], false);
1634         break;
1635     case INDEX_op_sub2_i32:
1636         tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
1637                         (int32_t)args[4], args[5], const_args[4],
1638                         const_args[5], true);
1639         break;
1640     case INDEX_op_sub2_i64:
1641         tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
1642                         args[5], const_args[4], const_args[5], true);
1643         break;
1644
1645     case INDEX_op_muluh_i64:
1646         tcg_out_insn(s, 3508, UMULH, TCG_TYPE_I64, a0, a1, a2);
1647         break;
1648     case INDEX_op_mulsh_i64:
1649         tcg_out_insn(s, 3508, SMULH, TCG_TYPE_I64, a0, a1, a2);
1650         break;
1651
1652     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1653     case INDEX_op_mov_i64:
1654     case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
1655     case INDEX_op_movi_i64:
1656     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1657     default:
1658         tcg_abort();
1659     }
1660
1661 #undef REG0
1662 }
1663
1664 static const TCGTargetOpDef aarch64_op_defs[] = {
1665     { INDEX_op_exit_tb, { } },
1666     { INDEX_op_goto_tb, { } },
1667     { INDEX_op_br, { } },
1668
1669     { INDEX_op_ld8u_i32, { "r", "r" } },
1670     { INDEX_op_ld8s_i32, { "r", "r" } },
1671     { INDEX_op_ld16u_i32, { "r", "r" } },
1672     { INDEX_op_ld16s_i32, { "r", "r" } },
1673     { INDEX_op_ld_i32, { "r", "r" } },
1674     { INDEX_op_ld8u_i64, { "r", "r" } },
1675     { INDEX_op_ld8s_i64, { "r", "r" } },
1676     { INDEX_op_ld16u_i64, { "r", "r" } },
1677     { INDEX_op_ld16s_i64, { "r", "r" } },
1678     { INDEX_op_ld32u_i64, { "r", "r" } },
1679     { INDEX_op_ld32s_i64, { "r", "r" } },
1680     { INDEX_op_ld_i64, { "r", "r" } },
1681
1682     { INDEX_op_st8_i32, { "rZ", "r" } },
1683     { INDEX_op_st16_i32, { "rZ", "r" } },
1684     { INDEX_op_st_i32, { "rZ", "r" } },
1685     { INDEX_op_st8_i64, { "rZ", "r" } },
1686     { INDEX_op_st16_i64, { "rZ", "r" } },
1687     { INDEX_op_st32_i64, { "rZ", "r" } },
1688     { INDEX_op_st_i64, { "rZ", "r" } },
1689
1690     { INDEX_op_add_i32, { "r", "r", "rA" } },
1691     { INDEX_op_add_i64, { "r", "r", "rA" } },
1692     { INDEX_op_sub_i32, { "r", "r", "rA" } },
1693     { INDEX_op_sub_i64, { "r", "r", "rA" } },
1694     { INDEX_op_mul_i32, { "r", "r", "r" } },
1695     { INDEX_op_mul_i64, { "r", "r", "r" } },
1696     { INDEX_op_div_i32, { "r", "r", "r" } },
1697     { INDEX_op_div_i64, { "r", "r", "r" } },
1698     { INDEX_op_divu_i32, { "r", "r", "r" } },
1699     { INDEX_op_divu_i64, { "r", "r", "r" } },
1700     { INDEX_op_rem_i32, { "r", "r", "r" } },
1701     { INDEX_op_rem_i64, { "r", "r", "r" } },
1702     { INDEX_op_remu_i32, { "r", "r", "r" } },
1703     { INDEX_op_remu_i64, { "r", "r", "r" } },
1704     { INDEX_op_and_i32, { "r", "r", "rL" } },
1705     { INDEX_op_and_i64, { "r", "r", "rL" } },
1706     { INDEX_op_or_i32, { "r", "r", "rL" } },
1707     { INDEX_op_or_i64, { "r", "r", "rL" } },
1708     { INDEX_op_xor_i32, { "r", "r", "rL" } },
1709     { INDEX_op_xor_i64, { "r", "r", "rL" } },
1710     { INDEX_op_andc_i32, { "r", "r", "rL" } },
1711     { INDEX_op_andc_i64, { "r", "r", "rL" } },
1712     { INDEX_op_orc_i32, { "r", "r", "rL" } },
1713     { INDEX_op_orc_i64, { "r", "r", "rL" } },
1714     { INDEX_op_eqv_i32, { "r", "r", "rL" } },
1715     { INDEX_op_eqv_i64, { "r", "r", "rL" } },
1716
1717     { INDEX_op_neg_i32, { "r", "r" } },
1718     { INDEX_op_neg_i64, { "r", "r" } },
1719     { INDEX_op_not_i32, { "r", "r" } },
1720     { INDEX_op_not_i64, { "r", "r" } },
1721
1722     { INDEX_op_shl_i32, { "r", "r", "ri" } },
1723     { INDEX_op_shr_i32, { "r", "r", "ri" } },
1724     { INDEX_op_sar_i32, { "r", "r", "ri" } },
1725     { INDEX_op_rotl_i32, { "r", "r", "ri" } },
1726     { INDEX_op_rotr_i32, { "r", "r", "ri" } },
1727     { INDEX_op_shl_i64, { "r", "r", "ri" } },
1728     { INDEX_op_shr_i64, { "r", "r", "ri" } },
1729     { INDEX_op_sar_i64, { "r", "r", "ri" } },
1730     { INDEX_op_rotl_i64, { "r", "r", "ri" } },
1731     { INDEX_op_rotr_i64, { "r", "r", "ri" } },
1732
1733     { INDEX_op_brcond_i32, { "r", "rA" } },
1734     { INDEX_op_brcond_i64, { "r", "rA" } },
1735     { INDEX_op_setcond_i32, { "r", "r", "rA" } },
1736     { INDEX_op_setcond_i64, { "r", "r", "rA" } },
1737     { INDEX_op_movcond_i32, { "r", "r", "rA", "rZ", "rZ" } },
1738     { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } },
1739
1740     { INDEX_op_qemu_ld_i32, { "r", "l" } },
1741     { INDEX_op_qemu_ld_i64, { "r", "l" } },
1742     { INDEX_op_qemu_st_i32, { "lZ", "l" } },
1743     { INDEX_op_qemu_st_i64, { "lZ", "l" } },
1744
1745     { INDEX_op_bswap16_i32, { "r", "r" } },
1746     { INDEX_op_bswap32_i32, { "r", "r" } },
1747     { INDEX_op_bswap16_i64, { "r", "r" } },
1748     { INDEX_op_bswap32_i64, { "r", "r" } },
1749     { INDEX_op_bswap64_i64, { "r", "r" } },
1750
1751     { INDEX_op_ext8s_i32, { "r", "r" } },
1752     { INDEX_op_ext16s_i32, { "r", "r" } },
1753     { INDEX_op_ext8u_i32, { "r", "r" } },
1754     { INDEX_op_ext16u_i32, { "r", "r" } },
1755
1756     { INDEX_op_ext8s_i64, { "r", "r" } },
1757     { INDEX_op_ext16s_i64, { "r", "r" } },
1758     { INDEX_op_ext32s_i64, { "r", "r" } },
1759     { INDEX_op_ext8u_i64, { "r", "r" } },
1760     { INDEX_op_ext16u_i64, { "r", "r" } },
1761     { INDEX_op_ext32u_i64, { "r", "r" } },
1762     { INDEX_op_ext_i32_i64, { "r", "r" } },
1763     { INDEX_op_extu_i32_i64, { "r", "r" } },
1764
1765     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1766     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
1767
1768     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
1769     { INDEX_op_add2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
1770     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
1771     { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
1772
1773     { INDEX_op_muluh_i64, { "r", "r", "r" } },
1774     { INDEX_op_mulsh_i64, { "r", "r", "r" } },
1775
1776     { -1 },
1777 };
1778
1779 static void tcg_target_init(TCGContext *s)
1780 {
1781     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1782     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1783
1784     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1785                      (1 << TCG_REG_X0) | (1 << TCG_REG_X1) |
1786                      (1 << TCG_REG_X2) | (1 << TCG_REG_X3) |
1787                      (1 << TCG_REG_X4) | (1 << TCG_REG_X5) |
1788                      (1 << TCG_REG_X6) | (1 << TCG_REG_X7) |
1789                      (1 << TCG_REG_X8) | (1 << TCG_REG_X9) |
1790                      (1 << TCG_REG_X10) | (1 << TCG_REG_X11) |
1791                      (1 << TCG_REG_X12) | (1 << TCG_REG_X13) |
1792                      (1 << TCG_REG_X14) | (1 << TCG_REG_X15) |
1793                      (1 << TCG_REG_X16) | (1 << TCG_REG_X17) |
1794                      (1 << TCG_REG_X18) | (1 << TCG_REG_X30));
1795
1796     tcg_regset_clear(s->reserved_regs);
1797     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
1798     tcg_regset_set_reg(s->reserved_regs, TCG_REG_FP);
1799     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
1800     tcg_regset_set_reg(s->reserved_regs, TCG_REG_X18); /* platform register */
1801
1802     tcg_add_target_add_op_defs(aarch64_op_defs);
1803 }
1804
1805 /* Saving pairs: (X19, X20) .. (X27, X28), (X29(fp), X30(lr)).  */
1806 #define PUSH_SIZE  ((30 - 19 + 1) * 8)
1807
1808 #define FRAME_SIZE \
1809     ((PUSH_SIZE \
1810       + TCG_STATIC_CALL_ARGS_SIZE \
1811       + CPU_TEMP_BUF_NLONGS * sizeof(long) \
1812       + TCG_TARGET_STACK_ALIGN - 1) \
1813      & ~(TCG_TARGET_STACK_ALIGN - 1))
1814
1815 /* We're expecting a 2 byte uleb128 encoded value.  */
1816 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
1817
1818 /* We're expecting to use a single ADDI insn.  */
1819 QEMU_BUILD_BUG_ON(FRAME_SIZE - PUSH_SIZE > 0xfff);
1820
1821 static void tcg_target_qemu_prologue(TCGContext *s)
1822 {
1823     TCGReg r;
1824
1825     /* Push (FP, LR) and allocate space for all saved registers.  */
1826     tcg_out_insn(s, 3314, STP, TCG_REG_FP, TCG_REG_LR,
1827                  TCG_REG_SP, -PUSH_SIZE, 1, 1);
1828
1829     /* Set up frame pointer for canonical unwinding.  */
1830     tcg_out_movr_sp(s, TCG_TYPE_I64, TCG_REG_FP, TCG_REG_SP);
1831
1832     /* Store callee-preserved regs x19..x28.  */
1833     for (r = TCG_REG_X19; r <= TCG_REG_X27; r += 2) {
1834         int ofs = (r - TCG_REG_X19 + 2) * 8;
1835         tcg_out_insn(s, 3314, STP, r, r + 1, TCG_REG_SP, ofs, 1, 0);
1836     }
1837
1838     /* Make stack space for TCG locals.  */
1839     tcg_out_insn(s, 3401, SUBI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
1840                  FRAME_SIZE - PUSH_SIZE);
1841
1842     /* Inform TCG about how to find TCG locals with register, offset, size.  */
1843     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE,
1844                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1845
1846 #if !defined(CONFIG_SOFTMMU)
1847     if (USE_GUEST_BASE) {
1848         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_GUEST_BASE, guest_base);
1849         tcg_regset_set_reg(s->reserved_regs, TCG_REG_GUEST_BASE);
1850     }
1851 #endif
1852
1853     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1854     tcg_out_insn(s, 3207, BR, tcg_target_call_iarg_regs[1]);
1855
1856     tb_ret_addr = s->code_ptr;
1857
1858     /* Remove TCG locals stack space.  */
1859     tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
1860                  FRAME_SIZE - PUSH_SIZE);
1861
1862     /* Restore registers x19..x28.  */
1863     for (r = TCG_REG_X19; r <= TCG_REG_X27; r += 2) {
1864         int ofs = (r - TCG_REG_X19 + 2) * 8;
1865         tcg_out_insn(s, 3314, LDP, r, r + 1, TCG_REG_SP, ofs, 1, 0);
1866     }
1867
1868     /* Pop (FP, LR), restore SP to previous frame.  */
1869     tcg_out_insn(s, 3314, LDP, TCG_REG_FP, TCG_REG_LR,
1870                  TCG_REG_SP, PUSH_SIZE, 0, 1);
1871     tcg_out_insn(s, 3207, RET, TCG_REG_LR);
1872 }
1873
1874 typedef struct {
1875     DebugFrameHeader h;
1876     uint8_t fde_def_cfa[4];
1877     uint8_t fde_reg_ofs[24];
1878 } DebugFrame;
1879
1880 #define ELF_HOST_MACHINE EM_AARCH64
1881
1882 static const DebugFrame debug_frame = {
1883     .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1884     .h.cie.id = -1,
1885     .h.cie.version = 1,
1886     .h.cie.code_align = 1,
1887     .h.cie.data_align = 0x78,             /* sleb128 -8 */
1888     .h.cie.return_column = TCG_REG_LR,
1889
1890     /* Total FDE size does not include the "len" member.  */
1891     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
1892
1893     .fde_def_cfa = {
1894         12, TCG_REG_SP,                 /* DW_CFA_def_cfa sp, ... */
1895         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
1896         (FRAME_SIZE >> 7)
1897     },
1898     .fde_reg_ofs = {
1899         0x80 + 28, 1,                   /* DW_CFA_offset, x28,  -8 */
1900         0x80 + 27, 2,                   /* DW_CFA_offset, x27, -16 */
1901         0x80 + 26, 3,                   /* DW_CFA_offset, x26, -24 */
1902         0x80 + 25, 4,                   /* DW_CFA_offset, x25, -32 */
1903         0x80 + 24, 5,                   /* DW_CFA_offset, x24, -40 */
1904         0x80 + 23, 6,                   /* DW_CFA_offset, x23, -48 */
1905         0x80 + 22, 7,                   /* DW_CFA_offset, x22, -56 */
1906         0x80 + 21, 8,                   /* DW_CFA_offset, x21, -64 */
1907         0x80 + 20, 9,                   /* DW_CFA_offset, x20, -72 */
1908         0x80 + 19, 10,                  /* DW_CFA_offset, x1p, -80 */
1909         0x80 + 30, 11,                  /* DW_CFA_offset,  lr, -88 */
1910         0x80 + 29, 12,                  /* DW_CFA_offset,  fp, -96 */
1911     }
1912 };
1913
1914 void tcg_register_jit(void *buf, size_t buf_size)
1915 {
1916     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1917 }
This page took 0.133528 seconds and 4 git commands to generate.