net: Use id_generate() in the network subsystem, too
[qemu/ar7.git] / tcg / arm / tcg-target.c.inc
blob8457108a87a17c2628f5a5c8311591be6a6c6172
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008 Andrzej Zaborowski
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
25 #include "elf.h"
26 #include "../tcg-pool.c.inc"
28 int arm_arch = __ARM_ARCH;
30 #ifndef use_idiv_instructions
31 bool use_idiv_instructions;
32 #endif
34 /* ??? Ought to think about changing CONFIG_SOFTMMU to always defined.  */
35 #ifdef CONFIG_SOFTMMU
36 # define USING_SOFTMMU 1
37 #else
38 # define USING_SOFTMMU 0
39 #endif
41 #ifdef CONFIG_DEBUG_TCG
42 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
43     "%r0",
44     "%r1",
45     "%r2",
46     "%r3",
47     "%r4",
48     "%r5",
49     "%r6",
50     "%r7",
51     "%r8",
52     "%r9",
53     "%r10",
54     "%r11",
55     "%r12",
56     "%r13",
57     "%r14",
58     "%pc",
60 #endif
62 static const int tcg_target_reg_alloc_order[] = {
63     TCG_REG_R4,
64     TCG_REG_R5,
65     TCG_REG_R6,
66     TCG_REG_R7,
67     TCG_REG_R8,
68     TCG_REG_R9,
69     TCG_REG_R10,
70     TCG_REG_R11,
71     TCG_REG_R13,
72     TCG_REG_R0,
73     TCG_REG_R1,
74     TCG_REG_R2,
75     TCG_REG_R3,
76     TCG_REG_R12,
77     TCG_REG_R14,
80 static const int tcg_target_call_iarg_regs[4] = {
81     TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
83 static const int tcg_target_call_oarg_regs[2] = {
84     TCG_REG_R0, TCG_REG_R1
87 #define TCG_REG_TMP  TCG_REG_R12
89 enum arm_cond_code_e {
90     COND_EQ = 0x0,
91     COND_NE = 0x1,
92     COND_CS = 0x2,      /* Unsigned greater or equal */
93     COND_CC = 0x3,      /* Unsigned less than */
94     COND_MI = 0x4,      /* Negative */
95     COND_PL = 0x5,      /* Zero or greater */
96     COND_VS = 0x6,      /* Overflow */
97     COND_VC = 0x7,      /* No overflow */
98     COND_HI = 0x8,      /* Unsigned greater than */
99     COND_LS = 0x9,      /* Unsigned less or equal */
100     COND_GE = 0xa,
101     COND_LT = 0xb,
102     COND_GT = 0xc,
103     COND_LE = 0xd,
104     COND_AL = 0xe,
107 #define TO_CPSR (1 << 20)
109 #define SHIFT_IMM_LSL(im)       (((im) << 7) | 0x00)
110 #define SHIFT_IMM_LSR(im)       (((im) << 7) | 0x20)
111 #define SHIFT_IMM_ASR(im)       (((im) << 7) | 0x40)
112 #define SHIFT_IMM_ROR(im)       (((im) << 7) | 0x60)
113 #define SHIFT_REG_LSL(rs)       (((rs) << 8) | 0x10)
114 #define SHIFT_REG_LSR(rs)       (((rs) << 8) | 0x30)
115 #define SHIFT_REG_ASR(rs)       (((rs) << 8) | 0x50)
116 #define SHIFT_REG_ROR(rs)       (((rs) << 8) | 0x70)
118 typedef enum {
119     ARITH_AND = 0x0 << 21,
120     ARITH_EOR = 0x1 << 21,
121     ARITH_SUB = 0x2 << 21,
122     ARITH_RSB = 0x3 << 21,
123     ARITH_ADD = 0x4 << 21,
124     ARITH_ADC = 0x5 << 21,
125     ARITH_SBC = 0x6 << 21,
126     ARITH_RSC = 0x7 << 21,
127     ARITH_TST = 0x8 << 21 | TO_CPSR,
128     ARITH_CMP = 0xa << 21 | TO_CPSR,
129     ARITH_CMN = 0xb << 21 | TO_CPSR,
130     ARITH_ORR = 0xc << 21,
131     ARITH_MOV = 0xd << 21,
132     ARITH_BIC = 0xe << 21,
133     ARITH_MVN = 0xf << 21,
135     INSN_CLZ       = 0x016f0f10,
136     INSN_RBIT      = 0x06ff0f30,
138     INSN_LDR_IMM   = 0x04100000,
139     INSN_LDR_REG   = 0x06100000,
140     INSN_STR_IMM   = 0x04000000,
141     INSN_STR_REG   = 0x06000000,
143     INSN_LDRH_IMM  = 0x005000b0,
144     INSN_LDRH_REG  = 0x001000b0,
145     INSN_LDRSH_IMM = 0x005000f0,
146     INSN_LDRSH_REG = 0x001000f0,
147     INSN_STRH_IMM  = 0x004000b0,
148     INSN_STRH_REG  = 0x000000b0,
150     INSN_LDRB_IMM  = 0x04500000,
151     INSN_LDRB_REG  = 0x06500000,
152     INSN_LDRSB_IMM = 0x005000d0,
153     INSN_LDRSB_REG = 0x001000d0,
154     INSN_STRB_IMM  = 0x04400000,
155     INSN_STRB_REG  = 0x06400000,
157     INSN_LDRD_IMM  = 0x004000d0,
158     INSN_LDRD_REG  = 0x000000d0,
159     INSN_STRD_IMM  = 0x004000f0,
160     INSN_STRD_REG  = 0x000000f0,
162     INSN_DMB_ISH   = 0xf57ff05b,
163     INSN_DMB_MCR   = 0xee070fba,
165     /* Architected nop introduced in v6k.  */
166     /* ??? This is an MSR (imm) 0,0,0 insn.  Anyone know if this
167        also Just So Happened to do nothing on pre-v6k so that we
168        don't need to conditionalize it?  */
169     INSN_NOP_v6k   = 0xe320f000,
170     /* Otherwise the assembler uses mov r0,r0 */
171     INSN_NOP_v4    = (COND_AL << 28) | ARITH_MOV,
172 } ARMInsn;
174 #define INSN_NOP   (use_armv7_instructions ? INSN_NOP_v6k : INSN_NOP_v4)
176 static const uint8_t tcg_cond_to_arm_cond[] = {
177     [TCG_COND_EQ] = COND_EQ,
178     [TCG_COND_NE] = COND_NE,
179     [TCG_COND_LT] = COND_LT,
180     [TCG_COND_GE] = COND_GE,
181     [TCG_COND_LE] = COND_LE,
182     [TCG_COND_GT] = COND_GT,
183     /* unsigned */
184     [TCG_COND_LTU] = COND_CC,
185     [TCG_COND_GEU] = COND_CS,
186     [TCG_COND_LEU] = COND_LS,
187     [TCG_COND_GTU] = COND_HI,
190 static bool reloc_pc24(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
192     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
193     ptrdiff_t offset = (tcg_ptr_byte_diff(target, src_rx) - 8) >> 2;
195     if (offset == sextract32(offset, 0, 24)) {
196         *src_rw = deposit32(*src_rw, 0, 24, offset);
197         return true;
198     }
199     return false;
202 static bool reloc_pc13(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
204     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
205     ptrdiff_t offset = tcg_ptr_byte_diff(target, src_rx) - 8;
207     if (offset >= -0xfff && offset <= 0xfff) {
208         tcg_insn_unit insn = *src_rw;
209         bool u = (offset >= 0);
210         if (!u) {
211             offset = -offset;
212         }
213         insn = deposit32(insn, 23, 1, u);
214         insn = deposit32(insn, 0, 12, offset);
215         *src_rw = insn;
216         return true;
217     }
218     return false;
221 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
222                         intptr_t value, intptr_t addend)
224     tcg_debug_assert(addend == 0);
226     if (type == R_ARM_PC24) {
227         return reloc_pc24(code_ptr, (const tcg_insn_unit *)value);
228     } else if (type == R_ARM_PC13) {
229         return reloc_pc13(code_ptr, (const tcg_insn_unit *)value);
230     } else {
231         g_assert_not_reached();
232     }
235 #define TCG_CT_CONST_ARM  0x100
236 #define TCG_CT_CONST_INV  0x200
237 #define TCG_CT_CONST_NEG  0x400
238 #define TCG_CT_CONST_ZERO 0x800
240 #define ALL_GENERAL_REGS  0xffffu
243  * r0-r2 will be overwritten when reading the tlb entry (softmmu only)
244  * and r0-r1 doing the byte swapping, so don't use these.
245  * r3 is removed for softmmu to avoid clashes with helper arguments.
246  */
247 #ifdef CONFIG_SOFTMMU
248 #define ALL_QLOAD_REGS \
249     (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
250                           (1 << TCG_REG_R2) | (1 << TCG_REG_R3) | \
251                           (1 << TCG_REG_R14)))
252 #define ALL_QSTORE_REGS \
253     (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1) | \
254                           (1 << TCG_REG_R2) | (1 << TCG_REG_R14) | \
255                           ((TARGET_LONG_BITS == 64) << TCG_REG_R3)))
256 #else
257 #define ALL_QLOAD_REGS   ALL_GENERAL_REGS
258 #define ALL_QSTORE_REGS \
259     (ALL_GENERAL_REGS & ~((1 << TCG_REG_R0) | (1 << TCG_REG_R1)))
260 #endif
262 static inline uint32_t rotl(uint32_t val, int n)
264   return (val << n) | (val >> (32 - n));
267 /* ARM immediates for ALU instructions are made of an unsigned 8-bit
268    right-rotated by an even amount between 0 and 30. */
269 static inline int encode_imm(uint32_t imm)
271     int shift;
273     /* simple case, only lower bits */
274     if ((imm & ~0xff) == 0)
275         return 0;
276     /* then try a simple even shift */
277     shift = ctz32(imm) & ~1;
278     if (((imm >> shift) & ~0xff) == 0)
279         return 32 - shift;
280     /* now try harder with rotations */
281     if ((rotl(imm, 2) & ~0xff) == 0)
282         return 2;
283     if ((rotl(imm, 4) & ~0xff) == 0)
284         return 4;
285     if ((rotl(imm, 6) & ~0xff) == 0)
286         return 6;
287     /* imm can't be encoded */
288     return -1;
291 static inline int check_fit_imm(uint32_t imm)
293     return encode_imm(imm) >= 0;
296 /* Test if a constant matches the constraint.
297  * TODO: define constraints for:
299  * ldr/str offset:   between -0xfff and 0xfff
300  * ldrh/strh offset: between -0xff and 0xff
301  * mov operand2:     values represented with x << (2 * y), x < 0x100
302  * add, sub, eor...: ditto
303  */
304 static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
305                                          const TCGArgConstraint *arg_ct)
307     int ct;
308     ct = arg_ct->ct;
309     if (ct & TCG_CT_CONST) {
310         return 1;
311     } else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) {
312         return 1;
313     } else if ((ct & TCG_CT_CONST_INV) && check_fit_imm(~val)) {
314         return 1;
315     } else if ((ct & TCG_CT_CONST_NEG) && check_fit_imm(-val)) {
316         return 1;
317     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
318         return 1;
319     } else {
320         return 0;
321     }
324 static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
326     tcg_out32(s, (cond << 28) | 0x0a000000 |
327                     (((offset - 8) >> 2) & 0x00ffffff));
330 static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
332     tcg_out32(s, (cond << 28) | 0x0b000000 |
333                     (((offset - 8) >> 2) & 0x00ffffff));
336 static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
338     tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
341 static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
343     tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
344                 (((offset - 8) >> 2) & 0x00ffffff));
347 static inline void tcg_out_dat_reg(TCGContext *s,
348                 int cond, int opc, int rd, int rn, int rm, int shift)
350     tcg_out32(s, (cond << 28) | (0 << 25) | opc |
351                     (rn << 16) | (rd << 12) | shift | rm);
354 static inline void tcg_out_nop(TCGContext *s)
356     tcg_out32(s, INSN_NOP);
359 static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
361     /* Simple reg-reg move, optimising out the 'do nothing' case */
362     if (rd != rm) {
363         tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
364     }
367 static inline void tcg_out_bx(TCGContext *s, int cond, TCGReg rn)
369     /* Unless the C portion of QEMU is compiled as thumb, we don't
370        actually need true BX semantics; merely a branch to an address
371        held in a register.  */
372     if (use_armv5t_instructions) {
373         tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
374     } else {
375         tcg_out_mov_reg(s, cond, TCG_REG_PC, rn);
376     }
379 static inline void tcg_out_dat_imm(TCGContext *s,
380                 int cond, int opc, int rd, int rn, int im)
382     tcg_out32(s, (cond << 28) | (1 << 25) | opc |
383                     (rn << 16) | (rd << 12) | im);
386 /* Note that this routine is used for both LDR and LDRH formats, so we do
387    not wish to include an immediate shift at this point.  */
388 static void tcg_out_memop_r(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
389                             TCGReg rn, TCGReg rm, bool u, bool p, bool w)
391     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24)
392               | (w << 21) | (rn << 16) | (rt << 12) | rm);
395 static void tcg_out_memop_8(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
396                             TCGReg rn, int imm8, bool p, bool w)
398     bool u = 1;
399     if (imm8 < 0) {
400         imm8 = -imm8;
401         u = 0;
402     }
403     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
404               (rn << 16) | (rt << 12) | ((imm8 & 0xf0) << 4) | (imm8 & 0xf));
407 static void tcg_out_memop_12(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
408                              TCGReg rn, int imm12, bool p, bool w)
410     bool u = 1;
411     if (imm12 < 0) {
412         imm12 = -imm12;
413         u = 0;
414     }
415     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
416               (rn << 16) | (rt << 12) | imm12);
419 static inline void tcg_out_ld32_12(TCGContext *s, int cond, TCGReg rt,
420                                    TCGReg rn, int imm12)
422     tcg_out_memop_12(s, cond, INSN_LDR_IMM, rt, rn, imm12, 1, 0);
425 static inline void tcg_out_st32_12(TCGContext *s, int cond, TCGReg rt,
426                                    TCGReg rn, int imm12)
428     tcg_out_memop_12(s, cond, INSN_STR_IMM, rt, rn, imm12, 1, 0);
431 static inline void tcg_out_ld32_r(TCGContext *s, int cond, TCGReg rt,
432                                   TCGReg rn, TCGReg rm)
434     tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 0);
437 static inline void tcg_out_st32_r(TCGContext *s, int cond, TCGReg rt,
438                                   TCGReg rn, TCGReg rm)
440     tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 0);
443 static inline void tcg_out_ldrd_8(TCGContext *s, int cond, TCGReg rt,
444                                    TCGReg rn, int imm8)
446     tcg_out_memop_8(s, cond, INSN_LDRD_IMM, rt, rn, imm8, 1, 0);
449 static inline void tcg_out_ldrd_r(TCGContext *s, int cond, TCGReg rt,
450                                   TCGReg rn, TCGReg rm)
452     tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
455 static inline void tcg_out_ldrd_rwb(TCGContext *s, int cond, TCGReg rt,
456                                     TCGReg rn, TCGReg rm)
458     tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 1);
461 static inline void tcg_out_strd_8(TCGContext *s, int cond, TCGReg rt,
462                                    TCGReg rn, int imm8)
464     tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
467 static inline void tcg_out_strd_r(TCGContext *s, int cond, TCGReg rt,
468                                   TCGReg rn, TCGReg rm)
470     tcg_out_memop_r(s, cond, INSN_STRD_REG, rt, rn, rm, 1, 1, 0);
473 /* Register pre-increment with base writeback.  */
474 static inline void tcg_out_ld32_rwb(TCGContext *s, int cond, TCGReg rt,
475                                     TCGReg rn, TCGReg rm)
477     tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 1);
480 static inline void tcg_out_st32_rwb(TCGContext *s, int cond, TCGReg rt,
481                                     TCGReg rn, TCGReg rm)
483     tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 1);
486 static inline void tcg_out_ld16u_8(TCGContext *s, int cond, TCGReg rt,
487                                    TCGReg rn, int imm8)
489     tcg_out_memop_8(s, cond, INSN_LDRH_IMM, rt, rn, imm8, 1, 0);
492 static inline void tcg_out_st16_8(TCGContext *s, int cond, TCGReg rt,
493                                   TCGReg rn, int imm8)
495     tcg_out_memop_8(s, cond, INSN_STRH_IMM, rt, rn, imm8, 1, 0);
498 static inline void tcg_out_ld16u_r(TCGContext *s, int cond, TCGReg rt,
499                                    TCGReg rn, TCGReg rm)
501     tcg_out_memop_r(s, cond, INSN_LDRH_REG, rt, rn, rm, 1, 1, 0);
504 static inline void tcg_out_st16_r(TCGContext *s, int cond, TCGReg rt,
505                                   TCGReg rn, TCGReg rm)
507     tcg_out_memop_r(s, cond, INSN_STRH_REG, rt, rn, rm, 1, 1, 0);
510 static inline void tcg_out_ld16s_8(TCGContext *s, int cond, TCGReg rt,
511                                    TCGReg rn, int imm8)
513     tcg_out_memop_8(s, cond, INSN_LDRSH_IMM, rt, rn, imm8, 1, 0);
516 static inline void tcg_out_ld16s_r(TCGContext *s, int cond, TCGReg rt,
517                                    TCGReg rn, TCGReg rm)
519     tcg_out_memop_r(s, cond, INSN_LDRSH_REG, rt, rn, rm, 1, 1, 0);
522 static inline void tcg_out_ld8_12(TCGContext *s, int cond, TCGReg rt,
523                                   TCGReg rn, int imm12)
525     tcg_out_memop_12(s, cond, INSN_LDRB_IMM, rt, rn, imm12, 1, 0);
528 static inline void tcg_out_st8_12(TCGContext *s, int cond, TCGReg rt,
529                                   TCGReg rn, int imm12)
531     tcg_out_memop_12(s, cond, INSN_STRB_IMM, rt, rn, imm12, 1, 0);
534 static inline void tcg_out_ld8_r(TCGContext *s, int cond, TCGReg rt,
535                                  TCGReg rn, TCGReg rm)
537     tcg_out_memop_r(s, cond, INSN_LDRB_REG, rt, rn, rm, 1, 1, 0);
540 static inline void tcg_out_st8_r(TCGContext *s, int cond, TCGReg rt,
541                                  TCGReg rn, TCGReg rm)
543     tcg_out_memop_r(s, cond, INSN_STRB_REG, rt, rn, rm, 1, 1, 0);
546 static inline void tcg_out_ld8s_8(TCGContext *s, int cond, TCGReg rt,
547                                   TCGReg rn, int imm8)
549     tcg_out_memop_8(s, cond, INSN_LDRSB_IMM, rt, rn, imm8, 1, 0);
552 static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
553                                   TCGReg rn, TCGReg rm)
555     tcg_out_memop_r(s, cond, INSN_LDRSB_REG, rt, rn, rm, 1, 1, 0);
558 static void tcg_out_movi_pool(TCGContext *s, int cond, int rd, uint32_t arg)
560     new_pool_label(s, arg, R_ARM_PC13, s->code_ptr, 0);
561     tcg_out_ld32_12(s, cond, rd, TCG_REG_PC, 0);
564 static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
566     int rot, diff, opc, sh1, sh2;
567     uint32_t tt0, tt1, tt2;
569     /* Check a single MOV/MVN before anything else.  */
570     rot = encode_imm(arg);
571     if (rot >= 0) {
572         tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0,
573                         rotl(arg, rot) | (rot << 7));
574         return;
575     }
576     rot = encode_imm(~arg);
577     if (rot >= 0) {
578         tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0,
579                         rotl(~arg, rot) | (rot << 7));
580         return;
581     }
583     /* Check for a pc-relative address.  This will usually be the TB,
584        or within the TB, which is immediately before the code block.  */
585     diff = tcg_pcrel_diff(s, (void *)arg) - 8;
586     if (diff >= 0) {
587         rot = encode_imm(diff);
588         if (rot >= 0) {
589             tcg_out_dat_imm(s, cond, ARITH_ADD, rd, TCG_REG_PC,
590                             rotl(diff, rot) | (rot << 7));
591             return;
592         }
593     } else {
594         rot = encode_imm(-diff);
595         if (rot >= 0) {
596             tcg_out_dat_imm(s, cond, ARITH_SUB, rd, TCG_REG_PC,
597                             rotl(-diff, rot) | (rot << 7));
598             return;
599         }
600     }
602     /* Use movw + movt.  */
603     if (use_armv7_instructions) {
604         /* movw */
605         tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
606                   | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
607         if (arg & 0xffff0000) {
608             /* movt */
609             tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
610                       | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
611         }
612         return;
613     }
615     /* Look for sequences of two insns.  If we have lots of 1's, we can
616        shorten the sequence by beginning with mvn and then clearing
617        higher bits with eor.  */
618     tt0 = arg;
619     opc = ARITH_MOV;
620     if (ctpop32(arg) > 16) {
621         tt0 = ~arg;
622         opc = ARITH_MVN;
623     }
624     sh1 = ctz32(tt0) & ~1;
625     tt1 = tt0 & ~(0xff << sh1);
626     sh2 = ctz32(tt1) & ~1;
627     tt2 = tt1 & ~(0xff << sh2);
628     if (tt2 == 0) {
629         rot = ((32 - sh1) << 7) & 0xf00;
630         tcg_out_dat_imm(s, cond, opc, rd,  0, ((tt0 >> sh1) & 0xff) | rot);
631         rot = ((32 - sh2) << 7) & 0xf00;
632         tcg_out_dat_imm(s, cond, ARITH_EOR, rd, rd,
633                         ((tt0 >> sh2) & 0xff) | rot);
634         return;
635     }
637     /* Otherwise, drop it into the constant pool.  */
638     tcg_out_movi_pool(s, cond, rd, arg);
641 static inline void tcg_out_dat_rI(TCGContext *s, int cond, int opc, TCGArg dst,
642                                   TCGArg lhs, TCGArg rhs, int rhs_is_const)
644     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
645      * rhs must satisfy the "rI" constraint.
646      */
647     if (rhs_is_const) {
648         int rot = encode_imm(rhs);
649         tcg_debug_assert(rot >= 0);
650         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
651     } else {
652         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
653     }
656 static void tcg_out_dat_rIK(TCGContext *s, int cond, int opc, int opinv,
657                             TCGReg dst, TCGReg lhs, TCGArg rhs,
658                             bool rhs_is_const)
660     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
661      * rhs must satisfy the "rIK" constraint.
662      */
663     if (rhs_is_const) {
664         int rot = encode_imm(rhs);
665         if (rot < 0) {
666             rhs = ~rhs;
667             rot = encode_imm(rhs);
668             tcg_debug_assert(rot >= 0);
669             opc = opinv;
670         }
671         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
672     } else {
673         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
674     }
677 static void tcg_out_dat_rIN(TCGContext *s, int cond, int opc, int opneg,
678                             TCGArg dst, TCGArg lhs, TCGArg rhs,
679                             bool rhs_is_const)
681     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
682      * rhs must satisfy the "rIN" constraint.
683      */
684     if (rhs_is_const) {
685         int rot = encode_imm(rhs);
686         if (rot < 0) {
687             rhs = -rhs;
688             rot = encode_imm(rhs);
689             tcg_debug_assert(rot >= 0);
690             opc = opneg;
691         }
692         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
693     } else {
694         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
695     }
698 static inline void tcg_out_mul32(TCGContext *s, int cond, TCGReg rd,
699                                  TCGReg rn, TCGReg rm)
701     /* if ArchVersion() < 6 && d == n then UNPREDICTABLE;  */
702     if (!use_armv6_instructions && rd == rn) {
703         if (rd == rm) {
704             /* rd == rn == rm; copy an input to tmp first.  */
705             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
706             rm = rn = TCG_REG_TMP;
707         } else {
708             rn = rm;
709             rm = rd;
710         }
711     }
712     /* mul */
713     tcg_out32(s, (cond << 28) | 0x90 | (rd << 16) | (rm << 8) | rn);
716 static inline void tcg_out_umull32(TCGContext *s, int cond, TCGReg rd0,
717                                    TCGReg rd1, TCGReg rn, TCGReg rm)
719     /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
720     if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
721         if (rd0 == rm || rd1 == rm) {
722             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
723             rn = TCG_REG_TMP;
724         } else {
725             TCGReg t = rn;
726             rn = rm;
727             rm = t;
728         }
729     }
730     /* umull */
731     tcg_out32(s, (cond << 28) | 0x00800090 |
732               (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
735 static inline void tcg_out_smull32(TCGContext *s, int cond, TCGReg rd0,
736                                    TCGReg rd1, TCGReg rn, TCGReg rm)
738     /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
739     if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
740         if (rd0 == rm || rd1 == rm) {
741             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
742             rn = TCG_REG_TMP;
743         } else {
744             TCGReg t = rn;
745             rn = rm;
746             rm = t;
747         }
748     }
749     /* smull */
750     tcg_out32(s, (cond << 28) | 0x00c00090 |
751               (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
754 static inline void tcg_out_sdiv(TCGContext *s, int cond, int rd, int rn, int rm)
756     tcg_out32(s, 0x0710f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
759 static inline void tcg_out_udiv(TCGContext *s, int cond, int rd, int rn, int rm)
761     tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
764 static inline void tcg_out_ext8s(TCGContext *s, int cond,
765                                  int rd, int rn)
767     if (use_armv6_instructions) {
768         /* sxtb */
769         tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
770     } else {
771         tcg_out_dat_reg(s, cond, ARITH_MOV,
772                         rd, 0, rn, SHIFT_IMM_LSL(24));
773         tcg_out_dat_reg(s, cond, ARITH_MOV,
774                         rd, 0, rd, SHIFT_IMM_ASR(24));
775     }
778 static inline void tcg_out_ext8u(TCGContext *s, int cond,
779                                  int rd, int rn)
781     tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
784 static inline void tcg_out_ext16s(TCGContext *s, int cond,
785                                   int rd, int rn)
787     if (use_armv6_instructions) {
788         /* sxth */
789         tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
790     } else {
791         tcg_out_dat_reg(s, cond, ARITH_MOV,
792                         rd, 0, rn, SHIFT_IMM_LSL(16));
793         tcg_out_dat_reg(s, cond, ARITH_MOV,
794                         rd, 0, rd, SHIFT_IMM_ASR(16));
795     }
798 static inline void tcg_out_ext16u(TCGContext *s, int cond,
799                                   int rd, int rn)
801     if (use_armv6_instructions) {
802         /* uxth */
803         tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
804     } else {
805         tcg_out_dat_reg(s, cond, ARITH_MOV,
806                         rd, 0, rn, SHIFT_IMM_LSL(16));
807         tcg_out_dat_reg(s, cond, ARITH_MOV,
808                         rd, 0, rd, SHIFT_IMM_LSR(16));
809     }
812 static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
814     if (use_armv6_instructions) {
815         /* revsh */
816         tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
817     } else {
818         tcg_out_dat_reg(s, cond, ARITH_MOV,
819                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
820         tcg_out_dat_reg(s, cond, ARITH_MOV,
821                         TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_ASR(16));
822         tcg_out_dat_reg(s, cond, ARITH_ORR,
823                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
824     }
827 static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
829     if (use_armv6_instructions) {
830         /* rev16 */
831         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
832     } else {
833         tcg_out_dat_reg(s, cond, ARITH_MOV,
834                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
835         tcg_out_dat_reg(s, cond, ARITH_MOV,
836                         TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_LSR(16));
837         tcg_out_dat_reg(s, cond, ARITH_ORR,
838                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
839     }
842 /* swap the two low bytes assuming that the two high input bytes and the
843    two high output bit can hold any value. */
844 static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn)
846     if (use_armv6_instructions) {
847         /* rev16 */
848         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
849     } else {
850         tcg_out_dat_reg(s, cond, ARITH_MOV,
851                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSR(8));
852         tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_TMP, TCG_REG_TMP, 0xff);
853         tcg_out_dat_reg(s, cond, ARITH_ORR,
854                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSL(8));
855     }
858 static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
860     if (use_armv6_instructions) {
861         /* rev */
862         tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
863     } else {
864         tcg_out_dat_reg(s, cond, ARITH_EOR,
865                         TCG_REG_TMP, rn, rn, SHIFT_IMM_ROR(16));
866         tcg_out_dat_imm(s, cond, ARITH_BIC,
867                         TCG_REG_TMP, TCG_REG_TMP, 0xff | 0x800);
868         tcg_out_dat_reg(s, cond, ARITH_MOV,
869                         rd, 0, rn, SHIFT_IMM_ROR(8));
870         tcg_out_dat_reg(s, cond, ARITH_EOR,
871                         rd, rd, TCG_REG_TMP, SHIFT_IMM_LSR(8));
872     }
875 static inline void tcg_out_deposit(TCGContext *s, int cond, TCGReg rd,
876                                    TCGArg a1, int ofs, int len, bool const_a1)
878     if (const_a1) {
879         /* bfi becomes bfc with rn == 15.  */
880         a1 = 15;
881     }
882     /* bfi/bfc */
883     tcg_out32(s, 0x07c00010 | (cond << 28) | (rd << 12) | a1
884               | (ofs << 7) | ((ofs + len - 1) << 16));
887 static inline void tcg_out_extract(TCGContext *s, int cond, TCGReg rd,
888                                    TCGArg a1, int ofs, int len)
890     /* ubfx */
891     tcg_out32(s, 0x07e00050 | (cond << 28) | (rd << 12) | a1
892               | (ofs << 7) | ((len - 1) << 16));
895 static inline void tcg_out_sextract(TCGContext *s, int cond, TCGReg rd,
896                                     TCGArg a1, int ofs, int len)
898     /* sbfx */
899     tcg_out32(s, 0x07a00050 | (cond << 28) | (rd << 12) | a1
900               | (ofs << 7) | ((len - 1) << 16));
903 static inline void tcg_out_ld32u(TCGContext *s, int cond,
904                 int rd, int rn, int32_t offset)
906     if (offset > 0xfff || offset < -0xfff) {
907         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
908         tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_TMP);
909     } else
910         tcg_out_ld32_12(s, cond, rd, rn, offset);
913 static inline void tcg_out_st32(TCGContext *s, int cond,
914                 int rd, int rn, int32_t offset)
916     if (offset > 0xfff || offset < -0xfff) {
917         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
918         tcg_out_st32_r(s, cond, rd, rn, TCG_REG_TMP);
919     } else
920         tcg_out_st32_12(s, cond, rd, rn, offset);
923 static inline void tcg_out_ld16u(TCGContext *s, int cond,
924                 int rd, int rn, int32_t offset)
926     if (offset > 0xff || offset < -0xff) {
927         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
928         tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_TMP);
929     } else
930         tcg_out_ld16u_8(s, cond, rd, rn, offset);
933 static inline void tcg_out_ld16s(TCGContext *s, int cond,
934                 int rd, int rn, int32_t offset)
936     if (offset > 0xff || offset < -0xff) {
937         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
938         tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_TMP);
939     } else
940         tcg_out_ld16s_8(s, cond, rd, rn, offset);
943 static inline void tcg_out_st16(TCGContext *s, int cond,
944                 int rd, int rn, int32_t offset)
946     if (offset > 0xff || offset < -0xff) {
947         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
948         tcg_out_st16_r(s, cond, rd, rn, TCG_REG_TMP);
949     } else
950         tcg_out_st16_8(s, cond, rd, rn, offset);
953 static inline void tcg_out_ld8u(TCGContext *s, int cond,
954                 int rd, int rn, int32_t offset)
956     if (offset > 0xfff || offset < -0xfff) {
957         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
958         tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_TMP);
959     } else
960         tcg_out_ld8_12(s, cond, rd, rn, offset);
963 static inline void tcg_out_ld8s(TCGContext *s, int cond,
964                 int rd, int rn, int32_t offset)
966     if (offset > 0xff || offset < -0xff) {
967         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
968         tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_TMP);
969     } else
970         tcg_out_ld8s_8(s, cond, rd, rn, offset);
973 static inline void tcg_out_st8(TCGContext *s, int cond,
974                 int rd, int rn, int32_t offset)
976     if (offset > 0xfff || offset < -0xfff) {
977         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
978         tcg_out_st8_r(s, cond, rd, rn, TCG_REG_TMP);
979     } else
980         tcg_out_st8_12(s, cond, rd, rn, offset);
983 /* The _goto case is normally between TBs within the same code buffer, and
984  * with the code buffer limited to 16MB we wouldn't need the long case.
985  * But we also use it for the tail-call to the qemu_ld/st helpers, which does.
986  */
987 static void tcg_out_goto(TCGContext *s, int cond, const tcg_insn_unit *addr)
989     intptr_t addri = (intptr_t)addr;
990     ptrdiff_t disp = tcg_pcrel_diff(s, addr);
992     if ((addri & 1) == 0 && disp - 8 < 0x01fffffd && disp - 8 > -0x01fffffd) {
993         tcg_out_b(s, cond, disp);
994         return;
995     }
996     tcg_out_movi_pool(s, cond, TCG_REG_PC, addri);
999 /* The call case is mostly used for helpers - so it's not unreasonable
1000  * for them to be beyond branch range */
1001 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *addr)
1003     intptr_t addri = (intptr_t)addr;
1004     ptrdiff_t disp = tcg_pcrel_diff(s, addr);
1006     if (disp - 8 < 0x02000000 && disp - 8 >= -0x02000000) {
1007         if (addri & 1) {
1008             /* Use BLX if the target is in Thumb mode */
1009             if (!use_armv5t_instructions) {
1010                 tcg_abort();
1011             }
1012             tcg_out_blx_imm(s, disp);
1013         } else {
1014             tcg_out_bl(s, COND_AL, disp);
1015         }
1016     } else if (use_armv7_instructions) {
1017         tcg_out_movi32(s, COND_AL, TCG_REG_TMP, addri);
1018         tcg_out_blx(s, COND_AL, TCG_REG_TMP);
1019     } else {
1020         /* ??? Know that movi_pool emits exactly 1 insn.  */
1021         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 0);
1022         tcg_out_movi_pool(s, COND_AL, TCG_REG_PC, addri);
1023     }
1026 static inline void tcg_out_goto_label(TCGContext *s, int cond, TCGLabel *l)
1028     if (l->has_value) {
1029         tcg_out_goto(s, cond, l->u.value_ptr);
1030     } else {
1031         tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, l, 0);
1032         tcg_out_b(s, cond, 0);
1033     }
1036 static inline void tcg_out_mb(TCGContext *s, TCGArg a0)
1038     if (use_armv7_instructions) {
1039         tcg_out32(s, INSN_DMB_ISH);
1040     } else if (use_armv6_instructions) {
1041         tcg_out32(s, INSN_DMB_MCR);
1042     }
1045 static TCGCond tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1046                             const int *const_args)
1048     TCGReg al = args[0];
1049     TCGReg ah = args[1];
1050     TCGArg bl = args[2];
1051     TCGArg bh = args[3];
1052     TCGCond cond = args[4];
1053     int const_bl = const_args[2];
1054     int const_bh = const_args[3];
1056     switch (cond) {
1057     case TCG_COND_EQ:
1058     case TCG_COND_NE:
1059     case TCG_COND_LTU:
1060     case TCG_COND_LEU:
1061     case TCG_COND_GTU:
1062     case TCG_COND_GEU:
1063         /* We perform a conditional comparision.  If the high half is
1064            equal, then overwrite the flags with the comparison of the
1065            low half.  The resulting flags cover the whole.  */
1066         tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0, ah, bh, const_bh);
1067         tcg_out_dat_rI(s, COND_EQ, ARITH_CMP, 0, al, bl, const_bl);
1068         return cond;
1070     case TCG_COND_LT:
1071     case TCG_COND_GE:
1072         /* We perform a double-word subtraction and examine the result.
1073            We do not actually need the result of the subtract, so the
1074            low part "subtract" is a compare.  For the high half we have
1075            no choice but to compute into a temporary.  */
1076         tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0, al, bl, const_bl);
1077         tcg_out_dat_rI(s, COND_AL, ARITH_SBC | TO_CPSR,
1078                        TCG_REG_TMP, ah, bh, const_bh);
1079         return cond;
1081     case TCG_COND_LE:
1082     case TCG_COND_GT:
1083         /* Similar, but with swapped arguments, via reversed subtract.  */
1084         tcg_out_dat_rI(s, COND_AL, ARITH_RSB | TO_CPSR,
1085                        TCG_REG_TMP, al, bl, const_bl);
1086         tcg_out_dat_rI(s, COND_AL, ARITH_RSC | TO_CPSR,
1087                        TCG_REG_TMP, ah, bh, const_bh);
1088         return tcg_swap_cond(cond);
1090     default:
1091         g_assert_not_reached();
1092     }
1095 #ifdef CONFIG_SOFTMMU
1096 #include "../tcg-ldst.c.inc"
1098 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
1099  *                                     int mmu_idx, uintptr_t ra)
1100  */
1101 static void * const qemu_ld_helpers[16] = {
1102     [MO_UB]   = helper_ret_ldub_mmu,
1103     [MO_SB]   = helper_ret_ldsb_mmu,
1105     [MO_LEUW] = helper_le_lduw_mmu,
1106     [MO_LEUL] = helper_le_ldul_mmu,
1107     [MO_LEQ]  = helper_le_ldq_mmu,
1108     [MO_LESW] = helper_le_ldsw_mmu,
1109     [MO_LESL] = helper_le_ldul_mmu,
1111     [MO_BEUW] = helper_be_lduw_mmu,
1112     [MO_BEUL] = helper_be_ldul_mmu,
1113     [MO_BEQ]  = helper_be_ldq_mmu,
1114     [MO_BESW] = helper_be_ldsw_mmu,
1115     [MO_BESL] = helper_be_ldul_mmu,
1118 /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
1119  *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
1120  */
1121 static void * const qemu_st_helpers[16] = {
1122     [MO_UB]   = helper_ret_stb_mmu,
1123     [MO_LEUW] = helper_le_stw_mmu,
1124     [MO_LEUL] = helper_le_stl_mmu,
1125     [MO_LEQ]  = helper_le_stq_mmu,
1126     [MO_BEUW] = helper_be_stw_mmu,
1127     [MO_BEUL] = helper_be_stl_mmu,
1128     [MO_BEQ]  = helper_be_stq_mmu,
1131 /* Helper routines for marshalling helper function arguments into
1132  * the correct registers and stack.
1133  * argreg is where we want to put this argument, arg is the argument itself.
1134  * Return value is the updated argreg ready for the next call.
1135  * Note that argreg 0..3 is real registers, 4+ on stack.
1137  * We provide routines for arguments which are: immediate, 32 bit
1138  * value in register, 16 and 8 bit values in register (which must be zero
1139  * extended before use) and 64 bit value in a lo:hi register pair.
1140  */
1141 #define DEFINE_TCG_OUT_ARG(NAME, ARGTYPE, MOV_ARG, EXT_ARG)                \
1142 static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg)              \
1143 {                                                                          \
1144     if (argreg < 4) {                                                      \
1145         MOV_ARG(s, COND_AL, argreg, arg);                                  \
1146     } else {                                                               \
1147         int ofs = (argreg - 4) * 4;                                        \
1148         EXT_ARG;                                                           \
1149         tcg_debug_assert(ofs + 4 <= TCG_STATIC_CALL_ARGS_SIZE);            \
1150         tcg_out_st32_12(s, COND_AL, arg, TCG_REG_CALL_STACK, ofs);         \
1151     }                                                                      \
1152     return argreg + 1;                                                     \
1155 DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
1156     (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1157 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u,
1158     (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1159 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
1160     (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1161 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
1163 static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
1164                                 TCGReg arglo, TCGReg arghi)
1166     /* 64 bit arguments must go in even/odd register pairs
1167      * and in 8-aligned stack slots.
1168      */
1169     if (argreg & 1) {
1170         argreg++;
1171     }
1172     if (use_armv6_instructions && argreg >= 4
1173         && (arglo & 1) == 0 && arghi == arglo + 1) {
1174         tcg_out_strd_8(s, COND_AL, arglo,
1175                        TCG_REG_CALL_STACK, (argreg - 4) * 4);
1176         return argreg + 2;
1177     } else {
1178         argreg = tcg_out_arg_reg32(s, argreg, arglo);
1179         argreg = tcg_out_arg_reg32(s, argreg, arghi);
1180         return argreg;
1181     }
1184 #define TLB_SHIFT       (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
1186 /* We expect to use an 9-bit sign-magnitude negative offset from ENV.  */
1187 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1188 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -256);
1190 /* These offsets are built into the LDRD below.  */
1191 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, mask) != 0);
1192 QEMU_BUILD_BUG_ON(offsetof(CPUTLBDescFast, table) != 4);
1194 /* Load and compare a TLB entry, leaving the flags set.  Returns the register
1195    containing the addend of the tlb entry.  Clobbers R0, R1, R2, TMP.  */
1197 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
1198                                MemOp opc, int mem_index, bool is_load)
1200     int cmp_off = (is_load ? offsetof(CPUTLBEntry, addr_read)
1201                    : offsetof(CPUTLBEntry, addr_write));
1202     int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1203     int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1204     int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1205     unsigned s_bits = opc & MO_SIZE;
1206     unsigned a_bits = get_alignment_bits(opc);
1208     /*
1209      * We don't support inline unaligned acceses, but we can easily
1210      * support overalignment checks.
1211      */
1212     if (a_bits < s_bits) {
1213         a_bits = s_bits;
1214     }
1216     /* Load env_tlb(env)->f[mmu_idx].{mask,table} into {r0,r1}.  */
1217     if (use_armv6_instructions) {
1218         tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_AREG0, fast_off);
1219     } else {
1220         tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R0, TCG_AREG0, mask_off);
1221         tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R1, TCG_AREG0, table_off);
1222     }
1224     /* Extract the tlb index from the address into R0.  */
1225     tcg_out_dat_reg(s, COND_AL, ARITH_AND, TCG_REG_R0, TCG_REG_R0, addrlo,
1226                     SHIFT_IMM_LSR(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
1228     /*
1229      * Add the tlb_table pointer, creating the CPUTLBEntry address in R1.
1230      * Load the tlb comparator into R2/R3 and the fast path addend into R1.
1231      */
1232     if (cmp_off == 0) {
1233         if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
1234             tcg_out_ldrd_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
1235         } else {
1236             tcg_out_ld32_rwb(s, COND_AL, TCG_REG_R2, TCG_REG_R1, TCG_REG_R0);
1237         }
1238     } else {
1239         tcg_out_dat_reg(s, COND_AL, ARITH_ADD,
1240                         TCG_REG_R1, TCG_REG_R1, TCG_REG_R0, 0);
1241         if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
1242             tcg_out_ldrd_8(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
1243         } else {
1244             tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R1, cmp_off);
1245         }
1246     }
1247     if (!use_armv6_instructions && TARGET_LONG_BITS == 64) {
1248         tcg_out_ld32_12(s, COND_AL, TCG_REG_R3, TCG_REG_R1, cmp_off + 4);
1249     }
1251     /* Load the tlb addend.  */
1252     tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R1,
1253                     offsetof(CPUTLBEntry, addend));
1255     /*
1256      * Check alignment, check comparators.
1257      * Do this in no more than 3 insns.  Use MOVW for v7, if possible,
1258      * to reduce the number of sequential conditional instructions.
1259      * Almost all guests have at least 4k pages, which means that we need
1260      * to clear at least 9 bits even for an 8-byte memory, which means it
1261      * isn't worth checking for an immediate operand for BIC.
1262      */
1263     if (use_armv7_instructions && TARGET_PAGE_BITS <= 16) {
1264         tcg_target_ulong mask = ~(TARGET_PAGE_MASK | ((1 << a_bits) - 1));
1266         tcg_out_movi32(s, COND_AL, TCG_REG_TMP, mask);
1267         tcg_out_dat_reg(s, COND_AL, ARITH_BIC, TCG_REG_TMP,
1268                         addrlo, TCG_REG_TMP, 0);
1269         tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R2, TCG_REG_TMP, 0);
1270     } else {
1271         if (a_bits) {
1272             tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo,
1273                             (1 << a_bits) - 1);
1274         }
1275         tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0, addrlo,
1276                         SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1277         tcg_out_dat_reg(s, (a_bits ? COND_EQ : COND_AL), ARITH_CMP,
1278                         0, TCG_REG_R2, TCG_REG_TMP,
1279                         SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1280     }
1282     if (TARGET_LONG_BITS == 64) {
1283         tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R3, addrhi, 0);
1284     }
1286     return TCG_REG_R1;
1289 /* Record the context of a call to the out of line helper code for the slow
1290    path for a load or store, so that we can later generate the correct
1291    helper code.  */
1292 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1293                                 TCGReg datalo, TCGReg datahi, TCGReg addrlo,
1294                                 TCGReg addrhi, tcg_insn_unit *raddr,
1295                                 tcg_insn_unit *label_ptr)
1297     TCGLabelQemuLdst *label = new_ldst_label(s);
1299     label->is_ld = is_ld;
1300     label->oi = oi;
1301     label->datalo_reg = datalo;
1302     label->datahi_reg = datahi;
1303     label->addrlo_reg = addrlo;
1304     label->addrhi_reg = addrhi;
1305     label->raddr = tcg_splitwx_to_rx(raddr);
1306     label->label_ptr[0] = label_ptr;
1309 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1311     TCGReg argreg, datalo, datahi;
1312     TCGMemOpIdx oi = lb->oi;
1313     MemOp opc = get_memop(oi);
1314     void *func;
1316     if (!reloc_pc24(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
1317         return false;
1318     }
1320     argreg = tcg_out_arg_reg32(s, TCG_REG_R0, TCG_AREG0);
1321     if (TARGET_LONG_BITS == 64) {
1322         argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1323     } else {
1324         argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1325     }
1326     argreg = tcg_out_arg_imm32(s, argreg, oi);
1327     argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1329     /* For armv6 we can use the canonical unsigned helpers and minimize
1330        icache usage.  For pre-armv6, use the signed helpers since we do
1331        not have a single insn sign-extend.  */
1332     if (use_armv6_instructions) {
1333         func = qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)];
1334     } else {
1335         func = qemu_ld_helpers[opc & (MO_BSWAP | MO_SSIZE)];
1336         if (opc & MO_SIGN) {
1337             opc = MO_UL;
1338         }
1339     }
1340     tcg_out_call(s, func);
1342     datalo = lb->datalo_reg;
1343     datahi = lb->datahi_reg;
1344     switch (opc & MO_SSIZE) {
1345     case MO_SB:
1346         tcg_out_ext8s(s, COND_AL, datalo, TCG_REG_R0);
1347         break;
1348     case MO_SW:
1349         tcg_out_ext16s(s, COND_AL, datalo, TCG_REG_R0);
1350         break;
1351     default:
1352         tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
1353         break;
1354     case MO_Q:
1355         if (datalo != TCG_REG_R1) {
1356             tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
1357             tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1);
1358         } else if (datahi != TCG_REG_R0) {
1359             tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1);
1360             tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_R0);
1361         } else {
1362             tcg_out_mov_reg(s, COND_AL, TCG_REG_TMP, TCG_REG_R0);
1363             tcg_out_mov_reg(s, COND_AL, datahi, TCG_REG_R1);
1364             tcg_out_mov_reg(s, COND_AL, datalo, TCG_REG_TMP);
1365         }
1366         break;
1367     }
1369     tcg_out_goto(s, COND_AL, lb->raddr);
1370     return true;
1373 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1375     TCGReg argreg, datalo, datahi;
1376     TCGMemOpIdx oi = lb->oi;
1377     MemOp opc = get_memop(oi);
1379     if (!reloc_pc24(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
1380         return false;
1381     }
1383     argreg = TCG_REG_R0;
1384     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1385     if (TARGET_LONG_BITS == 64) {
1386         argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1387     } else {
1388         argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1389     }
1391     datalo = lb->datalo_reg;
1392     datahi = lb->datahi_reg;
1393     switch (opc & MO_SIZE) {
1394     case MO_8:
1395         argreg = tcg_out_arg_reg8(s, argreg, datalo);
1396         break;
1397     case MO_16:
1398         argreg = tcg_out_arg_reg16(s, argreg, datalo);
1399         break;
1400     case MO_32:
1401     default:
1402         argreg = tcg_out_arg_reg32(s, argreg, datalo);
1403         break;
1404     case MO_64:
1405         argreg = tcg_out_arg_reg64(s, argreg, datalo, datahi);
1406         break;
1407     }
1409     argreg = tcg_out_arg_imm32(s, argreg, oi);
1410     argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1412     /* Tail-call to the helper, which will return to the fast path.  */
1413     tcg_out_goto(s, COND_AL, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1414     return true;
1416 #endif /* SOFTMMU */
1418 static inline void tcg_out_qemu_ld_index(TCGContext *s, MemOp opc,
1419                                          TCGReg datalo, TCGReg datahi,
1420                                          TCGReg addrlo, TCGReg addend)
1422     MemOp bswap = opc & MO_BSWAP;
1424     switch (opc & MO_SSIZE) {
1425     case MO_UB:
1426         tcg_out_ld8_r(s, COND_AL, datalo, addrlo, addend);
1427         break;
1428     case MO_SB:
1429         tcg_out_ld8s_r(s, COND_AL, datalo, addrlo, addend);
1430         break;
1431     case MO_UW:
1432         tcg_out_ld16u_r(s, COND_AL, datalo, addrlo, addend);
1433         if (bswap) {
1434             tcg_out_bswap16(s, COND_AL, datalo, datalo);
1435         }
1436         break;
1437     case MO_SW:
1438         if (bswap) {
1439             tcg_out_ld16u_r(s, COND_AL, datalo, addrlo, addend);
1440             tcg_out_bswap16s(s, COND_AL, datalo, datalo);
1441         } else {
1442             tcg_out_ld16s_r(s, COND_AL, datalo, addrlo, addend);
1443         }
1444         break;
1445     case MO_UL:
1446     default:
1447         tcg_out_ld32_r(s, COND_AL, datalo, addrlo, addend);
1448         if (bswap) {
1449             tcg_out_bswap32(s, COND_AL, datalo, datalo);
1450         }
1451         break;
1452     case MO_Q:
1453         {
1454             TCGReg dl = (bswap ? datahi : datalo);
1455             TCGReg dh = (bswap ? datalo : datahi);
1457             /* Avoid ldrd for user-only emulation, to handle unaligned.  */
1458             if (USING_SOFTMMU && use_armv6_instructions
1459                 && (dl & 1) == 0 && dh == dl + 1) {
1460                 tcg_out_ldrd_r(s, COND_AL, dl, addrlo, addend);
1461             } else if (dl != addend) {
1462                 tcg_out_ld32_rwb(s, COND_AL, dl, addend, addrlo);
1463                 tcg_out_ld32_12(s, COND_AL, dh, addend, 4);
1464             } else {
1465                 tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_TMP,
1466                                 addend, addrlo, SHIFT_IMM_LSL(0));
1467                 tcg_out_ld32_12(s, COND_AL, dl, TCG_REG_TMP, 0);
1468                 tcg_out_ld32_12(s, COND_AL, dh, TCG_REG_TMP, 4);
1469             }
1470             if (bswap) {
1471                 tcg_out_bswap32(s, COND_AL, dl, dl);
1472                 tcg_out_bswap32(s, COND_AL, dh, dh);
1473             }
1474         }
1475         break;
1476     }
1479 static inline void tcg_out_qemu_ld_direct(TCGContext *s, MemOp opc,
1480                                           TCGReg datalo, TCGReg datahi,
1481                                           TCGReg addrlo)
1483     MemOp bswap = opc & MO_BSWAP;
1485     switch (opc & MO_SSIZE) {
1486     case MO_UB:
1487         tcg_out_ld8_12(s, COND_AL, datalo, addrlo, 0);
1488         break;
1489     case MO_SB:
1490         tcg_out_ld8s_8(s, COND_AL, datalo, addrlo, 0);
1491         break;
1492     case MO_UW:
1493         tcg_out_ld16u_8(s, COND_AL, datalo, addrlo, 0);
1494         if (bswap) {
1495             tcg_out_bswap16(s, COND_AL, datalo, datalo);
1496         }
1497         break;
1498     case MO_SW:
1499         if (bswap) {
1500             tcg_out_ld16u_8(s, COND_AL, datalo, addrlo, 0);
1501             tcg_out_bswap16s(s, COND_AL, datalo, datalo);
1502         } else {
1503             tcg_out_ld16s_8(s, COND_AL, datalo, addrlo, 0);
1504         }
1505         break;
1506     case MO_UL:
1507     default:
1508         tcg_out_ld32_12(s, COND_AL, datalo, addrlo, 0);
1509         if (bswap) {
1510             tcg_out_bswap32(s, COND_AL, datalo, datalo);
1511         }
1512         break;
1513     case MO_Q:
1514         {
1515             TCGReg dl = (bswap ? datahi : datalo);
1516             TCGReg dh = (bswap ? datalo : datahi);
1518             /* Avoid ldrd for user-only emulation, to handle unaligned.  */
1519             if (USING_SOFTMMU && use_armv6_instructions
1520                 && (dl & 1) == 0 && dh == dl + 1) {
1521                 tcg_out_ldrd_8(s, COND_AL, dl, addrlo, 0);
1522             } else if (dl == addrlo) {
1523                 tcg_out_ld32_12(s, COND_AL, dh, addrlo, bswap ? 0 : 4);
1524                 tcg_out_ld32_12(s, COND_AL, dl, addrlo, bswap ? 4 : 0);
1525             } else {
1526                 tcg_out_ld32_12(s, COND_AL, dl, addrlo, bswap ? 4 : 0);
1527                 tcg_out_ld32_12(s, COND_AL, dh, addrlo, bswap ? 0 : 4);
1528             }
1529             if (bswap) {
1530                 tcg_out_bswap32(s, COND_AL, dl, dl);
1531                 tcg_out_bswap32(s, COND_AL, dh, dh);
1532             }
1533         }
1534         break;
1535     }
1538 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
1540     TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
1541     TCGMemOpIdx oi;
1542     MemOp opc;
1543 #ifdef CONFIG_SOFTMMU
1544     int mem_index;
1545     TCGReg addend;
1546     tcg_insn_unit *label_ptr;
1547 #endif
1549     datalo = *args++;
1550     datahi = (is64 ? *args++ : 0);
1551     addrlo = *args++;
1552     addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1553     oi = *args++;
1554     opc = get_memop(oi);
1556 #ifdef CONFIG_SOFTMMU
1557     mem_index = get_mmuidx(oi);
1558     addend = tcg_out_tlb_read(s, addrlo, addrhi, opc, mem_index, 1);
1560     /* This a conditional BL only to load a pointer within this opcode into LR
1561        for the slow path.  We will not be using the value for a tail call.  */
1562     label_ptr = s->code_ptr;
1563     tcg_out_bl(s, COND_NE, 0);
1565     tcg_out_qemu_ld_index(s, opc, datalo, datahi, addrlo, addend);
1567     add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
1568                         s->code_ptr, label_ptr);
1569 #else /* !CONFIG_SOFTMMU */
1570     if (guest_base) {
1571         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, guest_base);
1572         tcg_out_qemu_ld_index(s, opc, datalo, datahi, addrlo, TCG_REG_TMP);
1573     } else {
1574         tcg_out_qemu_ld_direct(s, opc, datalo, datahi, addrlo);
1575     }
1576 #endif
1579 static inline void tcg_out_qemu_st_index(TCGContext *s, int cond, MemOp opc,
1580                                          TCGReg datalo, TCGReg datahi,
1581                                          TCGReg addrlo, TCGReg addend)
1583     MemOp bswap = opc & MO_BSWAP;
1585     switch (opc & MO_SIZE) {
1586     case MO_8:
1587         tcg_out_st8_r(s, cond, datalo, addrlo, addend);
1588         break;
1589     case MO_16:
1590         if (bswap) {
1591             tcg_out_bswap16st(s, cond, TCG_REG_R0, datalo);
1592             tcg_out_st16_r(s, cond, TCG_REG_R0, addrlo, addend);
1593         } else {
1594             tcg_out_st16_r(s, cond, datalo, addrlo, addend);
1595         }
1596         break;
1597     case MO_32:
1598     default:
1599         if (bswap) {
1600             tcg_out_bswap32(s, cond, TCG_REG_R0, datalo);
1601             tcg_out_st32_r(s, cond, TCG_REG_R0, addrlo, addend);
1602         } else {
1603             tcg_out_st32_r(s, cond, datalo, addrlo, addend);
1604         }
1605         break;
1606     case MO_64:
1607         /* Avoid strd for user-only emulation, to handle unaligned.  */
1608         if (bswap) {
1609             tcg_out_bswap32(s, cond, TCG_REG_R0, datahi);
1610             tcg_out_st32_rwb(s, cond, TCG_REG_R0, addend, addrlo);
1611             tcg_out_bswap32(s, cond, TCG_REG_R0, datalo);
1612             tcg_out_st32_12(s, cond, TCG_REG_R0, addend, 4);
1613         } else if (USING_SOFTMMU && use_armv6_instructions
1614                    && (datalo & 1) == 0 && datahi == datalo + 1) {
1615             tcg_out_strd_r(s, cond, datalo, addrlo, addend);
1616         } else {
1617             tcg_out_st32_rwb(s, cond, datalo, addend, addrlo);
1618             tcg_out_st32_12(s, cond, datahi, addend, 4);
1619         }
1620         break;
1621     }
1624 static inline void tcg_out_qemu_st_direct(TCGContext *s, MemOp opc,
1625                                           TCGReg datalo, TCGReg datahi,
1626                                           TCGReg addrlo)
1628     MemOp bswap = opc & MO_BSWAP;
1630     switch (opc & MO_SIZE) {
1631     case MO_8:
1632         tcg_out_st8_12(s, COND_AL, datalo, addrlo, 0);
1633         break;
1634     case MO_16:
1635         if (bswap) {
1636             tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, datalo);
1637             tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addrlo, 0);
1638         } else {
1639             tcg_out_st16_8(s, COND_AL, datalo, addrlo, 0);
1640         }
1641         break;
1642     case MO_32:
1643     default:
1644         if (bswap) {
1645             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datalo);
1646             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 0);
1647         } else {
1648             tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0);
1649         }
1650         break;
1651     case MO_64:
1652         /* Avoid strd for user-only emulation, to handle unaligned.  */
1653         if (bswap) {
1654             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datahi);
1655             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 0);
1656             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, datalo);
1657             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addrlo, 4);
1658         } else if (USING_SOFTMMU && use_armv6_instructions
1659                    && (datalo & 1) == 0 && datahi == datalo + 1) {
1660             tcg_out_strd_8(s, COND_AL, datalo, addrlo, 0);
1661         } else {
1662             tcg_out_st32_12(s, COND_AL, datalo, addrlo, 0);
1663             tcg_out_st32_12(s, COND_AL, datahi, addrlo, 4);
1664         }
1665         break;
1666     }
1669 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
1671     TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
1672     TCGMemOpIdx oi;
1673     MemOp opc;
1674 #ifdef CONFIG_SOFTMMU
1675     int mem_index;
1676     TCGReg addend;
1677     tcg_insn_unit *label_ptr;
1678 #endif
1680     datalo = *args++;
1681     datahi = (is64 ? *args++ : 0);
1682     addrlo = *args++;
1683     addrhi = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1684     oi = *args++;
1685     opc = get_memop(oi);
1687 #ifdef CONFIG_SOFTMMU
1688     mem_index = get_mmuidx(oi);
1689     addend = tcg_out_tlb_read(s, addrlo, addrhi, opc, mem_index, 0);
1691     tcg_out_qemu_st_index(s, COND_EQ, opc, datalo, datahi, addrlo, addend);
1693     /* The conditional call must come last, as we're going to return here.  */
1694     label_ptr = s->code_ptr;
1695     tcg_out_bl(s, COND_NE, 0);
1697     add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
1698                         s->code_ptr, label_ptr);
1699 #else /* !CONFIG_SOFTMMU */
1700     if (guest_base) {
1701         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, guest_base);
1702         tcg_out_qemu_st_index(s, COND_AL, opc, datalo,
1703                               datahi, addrlo, TCG_REG_TMP);
1704     } else {
1705         tcg_out_qemu_st_direct(s, opc, datalo, datahi, addrlo);
1706     }
1707 #endif
1710 static void tcg_out_epilogue(TCGContext *s);
1712 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1713                 const TCGArg *args, const int *const_args)
1715     TCGArg a0, a1, a2, a3, a4, a5;
1716     int c;
1718     switch (opc) {
1719     case INDEX_op_exit_tb:
1720         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, args[0]);
1721         tcg_out_epilogue(s);
1722         break;
1723     case INDEX_op_goto_tb:
1724         {
1725             /* Indirect jump method */
1726             intptr_t ptr, dif, dil;
1727             TCGReg base = TCG_REG_PC;
1729             tcg_debug_assert(s->tb_jmp_insn_offset == 0);
1730             ptr = (intptr_t)tcg_splitwx_to_rx(s->tb_jmp_target_addr + args[0]);
1731             dif = tcg_pcrel_diff(s, (void *)ptr) - 8;
1732             dil = sextract32(dif, 0, 12);
1733             if (dif != dil) {
1734                 /* The TB is close, but outside the 12 bits addressable by
1735                    the load.  We can extend this to 20 bits with a sub of a
1736                    shifted immediate from pc.  In the vastly unlikely event
1737                    the code requires more than 1MB, we'll use 2 insns and
1738                    be no worse off.  */
1739                 base = TCG_REG_R0;
1740                 tcg_out_movi32(s, COND_AL, base, ptr - dil);
1741             }
1742             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, base, dil);
1743             set_jmp_reset_offset(s, args[0]);
1744         }
1745         break;
1746     case INDEX_op_goto_ptr:
1747         tcg_out_bx(s, COND_AL, args[0]);
1748         break;
1749     case INDEX_op_br:
1750         tcg_out_goto_label(s, COND_AL, arg_label(args[0]));
1751         break;
1753     case INDEX_op_ld8u_i32:
1754         tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
1755         break;
1756     case INDEX_op_ld8s_i32:
1757         tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
1758         break;
1759     case INDEX_op_ld16u_i32:
1760         tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
1761         break;
1762     case INDEX_op_ld16s_i32:
1763         tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
1764         break;
1765     case INDEX_op_ld_i32:
1766         tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
1767         break;
1768     case INDEX_op_st8_i32:
1769         tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
1770         break;
1771     case INDEX_op_st16_i32:
1772         tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
1773         break;
1774     case INDEX_op_st_i32:
1775         tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
1776         break;
1778     case INDEX_op_movcond_i32:
1779         /* Constraints mean that v2 is always in the same register as dest,
1780          * so we only need to do "if condition passed, move v1 to dest".
1781          */
1782         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1783                         args[1], args[2], const_args[2]);
1784         tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
1785                         ARITH_MVN, args[0], 0, args[3], const_args[3]);
1786         break;
1787     case INDEX_op_add_i32:
1788         tcg_out_dat_rIN(s, COND_AL, ARITH_ADD, ARITH_SUB,
1789                         args[0], args[1], args[2], const_args[2]);
1790         break;
1791     case INDEX_op_sub_i32:
1792         if (const_args[1]) {
1793             if (const_args[2]) {
1794                 tcg_out_movi32(s, COND_AL, args[0], args[1] - args[2]);
1795             } else {
1796                 tcg_out_dat_rI(s, COND_AL, ARITH_RSB,
1797                                args[0], args[2], args[1], 1);
1798             }
1799         } else {
1800             tcg_out_dat_rIN(s, COND_AL, ARITH_SUB, ARITH_ADD,
1801                             args[0], args[1], args[2], const_args[2]);
1802         }
1803         break;
1804     case INDEX_op_and_i32:
1805         tcg_out_dat_rIK(s, COND_AL, ARITH_AND, ARITH_BIC,
1806                         args[0], args[1], args[2], const_args[2]);
1807         break;
1808     case INDEX_op_andc_i32:
1809         tcg_out_dat_rIK(s, COND_AL, ARITH_BIC, ARITH_AND,
1810                         args[0], args[1], args[2], const_args[2]);
1811         break;
1812     case INDEX_op_or_i32:
1813         c = ARITH_ORR;
1814         goto gen_arith;
1815     case INDEX_op_xor_i32:
1816         c = ARITH_EOR;
1817         /* Fall through.  */
1818     gen_arith:
1819         tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);
1820         break;
1821     case INDEX_op_add2_i32:
1822         a0 = args[0], a1 = args[1], a2 = args[2];
1823         a3 = args[3], a4 = args[4], a5 = args[5];
1824         if (a0 == a3 || (a0 == a5 && !const_args[5])) {
1825             a0 = TCG_REG_TMP;
1826         }
1827         tcg_out_dat_rIN(s, COND_AL, ARITH_ADD | TO_CPSR, ARITH_SUB | TO_CPSR,
1828                         a0, a2, a4, const_args[4]);
1829         tcg_out_dat_rIK(s, COND_AL, ARITH_ADC, ARITH_SBC,
1830                         a1, a3, a5, const_args[5]);
1831         tcg_out_mov_reg(s, COND_AL, args[0], a0);
1832         break;
1833     case INDEX_op_sub2_i32:
1834         a0 = args[0], a1 = args[1], a2 = args[2];
1835         a3 = args[3], a4 = args[4], a5 = args[5];
1836         if ((a0 == a3 && !const_args[3]) || (a0 == a5 && !const_args[5])) {
1837             a0 = TCG_REG_TMP;
1838         }
1839         if (const_args[2]) {
1840             if (const_args[4]) {
1841                 tcg_out_movi32(s, COND_AL, a0, a4);
1842                 a4 = a0;
1843             }
1844             tcg_out_dat_rI(s, COND_AL, ARITH_RSB | TO_CPSR, a0, a4, a2, 1);
1845         } else {
1846             tcg_out_dat_rIN(s, COND_AL, ARITH_SUB | TO_CPSR,
1847                             ARITH_ADD | TO_CPSR, a0, a2, a4, const_args[4]);
1848         }
1849         if (const_args[3]) {
1850             if (const_args[5]) {
1851                 tcg_out_movi32(s, COND_AL, a1, a5);
1852                 a5 = a1;
1853             }
1854             tcg_out_dat_rI(s, COND_AL, ARITH_RSC, a1, a5, a3, 1);
1855         } else {
1856             tcg_out_dat_rIK(s, COND_AL, ARITH_SBC, ARITH_ADC,
1857                             a1, a3, a5, const_args[5]);
1858         }
1859         tcg_out_mov_reg(s, COND_AL, args[0], a0);
1860         break;
1861     case INDEX_op_neg_i32:
1862         tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
1863         break;
1864     case INDEX_op_not_i32:
1865         tcg_out_dat_reg(s, COND_AL,
1866                         ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
1867         break;
1868     case INDEX_op_mul_i32:
1869         tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
1870         break;
1871     case INDEX_op_mulu2_i32:
1872         tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1873         break;
1874     case INDEX_op_muls2_i32:
1875         tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1876         break;
1877     /* XXX: Perhaps args[2] & 0x1f is wrong */
1878     case INDEX_op_shl_i32:
1879         c = const_args[2] ?
1880                 SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
1881         goto gen_shift32;
1882     case INDEX_op_shr_i32:
1883         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
1884                 SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
1885         goto gen_shift32;
1886     case INDEX_op_sar_i32:
1887         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
1888                 SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
1889         goto gen_shift32;
1890     case INDEX_op_rotr_i32:
1891         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
1892                 SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
1893         /* Fall through.  */
1894     gen_shift32:
1895         tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
1896         break;
1898     case INDEX_op_rotl_i32:
1899         if (const_args[2]) {
1900             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1901                             ((0x20 - args[2]) & 0x1f) ?
1902                             SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
1903                             SHIFT_IMM_LSL(0));
1904         } else {
1905             tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[2], 0x20);
1906             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1907                             SHIFT_REG_ROR(TCG_REG_TMP));
1908         }
1909         break;
1911     case INDEX_op_ctz_i32:
1912         tcg_out_dat_reg(s, COND_AL, INSN_RBIT, TCG_REG_TMP, 0, args[1], 0);
1913         a1 = TCG_REG_TMP;
1914         goto do_clz;
1916     case INDEX_op_clz_i32:
1917         a1 = args[1];
1918     do_clz:
1919         a0 = args[0];
1920         a2 = args[2];
1921         c = const_args[2];
1922         if (c && a2 == 32) {
1923             tcg_out_dat_reg(s, COND_AL, INSN_CLZ, a0, 0, a1, 0);
1924             break;
1925         }
1926         tcg_out_dat_imm(s, COND_AL, ARITH_CMP, 0, a1, 0);
1927         tcg_out_dat_reg(s, COND_NE, INSN_CLZ, a0, 0, a1, 0);
1928         if (c || a0 != a2) {
1929             tcg_out_dat_rIK(s, COND_EQ, ARITH_MOV, ARITH_MVN, a0, 0, a2, c);
1930         }
1931         break;
1933     case INDEX_op_brcond_i32:
1934         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1935                        args[0], args[1], const_args[1]);
1936         tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]],
1937                            arg_label(args[3]));
1938         break;
1939     case INDEX_op_setcond_i32:
1940         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1941                         args[1], args[2], const_args[2]);
1942         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
1943                         ARITH_MOV, args[0], 0, 1);
1944         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
1945                         ARITH_MOV, args[0], 0, 0);
1946         break;
1948     case INDEX_op_brcond2_i32:
1949         c = tcg_out_cmp2(s, args, const_args);
1950         tcg_out_goto_label(s, tcg_cond_to_arm_cond[c], arg_label(args[5]));
1951         break;
1952     case INDEX_op_setcond2_i32:
1953         c = tcg_out_cmp2(s, args + 1, const_args + 1);
1954         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[c], ARITH_MOV, args[0], 0, 1);
1955         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(c)],
1956                         ARITH_MOV, args[0], 0, 0);
1957         break;
1959     case INDEX_op_qemu_ld_i32:
1960         tcg_out_qemu_ld(s, args, 0);
1961         break;
1962     case INDEX_op_qemu_ld_i64:
1963         tcg_out_qemu_ld(s, args, 1);
1964         break;
1965     case INDEX_op_qemu_st_i32:
1966         tcg_out_qemu_st(s, args, 0);
1967         break;
1968     case INDEX_op_qemu_st_i64:
1969         tcg_out_qemu_st(s, args, 1);
1970         break;
1972     case INDEX_op_bswap16_i32:
1973         tcg_out_bswap16(s, COND_AL, args[0], args[1]);
1974         break;
1975     case INDEX_op_bswap32_i32:
1976         tcg_out_bswap32(s, COND_AL, args[0], args[1]);
1977         break;
1979     case INDEX_op_ext8s_i32:
1980         tcg_out_ext8s(s, COND_AL, args[0], args[1]);
1981         break;
1982     case INDEX_op_ext16s_i32:
1983         tcg_out_ext16s(s, COND_AL, args[0], args[1]);
1984         break;
1985     case INDEX_op_ext16u_i32:
1986         tcg_out_ext16u(s, COND_AL, args[0], args[1]);
1987         break;
1989     case INDEX_op_deposit_i32:
1990         tcg_out_deposit(s, COND_AL, args[0], args[2],
1991                         args[3], args[4], const_args[2]);
1992         break;
1993     case INDEX_op_extract_i32:
1994         tcg_out_extract(s, COND_AL, args[0], args[1], args[2], args[3]);
1995         break;
1996     case INDEX_op_sextract_i32:
1997         tcg_out_sextract(s, COND_AL, args[0], args[1], args[2], args[3]);
1998         break;
1999     case INDEX_op_extract2_i32:
2000         /* ??? These optimization vs zero should be generic.  */
2001         /* ??? But we can't substitute 2 for 1 in the opcode stream yet.  */
2002         if (const_args[1]) {
2003             if (const_args[2]) {
2004                 tcg_out_movi(s, TCG_TYPE_REG, args[0], 0);
2005             } else {
2006                 tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
2007                                 args[2], SHIFT_IMM_LSL(32 - args[3]));
2008             }
2009         } else if (const_args[2]) {
2010             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0,
2011                             args[1], SHIFT_IMM_LSR(args[3]));
2012         } else {
2013             /* We can do extract2 in 2 insns, vs the 3 required otherwise.  */
2014             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP, 0,
2015                             args[2], SHIFT_IMM_LSL(32 - args[3]));
2016             tcg_out_dat_reg(s, COND_AL, ARITH_ORR, args[0], TCG_REG_TMP,
2017                             args[1], SHIFT_IMM_LSR(args[3]));
2018         }
2019         break;
2021     case INDEX_op_div_i32:
2022         tcg_out_sdiv(s, COND_AL, args[0], args[1], args[2]);
2023         break;
2024     case INDEX_op_divu_i32:
2025         tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
2026         break;
2028     case INDEX_op_mb:
2029         tcg_out_mb(s, args[0]);
2030         break;
2032     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
2033     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
2034     default:
2035         tcg_abort();
2036     }
2039 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
2041     switch (op) {
2042     case INDEX_op_goto_ptr:
2043         return C_O0_I1(r);
2045     case INDEX_op_ld8u_i32:
2046     case INDEX_op_ld8s_i32:
2047     case INDEX_op_ld16u_i32:
2048     case INDEX_op_ld16s_i32:
2049     case INDEX_op_ld_i32:
2050     case INDEX_op_neg_i32:
2051     case INDEX_op_not_i32:
2052     case INDEX_op_bswap16_i32:
2053     case INDEX_op_bswap32_i32:
2054     case INDEX_op_ext8s_i32:
2055     case INDEX_op_ext16s_i32:
2056     case INDEX_op_ext16u_i32:
2057     case INDEX_op_extract_i32:
2058     case INDEX_op_sextract_i32:
2059         return C_O1_I1(r, r);
2061     case INDEX_op_st8_i32:
2062     case INDEX_op_st16_i32:
2063     case INDEX_op_st_i32:
2064         return C_O0_I2(r, r);
2066     case INDEX_op_add_i32:
2067     case INDEX_op_sub_i32:
2068     case INDEX_op_setcond_i32:
2069         return C_O1_I2(r, r, rIN);
2071     case INDEX_op_and_i32:
2072     case INDEX_op_andc_i32:
2073     case INDEX_op_clz_i32:
2074     case INDEX_op_ctz_i32:
2075         return C_O1_I2(r, r, rIK);
2077     case INDEX_op_mul_i32:
2078     case INDEX_op_div_i32:
2079     case INDEX_op_divu_i32:
2080         return C_O1_I2(r, r, r);
2082     case INDEX_op_mulu2_i32:
2083     case INDEX_op_muls2_i32:
2084         return C_O2_I2(r, r, r, r);
2086     case INDEX_op_or_i32:
2087     case INDEX_op_xor_i32:
2088         return C_O1_I2(r, r, rI);
2090     case INDEX_op_shl_i32:
2091     case INDEX_op_shr_i32:
2092     case INDEX_op_sar_i32:
2093     case INDEX_op_rotl_i32:
2094     case INDEX_op_rotr_i32:
2095         return C_O1_I2(r, r, ri);
2097     case INDEX_op_brcond_i32:
2098         return C_O0_I2(r, rIN);
2099     case INDEX_op_deposit_i32:
2100         return C_O1_I2(r, 0, rZ);
2101     case INDEX_op_extract2_i32:
2102         return C_O1_I2(r, rZ, rZ);
2103     case INDEX_op_movcond_i32:
2104         return C_O1_I4(r, r, rIN, rIK, 0);
2105     case INDEX_op_add2_i32:
2106         return C_O2_I4(r, r, r, r, rIN, rIK);
2107     case INDEX_op_sub2_i32:
2108         return C_O2_I4(r, r, rI, rI, rIN, rIK);
2109     case INDEX_op_brcond2_i32:
2110         return C_O0_I4(r, r, rI, rI);
2111     case INDEX_op_setcond2_i32:
2112         return C_O1_I4(r, r, r, rI, rI);
2114     case INDEX_op_qemu_ld_i32:
2115         return TARGET_LONG_BITS == 32 ? C_O1_I1(r, l) : C_O1_I2(r, l, l);
2116     case INDEX_op_qemu_ld_i64:
2117         return TARGET_LONG_BITS == 32 ? C_O2_I1(r, r, l) : C_O2_I2(r, r, l, l);
2118     case INDEX_op_qemu_st_i32:
2119         return TARGET_LONG_BITS == 32 ? C_O0_I2(s, s) : C_O0_I3(s, s, s);
2120     case INDEX_op_qemu_st_i64:
2121         return TARGET_LONG_BITS == 32 ? C_O0_I3(s, s, s) : C_O0_I4(s, s, s, s);
2123     default:
2124         g_assert_not_reached();
2125     }
2128 static void tcg_target_init(TCGContext *s)
2130     /* Only probe for the platform and capabilities if we havn't already
2131        determined maximum values at compile time.  */
2132 #ifndef use_idiv_instructions
2133     {
2134         unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2135         use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
2136     }
2137 #endif
2138     if (__ARM_ARCH < 7) {
2139         const char *pl = (const char *)qemu_getauxval(AT_PLATFORM);
2140         if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
2141             arm_arch = pl[1] - '0';
2142         }
2143     }
2145     tcg_target_available_regs[TCG_TYPE_I32] = 0xffff;
2147     tcg_target_call_clobber_regs = 0;
2148     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2149     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
2150     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2151     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2152     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12);
2153     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
2155     s->reserved_regs = 0;
2156     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2157     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
2158     tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
2161 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
2162                               TCGReg arg1, intptr_t arg2)
2164     tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
2167 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
2168                               TCGReg arg1, intptr_t arg2)
2170     tcg_out_st32(s, COND_AL, arg, arg1, arg2);
2173 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
2174                                TCGReg base, intptr_t ofs)
2176     return false;
2179 static inline bool tcg_out_mov(TCGContext *s, TCGType type,
2180                                TCGReg ret, TCGReg arg)
2182     tcg_out_mov_reg(s, COND_AL, ret, arg);
2183     return true;
2186 static inline void tcg_out_movi(TCGContext *s, TCGType type,
2187                                 TCGReg ret, tcg_target_long arg)
2189     tcg_out_movi32(s, COND_AL, ret, arg);
2192 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2194     int i;
2195     for (i = 0; i < count; ++i) {
2196         p[i] = INSN_NOP;
2197     }
2200 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
2201    and tcg_register_jit.  */
2203 #define PUSH_SIZE  ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
2205 #define FRAME_SIZE \
2206     ((PUSH_SIZE \
2207       + TCG_STATIC_CALL_ARGS_SIZE \
2208       + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2209       + TCG_TARGET_STACK_ALIGN - 1) \
2210      & -TCG_TARGET_STACK_ALIGN)
2212 #define STACK_ADDEND  (FRAME_SIZE - PUSH_SIZE)
2214 static void tcg_target_qemu_prologue(TCGContext *s)
2216     /* Calling convention requires us to save r4-r11 and lr.  */
2217     /* stmdb sp!, { r4 - r11, lr } */
2218     tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
2220     /* Reserve callee argument and tcg temp space.  */
2221     tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
2222                    TCG_REG_CALL_STACK, STACK_ADDEND, 1);
2223     tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2224                   CPU_TEMP_BUF_NLONGS * sizeof(long));
2226     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2228     tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
2230     /*
2231      * Return path for goto_ptr. Set return value to 0, a-la exit_tb,
2232      * and fall through to the rest of the epilogue.
2233      */
2234     tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2235     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, 0);
2236     tcg_out_epilogue(s);
2239 static void tcg_out_epilogue(TCGContext *s)
2241     /* Release local stack frame.  */
2242     tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
2243                    TCG_REG_CALL_STACK, STACK_ADDEND, 1);
2245     /* ldmia sp!, { r4 - r11, pc } */
2246     tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
2249 typedef struct {
2250     DebugFrameHeader h;
2251     uint8_t fde_def_cfa[4];
2252     uint8_t fde_reg_ofs[18];
2253 } DebugFrame;
2255 #define ELF_HOST_MACHINE EM_ARM
2257 /* We're expecting a 2 byte uleb128 encoded value.  */
2258 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2260 static const DebugFrame debug_frame = {
2261     .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2262     .h.cie.id = -1,
2263     .h.cie.version = 1,
2264     .h.cie.code_align = 1,
2265     .h.cie.data_align = 0x7c,             /* sleb128 -4 */
2266     .h.cie.return_column = 14,
2268     /* Total FDE size does not include the "len" member.  */
2269     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
2271     .fde_def_cfa = {
2272         12, 13,                         /* DW_CFA_def_cfa sp, ... */
2273         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2274         (FRAME_SIZE >> 7)
2275     },
2276     .fde_reg_ofs = {
2277         /* The following must match the stmdb in the prologue.  */
2278         0x8e, 1,                        /* DW_CFA_offset, lr, -4 */
2279         0x8b, 2,                        /* DW_CFA_offset, r11, -8 */
2280         0x8a, 3,                        /* DW_CFA_offset, r10, -12 */
2281         0x89, 4,                        /* DW_CFA_offset, r9, -16 */
2282         0x88, 5,                        /* DW_CFA_offset, r8, -20 */
2283         0x87, 6,                        /* DW_CFA_offset, r7, -24 */
2284         0x86, 7,                        /* DW_CFA_offset, r6, -28 */
2285         0x85, 8,                        /* DW_CFA_offset, r5, -32 */
2286         0x84, 9,                        /* DW_CFA_offset, r4, -36 */
2287     }
2290 void tcg_register_jit(const void *buf, size_t buf_size)
2292     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));