exec: move include files to include/exec/
[sdk/emulator/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 #if defined(__ARM_ARCH_7__) ||  \
26     defined(__ARM_ARCH_7A__) || \
27     defined(__ARM_ARCH_7EM__) || \
28     defined(__ARM_ARCH_7M__) || \
29     defined(__ARM_ARCH_7R__)
30 #define USE_ARMV7_INSTRUCTIONS
31 #endif
32
33 #if defined(USE_ARMV7_INSTRUCTIONS) || \
34     defined(__ARM_ARCH_6J__) || \
35     defined(__ARM_ARCH_6K__) || \
36     defined(__ARM_ARCH_6T2__) || \
37     defined(__ARM_ARCH_6Z__) || \
38     defined(__ARM_ARCH_6ZK__)
39 #define USE_ARMV6_INSTRUCTIONS
40 #endif
41
42 #if defined(USE_ARMV6_INSTRUCTIONS) || \
43     defined(__ARM_ARCH_5T__) || \
44     defined(__ARM_ARCH_5TE__) || \
45     defined(__ARM_ARCH_5TEJ__)
46 #define USE_ARMV5_INSTRUCTIONS
47 #endif
48
49 #ifdef USE_ARMV5_INSTRUCTIONS
50 static const int use_armv5_instructions = 1;
51 #else
52 static const int use_armv5_instructions = 0;
53 #endif
54 #undef USE_ARMV5_INSTRUCTIONS
55
56 #ifdef USE_ARMV6_INSTRUCTIONS
57 static const int use_armv6_instructions = 1;
58 #else
59 static const int use_armv6_instructions = 0;
60 #endif
61 #undef USE_ARMV6_INSTRUCTIONS
62
63 #ifdef USE_ARMV7_INSTRUCTIONS
64 static const int use_armv7_instructions = 1;
65 #else
66 static const int use_armv7_instructions = 0;
67 #endif
68 #undef USE_ARMV7_INSTRUCTIONS
69
70 #ifndef NDEBUG
71 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
72     "%r0",
73     "%r1",
74     "%r2",
75     "%r3",
76     "%r4",
77     "%r5",
78     "%r6",
79     "%r7",
80     "%r8",
81     "%r9",
82     "%r10",
83     "%r11",
84     "%r12",
85     "%r13",
86     "%r14",
87     "%pc",
88 };
89 #endif
90
91 static const int tcg_target_reg_alloc_order[] = {
92     TCG_REG_R4,
93     TCG_REG_R5,
94     TCG_REG_R6,
95     TCG_REG_R7,
96     TCG_REG_R8,
97     TCG_REG_R9,
98     TCG_REG_R10,
99     TCG_REG_R11,
100     TCG_REG_R13,
101     TCG_REG_R0,
102     TCG_REG_R1,
103     TCG_REG_R2,
104     TCG_REG_R3,
105     TCG_REG_R12,
106     TCG_REG_R14,
107 };
108
109 static const int tcg_target_call_iarg_regs[4] = {
110     TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
111 };
112 static const int tcg_target_call_oarg_regs[2] = {
113     TCG_REG_R0, TCG_REG_R1
114 };
115
116 static inline void reloc_abs32(void *code_ptr, tcg_target_long target)
117 {
118     *(uint32_t *) code_ptr = target;
119 }
120
121 static inline void reloc_pc24(void *code_ptr, tcg_target_long target)
122 {
123     uint32_t offset = ((target - ((tcg_target_long) code_ptr + 8)) >> 2);
124
125     *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
126                              | (offset & 0xffffff);
127 }
128
129 static void patch_reloc(uint8_t *code_ptr, int type,
130                 tcg_target_long value, tcg_target_long addend)
131 {
132     switch (type) {
133     case R_ARM_ABS32:
134         reloc_abs32(code_ptr, value);
135         break;
136
137     case R_ARM_CALL:
138     case R_ARM_JUMP24:
139     default:
140         tcg_abort();
141
142     case R_ARM_PC24:
143         reloc_pc24(code_ptr, value);
144         break;
145     }
146 }
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
159     case 'r':
160         ct->ct |= TCG_CT_REG;
161         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
162         break;
163
164     /* qemu_ld address */
165     case 'l':
166         ct->ct |= TCG_CT_REG;
167         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
168 #ifdef CONFIG_SOFTMMU
169         /* r0 and r1 will be overwritten when reading the tlb entry,
170            so don't use these. */
171         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
172         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
173 #if TARGET_LONG_BITS == 64
174         /* If we're passing env to the helper as r0 and need a regpair
175          * for the address then r2 will be overwritten as we're setting
176          * up the args to the helper.
177          */
178         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
179 #endif
180 #endif
181         break;
182     case 'L':
183         ct->ct |= TCG_CT_REG;
184         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
185 #ifdef CONFIG_SOFTMMU
186         /* r1 is still needed to load data_reg or data_reg2,
187            so don't use it. */
188         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
189 #endif
190         break;
191
192     /* qemu_st address & data_reg */
193     case 's':
194         ct->ct |= TCG_CT_REG;
195         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
196         /* r0 and r1 will be overwritten when reading the tlb entry
197            (softmmu only) and doing the byte swapping, so don't
198            use these. */
199         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
200         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
201 #if defined(CONFIG_SOFTMMU) && (TARGET_LONG_BITS == 64)
202         /* Avoid clashes with registers being used for helper args */
203         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
204         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
205 #endif
206         break;
207     /* qemu_st64 data_reg2 */
208     case 'S':
209         ct->ct |= TCG_CT_REG;
210         tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
211         /* r0 and r1 will be overwritten when reading the tlb entry
212             (softmmu only) and doing the byte swapping, so don't
213             use these. */
214         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
215         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
216 #ifdef CONFIG_SOFTMMU
217         /* r2 is still needed to load data_reg, so don't use it. */
218         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
219 #if TARGET_LONG_BITS == 64
220         /* Avoid clashes with registers being used for helper args */
221         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
222 #endif
223 #endif
224         break;
225
226     default:
227         return -1;
228     }
229     ct_str++;
230     *pct_str = ct_str;
231
232     return 0;
233 }
234
235 static inline uint32_t rotl(uint32_t val, int n)
236 {
237   return (val << n) | (val >> (32 - n));
238 }
239
240 /* ARM immediates for ALU instructions are made of an unsigned 8-bit
241    right-rotated by an even amount between 0 and 30. */
242 static inline int encode_imm(uint32_t imm)
243 {
244     int shift;
245
246     /* simple case, only lower bits */
247     if ((imm & ~0xff) == 0)
248         return 0;
249     /* then try a simple even shift */
250     shift = ctz32(imm) & ~1;
251     if (((imm >> shift) & ~0xff) == 0)
252         return 32 - shift;
253     /* now try harder with rotations */
254     if ((rotl(imm, 2) & ~0xff) == 0)
255         return 2;
256     if ((rotl(imm, 4) & ~0xff) == 0)
257         return 4;
258     if ((rotl(imm, 6) & ~0xff) == 0)
259         return 6;
260     /* imm can't be encoded */
261     return -1;
262 }
263
264 static inline int check_fit_imm(uint32_t imm)
265 {
266     return encode_imm(imm) >= 0;
267 }
268
269 /* Test if a constant matches the constraint.
270  * TODO: define constraints for:
271  *
272  * ldr/str offset:   between -0xfff and 0xfff
273  * ldrh/strh offset: between -0xff and 0xff
274  * mov operand2:     values represented with x << (2 * y), x < 0x100
275  * add, sub, eor...: ditto
276  */
277 static inline int tcg_target_const_match(tcg_target_long val,
278                 const TCGArgConstraint *arg_ct)
279 {
280     int ct;
281     ct = arg_ct->ct;
282     if (ct & TCG_CT_CONST)
283         return 1;
284     else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val))
285         return 1;
286     else
287         return 0;
288 }
289
290 enum arm_data_opc_e {
291     ARITH_AND = 0x0,
292     ARITH_EOR = 0x1,
293     ARITH_SUB = 0x2,
294     ARITH_RSB = 0x3,
295     ARITH_ADD = 0x4,
296     ARITH_ADC = 0x5,
297     ARITH_SBC = 0x6,
298     ARITH_RSC = 0x7,
299     ARITH_TST = 0x8,
300     ARITH_CMP = 0xa,
301     ARITH_CMN = 0xb,
302     ARITH_ORR = 0xc,
303     ARITH_MOV = 0xd,
304     ARITH_BIC = 0xe,
305     ARITH_MVN = 0xf,
306 };
307
308 #define TO_CPSR(opc) \
309   ((opc == ARITH_CMP || opc == ARITH_CMN || opc == ARITH_TST) << 20)
310
311 #define SHIFT_IMM_LSL(im)       (((im) << 7) | 0x00)
312 #define SHIFT_IMM_LSR(im)       (((im) << 7) | 0x20)
313 #define SHIFT_IMM_ASR(im)       (((im) << 7) | 0x40)
314 #define SHIFT_IMM_ROR(im)       (((im) << 7) | 0x60)
315 #define SHIFT_REG_LSL(rs)       (((rs) << 8) | 0x10)
316 #define SHIFT_REG_LSR(rs)       (((rs) << 8) | 0x30)
317 #define SHIFT_REG_ASR(rs)       (((rs) << 8) | 0x50)
318 #define SHIFT_REG_ROR(rs)       (((rs) << 8) | 0x70)
319
320 enum arm_cond_code_e {
321     COND_EQ = 0x0,
322     COND_NE = 0x1,
323     COND_CS = 0x2,      /* Unsigned greater or equal */
324     COND_CC = 0x3,      /* Unsigned less than */
325     COND_MI = 0x4,      /* Negative */
326     COND_PL = 0x5,      /* Zero or greater */
327     COND_VS = 0x6,      /* Overflow */
328     COND_VC = 0x7,      /* No overflow */
329     COND_HI = 0x8,      /* Unsigned greater than */
330     COND_LS = 0x9,      /* Unsigned less or equal */
331     COND_GE = 0xa,
332     COND_LT = 0xb,
333     COND_GT = 0xc,
334     COND_LE = 0xd,
335     COND_AL = 0xe,
336 };
337
338 static const uint8_t tcg_cond_to_arm_cond[] = {
339     [TCG_COND_EQ] = COND_EQ,
340     [TCG_COND_NE] = COND_NE,
341     [TCG_COND_LT] = COND_LT,
342     [TCG_COND_GE] = COND_GE,
343     [TCG_COND_LE] = COND_LE,
344     [TCG_COND_GT] = COND_GT,
345     /* unsigned */
346     [TCG_COND_LTU] = COND_CC,
347     [TCG_COND_GEU] = COND_CS,
348     [TCG_COND_LEU] = COND_LS,
349     [TCG_COND_GTU] = COND_HI,
350 };
351
352 static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
353 {
354     tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
355 }
356
357 static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
358 {
359     tcg_out32(s, (cond << 28) | 0x0a000000 |
360                     (((offset - 8) >> 2) & 0x00ffffff));
361 }
362
363 static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
364 {
365     /* We pay attention here to not modify the branch target by skipping
366        the corresponding bytes. This ensure that caches and memory are
367        kept coherent during retranslation. */
368 #ifdef HOST_WORDS_BIGENDIAN
369     tcg_out8(s, (cond << 4) | 0x0a);
370     s->code_ptr += 3;
371 #else
372     s->code_ptr += 3;
373     tcg_out8(s, (cond << 4) | 0x0a);
374 #endif
375 }
376
377 static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
378 {
379     tcg_out32(s, (cond << 28) | 0x0b000000 |
380                     (((offset - 8) >> 2) & 0x00ffffff));
381 }
382
383 static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
384 {
385     tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
386 }
387
388 static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
389 {
390     tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
391                 (((offset - 8) >> 2) & 0x00ffffff));
392 }
393
394 static inline void tcg_out_dat_reg(TCGContext *s,
395                 int cond, int opc, int rd, int rn, int rm, int shift)
396 {
397     tcg_out32(s, (cond << 28) | (0 << 25) | (opc << 21) | TO_CPSR(opc) |
398                     (rn << 16) | (rd << 12) | shift | rm);
399 }
400
401 static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
402 {
403     /* Simple reg-reg move, optimising out the 'do nothing' case */
404     if (rd != rm) {
405         tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
406     }
407 }
408
409 static inline void tcg_out_dat_reg2(TCGContext *s,
410                 int cond, int opc0, int opc1, int rd0, int rd1,
411                 int rn0, int rn1, int rm0, int rm1, int shift)
412 {
413     if (rd0 == rn1 || rd0 == rm1) {
414         tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
415                         (rn0 << 16) | (8 << 12) | shift | rm0);
416         tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
417                         (rn1 << 16) | (rd1 << 12) | shift | rm1);
418         tcg_out_dat_reg(s, cond, ARITH_MOV,
419                         rd0, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
420     } else {
421         tcg_out32(s, (cond << 28) | (0 << 25) | (opc0 << 21) | (1 << 20) |
422                         (rn0 << 16) | (rd0 << 12) | shift | rm0);
423         tcg_out32(s, (cond << 28) | (0 << 25) | (opc1 << 21) |
424                         (rn1 << 16) | (rd1 << 12) | shift | rm1);
425     }
426 }
427
428 static inline void tcg_out_dat_imm(TCGContext *s,
429                 int cond, int opc, int rd, int rn, int im)
430 {
431     tcg_out32(s, (cond << 28) | (1 << 25) | (opc << 21) | TO_CPSR(opc) |
432                     (rn << 16) | (rd << 12) | im);
433 }
434
435 static inline void tcg_out_movi32(TCGContext *s,
436                 int cond, int rd, uint32_t arg)
437 {
438     /* TODO: This is very suboptimal, we can easily have a constant
439      * pool somewhere after all the instructions.  */
440     if ((int)arg < 0 && (int)arg >= -0x100) {
441         tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0, (~arg) & 0xff);
442     } else if (use_armv7_instructions) {
443         /* use movw/movt */
444         /* movw */
445         tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
446                   | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
447         if (arg & 0xffff0000) {
448             /* movt */
449             tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
450                       | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
451         }
452     } else {
453         int opc = ARITH_MOV;
454         int rn = 0;
455
456         do {
457             int i, rot;
458
459             i = ctz32(arg) & ~1;
460             rot = ((32 - i) << 7) & 0xf00;
461             tcg_out_dat_imm(s, cond, opc, rd, rn, ((arg >> i) & 0xff) | rot);
462             arg &= ~(0xff << i);
463
464             opc = ARITH_ORR;
465             rn = rd;
466         } while (arg);
467     }
468 }
469
470 static inline void tcg_out_dat_rI(TCGContext *s, int cond, int opc, TCGArg dst,
471                                   TCGArg lhs, TCGArg rhs, int rhs_is_const)
472 {
473     /* Emit either the reg,imm or reg,reg form of a data-processing insn.
474      * rhs must satisfy the "rI" constraint.
475      */
476     if (rhs_is_const) {
477         int rot = encode_imm(rhs);
478         assert(rot >= 0);
479         tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
480     } else {
481         tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
482     }
483 }
484
485 static inline void tcg_out_mul32(TCGContext *s,
486                 int cond, int rd, int rs, int rm)
487 {
488     if (rd != rm)
489         tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
490                         (rs << 8) | 0x90 | rm);
491     else if (rd != rs)
492         tcg_out32(s, (cond << 28) | (rd << 16) | (0 << 12) |
493                         (rm << 8) | 0x90 | rs);
494     else {
495         tcg_out32(s, (cond << 28) | ( 8 << 16) | (0 << 12) |
496                         (rs << 8) | 0x90 | rm);
497         tcg_out_dat_reg(s, cond, ARITH_MOV,
498                         rd, 0, TCG_REG_R8, SHIFT_IMM_LSL(0));
499     }
500 }
501
502 static inline void tcg_out_umull32(TCGContext *s,
503                 int cond, int rd0, int rd1, int rs, int rm)
504 {
505     if (rd0 != rm && rd1 != rm)
506         tcg_out32(s, (cond << 28) | 0x800090 |
507                         (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
508     else if (rd0 != rs && rd1 != rs)
509         tcg_out32(s, (cond << 28) | 0x800090 |
510                         (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
511     else {
512         tcg_out_dat_reg(s, cond, ARITH_MOV,
513                         TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
514         tcg_out32(s, (cond << 28) | 0x800098 |
515                         (rd1 << 16) | (rd0 << 12) | (rs << 8));
516     }
517 }
518
519 static inline void tcg_out_smull32(TCGContext *s,
520                 int cond, int rd0, int rd1, int rs, int rm)
521 {
522     if (rd0 != rm && rd1 != rm)
523         tcg_out32(s, (cond << 28) | 0xc00090 |
524                         (rd1 << 16) | (rd0 << 12) | (rs << 8) | rm);
525     else if (rd0 != rs && rd1 != rs)
526         tcg_out32(s, (cond << 28) | 0xc00090 |
527                         (rd1 << 16) | (rd0 << 12) | (rm << 8) | rs);
528     else {
529         tcg_out_dat_reg(s, cond, ARITH_MOV,
530                         TCG_REG_R8, 0, rm, SHIFT_IMM_LSL(0));
531         tcg_out32(s, (cond << 28) | 0xc00098 |
532                         (rd1 << 16) | (rd0 << 12) | (rs << 8));
533     }
534 }
535
536 static inline void tcg_out_ext8s(TCGContext *s, int cond,
537                                  int rd, int rn)
538 {
539     if (use_armv6_instructions) {
540         /* sxtb */
541         tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
542     } else {
543         tcg_out_dat_reg(s, cond, ARITH_MOV,
544                         rd, 0, rn, SHIFT_IMM_LSL(24));
545         tcg_out_dat_reg(s, cond, ARITH_MOV,
546                         rd, 0, rd, SHIFT_IMM_ASR(24));
547     }
548 }
549
550 static inline void tcg_out_ext8u(TCGContext *s, int cond,
551                                  int rd, int rn)
552 {
553     tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
554 }
555
556 static inline void tcg_out_ext16s(TCGContext *s, int cond,
557                                   int rd, int rn)
558 {
559     if (use_armv6_instructions) {
560         /* sxth */
561         tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
562     } else {
563         tcg_out_dat_reg(s, cond, ARITH_MOV,
564                         rd, 0, rn, SHIFT_IMM_LSL(16));
565         tcg_out_dat_reg(s, cond, ARITH_MOV,
566                         rd, 0, rd, SHIFT_IMM_ASR(16));
567     }
568 }
569
570 static inline void tcg_out_ext16u(TCGContext *s, int cond,
571                                   int rd, int rn)
572 {
573     if (use_armv6_instructions) {
574         /* uxth */
575         tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
576     } else {
577         tcg_out_dat_reg(s, cond, ARITH_MOV,
578                         rd, 0, rn, SHIFT_IMM_LSL(16));
579         tcg_out_dat_reg(s, cond, ARITH_MOV,
580                         rd, 0, rd, SHIFT_IMM_LSR(16));
581     }
582 }
583
584 static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
585 {
586     if (use_armv6_instructions) {
587         /* revsh */
588         tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
589     } else {
590         tcg_out_dat_reg(s, cond, ARITH_MOV,
591                         TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
592         tcg_out_dat_reg(s, cond, ARITH_MOV,
593                         TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_ASR(16));
594         tcg_out_dat_reg(s, cond, ARITH_ORR,
595                         rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
596     }
597 }
598
599 static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
600 {
601     if (use_armv6_instructions) {
602         /* rev16 */
603         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
604     } else {
605         tcg_out_dat_reg(s, cond, ARITH_MOV,
606                         TCG_REG_R8, 0, rn, SHIFT_IMM_LSL(24));
607         tcg_out_dat_reg(s, cond, ARITH_MOV,
608                         TCG_REG_R8, 0, TCG_REG_R8, SHIFT_IMM_LSR(16));
609         tcg_out_dat_reg(s, cond, ARITH_ORR,
610                         rd, TCG_REG_R8, rn, SHIFT_IMM_LSR(8));
611     }
612 }
613
614 /* swap the two low bytes assuming that the two high input bytes and the
615    two high output bit can hold any value. */
616 static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn)
617 {
618     if (use_armv6_instructions) {
619         /* rev16 */
620         tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
621     } else {
622         tcg_out_dat_reg(s, cond, ARITH_MOV,
623                         TCG_REG_R8, 0, rn, SHIFT_IMM_LSR(8));
624         tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_R8, TCG_REG_R8, 0xff);
625         tcg_out_dat_reg(s, cond, ARITH_ORR,
626                         rd, TCG_REG_R8, rn, SHIFT_IMM_LSL(8));
627     }
628 }
629
630 static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
631 {
632     if (use_armv6_instructions) {
633         /* rev */
634         tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
635     } else {
636         tcg_out_dat_reg(s, cond, ARITH_EOR,
637                         TCG_REG_R8, rn, rn, SHIFT_IMM_ROR(16));
638         tcg_out_dat_imm(s, cond, ARITH_BIC,
639                         TCG_REG_R8, TCG_REG_R8, 0xff | 0x800);
640         tcg_out_dat_reg(s, cond, ARITH_MOV,
641                         rd, 0, rn, SHIFT_IMM_ROR(8));
642         tcg_out_dat_reg(s, cond, ARITH_EOR,
643                         rd, rd, TCG_REG_R8, SHIFT_IMM_LSR(8));
644     }
645 }
646
647 static inline void tcg_out_ld32_12(TCGContext *s, int cond,
648                 int rd, int rn, tcg_target_long im)
649 {
650     if (im >= 0)
651         tcg_out32(s, (cond << 28) | 0x05900000 |
652                         (rn << 16) | (rd << 12) | (im & 0xfff));
653     else
654         tcg_out32(s, (cond << 28) | 0x05100000 |
655                         (rn << 16) | (rd << 12) | ((-im) & 0xfff));
656 }
657
658 /* Offset pre-increment with base writeback.  */
659 static inline void tcg_out_ld32_12wb(TCGContext *s, int cond,
660                                      int rd, int rn, tcg_target_long im)
661 {
662     /* ldr with writeback and both register equals is UNPREDICTABLE */
663     assert(rd != rn);
664
665     if (im >= 0) {
666         tcg_out32(s, (cond << 28) | 0x05b00000 |
667                         (rn << 16) | (rd << 12) | (im & 0xfff));
668     } else {
669         tcg_out32(s, (cond << 28) | 0x05300000 |
670                         (rn << 16) | (rd << 12) | ((-im) & 0xfff));
671     }
672 }
673
674 static inline void tcg_out_st32_12(TCGContext *s, int cond,
675                 int rd, int rn, tcg_target_long im)
676 {
677     if (im >= 0)
678         tcg_out32(s, (cond << 28) | 0x05800000 |
679                         (rn << 16) | (rd << 12) | (im & 0xfff));
680     else
681         tcg_out32(s, (cond << 28) | 0x05000000 |
682                         (rn << 16) | (rd << 12) | ((-im) & 0xfff));
683 }
684
685 static inline void tcg_out_ld32_r(TCGContext *s, int cond,
686                 int rd, int rn, int rm)
687 {
688     tcg_out32(s, (cond << 28) | 0x07900000 |
689                     (rn << 16) | (rd << 12) | rm);
690 }
691
692 static inline void tcg_out_st32_r(TCGContext *s, int cond,
693                 int rd, int rn, int rm)
694 {
695     tcg_out32(s, (cond << 28) | 0x07800000 |
696                     (rn << 16) | (rd << 12) | rm);
697 }
698
699 /* Register pre-increment with base writeback.  */
700 static inline void tcg_out_ld32_rwb(TCGContext *s, int cond,
701                 int rd, int rn, int rm)
702 {
703     tcg_out32(s, (cond << 28) | 0x07b00000 |
704                     (rn << 16) | (rd << 12) | rm);
705 }
706
707 static inline void tcg_out_st32_rwb(TCGContext *s, int cond,
708                 int rd, int rn, int rm)
709 {
710     tcg_out32(s, (cond << 28) | 0x07a00000 |
711                     (rn << 16) | (rd << 12) | rm);
712 }
713
714 static inline void tcg_out_ld16u_8(TCGContext *s, int cond,
715                 int rd, int rn, tcg_target_long im)
716 {
717     if (im >= 0)
718         tcg_out32(s, (cond << 28) | 0x01d000b0 |
719                         (rn << 16) | (rd << 12) |
720                         ((im & 0xf0) << 4) | (im & 0xf));
721     else
722         tcg_out32(s, (cond << 28) | 0x015000b0 |
723                         (rn << 16) | (rd << 12) |
724                         (((-im) & 0xf0) << 4) | ((-im) & 0xf));
725 }
726
727 static inline void tcg_out_st16_8(TCGContext *s, int cond,
728                 int rd, int rn, tcg_target_long im)
729 {
730     if (im >= 0)
731         tcg_out32(s, (cond << 28) | 0x01c000b0 |
732                         (rn << 16) | (rd << 12) |
733                         ((im & 0xf0) << 4) | (im & 0xf));
734     else
735         tcg_out32(s, (cond << 28) | 0x014000b0 |
736                         (rn << 16) | (rd << 12) |
737                         (((-im) & 0xf0) << 4) | ((-im) & 0xf));
738 }
739
740 static inline void tcg_out_ld16u_r(TCGContext *s, int cond,
741                 int rd, int rn, int rm)
742 {
743     tcg_out32(s, (cond << 28) | 0x019000b0 |
744                     (rn << 16) | (rd << 12) | rm);
745 }
746
747 static inline void tcg_out_st16_r(TCGContext *s, int cond,
748                 int rd, int rn, int rm)
749 {
750     tcg_out32(s, (cond << 28) | 0x018000b0 |
751                     (rn << 16) | (rd << 12) | rm);
752 }
753
754 static inline void tcg_out_ld16s_8(TCGContext *s, int cond,
755                 int rd, int rn, tcg_target_long im)
756 {
757     if (im >= 0)
758         tcg_out32(s, (cond << 28) | 0x01d000f0 |
759                         (rn << 16) | (rd << 12) |
760                         ((im & 0xf0) << 4) | (im & 0xf));
761     else
762         tcg_out32(s, (cond << 28) | 0x015000f0 |
763                         (rn << 16) | (rd << 12) |
764                         (((-im) & 0xf0) << 4) | ((-im) & 0xf));
765 }
766
767 static inline void tcg_out_ld16s_r(TCGContext *s, int cond,
768                 int rd, int rn, int rm)
769 {
770     tcg_out32(s, (cond << 28) | 0x019000f0 |
771                     (rn << 16) | (rd << 12) | rm);
772 }
773
774 static inline void tcg_out_ld8_12(TCGContext *s, int cond,
775                 int rd, int rn, tcg_target_long im)
776 {
777     if (im >= 0)
778         tcg_out32(s, (cond << 28) | 0x05d00000 |
779                         (rn << 16) | (rd << 12) | (im & 0xfff));
780     else
781         tcg_out32(s, (cond << 28) | 0x05500000 |
782                         (rn << 16) | (rd << 12) | ((-im) & 0xfff));
783 }
784
785 static inline void tcg_out_st8_12(TCGContext *s, int cond,
786                 int rd, int rn, tcg_target_long im)
787 {
788     if (im >= 0)
789         tcg_out32(s, (cond << 28) | 0x05c00000 |
790                         (rn << 16) | (rd << 12) | (im & 0xfff));
791     else
792         tcg_out32(s, (cond << 28) | 0x05400000 |
793                         (rn << 16) | (rd << 12) | ((-im) & 0xfff));
794 }
795
796 static inline void tcg_out_ld8_r(TCGContext *s, int cond,
797                 int rd, int rn, int rm)
798 {
799     tcg_out32(s, (cond << 28) | 0x07d00000 |
800                     (rn << 16) | (rd << 12) | rm);
801 }
802
803 static inline void tcg_out_st8_r(TCGContext *s, int cond,
804                 int rd, int rn, int rm)
805 {
806     tcg_out32(s, (cond << 28) | 0x07c00000 |
807                     (rn << 16) | (rd << 12) | rm);
808 }
809
810 static inline void tcg_out_ld8s_8(TCGContext *s, int cond,
811                 int rd, int rn, tcg_target_long im)
812 {
813     if (im >= 0)
814         tcg_out32(s, (cond << 28) | 0x01d000d0 |
815                         (rn << 16) | (rd << 12) |
816                         ((im & 0xf0) << 4) | (im & 0xf));
817     else
818         tcg_out32(s, (cond << 28) | 0x015000d0 |
819                         (rn << 16) | (rd << 12) |
820                         (((-im) & 0xf0) << 4) | ((-im) & 0xf));
821 }
822
823 static inline void tcg_out_ld8s_r(TCGContext *s, int cond,
824                 int rd, int rn, int rm)
825 {
826     tcg_out32(s, (cond << 28) | 0x019000d0 |
827                     (rn << 16) | (rd << 12) | rm);
828 }
829
830 static inline void tcg_out_ld32u(TCGContext *s, int cond,
831                 int rd, int rn, int32_t offset)
832 {
833     if (offset > 0xfff || offset < -0xfff) {
834         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
835         tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_R8);
836     } else
837         tcg_out_ld32_12(s, cond, rd, rn, offset);
838 }
839
840 static inline void tcg_out_st32(TCGContext *s, int cond,
841                 int rd, int rn, int32_t offset)
842 {
843     if (offset > 0xfff || offset < -0xfff) {
844         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
845         tcg_out_st32_r(s, cond, rd, rn, TCG_REG_R8);
846     } else
847         tcg_out_st32_12(s, cond, rd, rn, offset);
848 }
849
850 static inline void tcg_out_ld16u(TCGContext *s, int cond,
851                 int rd, int rn, int32_t offset)
852 {
853     if (offset > 0xff || offset < -0xff) {
854         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
855         tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_R8);
856     } else
857         tcg_out_ld16u_8(s, cond, rd, rn, offset);
858 }
859
860 static inline void tcg_out_ld16s(TCGContext *s, int cond,
861                 int rd, int rn, int32_t offset)
862 {
863     if (offset > 0xff || offset < -0xff) {
864         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
865         tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_R8);
866     } else
867         tcg_out_ld16s_8(s, cond, rd, rn, offset);
868 }
869
870 static inline void tcg_out_st16(TCGContext *s, int cond,
871                 int rd, int rn, int32_t offset)
872 {
873     if (offset > 0xff || offset < -0xff) {
874         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
875         tcg_out_st16_r(s, cond, rd, rn, TCG_REG_R8);
876     } else
877         tcg_out_st16_8(s, cond, rd, rn, offset);
878 }
879
880 static inline void tcg_out_ld8u(TCGContext *s, int cond,
881                 int rd, int rn, int32_t offset)
882 {
883     if (offset > 0xfff || offset < -0xfff) {
884         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
885         tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_R8);
886     } else
887         tcg_out_ld8_12(s, cond, rd, rn, offset);
888 }
889
890 static inline void tcg_out_ld8s(TCGContext *s, int cond,
891                 int rd, int rn, int32_t offset)
892 {
893     if (offset > 0xff || offset < -0xff) {
894         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
895         tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_R8);
896     } else
897         tcg_out_ld8s_8(s, cond, rd, rn, offset);
898 }
899
900 static inline void tcg_out_st8(TCGContext *s, int cond,
901                 int rd, int rn, int32_t offset)
902 {
903     if (offset > 0xfff || offset < -0xfff) {
904         tcg_out_movi32(s, cond, TCG_REG_R8, offset);
905         tcg_out_st8_r(s, cond, rd, rn, TCG_REG_R8);
906     } else
907         tcg_out_st8_12(s, cond, rd, rn, offset);
908 }
909
910 /* The _goto case is normally between TBs within the same code buffer,
911  * and with the code buffer limited to 16MB we shouldn't need the long
912  * case.
913  *
914  * .... except to the prologue that is in its own buffer.
915  */
916 static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
917 {
918     int32_t val;
919
920     if (addr & 1) {
921         /* goto to a Thumb destination isn't supported */
922         tcg_abort();
923     }
924
925     val = addr - (tcg_target_long) s->code_ptr;
926     if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd)
927         tcg_out_b(s, cond, val);
928     else {
929         if (cond == COND_AL) {
930             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
931             tcg_out32(s, addr);
932         } else {
933             tcg_out_movi32(s, cond, TCG_REG_R8, val - 8);
934             tcg_out_dat_reg(s, cond, ARITH_ADD,
935                             TCG_REG_PC, TCG_REG_PC,
936                             TCG_REG_R8, SHIFT_IMM_LSL(0));
937         }
938     }
939 }
940
941 /* The call case is mostly used for helpers - so it's not unreasonable
942  * for them to be beyond branch range */
943 static inline void tcg_out_call(TCGContext *s, uint32_t addr)
944 {
945     int32_t val;
946
947     val = addr - (tcg_target_long) s->code_ptr;
948     if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
949         if (addr & 1) {
950             /* Use BLX if the target is in Thumb mode */
951             if (!use_armv5_instructions) {
952                 tcg_abort();
953             }
954             tcg_out_blx_imm(s, val);
955         } else {
956             tcg_out_bl(s, COND_AL, val);
957         }
958     } else {
959         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
960         tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
961         tcg_out32(s, addr);
962     }
963 }
964
965 static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
966 {
967     if (use_armv5_instructions) {
968         tcg_out_blx(s, cond, arg);
969     } else {
970         tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
971                         TCG_REG_PC, SHIFT_IMM_LSL(0));
972         tcg_out_bx(s, cond, arg);
973     }
974 }
975
976 static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
977 {
978     TCGLabel *l = &s->labels[label_index];
979
980     if (l->has_value)
981         tcg_out_goto(s, cond, l->u.value);
982     else if (cond == COND_AL) {
983         tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
984         tcg_out_reloc(s, s->code_ptr, R_ARM_ABS32, label_index, 31337);
985         s->code_ptr += 4;
986     } else {
987         /* Probably this should be preferred even for COND_AL... */
988         tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
989         tcg_out_b_noaddr(s, cond);
990     }
991 }
992
993 #ifdef CONFIG_SOFTMMU
994
995 #include "exec/softmmu_defs.h"
996
997 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
998    int mmu_idx) */
999 static const void * const qemu_ld_helpers[4] = {
1000     helper_ldb_mmu,
1001     helper_ldw_mmu,
1002     helper_ldl_mmu,
1003     helper_ldq_mmu,
1004 };
1005
1006 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1007    uintxx_t val, int mmu_idx) */
1008 static const void * const qemu_st_helpers[4] = {
1009     helper_stb_mmu,
1010     helper_stw_mmu,
1011     helper_stl_mmu,
1012     helper_stq_mmu,
1013 };
1014
1015 /* Helper routines for marshalling helper function arguments into
1016  * the correct registers and stack.
1017  * argreg is where we want to put this argument, arg is the argument itself.
1018  * Return value is the updated argreg ready for the next call.
1019  * Note that argreg 0..3 is real registers, 4+ on stack.
1020  * When we reach the first stacked argument, we allocate space for it
1021  * and the following stacked arguments using "str r8, [sp, #-0x10]!".
1022  * Following arguments are filled in with "str r8, [sp, #0xNN]".
1023  * For more than 4 stacked arguments we'd need to know how much
1024  * space to allocate when we pushed the first stacked argument.
1025  * We don't need this, so don't implement it (and will assert if you try it.)
1026  *
1027  * We provide routines for arguments which are: immediate, 32 bit
1028  * value in register, 16 and 8 bit values in register (which must be zero
1029  * extended before use) and 64 bit value in a lo:hi register pair.
1030  */
1031 #define DEFINE_TCG_OUT_ARG(NAME, ARGPARAM)                                 \
1032     static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGPARAM)             \
1033     {                                                                      \
1034         if (argreg < 4) {                                                  \
1035             TCG_OUT_ARG_GET_ARG(argreg);                                   \
1036         } else if (argreg == 4) {                                          \
1037             TCG_OUT_ARG_GET_ARG(TCG_REG_R8);                               \
1038             tcg_out32(s, (COND_AL << 28) | 0x052d8010);                    \
1039         } else {                                                           \
1040             assert(argreg < 8);                                            \
1041             TCG_OUT_ARG_GET_ARG(TCG_REG_R8);                               \
1042             tcg_out32(s, (COND_AL << 28) | 0x058d8000 | (argreg - 4) * 4); \
1043         }                                                                  \
1044         return argreg + 1;                                                 \
1045     }
1046
1047 #define TCG_OUT_ARG_GET_ARG(A) tcg_out_dat_imm(s, COND_AL, ARITH_MOV, A, 0, arg)
1048 DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t arg)
1049 #undef TCG_OUT_ARG_GET_ARG
1050 #define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext8u(s, COND_AL, A, arg)
1051 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg arg)
1052 #undef TCG_OUT_ARG_GET_ARG
1053 #define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext16u(s, COND_AL, A, arg)
1054 DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg arg)
1055 #undef TCG_OUT_ARG_GET_ARG
1056
1057 /* We don't use the macro for this one to avoid an unnecessary reg-reg
1058  * move when storing to the stack.
1059  */
1060 static TCGReg tcg_out_arg_reg32(TCGContext *s, TCGReg argreg, TCGReg arg)
1061 {
1062     if (argreg < 4) {
1063         tcg_out_mov_reg(s, COND_AL, argreg, arg);
1064     } else if (argreg == 4) {
1065         /* str arg, [sp, #-0x10]! */
1066         tcg_out32(s, (COND_AL << 28) | 0x052d0010 | (arg << 12));
1067     } else {
1068         assert(argreg < 8);
1069         /* str arg, [sp, #0xNN] */
1070         tcg_out32(s, (COND_AL << 28) | 0x058d0000 |
1071                   (arg << 12) | (argreg - 4) * 4);
1072     }
1073     return argreg + 1;
1074 }
1075
1076 static inline TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
1077                                        TCGReg arglo, TCGReg arghi)
1078 {
1079     /* 64 bit arguments must go in even/odd register pairs
1080      * and in 8-aligned stack slots.
1081      */
1082     if (argreg & 1) {
1083         argreg++;
1084     }
1085     argreg = tcg_out_arg_reg32(s, argreg, arglo);
1086     argreg = tcg_out_arg_reg32(s, argreg, arghi);
1087     return argreg;
1088 }
1089
1090 static inline void tcg_out_arg_stacktidy(TCGContext *s, TCGReg argreg)
1091 {
1092     /* Output any necessary post-call cleanup of the stack */
1093     if (argreg > 4) {
1094         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
1095     }
1096 }
1097
1098 #endif
1099
1100 #define TLB_SHIFT       (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
1101
1102 static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
1103 {
1104     int addr_reg, data_reg, data_reg2, bswap;
1105 #ifdef CONFIG_SOFTMMU
1106     int mem_index, s_bits, tlb_offset;
1107     TCGReg argreg;
1108 # if TARGET_LONG_BITS == 64
1109     int addr_reg2;
1110 # endif
1111     uint32_t *label_ptr;
1112 #endif
1113
1114 #ifdef TARGET_WORDS_BIGENDIAN
1115     bswap = 1;
1116 #else
1117     bswap = 0;
1118 #endif
1119     data_reg = *args++;
1120     if (opc == 3)
1121         data_reg2 = *args++;
1122     else
1123         data_reg2 = 0; /* suppress warning */
1124     addr_reg = *args++;
1125 #ifdef CONFIG_SOFTMMU
1126 # if TARGET_LONG_BITS == 64
1127     addr_reg2 = *args++;
1128 # endif
1129     mem_index = *args;
1130     s_bits = opc & 3;
1131
1132     /* Should generate something like the following:
1133      *  shr r8, addr_reg, #TARGET_PAGE_BITS
1134      *  and r0, r8, #(CPU_TLB_SIZE - 1)   @ Assumption: CPU_TLB_BITS <= 8
1135      *  add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
1136      */
1137 #  if CPU_TLB_BITS > 8
1138 #   error
1139 #  endif
1140     tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_R8,
1141                     0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1142     tcg_out_dat_imm(s, COND_AL, ARITH_AND,
1143                     TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
1144     tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0,
1145                     TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
1146     /* We assume that the offset is contained within 20 bits.  */
1147     tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
1148     assert(tlb_offset & ~0xfffff == 0);
1149     if (tlb_offset > 0xfff) {
1150         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
1151                         0xa00 | (tlb_offset >> 12));
1152         tlb_offset &= 0xfff;
1153     }
1154     tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset);
1155     tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
1156                     TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1157     /* Check alignment.  */
1158     if (s_bits)
1159         tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
1160                         0, addr_reg, (1 << s_bits) - 1);
1161 #  if TARGET_LONG_BITS == 64
1162     /* XXX: possibly we could use a block data load in the first access.  */
1163     tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4);
1164     tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1165                     TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
1166 #  endif
1167     tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
1168                     offsetof(CPUTLBEntry, addend)
1169                     - offsetof(CPUTLBEntry, addr_read));
1170
1171     switch (opc) {
1172     case 0:
1173         tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1174         break;
1175     case 0 | 4:
1176         tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1177         break;
1178     case 1:
1179         tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1180         if (bswap) {
1181             tcg_out_bswap16(s, COND_EQ, data_reg, data_reg);
1182         }
1183         break;
1184     case 1 | 4:
1185         if (bswap) {
1186             tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1187             tcg_out_bswap16s(s, COND_EQ, data_reg, data_reg);
1188         } else {
1189             tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1190         }
1191         break;
1192     case 2:
1193     default:
1194         tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1195         if (bswap) {
1196             tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
1197         }
1198         break;
1199     case 3:
1200         if (bswap) {
1201             tcg_out_ld32_rwb(s, COND_EQ, data_reg2, TCG_REG_R1, addr_reg);
1202             tcg_out_ld32_12(s, COND_EQ, data_reg, TCG_REG_R1, 4);
1203             tcg_out_bswap32(s, COND_EQ, data_reg2, data_reg2);
1204             tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
1205         } else {
1206             tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
1207             tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
1208         }
1209         break;
1210     }
1211
1212     label_ptr = (void *) s->code_ptr;
1213     tcg_out_b_noaddr(s, COND_EQ);
1214
1215     /* TODO: move this code to where the constants pool will be */
1216     /* Note that this code relies on the constraints we set in arm_op_defs[]
1217      * to ensure that later arguments are not passed to us in registers we
1218      * trash by moving the earlier arguments into them.
1219      */
1220     argreg = TCG_REG_R0;
1221     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1222 #if TARGET_LONG_BITS == 64
1223     argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
1224 #else
1225     argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
1226 #endif
1227     argreg = tcg_out_arg_imm32(s, argreg, mem_index);
1228     tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]);
1229     tcg_out_arg_stacktidy(s, argreg);
1230
1231     switch (opc) {
1232     case 0 | 4:
1233         tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
1234         break;
1235     case 1 | 4:
1236         tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
1237         break;
1238     case 0:
1239     case 1:
1240     case 2:
1241     default:
1242         tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1243         break;
1244     case 3:
1245         tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1246         tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1247         break;
1248     }
1249
1250     reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
1251 #else /* !CONFIG_SOFTMMU */
1252     if (GUEST_BASE) {
1253         uint32_t offset = GUEST_BASE;
1254         int i;
1255         int rot;
1256
1257         while (offset) {
1258             i = ctz32(offset) & ~1;
1259             rot = ((32 - i) << 7) & 0xf00;
1260
1261             tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R8, addr_reg,
1262                             ((offset >> i) & 0xff) | rot);
1263             addr_reg = TCG_REG_R8;
1264             offset &= ~(0xff << i);
1265         }
1266     }
1267     switch (opc) {
1268     case 0:
1269         tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
1270         break;
1271     case 0 | 4:
1272         tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
1273         break;
1274     case 1:
1275         tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1276         if (bswap) {
1277             tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1278         }
1279         break;
1280     case 1 | 4:
1281         if (bswap) {
1282             tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1283             tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1284         } else {
1285             tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
1286         }
1287         break;
1288     case 2:
1289     default:
1290         tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
1291         if (bswap) {
1292             tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1293         }
1294         break;
1295     case 3:
1296         /* TODO: use block load -
1297          * check that data_reg2 > data_reg or the other way */
1298         if (data_reg == addr_reg) {
1299             tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1300             tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1301         } else {
1302             tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1303             tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1304         }
1305         if (bswap) {
1306             tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1307             tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
1308         }
1309         break;
1310     }
1311 #endif
1312 }
1313
1314 static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1315 {
1316     int addr_reg, data_reg, data_reg2, bswap;
1317 #ifdef CONFIG_SOFTMMU
1318     int mem_index, s_bits, tlb_offset;
1319     TCGReg argreg;
1320 # if TARGET_LONG_BITS == 64
1321     int addr_reg2;
1322 # endif
1323     uint32_t *label_ptr;
1324 #endif
1325
1326 #ifdef TARGET_WORDS_BIGENDIAN
1327     bswap = 1;
1328 #else
1329     bswap = 0;
1330 #endif
1331     data_reg = *args++;
1332     if (opc == 3)
1333         data_reg2 = *args++;
1334     else
1335         data_reg2 = 0; /* suppress warning */
1336     addr_reg = *args++;
1337 #ifdef CONFIG_SOFTMMU
1338 # if TARGET_LONG_BITS == 64
1339     addr_reg2 = *args++;
1340 # endif
1341     mem_index = *args;
1342     s_bits = opc & 3;
1343
1344     /* Should generate something like the following:
1345      *  shr r8, addr_reg, #TARGET_PAGE_BITS
1346      *  and r0, r8, #(CPU_TLB_SIZE - 1)   @ Assumption: CPU_TLB_BITS <= 8
1347      *  add r0, env, r0 lsl #CPU_TLB_ENTRY_BITS
1348      */
1349     tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
1350                     TCG_REG_R8, 0, addr_reg, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1351     tcg_out_dat_imm(s, COND_AL, ARITH_AND,
1352                     TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1);
1353     tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0,
1354                     TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
1355     /* We assume that the offset is contained within 20 bits.  */
1356     tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
1357     assert(tlb_offset & ~0xfffff == 0);
1358     if (tlb_offset > 0xfff) {
1359         tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
1360                         0xa00 | (tlb_offset >> 12));
1361         tlb_offset &= 0xfff;
1362     }
1363     tcg_out_ld32_12wb(s, COND_AL, TCG_REG_R1, TCG_REG_R0, tlb_offset);
1364     tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R1,
1365                     TCG_REG_R8, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1366     /* Check alignment.  */
1367     if (s_bits)
1368         tcg_out_dat_imm(s, COND_EQ, ARITH_TST,
1369                         0, addr_reg, (1 << s_bits) - 1);
1370 #  if TARGET_LONG_BITS == 64
1371     /* XXX: possibly we could use a block data load in the first access.  */
1372     tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0, 4);
1373     tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1374                     TCG_REG_R1, addr_reg2, SHIFT_IMM_LSL(0));
1375 #  endif
1376     tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R0,
1377                     offsetof(CPUTLBEntry, addend)
1378                     - offsetof(CPUTLBEntry, addr_write));
1379
1380     switch (opc) {
1381     case 0:
1382         tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1383         break;
1384     case 1:
1385         if (bswap) {
1386             tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg);
1387             tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
1388         } else {
1389             tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1390         }
1391         break;
1392     case 2:
1393     default:
1394         if (bswap) {
1395             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1396             tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
1397         } else {
1398             tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1399         }
1400         break;
1401     case 3:
1402         if (bswap) {
1403             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
1404             tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, addr_reg);
1405             tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1406             tcg_out_st32_12(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, 4);
1407         } else {
1408             tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
1409             tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
1410         }
1411         break;
1412     }
1413
1414     label_ptr = (void *) s->code_ptr;
1415     tcg_out_b_noaddr(s, COND_EQ);
1416
1417     /* TODO: move this code to where the constants pool will be */
1418     /* Note that this code relies on the constraints we set in arm_op_defs[]
1419      * to ensure that later arguments are not passed to us in registers we
1420      * trash by moving the earlier arguments into them.
1421      */
1422     argreg = TCG_REG_R0;
1423     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1424 #if TARGET_LONG_BITS == 64
1425     argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
1426 #else
1427     argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
1428 #endif
1429
1430     switch (opc) {
1431     case 0:
1432         argreg = tcg_out_arg_reg8(s, argreg, data_reg);
1433         break;
1434     case 1:
1435         argreg = tcg_out_arg_reg16(s, argreg, data_reg);
1436         break;
1437     case 2:
1438         argreg = tcg_out_arg_reg32(s, argreg, data_reg);
1439         break;
1440     case 3:
1441         argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2);
1442         break;
1443     }
1444
1445     argreg = tcg_out_arg_imm32(s, argreg, mem_index);
1446     tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]);
1447     tcg_out_arg_stacktidy(s, argreg);
1448
1449     reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
1450 #else /* !CONFIG_SOFTMMU */
1451     if (GUEST_BASE) {
1452         uint32_t offset = GUEST_BASE;
1453         int i;
1454         int 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_R1, addr_reg,
1461                             ((offset >> i) & 0xff) | rot);
1462             addr_reg = TCG_REG_R1;
1463             offset &= ~(0xff << i);
1464         }
1465     }
1466     switch (opc) {
1467     case 0:
1468         tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
1469         break;
1470     case 1:
1471         if (bswap) {
1472             tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg);
1473             tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1474         } else {
1475             tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
1476         }
1477         break;
1478     case 2:
1479     default:
1480         if (bswap) {
1481             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1482             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1483         } else {
1484             tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1485         }
1486         break;
1487     case 3:
1488         /* TODO: use block store -
1489          * check that data_reg2 > data_reg or the other way */
1490         if (bswap) {
1491             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
1492             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1493             tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1494             tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
1495         } else {
1496             tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1497             tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
1498         }
1499         break;
1500     }
1501 #endif
1502 }
1503
1504 static uint8_t *tb_ret_addr;
1505
1506 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1507                 const TCGArg *args, const int *const_args)
1508 {
1509     int c;
1510
1511     switch (opc) {
1512     case INDEX_op_exit_tb:
1513         {
1514             uint8_t *ld_ptr = s->code_ptr;
1515             if (args[0] >> 8)
1516                 tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1517             else
1518                 tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
1519             tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1520             if (args[0] >> 8) {
1521                 *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
1522                 tcg_out32(s, args[0]);
1523             }
1524         }
1525         break;
1526     case INDEX_op_goto_tb:
1527         if (s->tb_jmp_offset) {
1528             /* Direct jump method */
1529 #if defined(USE_DIRECT_JUMP)
1530             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1531             tcg_out_b_noaddr(s, COND_AL);
1532 #else
1533             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1534             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1535             tcg_out32(s, 0);
1536 #endif
1537         } else {
1538             /* Indirect jump method */
1539 #if 1
1540             c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
1541             if (c > 0xfff || c < -0xfff) {
1542                 tcg_out_movi32(s, COND_AL, TCG_REG_R0,
1543                                 (tcg_target_long) (s->tb_next + args[0]));
1544                 tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1545             } else
1546                 tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
1547 #else
1548             tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1549             tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1550             tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
1551 #endif
1552         }
1553         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1554         break;
1555     case INDEX_op_call:
1556         if (const_args[0])
1557             tcg_out_call(s, args[0]);
1558         else
1559             tcg_out_callr(s, COND_AL, args[0]);
1560         break;
1561     case INDEX_op_br:
1562         tcg_out_goto_label(s, COND_AL, args[0]);
1563         break;
1564
1565     case INDEX_op_ld8u_i32:
1566         tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
1567         break;
1568     case INDEX_op_ld8s_i32:
1569         tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
1570         break;
1571     case INDEX_op_ld16u_i32:
1572         tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
1573         break;
1574     case INDEX_op_ld16s_i32:
1575         tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
1576         break;
1577     case INDEX_op_ld_i32:
1578         tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
1579         break;
1580     case INDEX_op_st8_i32:
1581         tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
1582         break;
1583     case INDEX_op_st16_i32:
1584         tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
1585         break;
1586     case INDEX_op_st_i32:
1587         tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
1588         break;
1589
1590     case INDEX_op_mov_i32:
1591         tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
1592                         args[0], 0, args[1], SHIFT_IMM_LSL(0));
1593         break;
1594     case INDEX_op_movi_i32:
1595         tcg_out_movi32(s, COND_AL, args[0], args[1]);
1596         break;
1597     case INDEX_op_movcond_i32:
1598         /* Constraints mean that v2 is always in the same register as dest,
1599          * so we only need to do "if condition passed, move v1 to dest".
1600          */
1601         tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,
1602                        args[1], args[2], const_args[2]);
1603         tcg_out_dat_rI(s, tcg_cond_to_arm_cond[args[5]],
1604                        ARITH_MOV, args[0], 0, args[3], const_args[3]);
1605         break;
1606     case INDEX_op_add_i32:
1607         c = ARITH_ADD;
1608         goto gen_arith;
1609     case INDEX_op_sub_i32:
1610         c = ARITH_SUB;
1611         goto gen_arith;
1612     case INDEX_op_and_i32:
1613         c = ARITH_AND;
1614         goto gen_arith;
1615     case INDEX_op_andc_i32:
1616         c = ARITH_BIC;
1617         goto gen_arith;
1618     case INDEX_op_or_i32:
1619         c = ARITH_ORR;
1620         goto gen_arith;
1621     case INDEX_op_xor_i32:
1622         c = ARITH_EOR;
1623         /* Fall through.  */
1624     gen_arith:
1625         tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);
1626         break;
1627     case INDEX_op_add2_i32:
1628         tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC,
1629                         args[0], args[1], args[2], args[3],
1630                         args[4], args[5], SHIFT_IMM_LSL(0));
1631         break;
1632     case INDEX_op_sub2_i32:
1633         tcg_out_dat_reg2(s, COND_AL, ARITH_SUB, ARITH_SBC,
1634                         args[0], args[1], args[2], args[3],
1635                         args[4], args[5], SHIFT_IMM_LSL(0));
1636         break;
1637     case INDEX_op_neg_i32:
1638         tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
1639         break;
1640     case INDEX_op_not_i32:
1641         tcg_out_dat_reg(s, COND_AL,
1642                         ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
1643         break;
1644     case INDEX_op_mul_i32:
1645         tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
1646         break;
1647     case INDEX_op_mulu2_i32:
1648         tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1649         break;
1650     /* XXX: Perhaps args[2] & 0x1f is wrong */
1651     case INDEX_op_shl_i32:
1652         c = const_args[2] ?
1653                 SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
1654         goto gen_shift32;
1655     case INDEX_op_shr_i32:
1656         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
1657                 SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
1658         goto gen_shift32;
1659     case INDEX_op_sar_i32:
1660         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
1661                 SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
1662         goto gen_shift32;
1663     case INDEX_op_rotr_i32:
1664         c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
1665                 SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
1666         /* Fall through.  */
1667     gen_shift32:
1668         tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
1669         break;
1670
1671     case INDEX_op_rotl_i32:
1672         if (const_args[2]) {
1673             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1674                             ((0x20 - args[2]) & 0x1f) ?
1675                             SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
1676                             SHIFT_IMM_LSL(0));
1677         } else {
1678             tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_R8, args[1], 0x20);
1679             tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1680                             SHIFT_REG_ROR(TCG_REG_R8));
1681         }
1682         break;
1683
1684     case INDEX_op_brcond_i32:
1685         tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,
1686                        args[0], args[1], const_args[1]);
1687         tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
1688         break;
1689     case INDEX_op_brcond2_i32:
1690         /* The resulting conditions are:
1691          * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,
1692          * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,
1693          * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,
1694          * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
1695          * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
1696          * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,
1697          */
1698         tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
1699                         args[1], args[3], SHIFT_IMM_LSL(0));
1700         tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1701                         args[0], args[2], SHIFT_IMM_LSL(0));
1702         tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
1703         break;
1704     case INDEX_op_setcond_i32:
1705         tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,
1706                        args[1], args[2], const_args[2]);
1707         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
1708                         ARITH_MOV, args[0], 0, 1);
1709         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
1710                         ARITH_MOV, args[0], 0, 0);
1711         break;
1712     case INDEX_op_setcond2_i32:
1713         /* See brcond2_i32 comment */
1714         tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,
1715                         args[2], args[4], SHIFT_IMM_LSL(0));
1716         tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1717                         args[1], args[3], SHIFT_IMM_LSL(0));
1718         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],
1719                         ARITH_MOV, args[0], 0, 1);
1720         tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],
1721                         ARITH_MOV, args[0], 0, 0);
1722         break;
1723
1724     case INDEX_op_qemu_ld8u:
1725         tcg_out_qemu_ld(s, args, 0);
1726         break;
1727     case INDEX_op_qemu_ld8s:
1728         tcg_out_qemu_ld(s, args, 0 | 4);
1729         break;
1730     case INDEX_op_qemu_ld16u:
1731         tcg_out_qemu_ld(s, args, 1);
1732         break;
1733     case INDEX_op_qemu_ld16s:
1734         tcg_out_qemu_ld(s, args, 1 | 4);
1735         break;
1736     case INDEX_op_qemu_ld32:
1737         tcg_out_qemu_ld(s, args, 2);
1738         break;
1739     case INDEX_op_qemu_ld64:
1740         tcg_out_qemu_ld(s, args, 3);
1741         break;
1742
1743     case INDEX_op_qemu_st8:
1744         tcg_out_qemu_st(s, args, 0);
1745         break;
1746     case INDEX_op_qemu_st16:
1747         tcg_out_qemu_st(s, args, 1);
1748         break;
1749     case INDEX_op_qemu_st32:
1750         tcg_out_qemu_st(s, args, 2);
1751         break;
1752     case INDEX_op_qemu_st64:
1753         tcg_out_qemu_st(s, args, 3);
1754         break;
1755
1756     case INDEX_op_bswap16_i32:
1757         tcg_out_bswap16(s, COND_AL, args[0], args[1]);
1758         break;
1759     case INDEX_op_bswap32_i32:
1760         tcg_out_bswap32(s, COND_AL, args[0], args[1]);
1761         break;
1762
1763     case INDEX_op_ext8s_i32:
1764         tcg_out_ext8s(s, COND_AL, args[0], args[1]);
1765         break;
1766     case INDEX_op_ext16s_i32:
1767         tcg_out_ext16s(s, COND_AL, args[0], args[1]);
1768         break;
1769     case INDEX_op_ext16u_i32:
1770         tcg_out_ext16u(s, COND_AL, args[0], args[1]);
1771         break;
1772
1773     default:
1774         tcg_abort();
1775     }
1776 }
1777
1778 static const TCGTargetOpDef arm_op_defs[] = {
1779     { INDEX_op_exit_tb, { } },
1780     { INDEX_op_goto_tb, { } },
1781     { INDEX_op_call, { "ri" } },
1782     { INDEX_op_br, { } },
1783
1784     { INDEX_op_mov_i32, { "r", "r" } },
1785     { INDEX_op_movi_i32, { "r" } },
1786
1787     { INDEX_op_ld8u_i32, { "r", "r" } },
1788     { INDEX_op_ld8s_i32, { "r", "r" } },
1789     { INDEX_op_ld16u_i32, { "r", "r" } },
1790     { INDEX_op_ld16s_i32, { "r", "r" } },
1791     { INDEX_op_ld_i32, { "r", "r" } },
1792     { INDEX_op_st8_i32, { "r", "r" } },
1793     { INDEX_op_st16_i32, { "r", "r" } },
1794     { INDEX_op_st_i32, { "r", "r" } },
1795
1796     /* TODO: "r", "r", "ri" */
1797     { INDEX_op_add_i32, { "r", "r", "rI" } },
1798     { INDEX_op_sub_i32, { "r", "r", "rI" } },
1799     { INDEX_op_mul_i32, { "r", "r", "r" } },
1800     { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1801     { INDEX_op_and_i32, { "r", "r", "rI" } },
1802     { INDEX_op_andc_i32, { "r", "r", "rI" } },
1803     { INDEX_op_or_i32, { "r", "r", "rI" } },
1804     { INDEX_op_xor_i32, { "r", "r", "rI" } },
1805     { INDEX_op_neg_i32, { "r", "r" } },
1806     { INDEX_op_not_i32, { "r", "r" } },
1807
1808     { INDEX_op_shl_i32, { "r", "r", "ri" } },
1809     { INDEX_op_shr_i32, { "r", "r", "ri" } },
1810     { INDEX_op_sar_i32, { "r", "r", "ri" } },
1811     { INDEX_op_rotl_i32, { "r", "r", "ri" } },
1812     { INDEX_op_rotr_i32, { "r", "r", "ri" } },
1813
1814     { INDEX_op_brcond_i32, { "r", "rI" } },
1815     { INDEX_op_setcond_i32, { "r", "r", "rI" } },
1816     { INDEX_op_movcond_i32, { "r", "r", "rI", "rI", "0" } },
1817
1818     /* TODO: "r", "r", "r", "r", "ri", "ri" */
1819     { INDEX_op_add2_i32, { "r", "r", "r", "r", "r", "r" } },
1820     { INDEX_op_sub2_i32, { "r", "r", "r", "r", "r", "r" } },
1821     { INDEX_op_brcond2_i32, { "r", "r", "r", "r" } },
1822     { INDEX_op_setcond2_i32, { "r", "r", "r", "r", "r" } },
1823
1824 #if TARGET_LONG_BITS == 32
1825     { INDEX_op_qemu_ld8u, { "r", "l" } },
1826     { INDEX_op_qemu_ld8s, { "r", "l" } },
1827     { INDEX_op_qemu_ld16u, { "r", "l" } },
1828     { INDEX_op_qemu_ld16s, { "r", "l" } },
1829     { INDEX_op_qemu_ld32, { "r", "l" } },
1830     { INDEX_op_qemu_ld64, { "L", "L", "l" } },
1831
1832     { INDEX_op_qemu_st8, { "s", "s" } },
1833     { INDEX_op_qemu_st16, { "s", "s" } },
1834     { INDEX_op_qemu_st32, { "s", "s" } },
1835     { INDEX_op_qemu_st64, { "S", "S", "s" } },
1836 #else
1837     { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
1838     { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
1839     { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
1840     { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
1841     { INDEX_op_qemu_ld32, { "r", "l", "l" } },
1842     { INDEX_op_qemu_ld64, { "L", "L", "l", "l" } },
1843
1844     { INDEX_op_qemu_st8, { "s", "s", "s" } },
1845     { INDEX_op_qemu_st16, { "s", "s", "s" } },
1846     { INDEX_op_qemu_st32, { "s", "s", "s" } },
1847     { INDEX_op_qemu_st64, { "S", "S", "s", "s" } },
1848 #endif
1849
1850     { INDEX_op_bswap16_i32, { "r", "r" } },
1851     { INDEX_op_bswap32_i32, { "r", "r" } },
1852
1853     { INDEX_op_ext8s_i32, { "r", "r" } },
1854     { INDEX_op_ext16s_i32, { "r", "r" } },
1855     { INDEX_op_ext16u_i32, { "r", "r" } },
1856
1857     { -1 },
1858 };
1859
1860 static void tcg_target_init(TCGContext *s)
1861 {
1862 #if !defined(CONFIG_USER_ONLY)
1863     /* fail safe */
1864     if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1865         tcg_abort();
1866 #endif
1867
1868     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
1869     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1870                      (1 << TCG_REG_R0) |
1871                      (1 << TCG_REG_R1) |
1872                      (1 << TCG_REG_R2) |
1873                      (1 << TCG_REG_R3) |
1874                      (1 << TCG_REG_R12) |
1875                      (1 << TCG_REG_R14));
1876
1877     tcg_regset_clear(s->reserved_regs);
1878     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
1879     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R8);
1880     tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
1881
1882     tcg_add_target_add_op_defs(arm_op_defs);
1883     tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1884                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1885 }
1886
1887 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
1888                               TCGReg arg1, tcg_target_long arg2)
1889 {
1890     tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
1891 }
1892
1893 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1894                               TCGReg arg1, tcg_target_long arg2)
1895 {
1896     tcg_out_st32(s, COND_AL, arg, arg1, arg2);
1897 }
1898
1899 static inline void tcg_out_mov(TCGContext *s, TCGType type,
1900                                TCGReg ret, TCGReg arg)
1901 {
1902     tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
1903 }
1904
1905 static inline void tcg_out_movi(TCGContext *s, TCGType type,
1906                                 TCGReg ret, tcg_target_long arg)
1907 {
1908     tcg_out_movi32(s, COND_AL, ret, arg);
1909 }
1910
1911 static void tcg_target_qemu_prologue(TCGContext *s)
1912 {
1913     /* Calling convention requires us to save r4-r11 and lr;
1914      * save also r12 to maintain stack 8-alignment.
1915      */
1916
1917     /* stmdb sp!, { r4 - r12, lr } */
1918     tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);
1919
1920     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1921
1922     tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
1923     tb_ret_addr = s->code_ptr;
1924
1925     /* ldmia sp!, { r4 - r12, pc } */
1926     tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);
1927 }