]> Git Repo - qemu.git/blob - tcg/arm/tcg-target.c
tcg-arm: Move the tlb addend load earlier
[qemu.git] / tcg / arm / tcg-target.c
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  */
24
25 /* The __ARM_ARCH define is provided by gcc 4.8.  Construct it otherwise.  */
26 #ifndef __ARM_ARCH
27 # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
28      || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
29      || defined(__ARM_ARCH_7EM__)
30 #  define __ARM_ARCH 7
31 # elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
32        || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
33        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
34 #  define __ARM_ARCH 6
35 # elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \
36        || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
37        || defined(__ARM_ARCH_5TEJ__)
38 #  define __ARM_ARCH 5
39 # else
40 #  define __ARM_ARCH 4
41 # endif
42 #endif
43
44 static int arm_arch = __ARM_ARCH;
45
46 #if defined(__ARM_ARCH_5T__) \
47     || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
48 # define use_armv5t_instructions 1
49 #else
50 # define use_armv5t_instructions use_armv6_instructions
51 #endif
52
53 #define use_armv6_instructions  (__ARM_ARCH >= 6 || arm_arch >= 6)
54 #define use_armv7_instructions  (__ARM_ARCH >= 7 || arm_arch >= 7)
55
56 #ifndef use_idiv_instructions
57 bool use_idiv_instructions;
58 #endif
59 #ifdef CONFIG_GETAUXVAL
60 # include <sys/auxv.h>
61 #endif
62
63 #ifndef NDEBUG
64 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
65     "%r0",
66     "%r1",
67     "%r2",
68     "%r3",
69     "%r4",
70     "%r5",
71     "%r6",
72     "%r7",
73     "%r8",
74     "%r9",
75     "%r10",
76     "%r11",
77     "%r12",
78     "%r13",
79     "%r14",
80     "%pc",
81 };
82 #endif
83
84 static const int tcg_target_reg_alloc_order[] = {
85     TCG_REG_R4,
86     TCG_REG_R5,
87     TCG_REG_R6,
88     TCG_REG_R7,
89     TCG_REG_R8,
90     TCG_REG_R9,
91     TCG_REG_R10,
92     TCG_REG_R11,
93     TCG_REG_R13,
94     TCG_REG_R0,
95     TCG_REG_R1,
96     TCG_REG_R2,
97     TCG_REG_R3,
98     TCG_REG_R12,
99     TCG_REG_R14,
100 };
101
102 static const int tcg_target_call_iarg_regs[4] = {
103     TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
104 };
105 static const int tcg_target_call_oarg_regs[2] = {
106     TCG_REG_R0, TCG_REG_R1
107 };
108
109 #define TCG_REG_TMP  TCG_REG_R12
110
111 static inline void reloc_abs32(void *code_ptr, intptr_t target)
112 {
113     *(uint32_t *) code_ptr = target;
114 }
115
116 static inline void reloc_pc24(void *code_ptr, intptr_t target)
117 {
118     uint32_t offset = ((target - ((intptr_t)code_ptr + 8)) >> 2);
119
120     *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
121                              | (offset & 0xffffff);
122 }
123
124 static void patch_reloc(uint8_t *code_ptr, int type,
125                         intptr_t value, intptr_t addend)
126 {
127     switch (type) {
128     case R_ARM_ABS32:
129         reloc_abs32(code_ptr, value);
130         break;
131
132     case R_ARM_CALL:
133     case R_ARM_JUMP24:
134     default:
135         tcg_abort();
136
137     case R_ARM_PC24:
138         reloc_pc24(code_ptr, value);
139         break;
140     }
141 }
142
143 #define TCG_CT_CONST_ARM  0x100
144 #define TCG_CT_CONST_INV  0x200
145 #define TCG_CT_CONST_NEG  0x400
146 #define TCG_CT_CONST_ZERO 0x800
147
148 /* parse target specific constraints */
149 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
150 {
151     const char *ct_str;
152
153     ct_str = *pct_str;
154     switch (ct_str[0]) {
155     case 'I':
156         ct->ct |= TCG_CT_CONST_ARM;
157         break;
158     case 'K':
159         ct->ct |= TCG_CT_CONST_INV;
160         break;
161     case 'N': /* The gcc constraint letter is L, already used here.  */
162         ct->ct |= TCG_CT_CONST_NEG;
163         break;
164     case 'Z':
165         ct->ct |= TCG_CT_CONST_ZERO;
166         break;
167
168     case 'r':
169         ct->ct |= TCG_CT_REG;
170         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
171         break;
172
173     /* qemu_ld address */
174     case 'l':
175         ct->ct |= TCG_CT_REG;
176         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
177 #ifdef CONFIG_SOFTMMU
178         /* r0-r2,lr will be overwritten when reading the tlb entry,
179            so don't use these. */
180         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
181         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
182         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
183         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
184 #endif
185         break;
186
187     /* qemu_st address & data_reg */
188     case 's':
189         ct->ct |= TCG_CT_REG;
190         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
191         /* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
192            and r0-r1 doing the byte swapping, so don't use these. */
193         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
194         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
195 #if defined(CONFIG_SOFTMMU)
196         /* Avoid clashes with registers being used for helper args */
197         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
198 #if TARGET_LONG_BITS == 64
199         /* Avoid clashes with registers being used for helper args */
200         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
201 #endif
202         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
203 #endif
204         break;
205
206     default:
207         return -1;
208     }
209     ct_str++;
210     *pct_str = ct_str;
211
212     return 0;
213 }
214
215 static inline uint32_t rotl(uint32_t val, int n)
216 {
217   return (val << n) | (val >> (32 - n));
218 }
219
220 /* ARM immediates for ALU instructions are made of an unsigned 8-bit
221    right-rotated by an even amount between 0 and 30. */
222 static inline int encode_imm(uint32_t imm)
223 {
224     int shift;
225
226     /* simple case, only lower bits */
227     if ((imm & ~0xff) == 0)
228         return 0;
229     /* then try a simple even shift */
230     shift = ctz32(imm) & ~1;
231     if (((imm >> shift) & ~0xff) == 0)
232         return 32 - shift;
233     /* now try harder with rotations */
234     if ((rotl(imm, 2) & ~0xff) == 0)
235         return 2;
236     if ((rotl(imm, 4) & ~0xff) == 0)
237         return 4;
238     if ((rotl(imm, 6) & ~0xff) == 0)
239         return 6;
240     /* imm can't be encoded */
241     return -1;
242 }
243
244 static inline int check_fit_imm(uint32_t imm)
245 {
246     return encode_imm(imm) >= 0;
247 }
248
249 /* Test if a constant matches the constraint.
250  * TODO: define constraints for:
251  *
252  * ldr/str offset:   between -0xfff and 0xfff
253  * ldrh/strh offset: between -0xff and 0xff
254  * mov operand2:     values represented with x << (2 * y), x < 0x100
255  * add, sub, eor...: ditto
256  */
257 static inline int tcg_target_const_match(tcg_target_long val,
258                                          const TCGArgConstraint *arg_ct)
259 {
260     int ct;
261     ct = arg_ct->ct;
262     if (ct & TCG_CT_CONST) {
263         return 1;
264     } else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) {
265         return 1;
266     } else if ((ct & TCG_CT_CONST_INV) && check_fit_imm(~val)) {
267         return 1;
268     } else if ((ct & TCG_CT_CONST_NEG) && check_fit_imm(-val)) {
269         return 1;
270     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
271         return 1;
272     } else {
273         return 0;
274     }
275 }
276
277 #define TO_CPSR (1 << 20)
278
279 typedef enum {
280     ARITH_AND = 0x0 << 21,
281     ARITH_EOR = 0x1 << 21,
282     ARITH_SUB = 0x2 << 21,
283     ARITH_RSB = 0x3 << 21,
284     ARITH_ADD = 0x4 << 21,
285     ARITH_ADC = 0x5 << 21,
286     ARITH_SBC = 0x6 << 21,
287     ARITH_RSC = 0x7 << 21,
288     ARITH_TST = 0x8 << 21 | TO_CPSR,
289     ARITH_CMP = 0xa << 21 | TO_CPSR,
290     ARITH_CMN = 0xb << 21 | TO_CPSR,
291     ARITH_ORR = 0xc << 21,
292     ARITH_MOV = 0xd << 21,
293     ARITH_BIC = 0xe << 21,
294     ARITH_MVN = 0xf << 21,
295
296     INSN_LDR_IMM   = 0x04100000,
297     INSN_LDR_REG   = 0x06100000,
298     INSN_STR_IMM   = 0x04000000,
299     INSN_STR_REG   = 0x06000000,
300
301     INSN_LDRH_IMM  = 0x005000b0,
302     INSN_LDRH_REG  = 0x001000b0,
303     INSN_LDRSH_IMM = 0x005000f0,
304     INSN_LDRSH_REG = 0x001000f0,
305     INSN_STRH_IMM  = 0x004000b0,
306     INSN_STRH_REG  = 0x000000b0,
307
308     INSN_LDRB_IMM  = 0x04500000,
309     INSN_LDRB_REG  = 0x06500000,
310     INSN_LDRSB_IMM = 0x005000d0,
311     INSN_LDRSB_REG = 0x001000d0,
312     INSN_STRB_IMM  = 0x04400000,
313     INSN_STRB_REG  = 0x06400000,
314
315     INSN_LDRD_IMM  = 0x004000d0,
316     INSN_LDRD_REG  = 0x000000d0,
317     INSN_STRD_IMM  = 0x004000f0,
318     INSN_STRD_REG  = 0x000000f0,
319 } ARMInsn;
320
321 #define SHIFT_IMM_LSL(im)       (((im) << 7) | 0x00)
322 #define SHIFT_IMM_LSR(im)       (((im) << 7) | 0x20)
323 #define SHIFT_IMM_ASR(im)       (((im) << 7) | 0x40)
324 #define SHIFT_IMM_ROR(im)       (((im) << 7) | 0x60)
325 #define SHIFT_REG_LSL(rs)       (((rs) << 8) | 0x10)
326 #define SHIFT_REG_LSR(rs)       (((rs) << 8) | 0x30)
327 #define SHIFT_REG_ASR(rs)       (((rs) << 8) | 0x50)
328 #define SHIFT_REG_ROR(rs)       (((rs) << 8) | 0x70)
329
330 enum arm_cond_code_e {
331     COND_EQ = 0x0,
332     COND_NE = 0x1,
333     COND_CS = 0x2,      /* Unsigned greater or equal */
334     COND_CC = 0x3,      /* Unsigned less than */
335     COND_MI = 0x4,      /* Negative */
336     COND_PL = 0x5,      /* Zero or greater */
337     COND_VS = 0x6,      /* Overflow */
338     COND_VC = 0x7,      /* No overflow */
339     COND_HI = 0x8,      /* Unsigned greater than */
340     COND_LS = 0x9,      /* Unsigned less or equal */
341     COND_GE = 0xa,
342     COND_LT = 0xb,
343     COND_GT = 0xc,
344     COND_LE = 0xd,
345     COND_AL = 0xe,
346 };
347
348 static const uint8_t tcg_cond_to_arm_cond[] = {
349     [TCG_COND_EQ] = COND_EQ,
350     [TCG_COND_NE] = COND_NE,
351     [TCG_COND_LT] = COND_LT,
352     [TCG_COND_GE] = COND_GE,
353     [TCG_COND_LE] = COND_LE,
354     [TCG_COND_GT] = COND_GT,
355     /* unsigned */
356     [TCG_COND_LTU] = COND_CC,
357     [TCG_COND_GEU] = COND_CS,
358     [TCG_COND_LEU] = COND_LS,
359     [TCG_COND_GTU] = COND_HI,
360 };
361
362 static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
363 {
364     tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
365 }
366
367 static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
368 {
369     tcg_out32(s, (cond << 28) | 0x0a000000 |
370                     (((offset - 8) >> 2) & 0x00ffffff));
371 }
372
373 static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
374 {
375     /* We pay attention here to not modify the branch target by skipping
376        the corresponding bytes. This ensure that caches and memory are
377        kept coherent during retranslation. */
378     s->code_ptr += 3;
379     tcg_out8(s, (cond << 4) | 0x0a);
380 }
381
382 static inline void tcg_out_bl_noaddr(TCGContext *s, int cond)
383 {
384     /* We pay attention here to not modify the branch target by skipping
385        the corresponding bytes. This ensure that caches and memory are
386        kept coherent during retranslation. */
387     s->code_ptr += 3;
388     tcg_out8(s, (cond << 4) | 0x0b);
389 }
390
391 static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
392 {
393     tcg_out32(s, (cond << 28) | 0x0b000000 |
394                     (((offset - 8) >> 2) & 0x00ffffff));
395 }
396
397 static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
398 {
399     tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
400 }
401
402 static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
403 {
404     tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
405                 (((offset - 8) >> 2) & 0x00ffffff));
406 }
407
408 static inline void tcg_out_dat_reg(TCGContext *s,
409                 int cond, int opc, int rd, int rn, int rm, int shift)
410 {
411     tcg_out32(s, (cond << 28) | (0 << 25) | opc |
412                     (rn << 16) | (rd << 12) | shift | rm);
413 }
414
415 static inline void tcg_out_nop(TCGContext *s)
416 {
417     if (use_armv7_instructions) {
418         /* Architected nop introduced in v6k.  */
419         /* ??? This is an MSR (imm) 0,0,0 insn.  Anyone know if this
420            also Just So Happened to do nothing on pre-v6k so that we
421            don't need to conditionalize it?  */
422         tcg_out32(s, 0xe320f000);
423     } else {
424         /* Prior to that the assembler uses mov r0, r0.  */
425         tcg_out_dat_reg(s, COND_AL, ARITH_MOV, 0, 0, 0, SHIFT_IMM_LSL(0));
426     }
427 }
428
429 static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
430 {
431     /* Simple reg-reg move, optimising out the 'do nothing' case */
432     if (rd != rm) {
433         tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
434     }
435 }
436
437 static inline void tcg_out_dat_imm(TCGContext *s,
438                 int cond, int opc, int rd, int rn, int im)
439 {
440     tcg_out32(s, (cond << 28) | (1 << 25) | opc |
441                     (rn << 16) | (rd << 12) | im);
442 }
443
444 static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
445 {
446     int rot, opc, rn;
447
448     /* For armv7, make sure not to use movw+movt when mov/mvn would do.
449        Speed things up by only checking when movt would be required.
450        Prior to armv7, have one go at fully rotated immediates before
451        doing the decomposition thing below.  */
452     if (!use_armv7_instructions || (arg & 0xffff0000)) {
453         rot = encode_imm(arg);
454         if (rot >= 0) {
455             tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0,
456                             rotl(arg, rot) | (rot << 7));
457             return;
458         }
459         rot = encode_imm(~arg);
460         if (rot >= 0) {
461             tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0,
462                             rotl(~arg, rot) | (rot << 7));
463             return;
464         }
465     }
466
467     /* Use movw + movt.  */
468     if (use_armv7_instructions) {
469         /* movw */
470         tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
471                   | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
472         if (arg & 0xffff0000) {
473             /* movt */
474             tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
475                       | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
476         }
477         return;
478     }
479
480     /* TODO: This is very suboptimal, we can easily have a constant
481        pool somewhere after all the instructions.  */
482     opc = ARITH_MOV;
483     rn = 0;
484     /* If we have lots of leading 1's, we can shorten the sequence by
485        beginning with mvn and then clearing higher bits with eor.  */
486     if (clz32(~arg) > clz32(arg)) {
487         opc = ARITH_MVN, arg = ~arg;
488     }
489     do {
490         int i = ctz32(arg) & ~1;
491         rot = ((32 - i) << 7) & 0xf00;
492         tcg_out_dat_imm(s, cond, opc, rd, rn, ((arg >> i) & 0xff) | rot);
493         arg &= ~(0xff << i);
494
495         opc = ARITH_EOR;
496         rn = rd;
497     } while (arg);
498 }
499
500 static inline void tcg_out_dat_rI(TCGContext *s, int cond, int opc, TCGArg dst,
501                                   TCGArg lhs, TCGArg rhs, int rhs_is_const)
502 {
503     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
504      * rhs must satisfy the "rI" constraint.
505      */
506     if (rhs_is_const) {
507         int rot = encode_imm(rhs);
508         assert(rot >= 0);
509         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
510     } else {
511         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
512     }
513 }
514
515 static void tcg_out_dat_rIK(TCGContext *s, int cond, int opc, int opinv,
516                             TCGReg dst, TCGReg lhs, TCGArg rhs,
517                             bool rhs_is_const)
518 {
519     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
520      * rhs must satisfy the "rIK" constraint.
521      */
522     if (rhs_is_const) {
523         int rot = encode_imm(rhs);
524         if (rot < 0) {
525             rhs = ~rhs;
526             rot = encode_imm(rhs);
527             assert(rot >= 0);
528             opc = opinv;
529         }
530         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
531     } else {
532         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
533     }
534 }
535
536 static void tcg_out_dat_rIN(TCGContext *s, int cond, int opc, int opneg,
537                             TCGArg dst, TCGArg lhs, TCGArg rhs,
538                             bool rhs_is_const)
539 {
540     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
541      * rhs must satisfy the "rIN" constraint.
542      */
543     if (rhs_is_const) {
544         int rot = encode_imm(rhs);
545         if (rot < 0) {
546             rhs = -rhs;
547             rot = encode_imm(rhs);
548             assert(rot >= 0);
549             opc = opneg;
550         }
551         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
552     } else {
553         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
554     }
555 }
556
557 static inline void tcg_out_mul32(TCGContext *s, int cond, TCGReg rd,
558                                  TCGReg rn, TCGReg rm)
559 {
560     /* if ArchVersion() < 6 && d == n then UNPREDICTABLE;  */
561     if (!use_armv6_instructions && rd == rn) {
562         if (rd == rm) {
563             /* rd == rn == rm; copy an input to tmp first.  */
564             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
565             rm = rn = TCG_REG_TMP;
566         } else {
567             rn = rm;
568             rm = rd;
569         }
570     }
571     /* mul */
572     tcg_out32(s, (cond << 28) | 0x90 | (rd << 16) | (rm << 8) | rn);
573 }
574
575 static inline void tcg_out_umull32(TCGContext *s, int cond, TCGReg rd0,
576                                    TCGReg rd1, TCGReg rn, TCGReg rm)
577 {
578     /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
579     if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
580         if (rd0 == rm || rd1 == rm) {
581             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
582             rn = TCG_REG_TMP;
583         } else {
584             TCGReg t = rn;
585             rn = rm;
586             rm = t;
587         }
588     }
589     /* umull */
590     tcg_out32(s, (cond << 28) | 0x00800090 |
591               (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
592 }
593
594 static inline void tcg_out_smull32(TCGContext *s, int cond, TCGReg rd0,
595                                    TCGReg rd1, TCGReg rn, TCGReg rm)
596 {
597     /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
598     if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
599         if (rd0 == rm || rd1 == rm) {
600             tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
601             rn = TCG_REG_TMP;
602         } else {
603             TCGReg t = rn;
604             rn = rm;
605             rm = t;
606         }
607     }
608     /* smull */
609     tcg_out32(s, (cond << 28) | 0x00c00090 |
610               (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
611 }
612
613 static inline void tcg_out_sdiv(TCGContext *s, int cond, int rd, int rn, int rm)
614 {
615     tcg_out32(s, 0x0710f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
616 }
617
618 static inline void tcg_out_udiv(TCGContext *s, int cond, int rd, int rn, int rm)
619 {
620     tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
621 }
622
623 static inline void tcg_out_ext8s(TCGContext *s, int cond,
624                                  int rd, int rn)
625 {
626     if (use_armv6_instructions) {
627         /* sxtb */
628         tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
629     } else {
630         tcg_out_dat_reg(s, cond, ARITH_MOV,
631                         rd, 0, rn, SHIFT_IMM_LSL(24));
632         tcg_out_dat_reg(s, cond, ARITH_MOV,
633                         rd, 0, rd, SHIFT_IMM_ASR(24));
634     }
635 }
636
637 static inline void tcg_out_ext8u(TCGContext *s, int cond,
638                                  int rd, int rn)
639 {
640     tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
641 }
642
643 static inline void tcg_out_ext16s(TCGContext *s, int cond,
644                                   int rd, int rn)
645 {
646     if (use_armv6_instructions) {
647         /* sxth */
648         tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
649     } else {
650         tcg_out_dat_reg(s, cond, ARITH_MOV,
651                         rd, 0, rn, SHIFT_IMM_LSL(16));
652         tcg_out_dat_reg(s, cond, ARITH_MOV,
653                         rd, 0, rd, SHIFT_IMM_ASR(16));
654     }
655 }
656
657 static inline void tcg_out_ext16u(TCGContext *s, int cond,
658                                   int rd, int rn)
659 {
660     if (use_armv6_instructions) {
661         /* uxth */
662         tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
663     } else {
664         tcg_out_dat_reg(s, cond, ARITH_MOV,
665                         rd, 0, rn, SHIFT_IMM_LSL(16));
666         tcg_out_dat_reg(s, cond, ARITH_MOV,
667                         rd, 0, rd, SHIFT_IMM_LSR(16));
668     }
669 }
670
671 static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
672 {
673     if (use_armv6_instructions) {
674         /* revsh */
675         tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
676     } else {
677         tcg_out_dat_reg(s, cond, ARITH_MOV,
678                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
679         tcg_out_dat_reg(s, cond, ARITH_MOV,
680                         TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_ASR(16));
681         tcg_out_dat_reg(s, cond, ARITH_ORR,
682                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
683     }
684 }
685
686 static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
687 {
688     if (use_armv6_instructions) {
689         /* rev16 */
690         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
691     } else {
692         tcg_out_dat_reg(s, cond, ARITH_MOV,
693                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
694         tcg_out_dat_reg(s, cond, ARITH_MOV,
695                         TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_LSR(16));
696         tcg_out_dat_reg(s, cond, ARITH_ORR,
697                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
698     }
699 }
700
701 /* swap the two low bytes assuming that the two high input bytes and the
702    two high output bit can hold any value. */
703 static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn)
704 {
705     if (use_armv6_instructions) {
706         /* rev16 */
707         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
708     } else {
709         tcg_out_dat_reg(s, cond, ARITH_MOV,
710                         TCG_REG_TMP, 0, rn, SHIFT_IMM_LSR(8));
711         tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_TMP, TCG_REG_TMP, 0xff);
712         tcg_out_dat_reg(s, cond, ARITH_ORR,
713                         rd, TCG_REG_TMP, rn, SHIFT_IMM_LSL(8));
714     }
715 }
716
717 static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
718 {
719     if (use_armv6_instructions) {
720         /* rev */
721         tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
722     } else {
723         tcg_out_dat_reg(s, cond, ARITH_EOR,
724                         TCG_REG_TMP, rn, rn, SHIFT_IMM_ROR(16));
725         tcg_out_dat_imm(s, cond, ARITH_BIC,
726                         TCG_REG_TMP, TCG_REG_TMP, 0xff | 0x800);
727         tcg_out_dat_reg(s, cond, ARITH_MOV,
728                         rd, 0, rn, SHIFT_IMM_ROR(8));
729         tcg_out_dat_reg(s, cond, ARITH_EOR,
730                         rd, rd, TCG_REG_TMP, SHIFT_IMM_LSR(8));
731     }
732 }
733
734 bool tcg_target_deposit_valid(int ofs, int len)
735 {
736     /* ??? Without bfi, we could improve over generic code by combining
737        the right-shift from a non-zero ofs with the orr.  We do run into
738        problems when rd == rs, and the mask generated from ofs+len doesn't
739        fit into an immediate.  We would have to be careful not to pessimize
740        wrt the optimizations performed on the expanded code.  */
741     return use_armv7_instructions;
742 }
743
744 static inline void tcg_out_deposit(TCGContext *s, int cond, TCGReg rd,
745                                    TCGArg a1, int ofs, int len, bool const_a1)
746 {
747     if (const_a1) {
748         /* bfi becomes bfc with rn == 15.  */
749         a1 = 15;
750     }
751     /* bfi/bfc */
752     tcg_out32(s, 0x07c00010 | (cond << 28) | (rd << 12) | a1
753               | (ofs << 7) | ((ofs + len - 1) << 16));
754 }
755
756 /* Note that this routine is used for both LDR and LDRH formats, so we do
757    not wish to include an immediate shift at this point.  */
758 static void tcg_out_memop_r(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
759                             TCGReg rn, TCGReg rm, bool u, bool p, bool w)
760 {
761     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24)
762               | (w << 21) | (rn << 16) | (rt << 12) | rm);
763 }
764
765 static void tcg_out_memop_8(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
766                             TCGReg rn, int imm8, bool p, bool w)
767 {
768     bool u = 1;
769     if (imm8 < 0) {
770         imm8 = -imm8;
771         u = 0;
772     }
773     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
774               (rn << 16) | (rt << 12) | ((imm8 & 0xf0) << 4) | (imm8 & 0xf));
775 }
776
777 static void tcg_out_memop_12(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
778                              TCGReg rn, int imm12, bool p, bool w)
779 {
780     bool u = 1;
781     if (imm12 < 0) {
782         imm12 = -imm12;
783         u = 0;
784     }
785     tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
786               (rn << 16) | (rt << 12) | imm12);
787 }
788
789 static inline void tcg_out_ld32_12(TCGContext *s, int cond, TCGReg rt,
790                                    TCGReg rn, int imm12)
791 {
792     tcg_out_memop_12(s, cond, INSN_LDR_IMM, rt, rn, imm12, 1, 0);
793 }
794
795 static inline void tcg_out_st32_12(TCGContext *s, int cond, TCGReg rt,
796                                    TCGReg rn, int imm12)
797 {
798     tcg_out_memop_12(s, cond, INSN_STR_IMM, rt, rn, imm12, 1, 0);
799 }
800
801 static inline void tcg_out_ld32_r(TCGContext *s, int cond, TCGReg rt,
802                                   TCGReg rn, TCGReg rm)
803 {
804     tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 0);
805 }
806
807 static inline void tcg_out_st32_r(TCGContext *s, int cond, TCGReg rt,
808                                   TCGReg rn, TCGReg rm)
809 {
810     tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 0);
811 }
812
813 static inline void tcg_out_ldrd_8(TCGContext *s, int cond, TCGReg rt,
814                                    TCGReg rn, int imm8)
815 {
816     tcg_out_memop_8(s, cond, INSN_LDRD_IMM, rt, rn, imm8, 1, 0);
817 }
818
819 static inline void tcg_out_ldrd_r(TCGContext *s, int cond, TCGReg rt,
820                                   TCGReg rn, TCGReg rm)
821 {
822     tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
823 }
824
825 static inline void tcg_out_strd_8(TCGContext *s, int cond, TCGReg rt,
826                                    TCGReg rn, int imm8)
827 {
828     tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
829 }
830
831 static inline void tcg_out_strd_r(TCGContext *s, int cond, TCGReg rt,
832                                   TCGReg rn, TCGReg rm)
833 {
834     tcg_out_memop_r(s, cond, INSN_STRD_REG, rt, rn, rm, 1, 1, 0);
835 }
836
837 /* Register pre-increment with base writeback.  */
838 static inline void tcg_out_ld32_rwb(TCGContext *s, int cond, TCGReg rt,
839                                     TCGReg rn, TCGReg rm)
840 {
841     tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 1);
842 }
843
844 static inline void tcg_out_st32_rwb(TCGContext *s, int cond, TCGReg rt,
845                                     TCGReg rn, TCGReg rm)
846 {
847     tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 1);
848 }
849
850 static inline void tcg_out_ld16u_8(TCGContext *s, int cond, TCGReg rt,
851                                    TCGReg rn, int imm8)
852 {
853     tcg_out_memop_8(s, cond, INSN_LDRH_IMM, rt, rn, imm8, 1, 0);
854 }
855
856 static inline void tcg_out_st16_8(TCGContext *s, int cond, TCGReg rt,
857                                   TCGReg rn, int imm8)
858 {
859     tcg_out_memop_8(s, cond, INSN_STRH_IMM, rt, rn, imm8, 1, 0);
860 }
861
862 static inline void tcg_out_ld16u_r(TCGContext *s, int cond, TCGReg rt,
863                                    TCGReg rn, TCGReg rm)
864 {
865     tcg_out_memop_r(s, cond, INSN_LDRH_REG, rt, rn, rm, 1, 1, 0);
866 }
867
868 static inline void tcg_out_st16_r(TCGContext *s, int cond, TCGReg rt,
869                                   TCGReg rn, TCGReg rm)
870 {
871     tcg_out_memop_r(s, cond, INSN_STRH_REG, rt, rn, rm, 1, 1, 0);
872 }
873
874 static inline void tcg_out_ld16s_8(TCGContext *s, int cond, TCGReg rt,
875                                    TCGReg rn, int imm8)
876 {
877     tcg_out_memop_8(s, cond, INSN_LDRSH_IMM, rt, rn, imm8, 1, 0);
878 }
879
880 static inline void tcg_out_ld16s_r(TCGContext *s, int cond, TCGReg rt,
881                                    TCGReg rn, TCGReg rm)
882 {
883     tcg_out_memop_r(s, cond, INSN_LDRSH_REG, rt, rn, rm, 1, 1, 0);
884 }
885
886 static inline void tcg_out_ld8_12(TCGContext *s, int cond, TCGReg rt,
887                                   TCGReg rn, int imm12)
888 {
889     tcg_out_memop_12(s, cond, INSN_LDRB_IMM, rt, rn, imm12, 1, 0);
890 }
891
892 static inline void tcg_out_st8_12(TCGContext *s, int cond, TCGReg rt,
893                                   TCGReg rn, int imm12)
894 {
895     tcg_out_memop_12(s, cond, INSN_STRB_IMM, rt, rn, imm12, 1, 0);
896 }
897
898 static inline void tcg_out_ld8_r(TCGContext *s, int cond, TCGReg rt,
899                                  TCGReg rn, TCGReg rm)
900 {
901     tcg_out_memop_r(s, cond, INSN_LDRB_REG, rt, rn, rm, 1, 1, 0);
902 }
903
904 static inline void tcg_out_st8_r(TCGContext *s, int cond, TCGReg rt,
905                                  TCGReg rn, TCGReg rm)
906 {
907     tcg_out_memop_r(s, cond, INSN_STRB_REG, rt, rn, rm, 1, 1, 0);
908 }
909
910 static inline void tcg_out_ld8s_8(TCGContext *s, int cond, TCGReg rt,
911                                   TCGReg rn, int imm8)
912 {
913     tcg_out_memop_8(s, cond, INSN_LDRSB_IMM, rt, rn, imm8, 1, 0);
914 }
915
916 static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
917                                   TCGReg rn, TCGReg rm)
918 {
919     tcg_out_memop_r(s, cond, INSN_LDRSB_REG, rt, rn, rm, 1, 1, 0);
920 }
921
922 static inline void tcg_out_ld32u(TCGContext *s, int cond,
923                 int rd, int rn, int32_t offset)
924 {
925     if (offset > 0xfff || offset < -0xfff) {
926         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
927         tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_TMP);
928     } else
929         tcg_out_ld32_12(s, cond, rd, rn, offset);
930 }
931
932 static inline void tcg_out_st32(TCGContext *s, int cond,
933                 int rd, int rn, int32_t offset)
934 {
935     if (offset > 0xfff || offset < -0xfff) {
936         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
937         tcg_out_st32_r(s, cond, rd, rn, TCG_REG_TMP);
938     } else
939         tcg_out_st32_12(s, cond, rd, rn, offset);
940 }
941
942 static inline void tcg_out_ld16u(TCGContext *s, int cond,
943                 int rd, int rn, int32_t offset)
944 {
945     if (offset > 0xff || offset < -0xff) {
946         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
947         tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_TMP);
948     } else
949         tcg_out_ld16u_8(s, cond, rd, rn, offset);
950 }
951
952 static inline void tcg_out_ld16s(TCGContext *s, int cond,
953                 int rd, int rn, int32_t offset)
954 {
955     if (offset > 0xff || offset < -0xff) {
956         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
957         tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_TMP);
958     } else
959         tcg_out_ld16s_8(s, cond, rd, rn, offset);
960 }
961
962 static inline void tcg_out_st16(TCGContext *s, int cond,
963                 int rd, int rn, int32_t offset)
964 {
965     if (offset > 0xff || offset < -0xff) {
966         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
967         tcg_out_st16_r(s, cond, rd, rn, TCG_REG_TMP);
968     } else
969         tcg_out_st16_8(s, cond, rd, rn, offset);
970 }
971
972 static inline void tcg_out_ld8u(TCGContext *s, int cond,
973                 int rd, int rn, int32_t offset)
974 {
975     if (offset > 0xfff || offset < -0xfff) {
976         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
977         tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_TMP);
978     } else
979         tcg_out_ld8_12(s, cond, rd, rn, offset);
980 }
981
982 static inline void tcg_out_ld8s(TCGContext *s, int cond,
983                 int rd, int rn, int32_t offset)
984 {
985     if (offset > 0xff || offset < -0xff) {
986         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
987         tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_TMP);
988     } else
989         tcg_out_ld8s_8(s, cond, rd, rn, offset);
990 }
991
992 static inline void tcg_out_st8(TCGContext *s, int cond,
993                 int rd, int rn, int32_t offset)
994 {
995     if (offset > 0xfff || offset < -0xfff) {
996         tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
997         tcg_out_st8_r(s, cond, rd, rn, TCG_REG_TMP);
998     } else
999         tcg_out_st8_12(s, cond, rd, rn, offset);
1000 }
1001
1002 /* The _goto case is normally between TBs within the same code buffer, and
1003  * with the code buffer limited to 16MB we wouldn't need the long case.
1004  * But we also use it for the tail-call to the qemu_ld/st helpers, which does.
1005  */
1006 static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
1007 {
1008     int32_t disp = addr - (tcg_target_long) s->code_ptr;
1009
1010     if ((addr & 1) == 0 && disp - 8 < 0x01fffffd && disp - 8 > -0x01fffffd) {
1011         tcg_out_b(s, cond, disp);
1012         return;
1013     }
1014
1015     tcg_out_movi32(s, cond, TCG_REG_TMP, addr);
1016     if (use_armv5t_instructions) {
1017         tcg_out_bx(s, cond, TCG_REG_TMP);
1018     } else {
1019         if (addr & 1) {
1020             tcg_abort();
1021         }
1022         tcg_out_mov_reg(s, cond, TCG_REG_PC, TCG_REG_TMP);
1023     }
1024 }
1025
1026 /* The call case is mostly used for helpers - so it's not unreasonable
1027  * for them to be beyond branch range */
1028 static inline void tcg_out_call(TCGContext *s, uint32_t addr)
1029 {
1030     int32_t val;
1031
1032     val = addr - (tcg_target_long) s->code_ptr;
1033     if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
1034         if (addr & 1) {
1035             /* Use BLX if the target is in Thumb mode */
1036             if (!use_armv5t_instructions) {
1037                 tcg_abort();
1038             }
1039             tcg_out_blx_imm(s, val);
1040         } else {
1041             tcg_out_bl(s, COND_AL, val);
1042         }
1043     } else if (use_armv7_instructions) {
1044         tcg_out_movi32(s, COND_AL, TCG_REG_TMP, addr);
1045         tcg_out_blx(s, COND_AL, TCG_REG_TMP);
1046     } else {
1047         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
1048         tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1049         tcg_out32(s, addr);
1050     }
1051 }
1052
1053 static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
1054 {
1055     if (use_armv5t_instructions) {
1056         tcg_out_blx(s, cond, arg);
1057     } else {
1058         tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
1059                         TCG_REG_PC, SHIFT_IMM_LSL(0));
1060         tcg_out_bx(s, cond, arg);
1061     }
1062 }
1063
1064 static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
1065 {
1066     TCGLabel *l = &s->labels[label_index];
1067
1068     if (l->has_value) {
1069         tcg_out_goto(s, cond, l->u.value);
1070     } else {
1071         tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
1072         tcg_out_b_noaddr(s, cond);
1073     }
1074 }
1075
1076 #ifdef CONFIG_SOFTMMU
1077 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
1078  *                                     int mmu_idx, uintptr_t ra)
1079  */
1080 static const void * const qemu_ld_helpers[8] = {
1081     helper_ret_ldub_mmu,
1082     helper_ret_lduw_mmu,
1083     helper_ret_ldul_mmu,
1084     helper_ret_ldq_mmu,
1085
1086     helper_ret_ldsb_mmu,
1087     helper_ret_ldsw_mmu,
1088     helper_ret_ldul_mmu,
1089     helper_ret_ldq_mmu,
1090 };
1091
1092 /* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
1093  *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
1094  */
1095 static const void * const qemu_st_helpers[4] = {
1096     helper_ret_stb_mmu,
1097     helper_ret_stw_mmu,
1098     helper_ret_stl_mmu,
1099     helper_ret_stq_mmu,
1100 };
1101
1102 /* Helper routines for marshalling helper function arguments into
1103  * the correct registers and stack.
1104  * argreg is where we want to put this argument, arg is the argument itself.
1105  * Return value is the updated argreg ready for the next call.
1106  * Note that argreg 0..3 is real registers, 4+ on stack.
1107  *
1108  * We provide routines for arguments which are: immediate, 32 bit
1109  * value in register, 16 and 8 bit values in register (which must be zero
1110  * extended before use) and 64 bit value in a lo:hi register pair.
1111  */
1112 #define DEFINE_TCG_OUT_ARG(NAME, ARGTYPE, MOV_ARG, EXT_ARG)                \
1113 static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg)              \
1114 {                                                                          \
1115     if (argreg < 4) {                                                      \
1116         MOV_ARG(s, COND_AL, argreg, arg);                                  \
1117     } else {                                                               \
1118         int ofs = (argreg - 4) * 4;                                        \
1119         EXT_ARG;                                                           \
1120         assert(ofs + 4 <= TCG_STATIC_CALL_ARGS_SIZE);                      \
1121         tcg_out_st32_12(s, COND_AL, arg, TCG_REG_CALL_STACK, ofs);         \
1122     }                                                                      \
1123     return argreg + 1;                                                     \
1124 }
1125
1126 DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
1127     (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1128 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u,
1129     (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1130 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
1131     (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1132 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
1133
1134 static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
1135                                 TCGReg arglo, TCGReg arghi)
1136 {
1137     /* 64 bit arguments must go in even/odd register pairs
1138      * and in 8-aligned stack slots.
1139      */
1140     if (argreg & 1) {
1141         argreg++;
1142     }
1143     if (use_armv6_instructions && argreg >= 4
1144         && (arglo & 1) == 0 && arghi == arglo + 1) {
1145         tcg_out_strd_8(s, COND_AL, arglo,
1146                        TCG_REG_CALL_STACK, (argreg - 4) * 4);
1147         return argreg + 2;
1148     } else {
1149         argreg = tcg_out_arg_reg32(s, argreg, arglo);
1150         argreg = tcg_out_arg_reg32(s, argreg, arghi);
1151         return argreg;
1152     }
1153 }
1154
1155 #define TLB_SHIFT       (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
1156
1157 /* We're expecting to use an 8-bit immediate and to mask.  */
1158 QEMU_BUILD_BUG_ON(CPU_TLB_BITS > 8);
1159
1160 /* We're expecting to use an 8-bit immediate add + 8-bit ldrd offset.
1161    Using the offset of the second entry in the last tlb table ensures
1162    that we can index all of the elements of the first entry.  */
1163 QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
1164                   > 0xffff);
1165
1166 /* Load and compare a TLB entry, leaving the flags set.  Returns the register
1167    containing the addend of the tlb entry.  Clobbers R0, R1, R2, TMP.  */
1168
1169 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
1170                                int s_bits, int mem_index, bool is_load)
1171 {
1172     TCGReg base = TCG_AREG0;
1173     int cmp_off =
1174         (is_load
1175          ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1176          : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1177     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1178
1179     /* Should generate something like the following:
1180      *   shr    tmp, addr_reg, #TARGET_PAGE_BITS                  (1)
1181      *   add    r2, env, #high
1182      *   and    r0, tmp, #(CPU_TLB_SIZE - 1)                      (2)
1183      *   add    r2, r2, r0, lsl #CPU_TLB_ENTRY_BITS               (3)
1184      *   ldr    r0, [r2, #cmp]                                    (4)
1185      *   tst    addr_reg, #s_mask
1186      *   ldr    r1, [r2, #add]                                    (5)
1187      *   cmpeq  r0, tmp, lsl #TARGET_PAGE_BITS
1188      */
1189     tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,
1190                     0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1191
1192     /* We checked that the offset is contained within 16 bits above.  */
1193     if (add_off > 0xfff || (use_armv6_instructions && cmp_off > 0xff)) {
1194         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1195                         (24 << 7) | (cmp_off >> 8));
1196         base = TCG_REG_R2;
1197         add_off -= cmp_off & 0xff00;
1198         cmp_off &= 0xff;
1199     }
1200
1201     tcg_out_dat_imm(s, COND_AL, ARITH_AND,
1202                     TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);
1203     tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1204                     TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
1205
1206     /* Load the tlb comparator.  Use ldrd if needed and available,
1207        but due to how the pointer needs setting up, ldm isn't useful.
1208        Base arm5 doesn't have ldrd, but armv5te does.  */
1209     if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
1210         tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);
1211     } else {
1212         tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);
1213         if (TARGET_LONG_BITS == 64) {
1214             tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, cmp_off + 4);
1215         }
1216     }
1217
1218     /* Check alignment.  */
1219     if (s_bits) {
1220         tcg_out_dat_imm(s, COND_AL, ARITH_TST,
1221                         0, addrlo, (1 << s_bits) - 1);
1222     }
1223
1224     /* Load the tlb addend.  */
1225     tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, add_off);
1226
1227     tcg_out_dat_reg(s, (s_bits ? COND_EQ : COND_AL), ARITH_CMP, 0,
1228                     TCG_REG_R0, TCG_REG_TMP, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1229
1230     if (TARGET_LONG_BITS == 64) {
1231         tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1232                         TCG_REG_R1, addrhi, SHIFT_IMM_LSL(0));
1233     }
1234
1235     return TCG_REG_R2;
1236 }
1237
1238 /* Record the context of a call to the out of line helper code for the slow
1239    path for a load or store, so that we can later generate the correct
1240    helper code.  */
1241 static void add_qemu_ldst_label(TCGContext *s, int is_ld, int opc,
1242                                 int data_reg, int data_reg2, int addrlo_reg,
1243                                 int addrhi_reg, int mem_index,
1244                                 uint8_t *raddr, uint8_t *label_ptr)
1245 {
1246     int idx;
1247     TCGLabelQemuLdst *label;
1248
1249     if (s->nb_qemu_ldst_labels >= TCG_MAX_QEMU_LDST) {
1250         tcg_abort();
1251     }
1252
1253     idx = s->nb_qemu_ldst_labels++;
1254     label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[idx];
1255     label->is_ld = is_ld;
1256     label->opc = opc;
1257     label->datalo_reg = data_reg;
1258     label->datahi_reg = data_reg2;
1259     label->addrlo_reg = addrlo_reg;
1260     label->addrhi_reg = addrhi_reg;
1261     label->mem_index = mem_index;
1262     label->raddr = raddr;
1263     label->label_ptr[0] = label_ptr;
1264 }
1265
1266 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1267 {
1268     TCGReg argreg, data_reg, data_reg2;
1269     int opc = lb->opc;
1270     uintptr_t func;
1271
1272     reloc_pc24(lb->label_ptr[0], (tcg_target_long)s->code_ptr);
1273
1274     argreg = tcg_out_arg_reg32(s, TCG_REG_R0, TCG_AREG0);
1275     if (TARGET_LONG_BITS == 64) {
1276         argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1277     } else {
1278         argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1279     }
1280     argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index);
1281     argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1282
1283     /* For armv6 we can use the canonical unsigned helpers and minimize
1284        icache usage.  For pre-armv6, use the signed helpers since we do
1285        not have a single insn sign-extend.  */
1286     if (use_armv6_instructions) {
1287         func = (uintptr_t)qemu_ld_helpers[opc & 3];
1288     } else {
1289         func = (uintptr_t)qemu_ld_helpers[opc];
1290         if (opc & 4) {
1291             opc = 2;
1292         }
1293     }
1294     tcg_out_call(s, func);
1295
1296     data_reg = lb->datalo_reg;
1297     data_reg2 = lb->datahi_reg;
1298     switch (opc) {
1299     case 0 | 4:
1300         tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
1301         break;
1302     case 1 | 4:
1303         tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
1304         break;
1305     default:
1306         tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1307         break;
1308     case 3:
1309         if (data_reg != TCG_REG_R1) {
1310             tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1311             tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1312         } else if (data_reg2 != TCG_REG_R0) {
1313             tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1314             tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1315         } else {
1316             tcg_out_mov_reg(s, COND_AL, TCG_REG_TMP, TCG_REG_R0);
1317             tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1318             tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_TMP);
1319         }
1320         break;
1321     }
1322
1323     tcg_out_goto(s, COND_AL, (tcg_target_long)lb->raddr);
1324 }
1325
1326 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1327 {
1328     TCGReg argreg, data_reg, data_reg2;
1329
1330     reloc_pc24(lb->label_ptr[0], (tcg_target_long)s->code_ptr);
1331
1332     argreg = TCG_REG_R0;
1333     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1334     if (TARGET_LONG_BITS == 64) {
1335         argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1336     } else {
1337         argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1338     }
1339
1340     data_reg = lb->datalo_reg;
1341     data_reg2 = lb->datahi_reg;
1342     switch (lb->opc) {
1343     case 0:
1344         argreg = tcg_out_arg_reg8(s, argreg, data_reg);
1345         break;
1346     case 1:
1347         argreg = tcg_out_arg_reg16(s, argreg, data_reg);
1348         break;
1349     case 2:
1350         argreg = tcg_out_arg_reg32(s, argreg, data_reg);
1351         break;
1352     case 3:
1353         argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2);
1354         break;
1355     }
1356
1357     argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index);
1358     argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1359
1360     /* Tail-call to the helper, which will return to the fast path.  */
1361     tcg_out_goto(s, COND_AL, (tcg_target_long) qemu_st_helpers[lb->opc & 3]);
1362 }
1363 #endif /* SOFTMMU */
1364
1365 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
1366 {
1367     TCGReg addr_reg, data_reg, data_reg2;
1368     bool bswap;
1369 #ifdef CONFIG_SOFTMMU
1370     int mem_index, s_bits;
1371     TCGReg addr_reg2, addend;
1372     uint8_t *label_ptr;
1373 #endif
1374 #ifdef TARGET_WORDS_BIGENDIAN
1375     bswap = 1;
1376 #else
1377     bswap = 0;
1378 #endif
1379
1380     data_reg = *args++;
1381     data_reg2 = (opc == 3 ? *args++ : 0);
1382     addr_reg = *args++;
1383 #ifdef CONFIG_SOFTMMU
1384     addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1385     mem_index = *args;
1386     s_bits = opc & 3;
1387
1388     addend = tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits, mem_index, 1);
1389
1390     /* This a conditional BL only to load a pointer within this opcode into LR
1391        for the slow path.  We will not be using the value for a tail call.  */
1392     label_ptr = s->code_ptr;
1393     tcg_out_bl_noaddr(s, COND_NE);
1394
1395     switch (opc) {
1396     case 0:
1397         tcg_out_ld8_r(s, COND_AL, data_reg, addr_reg, addend);
1398         break;
1399     case 0 | 4:
1400         tcg_out_ld8s_r(s, COND_AL, data_reg, addr_reg, addend);
1401         break;
1402     case 1:
1403         tcg_out_ld16u_r(s, COND_AL, data_reg, addr_reg, addend);
1404         if (bswap) {
1405             tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1406         }
1407         break;
1408     case 1 | 4:
1409         if (bswap) {
1410             tcg_out_ld16u_r(s, COND_AL, data_reg, addr_reg, addend);
1411             tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1412         } else {
1413             tcg_out_ld16s_r(s, COND_AL, data_reg, addr_reg, addend);
1414         }
1415         break;
1416     case 2:
1417     default:
1418         tcg_out_ld32_r(s, COND_AL, data_reg, addr_reg, addend);
1419         if (bswap) {
1420             tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1421         }
1422         break;
1423     case 3:
1424         {
1425             /* Be careful not to modify data_reg and data_reg2
1426                for the slow path below.  */
1427             TCGReg dl = (bswap ? data_reg2 : data_reg);
1428             TCGReg dh = (bswap ? data_reg : data_reg2);
1429
1430             if (use_armv6_instructions && (dl & 1) == 0 && dh == dl + 1) {
1431                 tcg_out_ldrd_r(s, COND_AL, dl, addr_reg, addend);
1432             } else if (dl != addend) {
1433                 tcg_out_ld32_rwb(s, COND_AL, dl, addend, addr_reg);
1434                 tcg_out_ld32_12(s, COND_AL, dh, addend, 4);
1435             } else {
1436                 tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_TMP,
1437                                 addend, addr_reg, SHIFT_IMM_LSL(0));
1438                 tcg_out_ld32_12(s, COND_AL, dl, TCG_REG_TMP, 0);
1439                 tcg_out_ld32_12(s, COND_AL, dh, TCG_REG_TMP, 4);
1440             }
1441             if (bswap) {
1442                 tcg_out_bswap32(s, COND_AL, dh, dh);
1443                 tcg_out_bswap32(s, COND_AL, dl, dl);
1444             }
1445         }
1446         break;
1447     }
1448
1449     add_qemu_ldst_label(s, 1, opc, data_reg, data_reg2, addr_reg, addr_reg2,
1450                         mem_index, s->code_ptr, label_ptr);
1451 #else /* !CONFIG_SOFTMMU */
1452     if (GUEST_BASE) {
1453         uint32_t offset = GUEST_BASE;
1454         int i, rot;
1455
1456         while (offset) {
1457             i = ctz32(offset) & ~1;
1458             rot = ((32 - i) << 7) & 0xf00;
1459
1460             tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_TMP, addr_reg,
1461                             ((offset >> i) & 0xff) | rot);
1462             addr_reg = TCG_REG_TMP;
1463             offset &= ~(0xff << i);
1464         }
1465     }
1466     switch (opc) {
1467     case 0:
1468         tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
1469         break;
1470     case 0 | 4:
1471         tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
1472         break;
1473     case 1:
1474         tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1475         if (bswap) {
1476             tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1477         }
1478         break;
1479     case 1 | 4:
1480         if (bswap) {
1481             tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1482             tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1483         } else {
1484             tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
1485         }
1486         break;
1487     case 2:
1488     default:
1489         tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
1490         if (bswap) {
1491             tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1492         }
1493         break;
1494     case 3:
1495         if (use_armv6_instructions && !bswap
1496             && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1497             tcg_out_ldrd_8(s, COND_AL, data_reg, addr_reg, 0);
1498         } else if (use_armv6_instructions && bswap
1499                    && (data_reg2 & 1) == 0 && data_reg == data_reg2 + 1) {
1500             tcg_out_ldrd_8(s, COND_AL, data_reg2, addr_reg, 0);
1501         } else if (data_reg == addr_reg) {
1502             tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1503             tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1504         } else {
1505             tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1506             tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1507         }
1508         if (bswap) {
1509             tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1510             tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
1511         }
1512         break;
1513     }
1514 #endif
1515 }
1516
1517 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1518 {
1519     TCGReg addr_reg, data_reg, data_reg2;
1520     bool bswap;
1521 #ifdef CONFIG_SOFTMMU
1522     int mem_index, s_bits;
1523     TCGReg addr_reg2, addend;
1524     uint8_t *label_ptr;
1525 #endif
1526 #ifdef TARGET_WORDS_BIGENDIAN
1527     bswap = 1;
1528 #else
1529     bswap = 0;
1530 #endif
1531
1532     data_reg = *args++;
1533     data_reg2 = (opc == 3 ? *args++ : 0);
1534     addr_reg = *args++;
1535 #ifdef CONFIG_SOFTMMU
1536     addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1537     mem_index = *args;
1538     s_bits = opc & 3;
1539
1540     addend = tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits, mem_index, 0);
1541
1542     switch (opc) {
1543     case 0:
1544         tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, addend);
1545         break;
1546     case 1:
1547         if (bswap) {
1548             tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg);
1549             tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, addend);
1550         } else {
1551             tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, addend);
1552         }
1553         break;
1554     case 2:
1555     default:
1556         if (bswap) {
1557             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1558             tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, addend);
1559         } else {
1560             tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, addend);
1561         }
1562         break;
1563     case 3:
1564         if (bswap) {
1565             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
1566             tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, addend, addr_reg);
1567             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1568             tcg_out_st32_12(s, COND_EQ, TCG_REG_R0, addend, 4);
1569         } else if (use_armv6_instructions
1570                    && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1571             tcg_out_strd_r(s, COND_EQ, data_reg, addr_reg, addend);
1572         } else {
1573             tcg_out_st32_rwb(s, COND_EQ, data_reg, addend, addr_reg);
1574             tcg_out_st32_12(s, COND_EQ, data_reg2, addend, 4);
1575         }
1576         break;
1577     }
1578
1579     /* The conditional call must come last, as we're going to return here.  */
1580     label_ptr = s->code_ptr;
1581     tcg_out_bl_noaddr(s, COND_NE);
1582
1583     add_qemu_ldst_label(s, 0, opc, data_reg, data_reg2, addr_reg, addr_reg2,
1584                         mem_index, s->code_ptr, label_ptr);
1585 #else /* !CONFIG_SOFTMMU */
1586     if (GUEST_BASE) {
1587         uint32_t offset = GUEST_BASE;
1588         int i;
1589         int rot;
1590
1591         while (offset) {
1592             i = ctz32(offset) & ~1;
1593             rot = ((32 - i) << 7) & 0xf00;
1594
1595             tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R1, addr_reg,
1596                             ((offset >> i) & 0xff) | rot);
1597             addr_reg = TCG_REG_R1;
1598             offset &= ~(0xff << i);
1599         }
1600     }
1601     switch (opc) {
1602     case 0:
1603         tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
1604         break;
1605     case 1:
1606         if (bswap) {
1607             tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg);
1608             tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1609         } else {
1610             tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
1611         }
1612         break;
1613     case 2:
1614     default:
1615         if (bswap) {
1616             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1617             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1618         } else {
1619             tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1620         }
1621         break;
1622     case 3:
1623         if (bswap) {
1624             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
1625             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1626             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1627             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
1628         } else if (use_armv6_instructions
1629                    && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1630             tcg_out_strd_8(s, COND_AL, data_reg, addr_reg, 0);
1631         } else {
1632             tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1633             tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
1634         }
1635         break;
1636     }
1637 #endif
1638 }
1639
1640 static uint8_t *tb_ret_addr;
1641
1642 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1643                 const TCGArg *args, const int *const_args)
1644 {
1645     TCGArg a0, a1, a2, a3, a4, a5;
1646     int c;
1647
1648     switch (opc) {
1649     case INDEX_op_exit_tb:
1650         if (use_armv7_instructions || check_fit_imm(args[0])) {
1651             tcg_out_movi32(s, COND_AL, TCG_REG_R0, args[0]);
1652             tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1653         } else {
1654             uint8_t *ld_ptr = s->code_ptr;
1655             tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1656             tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1657             *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
1658             tcg_out32(s, args[0]);
1659         }
1660         break;
1661     case INDEX_op_goto_tb:
1662         if (s->tb_jmp_offset) {
1663             /* Direct jump method */
1664 #if defined(USE_DIRECT_JUMP)
1665             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1666             tcg_out_b_noaddr(s, COND_AL);
1667 #else
1668             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1669             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1670             tcg_out32(s, 0);
1671 #endif
1672         } else {
1673             /* Indirect jump method */
1674 #if 1
1675             c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
1676             if (c > 0xfff || c < -0xfff) {
1677                 tcg_out_movi32(s, COND_AL, TCG_REG_R0,
1678                                 (tcg_target_long) (s->tb_next + args[0]));
1679                 tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1680             } else
1681                 tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
1682 #else
1683             tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1684             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1685             tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
1686 #endif
1687         }
1688         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1689         break;
1690     case INDEX_op_call:
1691         if (const_args[0])
1692             tcg_out_call(s, args[0]);
1693         else
1694             tcg_out_callr(s, COND_AL, args[0]);
1695         break;
1696     case INDEX_op_br:
1697         tcg_out_goto_label(s, COND_AL, args[0]);
1698         break;
1699
1700     case INDEX_op_ld8u_i32:
1701         tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
1702         break;
1703     case INDEX_op_ld8s_i32:
1704         tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
1705         break;
1706     case INDEX_op_ld16u_i32:
1707         tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
1708         break;
1709     case INDEX_op_ld16s_i32:
1710         tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
1711         break;
1712     case INDEX_op_ld_i32:
1713         tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
1714         break;
1715     case INDEX_op_st8_i32:
1716         tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
1717         break;
1718     case INDEX_op_st16_i32:
1719         tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
1720         break;
1721     case INDEX_op_st_i32:
1722         tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
1723         break;
1724
1725     case INDEX_op_mov_i32:
1726         tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
1727                         args[0], 0, args[1], SHIFT_IMM_LSL(0));
1728         break;
1729     case INDEX_op_movi_i32:
1730         tcg_out_movi32(s, COND_AL, args[0], args[1]);
1731         break;
1732     case INDEX_op_movcond_i32:
1733         /* Constraints mean that v2 is always in the same register as dest,
1734          * so we only need to do "if condition passed, move v1 to dest".
1735          */
1736         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1737                         args[1], args[2], const_args[2]);
1738         tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
1739                         ARITH_MVN, args[0], 0, args[3], const_args[3]);
1740         break;
1741     case INDEX_op_add_i32:
1742         tcg_out_dat_rIN(s, COND_AL, ARITH_ADD, ARITH_SUB,
1743                         args[0], args[1], args[2], const_args[2]);
1744         break;
1745     case INDEX_op_sub_i32:
1746         if (const_args[1]) {
1747             if (const_args[2]) {
1748                 tcg_out_movi32(s, COND_AL, args[0], args[1] - args[2]);
1749             } else {
1750                 tcg_out_dat_rI(s, COND_AL, ARITH_RSB,
1751                                args[0], args[2], args[1], 1);
1752             }
1753         } else {
1754             tcg_out_dat_rIN(s, COND_AL, ARITH_SUB, ARITH_ADD,
1755                             args[0], args[1], args[2], const_args[2]);
1756         }
1757         break;
1758     case INDEX_op_and_i32:
1759         tcg_out_dat_rIK(s, COND_AL, ARITH_AND, ARITH_BIC,
1760                         args[0], args[1], args[2], const_args[2]);
1761         break;
1762     case INDEX_op_andc_i32:
1763         tcg_out_dat_rIK(s, COND_AL, ARITH_BIC, ARITH_AND,
1764                         args[0], args[1], args[2], const_args[2]);
1765         break;
1766     case INDEX_op_or_i32:
1767         c = ARITH_ORR;
1768         goto gen_arith;
1769     case INDEX_op_xor_i32:
1770         c = ARITH_EOR;
1771         /* Fall through.  */
1772     gen_arith:
1773         tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);
1774         break;
1775     case INDEX_op_add2_i32:
1776         a0 = args[0], a1 = args[1], a2 = args[2];
1777         a3 = args[3], a4 = args[4], a5 = args[5];
1778         if (a0 == a3 || (a0 == a5 && !const_args[5])) {
1779             a0 = TCG_REG_TMP;
1780         }
1781         tcg_out_dat_rIN(s, COND_AL, ARITH_ADD | TO_CPSR, ARITH_SUB | TO_CPSR,
1782                         a0, a2, a4, const_args[4]);
1783         tcg_out_dat_rIK(s, COND_AL, ARITH_ADC, ARITH_SBC,
1784                         a1, a3, a5, const_args[5]);
1785         tcg_out_mov_reg(s, COND_AL, args[0], a0);
1786         break;
1787     case INDEX_op_sub2_i32:
1788         a0 = args[0], a1 = args[1], a2 = args[2];
1789         a3 = args[3], a4 = args[4], a5 = args[5];
1790         if ((a0 == a3 && !const_args[3]) || (a0 == a5 && !const_args[5])) {
1791             a0 = TCG_REG_TMP;
1792         }
1793         if (const_args[2]) {
1794             if (const_args[4]) {
1795                 tcg_out_movi32(s, COND_AL, a0, a4);
1796                 a4 = a0;
1797             }
1798             tcg_out_dat_rI(s, COND_AL, ARITH_RSB | TO_CPSR, a0, a4, a2, 1);
1799         } else {
1800             tcg_out_dat_rIN(s, COND_AL, ARITH_SUB | TO_CPSR,
1801                             ARITH_ADD | TO_CPSR, a0, a2, a4, const_args[4]);
1802         }
1803         if (const_args[3]) {
1804             if (const_args[5]) {
1805                 tcg_out_movi32(s, COND_AL, a1, a5);
1806                 a5 = a1;
1807             }
1808             tcg_out_dat_rI(s, COND_AL, ARITH_RSC, a1, a5, a3, 1);
1809         } else {
1810             tcg_out_dat_rIK(s, COND_AL, ARITH_SBC, ARITH_ADC,
1811                             a1, a3, a5, const_args[5]);
1812         }
1813         tcg_out_mov_reg(s, COND_AL, args[0], a0);
1814         break;
1815     case INDEX_op_neg_i32:
1816         tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
1817         break;
1818     case INDEX_op_not_i32:
1819         tcg_out_dat_reg(s, COND_AL,
1820                         ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
1821         break;
1822     case INDEX_op_mul_i32:
1823         tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
1824         break;
1825     case INDEX_op_mulu2_i32:
1826         tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1827         break;
1828     case INDEX_op_muls2_i32:
1829         tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1830         break;
1831     /* XXX: Perhaps args[2] & 0x1f is wrong */
1832     case INDEX_op_shl_i32:
1833         c = const_args[2] ?
1834                 SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
1835         goto gen_shift32;
1836     case INDEX_op_shr_i32:
1837         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
1838                 SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
1839         goto gen_shift32;
1840     case INDEX_op_sar_i32:
1841         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
1842                 SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
1843         goto gen_shift32;
1844     case INDEX_op_rotr_i32:
1845         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
1846                 SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
1847         /* Fall through.  */
1848     gen_shift32:
1849         tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
1850         break;
1851
1852     case INDEX_op_rotl_i32:
1853         if (const_args[2]) {
1854             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1855                             ((0x20 - args[2]) & 0x1f) ?
1856                             SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
1857                             SHIFT_IMM_LSL(0));
1858         } else {
1859             tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[1], 0x20);
1860             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1861                             SHIFT_REG_ROR(TCG_REG_TMP));
1862         }
1863         break;
1864
1865     case INDEX_op_brcond_i32:
1866         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1867                        args[0], args[1], const_args[1]);
1868         tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
1869         break;
1870     case INDEX_op_brcond2_i32:
1871         /* The resulting conditions are:
1872          * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,
1873          * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,
1874          * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,
1875          * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
1876          * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
1877          * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,
1878          */
1879         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1880                         args[1], args[3], const_args[3]);
1881         tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1882                         args[0], args[2], const_args[2]);
1883         tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
1884         break;
1885     case INDEX_op_setcond_i32:
1886         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1887                         args[1], args[2], const_args[2]);
1888         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
1889                         ARITH_MOV, args[0], 0, 1);
1890         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
1891                         ARITH_MOV, args[0], 0, 0);
1892         break;
1893     case INDEX_op_setcond2_i32:
1894         /* See brcond2_i32 comment */
1895         tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1896                         args[2], args[4], const_args[4]);
1897         tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1898                         args[1], args[3], const_args[3]);
1899         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],
1900                         ARITH_MOV, args[0], 0, 1);
1901         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],
1902                         ARITH_MOV, args[0], 0, 0);
1903         break;
1904
1905     case INDEX_op_qemu_ld8u:
1906         tcg_out_qemu_ld(s, args, 0);
1907         break;
1908     case INDEX_op_qemu_ld8s:
1909         tcg_out_qemu_ld(s, args, 0 | 4);
1910         break;
1911     case INDEX_op_qemu_ld16u:
1912         tcg_out_qemu_ld(s, args, 1);
1913         break;
1914     case INDEX_op_qemu_ld16s:
1915         tcg_out_qemu_ld(s, args, 1 | 4);
1916         break;
1917     case INDEX_op_qemu_ld32:
1918         tcg_out_qemu_ld(s, args, 2);
1919         break;
1920     case INDEX_op_qemu_ld64:
1921         tcg_out_qemu_ld(s, args, 3);
1922         break;
1923
1924     case INDEX_op_qemu_st8:
1925         tcg_out_qemu_st(s, args, 0);
1926         break;
1927     case INDEX_op_qemu_st16:
1928         tcg_out_qemu_st(s, args, 1);
1929         break;
1930     case INDEX_op_qemu_st32:
1931         tcg_out_qemu_st(s, args, 2);
1932         break;
1933     case INDEX_op_qemu_st64:
1934         tcg_out_qemu_st(s, args, 3);
1935         break;
1936
1937     case INDEX_op_bswap16_i32:
1938         tcg_out_bswap16(s, COND_AL, args[0], args[1]);
1939         break;
1940     case INDEX_op_bswap32_i32:
1941         tcg_out_bswap32(s, COND_AL, args[0], args[1]);
1942         break;
1943
1944     case INDEX_op_ext8s_i32:
1945         tcg_out_ext8s(s, COND_AL, args[0], args[1]);
1946         break;
1947     case INDEX_op_ext16s_i32:
1948         tcg_out_ext16s(s, COND_AL, args[0], args[1]);
1949         break;
1950     case INDEX_op_ext16u_i32:
1951         tcg_out_ext16u(s, COND_AL, args[0], args[1]);
1952         break;
1953
1954     case INDEX_op_deposit_i32:
1955         tcg_out_deposit(s, COND_AL, args[0], args[2],
1956                         args[3], args[4], const_args[2]);
1957         break;
1958
1959     case INDEX_op_div_i32:
1960         tcg_out_sdiv(s, COND_AL, args[0], args[1], args[2]);
1961         break;
1962     case INDEX_op_divu_i32:
1963         tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
1964         break;
1965
1966     default:
1967         tcg_abort();
1968     }
1969 }
1970
1971 #ifdef CONFIG_SOFTMMU
1972 /* Generate TB finalization at the end of block.  */
1973 void tcg_out_tb_finalize(TCGContext *s)
1974 {
1975     int i;
1976     for (i = 0; i < s->nb_qemu_ldst_labels; i++) {
1977         TCGLabelQemuLdst *label = &s->qemu_ldst_labels[i];
1978         if (label->is_ld) {
1979             tcg_out_qemu_ld_slow_path(s, label);
1980         } else {
1981             tcg_out_qemu_st_slow_path(s, label);
1982         }
1983     }
1984 }
1985 #endif /* SOFTMMU */
1986
1987 static const TCGTargetOpDef arm_op_defs[] = {
1988     { INDEX_op_exit_tb, { } },
1989     { INDEX_op_goto_tb, { } },
1990     { INDEX_op_call, { "ri" } },
1991     { INDEX_op_br, { } },
1992
1993     { INDEX_op_mov_i32, { "r", "r" } },
1994     { INDEX_op_movi_i32, { "r" } },
1995
1996     { INDEX_op_ld8u_i32, { "r", "r" } },
1997     { INDEX_op_ld8s_i32, { "r", "r" } },
1998     { INDEX_op_ld16u_i32, { "r", "r" } },
1999     { INDEX_op_ld16s_i32, { "r", "r" } },
2000     { INDEX_op_ld_i32, { "r", "r" } },
2001     { INDEX_op_st8_i32, { "r", "r" } },
2002     { INDEX_op_st16_i32, { "r", "r" } },
2003     { INDEX_op_st_i32, { "r", "r" } },
2004
2005     /* TODO: "r", "r", "ri" */
2006     { INDEX_op_add_i32, { "r", "r", "rIN" } },
2007     { INDEX_op_sub_i32, { "r", "rI", "rIN" } },
2008     { INDEX_op_mul_i32, { "r", "r", "r" } },
2009     { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
2010     { INDEX_op_muls2_i32, { "r", "r", "r", "r" } },
2011     { INDEX_op_and_i32, { "r", "r", "rIK" } },
2012     { INDEX_op_andc_i32, { "r", "r", "rIK" } },
2013     { INDEX_op_or_i32, { "r", "r", "rI" } },
2014     { INDEX_op_xor_i32, { "r", "r", "rI" } },
2015     { INDEX_op_neg_i32, { "r", "r" } },
2016     { INDEX_op_not_i32, { "r", "r" } },
2017
2018     { INDEX_op_shl_i32, { "r", "r", "ri" } },
2019     { INDEX_op_shr_i32, { "r", "r", "ri" } },
2020     { INDEX_op_sar_i32, { "r", "r", "ri" } },
2021     { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2022     { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2023
2024     { INDEX_op_brcond_i32, { "r", "rIN" } },
2025     { INDEX_op_setcond_i32, { "r", "r", "rIN" } },
2026     { INDEX_op_movcond_i32, { "r", "r", "rIN", "rIK", "0" } },
2027
2028     { INDEX_op_add2_i32, { "r", "r", "r", "r", "rIN", "rIK" } },
2029     { INDEX_op_sub2_i32, { "r", "r", "rI", "rI", "rIN", "rIK" } },
2030     { INDEX_op_brcond2_i32, { "r", "r", "rIN", "rIN" } },
2031     { INDEX_op_setcond2_i32, { "r", "r", "r", "rIN", "rIN" } },
2032
2033 #if TARGET_LONG_BITS == 32
2034     { INDEX_op_qemu_ld8u, { "r", "l" } },
2035     { INDEX_op_qemu_ld8s, { "r", "l" } },
2036     { INDEX_op_qemu_ld16u, { "r", "l" } },
2037     { INDEX_op_qemu_ld16s, { "r", "l" } },
2038     { INDEX_op_qemu_ld32, { "r", "l" } },
2039     { INDEX_op_qemu_ld64, { "r", "r", "l" } },
2040
2041     { INDEX_op_qemu_st8, { "s", "s" } },
2042     { INDEX_op_qemu_st16, { "s", "s" } },
2043     { INDEX_op_qemu_st32, { "s", "s" } },
2044     { INDEX_op_qemu_st64, { "s", "s", "s" } },
2045 #else
2046     { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
2047     { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
2048     { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
2049     { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
2050     { INDEX_op_qemu_ld32, { "r", "l", "l" } },
2051     { INDEX_op_qemu_ld64, { "r", "r", "l", "l" } },
2052
2053     { INDEX_op_qemu_st8, { "s", "s", "s" } },
2054     { INDEX_op_qemu_st16, { "s", "s", "s" } },
2055     { INDEX_op_qemu_st32, { "s", "s", "s" } },
2056     { INDEX_op_qemu_st64, { "s", "s", "s", "s" } },
2057 #endif
2058
2059     { INDEX_op_bswap16_i32, { "r", "r" } },
2060     { INDEX_op_bswap32_i32, { "r", "r" } },
2061
2062     { INDEX_op_ext8s_i32, { "r", "r" } },
2063     { INDEX_op_ext16s_i32, { "r", "r" } },
2064     { INDEX_op_ext16u_i32, { "r", "r" } },
2065
2066     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2067
2068     { INDEX_op_div_i32, { "r", "r", "r" } },
2069     { INDEX_op_divu_i32, { "r", "r", "r" } },
2070
2071     { -1 },
2072 };
2073
2074 static void tcg_target_init(TCGContext *s)
2075 {
2076 #if defined(CONFIG_GETAUXVAL)
2077     /* Only probe for the platform and capabilities if we havn't already
2078        determined maximum values at compile time.  */
2079 # if !defined(use_idiv_instructions)
2080     {
2081         unsigned long hwcap = getauxval(AT_HWCAP);
2082         use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
2083     }
2084 # endif
2085     if (__ARM_ARCH < 7) {
2086         const char *pl = (const char *)getauxval(AT_PLATFORM);
2087         if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
2088             arm_arch = pl[1] - '0';
2089         }
2090     }
2091 #endif /* GETAUXVAL */
2092
2093     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2094     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2095                      (1 << TCG_REG_R0) |
2096                      (1 << TCG_REG_R1) |
2097                      (1 << TCG_REG_R2) |
2098                      (1 << TCG_REG_R3) |
2099                      (1 << TCG_REG_R12) |
2100                      (1 << TCG_REG_R14));
2101
2102     tcg_regset_clear(s->reserved_regs);
2103     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2104     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
2105     tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
2106
2107     tcg_add_target_add_op_defs(arm_op_defs);
2108 }
2109
2110 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
2111                               TCGReg arg1, intptr_t arg2)
2112 {
2113     tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
2114 }
2115
2116 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
2117                               TCGReg arg1, intptr_t arg2)
2118 {
2119     tcg_out_st32(s, COND_AL, arg, arg1, arg2);
2120 }
2121
2122 static inline void tcg_out_mov(TCGContext *s, TCGType type,
2123                                TCGReg ret, TCGReg arg)
2124 {
2125     tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
2126 }
2127
2128 static inline void tcg_out_movi(TCGContext *s, TCGType type,
2129                                 TCGReg ret, tcg_target_long arg)
2130 {
2131     tcg_out_movi32(s, COND_AL, ret, arg);
2132 }
2133
2134 /* Compute frame size via macros, to share between tcg_target_qemu_prologue
2135    and tcg_register_jit.  */
2136
2137 #define PUSH_SIZE  ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
2138
2139 #define FRAME_SIZE \
2140     ((PUSH_SIZE \
2141       + TCG_STATIC_CALL_ARGS_SIZE \
2142       + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2143       + TCG_TARGET_STACK_ALIGN - 1) \
2144      & -TCG_TARGET_STACK_ALIGN)
2145
2146 static void tcg_target_qemu_prologue(TCGContext *s)
2147 {
2148     int stack_addend;
2149
2150     /* Calling convention requires us to save r4-r11 and lr.  */
2151     /* stmdb sp!, { r4 - r11, lr } */
2152     tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
2153
2154     /* Reserve callee argument and tcg temp space.  */
2155     stack_addend = FRAME_SIZE - PUSH_SIZE;
2156
2157     tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
2158                    TCG_REG_CALL_STACK, stack_addend, 1);
2159     tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2160                   CPU_TEMP_BUF_NLONGS * sizeof(long));
2161
2162     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2163
2164     tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
2165     tb_ret_addr = s->code_ptr;
2166
2167     /* Epilogue.  We branch here via tb_ret_addr.  */
2168     tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
2169                    TCG_REG_CALL_STACK, stack_addend, 1);
2170
2171     /* ldmia sp!, { r4 - r11, pc } */
2172     tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
2173 }
2174
2175 typedef struct {
2176     DebugFrameCIE cie;
2177     DebugFrameFDEHeader fde;
2178     uint8_t fde_def_cfa[4];
2179     uint8_t fde_reg_ofs[18];
2180 } DebugFrame;
2181
2182 #define ELF_HOST_MACHINE EM_ARM
2183
2184 /* We're expecting a 2 byte uleb128 encoded value.  */
2185 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2186
2187 static DebugFrame debug_frame = {
2188     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2189     .cie.id = -1,
2190     .cie.version = 1,
2191     .cie.code_align = 1,
2192     .cie.data_align = 0x7c,             /* sleb128 -4 */
2193     .cie.return_column = 14,
2194
2195     /* Total FDE size does not include the "len" member.  */
2196     .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2197
2198     .fde_def_cfa = {
2199         12, 13,                         /* DW_CFA_def_cfa sp, ... */
2200         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2201         (FRAME_SIZE >> 7)
2202     },
2203     .fde_reg_ofs = {
2204         /* The following must match the stmdb in the prologue.  */
2205         0x8e, 1,                        /* DW_CFA_offset, lr, -4 */
2206         0x8b, 2,                        /* DW_CFA_offset, r11, -8 */
2207         0x8a, 3,                        /* DW_CFA_offset, r10, -12 */
2208         0x89, 4,                        /* DW_CFA_offset, r9, -16 */
2209         0x88, 5,                        /* DW_CFA_offset, r8, -20 */
2210         0x87, 6,                        /* DW_CFA_offset, r7, -24 */
2211         0x86, 7,                        /* DW_CFA_offset, r6, -28 */
2212         0x85, 8,                        /* DW_CFA_offset, r5, -32 */
2213         0x84, 9,                        /* DW_CFA_offset, r4, -36 */
2214     }
2215 };
2216
2217 void tcg_register_jit(void *buf, size_t buf_size)
2218 {
2219     debug_frame.fde.func_start = (tcg_target_long) buf;
2220     debug_frame.fde.func_len = buf_size;
2221
2222     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2223 }
This page took 0.151313 seconds and 4 git commands to generate.