Statistics
| Branch: | Revision:

root / tcg / arm / tcg-target.c @ 702b33b1

History | View | Annotate | Download (66.4 kB)

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
#define TCG_REG_TMP  TCG_REG_R12
117

    
118
static inline void reloc_abs32(void *code_ptr, tcg_target_long target)
119
{
120
    *(uint32_t *) code_ptr = target;
121
}
122

    
123
static inline void reloc_pc24(void *code_ptr, tcg_target_long target)
124
{
125
    uint32_t offset = ((target - ((tcg_target_long) code_ptr + 8)) >> 2);
126

    
127
    *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
128
                             | (offset & 0xffffff);
129
}
130

    
131
static void patch_reloc(uint8_t *code_ptr, int type,
132
                tcg_target_long value, tcg_target_long addend)
133
{
134
    switch (type) {
135
    case R_ARM_ABS32:
136
        reloc_abs32(code_ptr, value);
137
        break;
138

    
139
    case R_ARM_CALL:
140
    case R_ARM_JUMP24:
141
    default:
142
        tcg_abort();
143

    
144
    case R_ARM_PC24:
145
        reloc_pc24(code_ptr, value);
146
        break;
147
    }
148
}
149

    
150
#define TCG_CT_CONST_ARM  0x100
151
#define TCG_CT_CONST_INV  0x200
152
#define TCG_CT_CONST_NEG  0x400
153
#define TCG_CT_CONST_ZERO 0x800
154

    
155
/* parse target specific constraints */
156
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
157
{
158
    const char *ct_str;
159

    
160
    ct_str = *pct_str;
161
    switch (ct_str[0]) {
162
    case 'I':
163
        ct->ct |= TCG_CT_CONST_ARM;
164
        break;
165
    case 'K':
166
        ct->ct |= TCG_CT_CONST_INV;
167
        break;
168
    case 'N': /* The gcc constraint letter is L, already used here.  */
169
        ct->ct |= TCG_CT_CONST_NEG;
170
        break;
171
    case 'Z':
172
        ct->ct |= TCG_CT_CONST_ZERO;
173
        break;
174

    
175
    case 'r':
176
        ct->ct |= TCG_CT_REG;
177
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
178
        break;
179

    
180
    /* qemu_ld address */
181
    case 'l':
182
        ct->ct |= TCG_CT_REG;
183
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
184
#ifdef CONFIG_SOFTMMU
185
        /* r0-r2 will be overwritten when reading the tlb entry,
186
           so don't use these. */
187
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
188
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
189
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
190
#endif
191
        break;
192
    case 'L':
193
        ct->ct |= TCG_CT_REG;
194
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
195
#ifdef CONFIG_SOFTMMU
196
        /* r1 is still needed to load data_reg or data_reg2,
197
           so don't use it. */
198
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
199
#endif
200
        break;
201

    
202
    /* qemu_st address & data_reg */
203
    case 's':
204
    /* qemu_st64 data_reg2 */
205
    case 'S':
206
        ct->ct |= TCG_CT_REG;
207
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
208
        /* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
209
           and r0-r1 doing the byte swapping, so don't use these. */
210
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
211
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
212
#if defined(CONFIG_SOFTMMU)
213
        /* Avoid clashes with registers being used for helper args */
214
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
215
#if TARGET_LONG_BITS == 64
216
        /* Avoid clashes with registers being used for helper args */
217
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
218
#endif
219
#endif
220
        break;
221

    
222
    default:
223
        return -1;
224
    }
225
    ct_str++;
226
    *pct_str = ct_str;
227

    
228
    return 0;
229
}
230

    
231
static inline uint32_t rotl(uint32_t val, int n)
232
{
233
  return (val << n) | (val >> (32 - n));
234
}
235

    
236
/* ARM immediates for ALU instructions are made of an unsigned 8-bit
237
   right-rotated by an even amount between 0 and 30. */
238
static inline int encode_imm(uint32_t imm)
239
{
240
    int shift;
241

    
242
    /* simple case, only lower bits */
243
    if ((imm & ~0xff) == 0)
244
        return 0;
245
    /* then try a simple even shift */
246
    shift = ctz32(imm) & ~1;
247
    if (((imm >> shift) & ~0xff) == 0)
248
        return 32 - shift;
249
    /* now try harder with rotations */
250
    if ((rotl(imm, 2) & ~0xff) == 0)
251
        return 2;
252
    if ((rotl(imm, 4) & ~0xff) == 0)
253
        return 4;
254
    if ((rotl(imm, 6) & ~0xff) == 0)
255
        return 6;
256
    /* imm can't be encoded */
257
    return -1;
258
}
259

    
260
static inline int check_fit_imm(uint32_t imm)
261
{
262
    return encode_imm(imm) >= 0;
263
}
264

    
265
/* Test if a constant matches the constraint.
266
 * TODO: define constraints for:
267
 *
268
 * ldr/str offset:   between -0xfff and 0xfff
269
 * ldrh/strh offset: between -0xff and 0xff
270
 * mov operand2:     values represented with x << (2 * y), x < 0x100
271
 * add, sub, eor...: ditto
272
 */
273
static inline int tcg_target_const_match(tcg_target_long val,
274
                                         const TCGArgConstraint *arg_ct)
275
{
276
    int ct;
277
    ct = arg_ct->ct;
278
    if (ct & TCG_CT_CONST) {
279
        return 1;
280
    } else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) {
281
        return 1;
282
    } else if ((ct & TCG_CT_CONST_INV) && check_fit_imm(~val)) {
283
        return 1;
284
    } else if ((ct & TCG_CT_CONST_NEG) && check_fit_imm(-val)) {
285
        return 1;
286
    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
287
        return 1;
288
    } else {
289
        return 0;
290
    }
291
}
292

    
293
#define TO_CPSR (1 << 20)
294

    
295
typedef enum {
296
    ARITH_AND = 0x0 << 21,
297
    ARITH_EOR = 0x1 << 21,
298
    ARITH_SUB = 0x2 << 21,
299
    ARITH_RSB = 0x3 << 21,
300
    ARITH_ADD = 0x4 << 21,
301
    ARITH_ADC = 0x5 << 21,
302
    ARITH_SBC = 0x6 << 21,
303
    ARITH_RSC = 0x7 << 21,
304
    ARITH_TST = 0x8 << 21 | TO_CPSR,
305
    ARITH_CMP = 0xa << 21 | TO_CPSR,
306
    ARITH_CMN = 0xb << 21 | TO_CPSR,
307
    ARITH_ORR = 0xc << 21,
308
    ARITH_MOV = 0xd << 21,
309
    ARITH_BIC = 0xe << 21,
310
    ARITH_MVN = 0xf << 21,
311

    
312
    INSN_LDR_IMM   = 0x04100000,
313
    INSN_LDR_REG   = 0x06100000,
314
    INSN_STR_IMM   = 0x04000000,
315
    INSN_STR_REG   = 0x06000000,
316

    
317
    INSN_LDRH_IMM  = 0x005000b0,
318
    INSN_LDRH_REG  = 0x001000b0,
319
    INSN_LDRSH_IMM = 0x005000f0,
320
    INSN_LDRSH_REG = 0x001000f0,
321
    INSN_STRH_IMM  = 0x004000b0,
322
    INSN_STRH_REG  = 0x000000b0,
323

    
324
    INSN_LDRB_IMM  = 0x04500000,
325
    INSN_LDRB_REG  = 0x06500000,
326
    INSN_LDRSB_IMM = 0x005000d0,
327
    INSN_LDRSB_REG = 0x001000d0,
328
    INSN_STRB_IMM  = 0x04400000,
329
    INSN_STRB_REG  = 0x06400000,
330

    
331
    INSN_LDRD_IMM  = 0x004000d0,
332
} ARMInsn;
333

    
334
#define SHIFT_IMM_LSL(im)        (((im) << 7) | 0x00)
335
#define SHIFT_IMM_LSR(im)        (((im) << 7) | 0x20)
336
#define SHIFT_IMM_ASR(im)        (((im) << 7) | 0x40)
337
#define SHIFT_IMM_ROR(im)        (((im) << 7) | 0x60)
338
#define SHIFT_REG_LSL(rs)        (((rs) << 8) | 0x10)
339
#define SHIFT_REG_LSR(rs)        (((rs) << 8) | 0x30)
340
#define SHIFT_REG_ASR(rs)        (((rs) << 8) | 0x50)
341
#define SHIFT_REG_ROR(rs)        (((rs) << 8) | 0x70)
342

    
343
enum arm_cond_code_e {
344
    COND_EQ = 0x0,
345
    COND_NE = 0x1,
346
    COND_CS = 0x2,        /* Unsigned greater or equal */
347
    COND_CC = 0x3,        /* Unsigned less than */
348
    COND_MI = 0x4,        /* Negative */
349
    COND_PL = 0x5,        /* Zero or greater */
350
    COND_VS = 0x6,        /* Overflow */
351
    COND_VC = 0x7,        /* No overflow */
352
    COND_HI = 0x8,        /* Unsigned greater than */
353
    COND_LS = 0x9,        /* Unsigned less or equal */
354
    COND_GE = 0xa,
355
    COND_LT = 0xb,
356
    COND_GT = 0xc,
357
    COND_LE = 0xd,
358
    COND_AL = 0xe,
359
};
360

    
361
static const uint8_t tcg_cond_to_arm_cond[] = {
362
    [TCG_COND_EQ] = COND_EQ,
363
    [TCG_COND_NE] = COND_NE,
364
    [TCG_COND_LT] = COND_LT,
365
    [TCG_COND_GE] = COND_GE,
366
    [TCG_COND_LE] = COND_LE,
367
    [TCG_COND_GT] = COND_GT,
368
    /* unsigned */
369
    [TCG_COND_LTU] = COND_CC,
370
    [TCG_COND_GEU] = COND_CS,
371
    [TCG_COND_LEU] = COND_LS,
372
    [TCG_COND_GTU] = COND_HI,
373
};
374

    
375
static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
376
{
377
    tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
378
}
379

    
380
static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
381
{
382
    tcg_out32(s, (cond << 28) | 0x0a000000 |
383
                    (((offset - 8) >> 2) & 0x00ffffff));
384
}
385

    
386
static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
387
{
388
    /* We pay attention here to not modify the branch target by skipping
389
       the corresponding bytes. This ensure that caches and memory are
390
       kept coherent during retranslation. */
391
#ifdef HOST_WORDS_BIGENDIAN
392
    tcg_out8(s, (cond << 4) | 0x0a);
393
    s->code_ptr += 3;
394
#else
395
    s->code_ptr += 3;
396
    tcg_out8(s, (cond << 4) | 0x0a);
397
#endif
398
}
399

    
400
static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
401
{
402
    tcg_out32(s, (cond << 28) | 0x0b000000 |
403
                    (((offset - 8) >> 2) & 0x00ffffff));
404
}
405

    
406
static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
407
{
408
    tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
409
}
410

    
411
static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
412
{
413
    tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
414
                (((offset - 8) >> 2) & 0x00ffffff));
415
}
416

    
417
static inline void tcg_out_dat_reg(TCGContext *s,
418
                int cond, int opc, int rd, int rn, int rm, int shift)
419
{
420
    tcg_out32(s, (cond << 28) | (0 << 25) | opc |
421
                    (rn << 16) | (rd << 12) | shift | rm);
422
}
423

    
424
static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
425
{
426
    /* Simple reg-reg move, optimising out the 'do nothing' case */
427
    if (rd != rm) {
428
        tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
429
    }
430
}
431

    
432
static inline void tcg_out_dat_imm(TCGContext *s,
433
                int cond, int opc, int rd, int rn, int im)
434
{
435
    tcg_out32(s, (cond << 28) | (1 << 25) | opc |
436
                    (rn << 16) | (rd << 12) | im);
437
}
438

    
439
static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
440
{
441
    int rot, opc, rn;
442

    
443
    /* For armv7, make sure not to use movw+movt when mov/mvn would do.
444
       Speed things up by only checking when movt would be required.
445
       Prior to armv7, have one go at fully rotated immediates before
446
       doing the decomposition thing below.  */
447
    if (!use_armv7_instructions || (arg & 0xffff0000)) {
448
        rot = encode_imm(arg);
449
        if (rot >= 0) {
450
            tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0,
451
                            rotl(arg, rot) | (rot << 7));
452
            return;
453
        }
454
        rot = encode_imm(~arg);
455
        if (rot >= 0) {
456
            tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0,
457
                            rotl(~arg, rot) | (rot << 7));
458
            return;
459
        }
460
    }
461

    
462
    /* Use movw + movt.  */
463
    if (use_armv7_instructions) {
464
        /* movw */
465
        tcg_out32(s, (cond << 28) | 0x03000000 | (rd << 12)
466
                  | ((arg << 4) & 0x000f0000) | (arg & 0xfff));
467
        if (arg & 0xffff0000) {
468
            /* movt */
469
            tcg_out32(s, (cond << 28) | 0x03400000 | (rd << 12)
470
                      | ((arg >> 12) & 0x000f0000) | ((arg >> 16) & 0xfff));
471
        }
472
        return;
473
    }
474

    
475
    /* TODO: This is very suboptimal, we can easily have a constant
476
       pool somewhere after all the instructions.  */
477
    opc = ARITH_MOV;
478
    rn = 0;
479
    /* If we have lots of leading 1's, we can shorten the sequence by
480
       beginning with mvn and then clearing higher bits with eor.  */
481
    if (clz32(~arg) > clz32(arg)) {
482
        opc = ARITH_MVN, arg = ~arg;
483
    }
484
    do {
485
        int i = ctz32(arg) & ~1;
486
        rot = ((32 - i) << 7) & 0xf00;
487
        tcg_out_dat_imm(s, cond, opc, rd, rn, ((arg >> i) & 0xff) | rot);
488
        arg &= ~(0xff << i);
489

    
490
        opc = ARITH_EOR;
491
        rn = rd;
492
    } while (arg);
493
}
494

    
495
static inline void tcg_out_dat_rI(TCGContext *s, int cond, int opc, TCGArg dst,
496
                                  TCGArg lhs, TCGArg rhs, int rhs_is_const)
497
{
498
    /* Emit either the reg,imm or reg,reg form of a data-processing insn.
499
     * rhs must satisfy the "rI" constraint.
500
     */
501
    if (rhs_is_const) {
502
        int rot = encode_imm(rhs);
503
        assert(rot >= 0);
504
        tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
505
    } else {
506
        tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
507
    }
508
}
509

    
510
static void tcg_out_dat_rIK(TCGContext *s, int cond, int opc, int opinv,
511
                            TCGReg dst, TCGReg lhs, TCGArg rhs,
512
                            bool rhs_is_const)
513
{
514
    /* Emit either the reg,imm or reg,reg form of a data-processing insn.
515
     * rhs must satisfy the "rIK" constraint.
516
     */
517
    if (rhs_is_const) {
518
        int rot = encode_imm(rhs);
519
        if (rot < 0) {
520
            rhs = ~rhs;
521
            rot = encode_imm(rhs);
522
            assert(rot >= 0);
523
            opc = opinv;
524
        }
525
        tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
526
    } else {
527
        tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
528
    }
529
}
530

    
531
static void tcg_out_dat_rIN(TCGContext *s, int cond, int opc, int opneg,
532
                            TCGArg dst, TCGArg lhs, TCGArg rhs,
533
                            bool rhs_is_const)
534
{
535
    /* Emit either the reg,imm or reg,reg form of a data-processing insn.
536
     * rhs must satisfy the "rIN" constraint.
537
     */
538
    if (rhs_is_const) {
539
        int rot = encode_imm(rhs);
540
        if (rot < 0) {
541
            rhs = -rhs;
542
            rot = encode_imm(rhs);
543
            assert(rot >= 0);
544
            opc = opneg;
545
        }
546
        tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));
547
    } else {
548
        tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));
549
    }
550
}
551

    
552
static inline void tcg_out_mul32(TCGContext *s, int cond, TCGReg rd,
553
                                 TCGReg rn, TCGReg rm)
554
{
555
    /* if ArchVersion() < 6 && d == n then UNPREDICTABLE;  */
556
    if (!use_armv6_instructions && rd == rn) {
557
        if (rd == rm) {
558
            /* rd == rn == rm; copy an input to tmp first.  */
559
            tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
560
            rm = rn = TCG_REG_TMP;
561
        } else {
562
            rn = rm;
563
            rm = rd;
564
        }
565
    }
566
    /* mul */
567
    tcg_out32(s, (cond << 28) | 0x90 | (rd << 16) | (rm << 8) | rn);
568
}
569

    
570
static inline void tcg_out_umull32(TCGContext *s, int cond, TCGReg rd0,
571
                                   TCGReg rd1, TCGReg rn, TCGReg rm)
572
{
573
    /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
574
    if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
575
        if (rd0 == rm || rd1 == rm) {
576
            tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
577
            rn = TCG_REG_TMP;
578
        } else {
579
            TCGReg t = rn;
580
            rn = rm;
581
            rm = t;
582
        }
583
    }
584
    /* umull */
585
    tcg_out32(s, (cond << 28) | 0x00800090 |
586
              (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
587
}
588

    
589
static inline void tcg_out_smull32(TCGContext *s, int cond, TCGReg rd0,
590
                                   TCGReg rd1, TCGReg rn, TCGReg rm)
591
{
592
    /* if ArchVersion() < 6 && (dHi == n || dLo == n) then UNPREDICTABLE;  */
593
    if (!use_armv6_instructions && (rd0 == rn || rd1 == rn)) {
594
        if (rd0 == rm || rd1 == rm) {
595
            tcg_out_mov_reg(s, cond, TCG_REG_TMP, rn);
596
            rn = TCG_REG_TMP;
597
        } else {
598
            TCGReg t = rn;
599
            rn = rm;
600
            rm = t;
601
        }
602
    }
603
    /* smull */
604
    tcg_out32(s, (cond << 28) | 0x00c00090 |
605
              (rd1 << 16) | (rd0 << 12) | (rm << 8) | rn);
606
}
607

    
608
static inline void tcg_out_sdiv(TCGContext *s, int cond, int rd, int rn, int rm)
609
{
610
    tcg_out32(s, 0x0710f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
611
}
612

    
613
static inline void tcg_out_udiv(TCGContext *s, int cond, int rd, int rn, int rm)
614
{
615
    tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
616
}
617

    
618
static inline void tcg_out_ext8s(TCGContext *s, int cond,
619
                                 int rd, int rn)
620
{
621
    if (use_armv6_instructions) {
622
        /* sxtb */
623
        tcg_out32(s, 0x06af0070 | (cond << 28) | (rd << 12) | rn);
624
    } else {
625
        tcg_out_dat_reg(s, cond, ARITH_MOV,
626
                        rd, 0, rn, SHIFT_IMM_LSL(24));
627
        tcg_out_dat_reg(s, cond, ARITH_MOV,
628
                        rd, 0, rd, SHIFT_IMM_ASR(24));
629
    }
630
}
631

    
632
static inline void tcg_out_ext8u(TCGContext *s, int cond,
633
                                 int rd, int rn)
634
{
635
    tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
636
}
637

    
638
static inline void tcg_out_ext16s(TCGContext *s, int cond,
639
                                  int rd, int rn)
640
{
641
    if (use_armv6_instructions) {
642
        /* sxth */
643
        tcg_out32(s, 0x06bf0070 | (cond << 28) | (rd << 12) | rn);
644
    } else {
645
        tcg_out_dat_reg(s, cond, ARITH_MOV,
646
                        rd, 0, rn, SHIFT_IMM_LSL(16));
647
        tcg_out_dat_reg(s, cond, ARITH_MOV,
648
                        rd, 0, rd, SHIFT_IMM_ASR(16));
649
    }
650
}
651

    
652
static inline void tcg_out_ext16u(TCGContext *s, int cond,
653
                                  int rd, int rn)
654
{
655
    if (use_armv6_instructions) {
656
        /* uxth */
657
        tcg_out32(s, 0x06ff0070 | (cond << 28) | (rd << 12) | rn);
658
    } else {
659
        tcg_out_dat_reg(s, cond, ARITH_MOV,
660
                        rd, 0, rn, SHIFT_IMM_LSL(16));
661
        tcg_out_dat_reg(s, cond, ARITH_MOV,
662
                        rd, 0, rd, SHIFT_IMM_LSR(16));
663
    }
664
}
665

    
666
static inline void tcg_out_bswap16s(TCGContext *s, int cond, int rd, int rn)
667
{
668
    if (use_armv6_instructions) {
669
        /* revsh */
670
        tcg_out32(s, 0x06ff0fb0 | (cond << 28) | (rd << 12) | rn);
671
    } else {
672
        tcg_out_dat_reg(s, cond, ARITH_MOV,
673
                        TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
674
        tcg_out_dat_reg(s, cond, ARITH_MOV,
675
                        TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_ASR(16));
676
        tcg_out_dat_reg(s, cond, ARITH_ORR,
677
                        rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
678
    }
679
}
680

    
681
static inline void tcg_out_bswap16(TCGContext *s, int cond, int rd, int rn)
682
{
683
    if (use_armv6_instructions) {
684
        /* rev16 */
685
        tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
686
    } else {
687
        tcg_out_dat_reg(s, cond, ARITH_MOV,
688
                        TCG_REG_TMP, 0, rn, SHIFT_IMM_LSL(24));
689
        tcg_out_dat_reg(s, cond, ARITH_MOV,
690
                        TCG_REG_TMP, 0, TCG_REG_TMP, SHIFT_IMM_LSR(16));
691
        tcg_out_dat_reg(s, cond, ARITH_ORR,
692
                        rd, TCG_REG_TMP, rn, SHIFT_IMM_LSR(8));
693
    }
694
}
695

    
696
/* swap the two low bytes assuming that the two high input bytes and the
697
   two high output bit can hold any value. */
698
static inline void tcg_out_bswap16st(TCGContext *s, int cond, int rd, int rn)
699
{
700
    if (use_armv6_instructions) {
701
        /* rev16 */
702
        tcg_out32(s, 0x06bf0fb0 | (cond << 28) | (rd << 12) | rn);
703
    } else {
704
        tcg_out_dat_reg(s, cond, ARITH_MOV,
705
                        TCG_REG_TMP, 0, rn, SHIFT_IMM_LSR(8));
706
        tcg_out_dat_imm(s, cond, ARITH_AND, TCG_REG_TMP, TCG_REG_TMP, 0xff);
707
        tcg_out_dat_reg(s, cond, ARITH_ORR,
708
                        rd, TCG_REG_TMP, rn, SHIFT_IMM_LSL(8));
709
    }
710
}
711

    
712
static inline void tcg_out_bswap32(TCGContext *s, int cond, int rd, int rn)
713
{
714
    if (use_armv6_instructions) {
715
        /* rev */
716
        tcg_out32(s, 0x06bf0f30 | (cond << 28) | (rd << 12) | rn);
717
    } else {
718
        tcg_out_dat_reg(s, cond, ARITH_EOR,
719
                        TCG_REG_TMP, rn, rn, SHIFT_IMM_ROR(16));
720
        tcg_out_dat_imm(s, cond, ARITH_BIC,
721
                        TCG_REG_TMP, TCG_REG_TMP, 0xff | 0x800);
722
        tcg_out_dat_reg(s, cond, ARITH_MOV,
723
                        rd, 0, rn, SHIFT_IMM_ROR(8));
724
        tcg_out_dat_reg(s, cond, ARITH_EOR,
725
                        rd, rd, TCG_REG_TMP, SHIFT_IMM_LSR(8));
726
    }
727
}
728

    
729
bool tcg_target_deposit_valid(int ofs, int len)
730
{
731
    /* ??? Without bfi, we could improve over generic code by combining
732
       the right-shift from a non-zero ofs with the orr.  We do run into
733
       problems when rd == rs, and the mask generated from ofs+len doesn't
734
       fit into an immediate.  We would have to be careful not to pessimize
735
       wrt the optimizations performed on the expanded code.  */
736
    return use_armv7_instructions;
737
}
738

    
739
static inline void tcg_out_deposit(TCGContext *s, int cond, TCGReg rd,
740
                                   TCGArg a1, int ofs, int len, bool const_a1)
741
{
742
    if (const_a1) {
743
        /* bfi becomes bfc with rn == 15.  */
744
        a1 = 15;
745
    }
746
    /* bfi/bfc */
747
    tcg_out32(s, 0x07c00010 | (cond << 28) | (rd << 12) | a1
748
              | (ofs << 7) | ((ofs + len - 1) << 16));
749
}
750

    
751
/* Note that this routine is used for both LDR and LDRH formats, so we do
752
   not wish to include an immediate shift at this point.  */
753
static void tcg_out_memop_r(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
754
                            TCGReg rn, TCGReg rm, bool u, bool p, bool w)
755
{
756
    tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24)
757
              | (w << 21) | (rn << 16) | (rt << 12) | rm);
758
}
759

    
760
static void tcg_out_memop_8(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
761
                            TCGReg rn, int imm8, bool p, bool w)
762
{
763
    bool u = 1;
764
    if (imm8 < 0) {
765
        imm8 = -imm8;
766
        u = 0;
767
    }
768
    tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
769
              (rn << 16) | (rt << 12) | ((imm8 & 0xf0) << 4) | (imm8 & 0xf));
770
}
771

    
772
static void tcg_out_memop_12(TCGContext *s, int cond, ARMInsn opc, TCGReg rt,
773
                             TCGReg rn, int imm12, bool p, bool w)
774
{
775
    bool u = 1;
776
    if (imm12 < 0) {
777
        imm12 = -imm12;
778
        u = 0;
779
    }
780
    tcg_out32(s, (cond << 28) | opc | (u << 23) | (p << 24) | (w << 21) |
781
              (rn << 16) | (rt << 12) | imm12);
782
}
783

    
784
static inline void tcg_out_ld32_12(TCGContext *s, int cond, TCGReg rt,
785
                                   TCGReg rn, int imm12)
786
{
787
    tcg_out_memop_12(s, cond, INSN_LDR_IMM, rt, rn, imm12, 1, 0);
788
}
789

    
790
static inline void tcg_out_st32_12(TCGContext *s, int cond, TCGReg rt,
791
                                   TCGReg rn, int imm12)
792
{
793
    tcg_out_memop_12(s, cond, INSN_STR_IMM, rt, rn, imm12, 1, 0);
794
}
795

    
796
static inline void tcg_out_ld32_r(TCGContext *s, int cond, TCGReg rt,
797
                                  TCGReg rn, TCGReg rm)
798
{
799
    tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 0);
800
}
801

    
802
static inline void tcg_out_st32_r(TCGContext *s, int cond, TCGReg rt,
803
                                  TCGReg rn, TCGReg rm)
804
{
805
    tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 0);
806
}
807

    
808
/* Register pre-increment with base writeback.  */
809
static inline void tcg_out_ld32_rwb(TCGContext *s, int cond, TCGReg rt,
810
                                    TCGReg rn, TCGReg rm)
811
{
812
    tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 1);
813
}
814

    
815
static inline void tcg_out_st32_rwb(TCGContext *s, int cond, TCGReg rt,
816
                                    TCGReg rn, TCGReg rm)
817
{
818
    tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 1);
819
}
820

    
821
static inline void tcg_out_ld16u_8(TCGContext *s, int cond, TCGReg rt,
822
                                   TCGReg rn, int imm8)
823
{
824
    tcg_out_memop_8(s, cond, INSN_LDRH_IMM, rt, rn, imm8, 1, 0);
825
}
826

    
827
static inline void tcg_out_st16_8(TCGContext *s, int cond, TCGReg rt,
828
                                  TCGReg rn, int imm8)
829
{
830
    tcg_out_memop_8(s, cond, INSN_STRH_IMM, rt, rn, imm8, 1, 0);
831
}
832

    
833
static inline void tcg_out_ld16u_r(TCGContext *s, int cond, TCGReg rt,
834
                                   TCGReg rn, TCGReg rm)
835
{
836
    tcg_out_memop_r(s, cond, INSN_LDRH_REG, rt, rn, rm, 1, 1, 0);
837
}
838

    
839
static inline void tcg_out_st16_r(TCGContext *s, int cond, TCGReg rt,
840
                                  TCGReg rn, TCGReg rm)
841
{
842
    tcg_out_memop_r(s, cond, INSN_STRH_REG, rt, rn, rm, 1, 1, 0);
843
}
844

    
845
static inline void tcg_out_ld16s_8(TCGContext *s, int cond, TCGReg rt,
846
                                   TCGReg rn, int imm8)
847
{
848
    tcg_out_memop_8(s, cond, INSN_LDRSH_IMM, rt, rn, imm8, 1, 0);
849
}
850

    
851
static inline void tcg_out_ld16s_r(TCGContext *s, int cond, TCGReg rt,
852
                                   TCGReg rn, TCGReg rm)
853
{
854
    tcg_out_memop_r(s, cond, INSN_LDRSH_REG, rt, rn, rm, 1, 1, 0);
855
}
856

    
857
static inline void tcg_out_ld8_12(TCGContext *s, int cond, TCGReg rt,
858
                                  TCGReg rn, int imm12)
859
{
860
    tcg_out_memop_12(s, cond, INSN_LDRB_IMM, rt, rn, imm12, 1, 0);
861
}
862

    
863
static inline void tcg_out_st8_12(TCGContext *s, int cond, TCGReg rt,
864
                                  TCGReg rn, int imm12)
865
{
866
    tcg_out_memop_12(s, cond, INSN_STRB_IMM, rt, rn, imm12, 1, 0);
867
}
868

    
869
static inline void tcg_out_ld8_r(TCGContext *s, int cond, TCGReg rt,
870
                                 TCGReg rn, TCGReg rm)
871
{
872
    tcg_out_memop_r(s, cond, INSN_LDRB_REG, rt, rn, rm, 1, 1, 0);
873
}
874

    
875
static inline void tcg_out_st8_r(TCGContext *s, int cond, TCGReg rt,
876
                                 TCGReg rn, TCGReg rm)
877
{
878
    tcg_out_memop_r(s, cond, INSN_STRB_REG, rt, rn, rm, 1, 1, 0);
879
}
880

    
881
static inline void tcg_out_ld8s_8(TCGContext *s, int cond, TCGReg rt,
882
                                  TCGReg rn, int imm8)
883
{
884
    tcg_out_memop_8(s, cond, INSN_LDRSB_IMM, rt, rn, imm8, 1, 0);
885
}
886

    
887
static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
888
                                  TCGReg rn, TCGReg rm)
889
{
890
    tcg_out_memop_r(s, cond, INSN_LDRSB_REG, rt, rn, rm, 1, 1, 0);
891
}
892

    
893
static inline void tcg_out_ld32u(TCGContext *s, int cond,
894
                int rd, int rn, int32_t offset)
895
{
896
    if (offset > 0xfff || offset < -0xfff) {
897
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
898
        tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_TMP);
899
    } else
900
        tcg_out_ld32_12(s, cond, rd, rn, offset);
901
}
902

    
903
static inline void tcg_out_st32(TCGContext *s, int cond,
904
                int rd, int rn, int32_t offset)
905
{
906
    if (offset > 0xfff || offset < -0xfff) {
907
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
908
        tcg_out_st32_r(s, cond, rd, rn, TCG_REG_TMP);
909
    } else
910
        tcg_out_st32_12(s, cond, rd, rn, offset);
911
}
912

    
913
static inline void tcg_out_ld16u(TCGContext *s, int cond,
914
                int rd, int rn, int32_t offset)
915
{
916
    if (offset > 0xff || offset < -0xff) {
917
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
918
        tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_TMP);
919
    } else
920
        tcg_out_ld16u_8(s, cond, rd, rn, offset);
921
}
922

    
923
static inline void tcg_out_ld16s(TCGContext *s, int cond,
924
                int rd, int rn, int32_t offset)
925
{
926
    if (offset > 0xff || offset < -0xff) {
927
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
928
        tcg_out_ld16s_r(s, cond, rd, rn, TCG_REG_TMP);
929
    } else
930
        tcg_out_ld16s_8(s, cond, rd, rn, offset);
931
}
932

    
933
static inline void tcg_out_st16(TCGContext *s, int cond,
934
                int rd, int rn, int32_t offset)
935
{
936
    if (offset > 0xff || offset < -0xff) {
937
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
938
        tcg_out_st16_r(s, cond, rd, rn, TCG_REG_TMP);
939
    } else
940
        tcg_out_st16_8(s, cond, rd, rn, offset);
941
}
942

    
943
static inline void tcg_out_ld8u(TCGContext *s, int cond,
944
                int rd, int rn, int32_t offset)
945
{
946
    if (offset > 0xfff || offset < -0xfff) {
947
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
948
        tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_TMP);
949
    } else
950
        tcg_out_ld8_12(s, cond, rd, rn, offset);
951
}
952

    
953
static inline void tcg_out_ld8s(TCGContext *s, int cond,
954
                int rd, int rn, int32_t offset)
955
{
956
    if (offset > 0xff || offset < -0xff) {
957
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
958
        tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_TMP);
959
    } else
960
        tcg_out_ld8s_8(s, cond, rd, rn, offset);
961
}
962

    
963
static inline void tcg_out_st8(TCGContext *s, int cond,
964
                int rd, int rn, int32_t offset)
965
{
966
    if (offset > 0xfff || offset < -0xfff) {
967
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
968
        tcg_out_st8_r(s, cond, rd, rn, TCG_REG_TMP);
969
    } else
970
        tcg_out_st8_12(s, cond, rd, rn, offset);
971
}
972

    
973
/* The _goto case is normally between TBs within the same code buffer,
974
 * and with the code buffer limited to 16MB we shouldn't need the long
975
 * case.
976
 *
977
 * .... except to the prologue that is in its own buffer.
978
 */
979
static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
980
{
981
    int32_t val;
982

    
983
    if (addr & 1) {
984
        /* goto to a Thumb destination isn't supported */
985
        tcg_abort();
986
    }
987

    
988
    val = addr - (tcg_target_long) s->code_ptr;
989
    if (val - 8 < 0x01fffffd && val - 8 > -0x01fffffd)
990
        tcg_out_b(s, cond, val);
991
    else {
992
        if (cond == COND_AL) {
993
            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
994
            tcg_out32(s, addr);
995
        } else {
996
            tcg_out_movi32(s, cond, TCG_REG_TMP, val - 8);
997
            tcg_out_dat_reg(s, cond, ARITH_ADD,
998
                            TCG_REG_PC, TCG_REG_PC,
999
                            TCG_REG_TMP, SHIFT_IMM_LSL(0));
1000
        }
1001
    }
1002
}
1003

    
1004
/* The call case is mostly used for helpers - so it's not unreasonable
1005
 * for them to be beyond branch range */
1006
static inline void tcg_out_call(TCGContext *s, uint32_t addr)
1007
{
1008
    int32_t val;
1009

    
1010
    val = addr - (tcg_target_long) s->code_ptr;
1011
    if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
1012
        if (addr & 1) {
1013
            /* Use BLX if the target is in Thumb mode */
1014
            if (!use_armv5_instructions) {
1015
                tcg_abort();
1016
            }
1017
            tcg_out_blx_imm(s, val);
1018
        } else {
1019
            tcg_out_bl(s, COND_AL, val);
1020
        }
1021
    } else {
1022
        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
1023
        tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1024
        tcg_out32(s, addr);
1025
    }
1026
}
1027

    
1028
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
1029
{
1030
    if (use_armv5_instructions) {
1031
        tcg_out_blx(s, cond, arg);
1032
    } else {
1033
        tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
1034
                        TCG_REG_PC, SHIFT_IMM_LSL(0));
1035
        tcg_out_bx(s, cond, arg);
1036
    }
1037
}
1038

    
1039
static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
1040
{
1041
    TCGLabel *l = &s->labels[label_index];
1042

    
1043
    if (l->has_value)
1044
        tcg_out_goto(s, cond, l->u.value);
1045
    else if (cond == COND_AL) {
1046
        tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1047
        tcg_out_reloc(s, s->code_ptr, R_ARM_ABS32, label_index, 31337);
1048
        s->code_ptr += 4;
1049
    } else {
1050
        /* Probably this should be preferred even for COND_AL... */
1051
        tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
1052
        tcg_out_b_noaddr(s, cond);
1053
    }
1054
}
1055

    
1056
#ifdef CONFIG_SOFTMMU
1057

    
1058
#include "exec/softmmu_defs.h"
1059

    
1060
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1061
   int mmu_idx) */
1062
static const void * const qemu_ld_helpers[4] = {
1063
    helper_ldb_mmu,
1064
    helper_ldw_mmu,
1065
    helper_ldl_mmu,
1066
    helper_ldq_mmu,
1067
};
1068

    
1069
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1070
   uintxx_t val, int mmu_idx) */
1071
static const void * const qemu_st_helpers[4] = {
1072
    helper_stb_mmu,
1073
    helper_stw_mmu,
1074
    helper_stl_mmu,
1075
    helper_stq_mmu,
1076
};
1077

    
1078
/* Helper routines for marshalling helper function arguments into
1079
 * the correct registers and stack.
1080
 * argreg is where we want to put this argument, arg is the argument itself.
1081
 * Return value is the updated argreg ready for the next call.
1082
 * Note that argreg 0..3 is real registers, 4+ on stack.
1083
 *
1084
 * We provide routines for arguments which are: immediate, 32 bit
1085
 * value in register, 16 and 8 bit values in register (which must be zero
1086
 * extended before use) and 64 bit value in a lo:hi register pair.
1087
 */
1088
#define DEFINE_TCG_OUT_ARG(NAME, ARGTYPE, MOV_ARG, EXT_ARG)                \
1089
static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg)              \
1090
{                                                                          \
1091
    if (argreg < 4) {                                                      \
1092
        MOV_ARG(s, COND_AL, argreg, arg);                                  \
1093
    } else {                                                               \
1094
        int ofs = (argreg - 4) * 4;                                        \
1095
        EXT_ARG;                                                           \
1096
        assert(ofs + 4 <= TCG_STATIC_CALL_ARGS_SIZE);                      \
1097
        tcg_out_st32_12(s, COND_AL, arg, TCG_REG_CALL_STACK, ofs);         \
1098
    }                                                                      \
1099
    return argreg + 1;                                                     \
1100
}
1101

    
1102
DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
1103
    (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1104
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u,
1105
    (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1106
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
1107
    (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1108
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
1109

    
1110
static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
1111
                                TCGReg arglo, TCGReg arghi)
1112
{
1113
    /* 64 bit arguments must go in even/odd register pairs
1114
     * and in 8-aligned stack slots.
1115
     */
1116
    if (argreg & 1) {
1117
        argreg++;
1118
    }
1119
    argreg = tcg_out_arg_reg32(s, argreg, arglo);
1120
    argreg = tcg_out_arg_reg32(s, argreg, arghi);
1121
    return argreg;
1122
}
1123

    
1124
#define TLB_SHIFT        (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
1125

    
1126
/* Load and compare a TLB entry, leaving the flags set.  Leaves R2 pointing
1127
   to the tlb entry.  Clobbers R1 and TMP.  */
1128

    
1129
static void tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
1130
                             int s_bits, int tlb_offset)
1131
{
1132
    TCGReg base = TCG_AREG0;
1133

    
1134
    /* Should generate something like the following:
1135
     * pre-v7:
1136
     *   shr    tmp, addr_reg, #TARGET_PAGE_BITS                  (1)
1137
     *   add    r2, env, #off & 0xff00
1138
     *   and    r0, tmp, #(CPU_TLB_SIZE - 1)                      (2)
1139
     *   add    r2, r2, r0, lsl #CPU_TLB_ENTRY_BITS               (3)
1140
     *   ldr    r0, [r2, #off & 0xff]!                            (4)
1141
     *   tst    addr_reg, #s_mask
1142
     *   cmpeq  r0, tmp, lsl #TARGET_PAGE_BITS                    (5)
1143
     *
1144
     * v7 (not implemented yet):
1145
     *   ubfx   r2, addr_reg, #TARGET_PAGE_BITS, #CPU_TLB_BITS    (1)
1146
     *   movw   tmp, #~TARGET_PAGE_MASK & ~s_mask
1147
     *   movw   r0, #off
1148
     *   add    r2, env, r2, lsl #CPU_TLB_ENTRY_BITS              (2)
1149
     *   bic    tmp, addr_reg, tmp
1150
     *   ldr    r0, [r2, r0]!                                     (3)
1151
     *   cmp    r0, tmp                                           (4)
1152
     */
1153
#  if CPU_TLB_BITS > 8
1154
#   error
1155
#  endif
1156
    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,
1157
                    0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1158

    
1159
    /* We assume that the offset is contained within 16 bits.  */
1160
    assert((tlb_offset & ~0xffff) == 0);
1161
    if (tlb_offset > 0xff) {
1162
        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1163
                        (24 << 7) | (tlb_offset >> 8));
1164
        tlb_offset &= 0xff;
1165
        base = TCG_REG_R2;
1166
    }
1167

    
1168
    tcg_out_dat_imm(s, COND_AL, ARITH_AND,
1169
                    TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);
1170
    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1171
                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
1172

    
1173
    /* Load the tlb comparator.  Use ldrd if needed and available,
1174
       but due to how the pointer needs setting up, ldm isn't useful.
1175
       Base arm5 doesn't have ldrd, but armv5te does.  */
1176
    if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
1177
        tcg_out_memop_8(s, COND_AL, INSN_LDRD_IMM, TCG_REG_R0,
1178
                        TCG_REG_R2, tlb_offset, 1, 1);
1179
    } else {
1180
        tcg_out_memop_12(s, COND_AL, INSN_LDR_IMM, TCG_REG_R0,
1181
                         TCG_REG_R2, tlb_offset, 1, 1);
1182
        if (TARGET_LONG_BITS == 64) {
1183
            tcg_out_memop_12(s, COND_AL, INSN_LDR_IMM, TCG_REG_R0,
1184
                             TCG_REG_R2, 4, 1, 0);
1185
        }
1186
    }
1187

    
1188
    /* Check alignment.  */
1189
    if (s_bits) {
1190
        tcg_out_dat_imm(s, COND_AL, ARITH_TST,
1191
                        0, addrlo, (1 << s_bits) - 1);
1192
    }
1193

    
1194
    tcg_out_dat_reg(s, (s_bits ? COND_EQ : COND_AL), ARITH_CMP, 0,
1195
                    TCG_REG_R0, TCG_REG_TMP, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1196

    
1197
    if (TARGET_LONG_BITS == 64) {
1198
        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1199
                        TCG_REG_R1, addrhi, SHIFT_IMM_LSL(0));
1200
    }
1201
}
1202
#endif /* SOFTMMU */
1203

    
1204
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
1205
{
1206
    TCGReg addr_reg, data_reg, data_reg2;
1207
    bool bswap;
1208
#ifdef CONFIG_SOFTMMU
1209
    int mem_index, s_bits;
1210
    TCGReg argreg, addr_reg2;
1211
    uint32_t *label_ptr;
1212
#endif
1213
#ifdef TARGET_WORDS_BIGENDIAN
1214
    bswap = 1;
1215
#else
1216
    bswap = 0;
1217
#endif
1218

    
1219
    data_reg = *args++;
1220
    data_reg2 = (opc == 3 ? *args++ : 0);
1221
    addr_reg = *args++;
1222
#ifdef CONFIG_SOFTMMU
1223
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1224
    mem_index = *args;
1225
    s_bits = opc & 3;
1226

    
1227
    tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits,
1228
                     offsetof(CPUArchState, tlb_table[mem_index][0].addr_read));
1229

    
1230
    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R2,
1231
                    offsetof(CPUTLBEntry, addend)
1232
                    - offsetof(CPUTLBEntry, addr_read));
1233

    
1234
    switch (opc) {
1235
    case 0:
1236
        tcg_out_ld8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1237
        break;
1238
    case 0 | 4:
1239
        tcg_out_ld8s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1240
        break;
1241
    case 1:
1242
        tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1243
        if (bswap) {
1244
            tcg_out_bswap16(s, COND_EQ, data_reg, data_reg);
1245
        }
1246
        break;
1247
    case 1 | 4:
1248
        if (bswap) {
1249
            tcg_out_ld16u_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1250
            tcg_out_bswap16s(s, COND_EQ, data_reg, data_reg);
1251
        } else {
1252
            tcg_out_ld16s_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1253
        }
1254
        break;
1255
    case 2:
1256
    default:
1257
        tcg_out_ld32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1258
        if (bswap) {
1259
            tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
1260
        }
1261
        break;
1262
    case 3:
1263
        if (bswap) {
1264
            tcg_out_ld32_rwb(s, COND_EQ, data_reg2, TCG_REG_R1, addr_reg);
1265
            tcg_out_ld32_12(s, COND_EQ, data_reg, TCG_REG_R1, 4);
1266
            tcg_out_bswap32(s, COND_EQ, data_reg2, data_reg2);
1267
            tcg_out_bswap32(s, COND_EQ, data_reg, data_reg);
1268
        } else {
1269
            tcg_out_ld32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
1270
            tcg_out_ld32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
1271
        }
1272
        break;
1273
    }
1274

    
1275
    label_ptr = (void *) s->code_ptr;
1276
    tcg_out_b_noaddr(s, COND_EQ);
1277

    
1278
    /* TODO: move this code to where the constants pool will be */
1279
    /* Note that this code relies on the constraints we set in arm_op_defs[]
1280
     * to ensure that later arguments are not passed to us in registers we
1281
     * trash by moving the earlier arguments into them.
1282
     */
1283
    argreg = TCG_REG_R0;
1284
    argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1285
    if (TARGET_LONG_BITS == 64) {
1286
        argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
1287
    } else {
1288
        argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
1289
    }
1290
    argreg = tcg_out_arg_imm32(s, argreg, mem_index);
1291
    tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]);
1292

    
1293
    switch (opc) {
1294
    case 0 | 4:
1295
        tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
1296
        break;
1297
    case 1 | 4:
1298
        tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
1299
        break;
1300
    case 0:
1301
    case 1:
1302
    case 2:
1303
    default:
1304
        tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1305
        break;
1306
    case 3:
1307
        tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1308
        tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1309
        break;
1310
    }
1311

    
1312
    reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
1313
#else /* !CONFIG_SOFTMMU */
1314
    if (GUEST_BASE) {
1315
        uint32_t offset = GUEST_BASE;
1316
        int i, rot;
1317

    
1318
        while (offset) {
1319
            i = ctz32(offset) & ~1;
1320
            rot = ((32 - i) << 7) & 0xf00;
1321

    
1322
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_TMP, addr_reg,
1323
                            ((offset >> i) & 0xff) | rot);
1324
            addr_reg = TCG_REG_TMP;
1325
            offset &= ~(0xff << i);
1326
        }
1327
    }
1328
    switch (opc) {
1329
    case 0:
1330
        tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
1331
        break;
1332
    case 0 | 4:
1333
        tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
1334
        break;
1335
    case 1:
1336
        tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1337
        if (bswap) {
1338
            tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1339
        }
1340
        break;
1341
    case 1 | 4:
1342
        if (bswap) {
1343
            tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1344
            tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1345
        } else {
1346
            tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
1347
        }
1348
        break;
1349
    case 2:
1350
    default:
1351
        tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
1352
        if (bswap) {
1353
            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1354
        }
1355
        break;
1356
    case 3:
1357
        /* TODO: use block load -
1358
         * check that data_reg2 > data_reg or the other way */
1359
        if (data_reg == addr_reg) {
1360
            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1361
            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1362
        } else {
1363
            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1364
            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1365
        }
1366
        if (bswap) {
1367
            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1368
            tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
1369
        }
1370
        break;
1371
    }
1372
#endif
1373
}
1374

    
1375
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1376
{
1377
    TCGReg addr_reg, data_reg, data_reg2;
1378
    bool bswap;
1379
#ifdef CONFIG_SOFTMMU
1380
    int mem_index, s_bits;
1381
    TCGReg argreg, addr_reg2;
1382
    uint32_t *label_ptr;
1383
#endif
1384
#ifdef TARGET_WORDS_BIGENDIAN
1385
    bswap = 1;
1386
#else
1387
    bswap = 0;
1388
#endif
1389

    
1390
    data_reg = *args++;
1391
    data_reg2 = (opc == 3 ? *args++ : 0);
1392
    addr_reg = *args++;
1393
#ifdef CONFIG_SOFTMMU
1394
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1395
    mem_index = *args;
1396
    s_bits = opc & 3;
1397

    
1398
    tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits,
1399
                     offsetof(CPUArchState,
1400
                              tlb_table[mem_index][0].addr_write));
1401

    
1402
    tcg_out_ld32_12(s, COND_EQ, TCG_REG_R1, TCG_REG_R2,
1403
                    offsetof(CPUTLBEntry, addend)
1404
                    - offsetof(CPUTLBEntry, addr_write));
1405

    
1406
    switch (opc) {
1407
    case 0:
1408
        tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1409
        break;
1410
    case 1:
1411
        if (bswap) {
1412
            tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg);
1413
            tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
1414
        } else {
1415
            tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1416
        }
1417
        break;
1418
    case 2:
1419
    default:
1420
        if (bswap) {
1421
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1422
            tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, TCG_REG_R1);
1423
        } else {
1424
            tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, TCG_REG_R1);
1425
        }
1426
        break;
1427
    case 3:
1428
        if (bswap) {
1429
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
1430
            tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, addr_reg);
1431
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1432
            tcg_out_st32_12(s, COND_EQ, TCG_REG_R0, TCG_REG_R1, 4);
1433
        } else {
1434
            tcg_out_st32_rwb(s, COND_EQ, data_reg, TCG_REG_R1, addr_reg);
1435
            tcg_out_st32_12(s, COND_EQ, data_reg2, TCG_REG_R1, 4);
1436
        }
1437
        break;
1438
    }
1439

    
1440
    label_ptr = (void *) s->code_ptr;
1441
    tcg_out_b_noaddr(s, COND_EQ);
1442

    
1443
    /* TODO: move this code to where the constants pool will be */
1444
    /* Note that this code relies on the constraints we set in arm_op_defs[]
1445
     * to ensure that later arguments are not passed to us in registers we
1446
     * trash by moving the earlier arguments into them.
1447
     */
1448
    argreg = TCG_REG_R0;
1449
    argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1450
    if (TARGET_LONG_BITS == 64) {
1451
        argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
1452
    } else {
1453
        argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
1454
    }
1455

    
1456
    switch (opc) {
1457
    case 0:
1458
        argreg = tcg_out_arg_reg8(s, argreg, data_reg);
1459
        break;
1460
    case 1:
1461
        argreg = tcg_out_arg_reg16(s, argreg, data_reg);
1462
        break;
1463
    case 2:
1464
        argreg = tcg_out_arg_reg32(s, argreg, data_reg);
1465
        break;
1466
    case 3:
1467
        argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2);
1468
        break;
1469
    }
1470

    
1471
    argreg = tcg_out_arg_imm32(s, argreg, mem_index);
1472
    tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]);
1473

    
1474
    reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
1475
#else /* !CONFIG_SOFTMMU */
1476
    if (GUEST_BASE) {
1477
        uint32_t offset = GUEST_BASE;
1478
        int i;
1479
        int rot;
1480

    
1481
        while (offset) {
1482
            i = ctz32(offset) & ~1;
1483
            rot = ((32 - i) << 7) & 0xf00;
1484

    
1485
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R1, addr_reg,
1486
                            ((offset >> i) & 0xff) | rot);
1487
            addr_reg = TCG_REG_R1;
1488
            offset &= ~(0xff << i);
1489
        }
1490
    }
1491
    switch (opc) {
1492
    case 0:
1493
        tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
1494
        break;
1495
    case 1:
1496
        if (bswap) {
1497
            tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg);
1498
            tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1499
        } else {
1500
            tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
1501
        }
1502
        break;
1503
    case 2:
1504
    default:
1505
        if (bswap) {
1506
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1507
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1508
        } else {
1509
            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1510
        }
1511
        break;
1512
    case 3:
1513
        /* TODO: use block store -
1514
         * check that data_reg2 > data_reg or the other way */
1515
        if (bswap) {
1516
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
1517
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1518
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1519
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
1520
        } else {
1521
            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1522
            tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
1523
        }
1524
        break;
1525
    }
1526
#endif
1527
}
1528

    
1529
static uint8_t *tb_ret_addr;
1530

    
1531
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1532
                const TCGArg *args, const int *const_args)
1533
{
1534
    TCGArg a0, a1, a2, a3, a4, a5;
1535
    int c;
1536

    
1537
    switch (opc) {
1538
    case INDEX_op_exit_tb:
1539
        {
1540
            uint8_t *ld_ptr = s->code_ptr;
1541
            if (args[0] >> 8)
1542
                tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1543
            else
1544
                tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);
1545
            tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1546
            if (args[0] >> 8) {
1547
                *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
1548
                tcg_out32(s, args[0]);
1549
            }
1550
        }
1551
        break;
1552
    case INDEX_op_goto_tb:
1553
        if (s->tb_jmp_offset) {
1554
            /* Direct jump method */
1555
#if defined(USE_DIRECT_JUMP)
1556
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1557
            tcg_out_b_noaddr(s, COND_AL);
1558
#else
1559
            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1560
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1561
            tcg_out32(s, 0);
1562
#endif
1563
        } else {
1564
            /* Indirect jump method */
1565
#if 1
1566
            c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
1567
            if (c > 0xfff || c < -0xfff) {
1568
                tcg_out_movi32(s, COND_AL, TCG_REG_R0,
1569
                                (tcg_target_long) (s->tb_next + args[0]));
1570
                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1571
            } else
1572
                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
1573
#else
1574
            tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1575
            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1576
            tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
1577
#endif
1578
        }
1579
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1580
        break;
1581
    case INDEX_op_call:
1582
        if (const_args[0])
1583
            tcg_out_call(s, args[0]);
1584
        else
1585
            tcg_out_callr(s, COND_AL, args[0]);
1586
        break;
1587
    case INDEX_op_br:
1588
        tcg_out_goto_label(s, COND_AL, args[0]);
1589
        break;
1590

    
1591
    case INDEX_op_ld8u_i32:
1592
        tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
1593
        break;
1594
    case INDEX_op_ld8s_i32:
1595
        tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
1596
        break;
1597
    case INDEX_op_ld16u_i32:
1598
        tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
1599
        break;
1600
    case INDEX_op_ld16s_i32:
1601
        tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
1602
        break;
1603
    case INDEX_op_ld_i32:
1604
        tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
1605
        break;
1606
    case INDEX_op_st8_i32:
1607
        tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
1608
        break;
1609
    case INDEX_op_st16_i32:
1610
        tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
1611
        break;
1612
    case INDEX_op_st_i32:
1613
        tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
1614
        break;
1615

    
1616
    case INDEX_op_mov_i32:
1617
        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
1618
                        args[0], 0, args[1], SHIFT_IMM_LSL(0));
1619
        break;
1620
    case INDEX_op_movi_i32:
1621
        tcg_out_movi32(s, COND_AL, args[0], args[1]);
1622
        break;
1623
    case INDEX_op_movcond_i32:
1624
        /* Constraints mean that v2 is always in the same register as dest,
1625
         * so we only need to do "if condition passed, move v1 to dest".
1626
         */
1627
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1628
                        args[1], args[2], const_args[2]);
1629
        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
1630
                        ARITH_MVN, args[0], 0, args[3], const_args[3]);
1631
        break;
1632
    case INDEX_op_add_i32:
1633
        tcg_out_dat_rIN(s, COND_AL, ARITH_ADD, ARITH_SUB,
1634
                        args[0], args[1], args[2], const_args[2]);
1635
        break;
1636
    case INDEX_op_sub_i32:
1637
        if (const_args[1]) {
1638
            if (const_args[2]) {
1639
                tcg_out_movi32(s, COND_AL, args[0], args[1] - args[2]);
1640
            } else {
1641
                tcg_out_dat_rI(s, COND_AL, ARITH_RSB,
1642
                               args[0], args[2], args[1], 1);
1643
            }
1644
        } else {
1645
            tcg_out_dat_rIN(s, COND_AL, ARITH_SUB, ARITH_ADD,
1646
                            args[0], args[1], args[2], const_args[2]);
1647
        }
1648
        break;
1649
    case INDEX_op_and_i32:
1650
        tcg_out_dat_rIK(s, COND_AL, ARITH_AND, ARITH_BIC,
1651
                        args[0], args[1], args[2], const_args[2]);
1652
        break;
1653
    case INDEX_op_andc_i32:
1654
        tcg_out_dat_rIK(s, COND_AL, ARITH_BIC, ARITH_AND,
1655
                        args[0], args[1], args[2], const_args[2]);
1656
        break;
1657
    case INDEX_op_or_i32:
1658
        c = ARITH_ORR;
1659
        goto gen_arith;
1660
    case INDEX_op_xor_i32:
1661
        c = ARITH_EOR;
1662
        /* Fall through.  */
1663
    gen_arith:
1664
        tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);
1665
        break;
1666
    case INDEX_op_add2_i32:
1667
        a0 = args[0], a1 = args[1], a2 = args[2];
1668
        a3 = args[3], a4 = args[4], a5 = args[5];
1669
        if (a0 == a3 || (a0 == a5 && !const_args[5])) {
1670
            a0 = TCG_REG_TMP;
1671
        }
1672
        tcg_out_dat_rIN(s, COND_AL, ARITH_ADD | TO_CPSR, ARITH_SUB | TO_CPSR,
1673
                        a0, a2, a4, const_args[4]);
1674
        tcg_out_dat_rIK(s, COND_AL, ARITH_ADC, ARITH_SBC,
1675
                        a1, a3, a5, const_args[5]);
1676
        tcg_out_mov_reg(s, COND_AL, args[0], a0);
1677
        break;
1678
    case INDEX_op_sub2_i32:
1679
        a0 = args[0], a1 = args[1], a2 = args[2];
1680
        a3 = args[3], a4 = args[4], a5 = args[5];
1681
        if ((a0 == a3 && !const_args[3]) || (a0 == a5 && !const_args[5])) {
1682
            a0 = TCG_REG_TMP;
1683
        }
1684
        if (const_args[2]) {
1685
            if (const_args[4]) {
1686
                tcg_out_movi32(s, COND_AL, a0, a4);
1687
                a4 = a0;
1688
            }
1689
            tcg_out_dat_rI(s, COND_AL, ARITH_RSB | TO_CPSR, a0, a4, a2, 1);
1690
        } else {
1691
            tcg_out_dat_rIN(s, COND_AL, ARITH_SUB | TO_CPSR,
1692
                            ARITH_ADD | TO_CPSR, a0, a2, a4, const_args[4]);
1693
        }
1694
        if (const_args[3]) {
1695
            if (const_args[5]) {
1696
                tcg_out_movi32(s, COND_AL, a1, a5);
1697
                a5 = a1;
1698
            }
1699
            tcg_out_dat_rI(s, COND_AL, ARITH_RSC, a1, a5, a3, 1);
1700
        } else {
1701
            tcg_out_dat_rIK(s, COND_AL, ARITH_SBC, ARITH_ADC,
1702
                            a1, a3, a5, const_args[5]);
1703
        }
1704
        tcg_out_mov_reg(s, COND_AL, args[0], a0);
1705
        break;
1706
    case INDEX_op_neg_i32:
1707
        tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
1708
        break;
1709
    case INDEX_op_not_i32:
1710
        tcg_out_dat_reg(s, COND_AL,
1711
                        ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
1712
        break;
1713
    case INDEX_op_mul_i32:
1714
        tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
1715
        break;
1716
    case INDEX_op_mulu2_i32:
1717
        tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1718
        break;
1719
    case INDEX_op_muls2_i32:
1720
        tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1721
        break;
1722
    /* XXX: Perhaps args[2] & 0x1f is wrong */
1723
    case INDEX_op_shl_i32:
1724
        c = const_args[2] ?
1725
                SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
1726
        goto gen_shift32;
1727
    case INDEX_op_shr_i32:
1728
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
1729
                SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
1730
        goto gen_shift32;
1731
    case INDEX_op_sar_i32:
1732
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
1733
                SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
1734
        goto gen_shift32;
1735
    case INDEX_op_rotr_i32:
1736
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
1737
                SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
1738
        /* Fall through.  */
1739
    gen_shift32:
1740
        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
1741
        break;
1742

    
1743
    case INDEX_op_rotl_i32:
1744
        if (const_args[2]) {
1745
            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1746
                            ((0x20 - args[2]) & 0x1f) ?
1747
                            SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
1748
                            SHIFT_IMM_LSL(0));
1749
        } else {
1750
            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[1], 0x20);
1751
            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1752
                            SHIFT_REG_ROR(TCG_REG_TMP));
1753
        }
1754
        break;
1755

    
1756
    case INDEX_op_brcond_i32:
1757
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1758
                       args[0], args[1], const_args[1]);
1759
        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
1760
        break;
1761
    case INDEX_op_brcond2_i32:
1762
        /* The resulting conditions are:
1763
         * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,
1764
         * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,
1765
         * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,
1766
         * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
1767
         * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
1768
         * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,
1769
         */
1770
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1771
                        args[1], args[3], const_args[3]);
1772
        tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1773
                        args[0], args[2], const_args[2]);
1774
        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
1775
        break;
1776
    case INDEX_op_setcond_i32:
1777
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1778
                        args[1], args[2], const_args[2]);
1779
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
1780
                        ARITH_MOV, args[0], 0, 1);
1781
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
1782
                        ARITH_MOV, args[0], 0, 0);
1783
        break;
1784
    case INDEX_op_setcond2_i32:
1785
        /* See brcond2_i32 comment */
1786
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1787
                        args[2], args[4], const_args[4]);
1788
        tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1789
                        args[1], args[3], const_args[3]);
1790
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],
1791
                        ARITH_MOV, args[0], 0, 1);
1792
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],
1793
                        ARITH_MOV, args[0], 0, 0);
1794
        break;
1795

    
1796
    case INDEX_op_qemu_ld8u:
1797
        tcg_out_qemu_ld(s, args, 0);
1798
        break;
1799
    case INDEX_op_qemu_ld8s:
1800
        tcg_out_qemu_ld(s, args, 0 | 4);
1801
        break;
1802
    case INDEX_op_qemu_ld16u:
1803
        tcg_out_qemu_ld(s, args, 1);
1804
        break;
1805
    case INDEX_op_qemu_ld16s:
1806
        tcg_out_qemu_ld(s, args, 1 | 4);
1807
        break;
1808
    case INDEX_op_qemu_ld32:
1809
        tcg_out_qemu_ld(s, args, 2);
1810
        break;
1811
    case INDEX_op_qemu_ld64:
1812
        tcg_out_qemu_ld(s, args, 3);
1813
        break;
1814

    
1815
    case INDEX_op_qemu_st8:
1816
        tcg_out_qemu_st(s, args, 0);
1817
        break;
1818
    case INDEX_op_qemu_st16:
1819
        tcg_out_qemu_st(s, args, 1);
1820
        break;
1821
    case INDEX_op_qemu_st32:
1822
        tcg_out_qemu_st(s, args, 2);
1823
        break;
1824
    case INDEX_op_qemu_st64:
1825
        tcg_out_qemu_st(s, args, 3);
1826
        break;
1827

    
1828
    case INDEX_op_bswap16_i32:
1829
        tcg_out_bswap16(s, COND_AL, args[0], args[1]);
1830
        break;
1831
    case INDEX_op_bswap32_i32:
1832
        tcg_out_bswap32(s, COND_AL, args[0], args[1]);
1833
        break;
1834

    
1835
    case INDEX_op_ext8s_i32:
1836
        tcg_out_ext8s(s, COND_AL, args[0], args[1]);
1837
        break;
1838
    case INDEX_op_ext16s_i32:
1839
        tcg_out_ext16s(s, COND_AL, args[0], args[1]);
1840
        break;
1841
    case INDEX_op_ext16u_i32:
1842
        tcg_out_ext16u(s, COND_AL, args[0], args[1]);
1843
        break;
1844

    
1845
    case INDEX_op_deposit_i32:
1846
        tcg_out_deposit(s, COND_AL, args[0], args[2],
1847
                        args[3], args[4], const_args[2]);
1848
        break;
1849

    
1850
    case INDEX_op_div_i32:
1851
        tcg_out_sdiv(s, COND_AL, args[0], args[1], args[2]);
1852
        break;
1853
    case INDEX_op_divu_i32:
1854
        tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
1855
        break;
1856
    case INDEX_op_rem_i32:
1857
        tcg_out_sdiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
1858
        tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
1859
        tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
1860
                        SHIFT_IMM_LSL(0));
1861
        break;
1862
    case INDEX_op_remu_i32:
1863
        tcg_out_udiv(s, COND_AL, TCG_REG_TMP, args[1], args[2]);
1864
        tcg_out_mul32(s, COND_AL, TCG_REG_TMP, TCG_REG_TMP, args[2]);
1865
        tcg_out_dat_reg(s, COND_AL, ARITH_SUB, args[0], args[1], TCG_REG_TMP,
1866
                        SHIFT_IMM_LSL(0));
1867
        break;
1868

    
1869
    default:
1870
        tcg_abort();
1871
    }
1872
}
1873

    
1874
static const TCGTargetOpDef arm_op_defs[] = {
1875
    { INDEX_op_exit_tb, { } },
1876
    { INDEX_op_goto_tb, { } },
1877
    { INDEX_op_call, { "ri" } },
1878
    { INDEX_op_br, { } },
1879

    
1880
    { INDEX_op_mov_i32, { "r", "r" } },
1881
    { INDEX_op_movi_i32, { "r" } },
1882

    
1883
    { INDEX_op_ld8u_i32, { "r", "r" } },
1884
    { INDEX_op_ld8s_i32, { "r", "r" } },
1885
    { INDEX_op_ld16u_i32, { "r", "r" } },
1886
    { INDEX_op_ld16s_i32, { "r", "r" } },
1887
    { INDEX_op_ld_i32, { "r", "r" } },
1888
    { INDEX_op_st8_i32, { "r", "r" } },
1889
    { INDEX_op_st16_i32, { "r", "r" } },
1890
    { INDEX_op_st_i32, { "r", "r" } },
1891

    
1892
    /* TODO: "r", "r", "ri" */
1893
    { INDEX_op_add_i32, { "r", "r", "rIN" } },
1894
    { INDEX_op_sub_i32, { "r", "rI", "rIN" } },
1895
    { INDEX_op_mul_i32, { "r", "r", "r" } },
1896
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
1897
    { INDEX_op_muls2_i32, { "r", "r", "r", "r" } },
1898
    { INDEX_op_and_i32, { "r", "r", "rIK" } },
1899
    { INDEX_op_andc_i32, { "r", "r", "rIK" } },
1900
    { INDEX_op_or_i32, { "r", "r", "rI" } },
1901
    { INDEX_op_xor_i32, { "r", "r", "rI" } },
1902
    { INDEX_op_neg_i32, { "r", "r" } },
1903
    { INDEX_op_not_i32, { "r", "r" } },
1904

    
1905
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
1906
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
1907
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
1908
    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
1909
    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
1910

    
1911
    { INDEX_op_brcond_i32, { "r", "rIN" } },
1912
    { INDEX_op_setcond_i32, { "r", "r", "rIN" } },
1913
    { INDEX_op_movcond_i32, { "r", "r", "rIN", "rIK", "0" } },
1914

    
1915
    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rIN", "rIK" } },
1916
    { INDEX_op_sub2_i32, { "r", "r", "rI", "rI", "rIN", "rIK" } },
1917
    { INDEX_op_brcond2_i32, { "r", "r", "rIN", "rIN" } },
1918
    { INDEX_op_setcond2_i32, { "r", "r", "r", "rIN", "rIN" } },
1919

    
1920
#if TARGET_LONG_BITS == 32
1921
    { INDEX_op_qemu_ld8u, { "r", "l" } },
1922
    { INDEX_op_qemu_ld8s, { "r", "l" } },
1923
    { INDEX_op_qemu_ld16u, { "r", "l" } },
1924
    { INDEX_op_qemu_ld16s, { "r", "l" } },
1925
    { INDEX_op_qemu_ld32, { "r", "l" } },
1926
    { INDEX_op_qemu_ld64, { "L", "L", "l" } },
1927

    
1928
    { INDEX_op_qemu_st8, { "s", "s" } },
1929
    { INDEX_op_qemu_st16, { "s", "s" } },
1930
    { INDEX_op_qemu_st32, { "s", "s" } },
1931
    { INDEX_op_qemu_st64, { "S", "S", "s" } },
1932
#else
1933
    { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
1934
    { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
1935
    { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
1936
    { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
1937
    { INDEX_op_qemu_ld32, { "r", "l", "l" } },
1938
    { INDEX_op_qemu_ld64, { "L", "L", "l", "l" } },
1939

    
1940
    { INDEX_op_qemu_st8, { "s", "s", "s" } },
1941
    { INDEX_op_qemu_st16, { "s", "s", "s" } },
1942
    { INDEX_op_qemu_st32, { "s", "s", "s" } },
1943
    { INDEX_op_qemu_st64, { "S", "S", "s", "s" } },
1944
#endif
1945

    
1946
    { INDEX_op_bswap16_i32, { "r", "r" } },
1947
    { INDEX_op_bswap32_i32, { "r", "r" } },
1948

    
1949
    { INDEX_op_ext8s_i32, { "r", "r" } },
1950
    { INDEX_op_ext16s_i32, { "r", "r" } },
1951
    { INDEX_op_ext16u_i32, { "r", "r" } },
1952

    
1953
    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
1954

    
1955
#if TCG_TARGET_HAS_div_i32
1956
    { INDEX_op_div_i32, { "r", "r", "r" } },
1957
    { INDEX_op_rem_i32, { "r", "r", "r" } },
1958
    { INDEX_op_divu_i32, { "r", "r", "r" } },
1959
    { INDEX_op_remu_i32, { "r", "r", "r" } },
1960
#endif
1961

    
1962
    { -1 },
1963
};
1964

    
1965
static void tcg_target_init(TCGContext *s)
1966
{
1967
#if !defined(CONFIG_USER_ONLY)
1968
    /* fail safe */
1969
    if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1970
        tcg_abort();
1971
#endif
1972

    
1973
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
1974
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1975
                     (1 << TCG_REG_R0) |
1976
                     (1 << TCG_REG_R1) |
1977
                     (1 << TCG_REG_R2) |
1978
                     (1 << TCG_REG_R3) |
1979
                     (1 << TCG_REG_R12) |
1980
                     (1 << TCG_REG_R14));
1981

    
1982
    tcg_regset_clear(s->reserved_regs);
1983
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
1984
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
1985
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
1986

    
1987
    tcg_add_target_add_op_defs(arm_op_defs);
1988
}
1989

    
1990
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
1991
                              TCGReg arg1, tcg_target_long arg2)
1992
{
1993
    tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
1994
}
1995

    
1996
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1997
                              TCGReg arg1, tcg_target_long arg2)
1998
{
1999
    tcg_out_st32(s, COND_AL, arg, arg1, arg2);
2000
}
2001

    
2002
static inline void tcg_out_mov(TCGContext *s, TCGType type,
2003
                               TCGReg ret, TCGReg arg)
2004
{
2005
    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
2006
}
2007

    
2008
static inline void tcg_out_movi(TCGContext *s, TCGType type,
2009
                                TCGReg ret, tcg_target_long arg)
2010
{
2011
    tcg_out_movi32(s, COND_AL, ret, arg);
2012
}
2013

    
2014
static void tcg_target_qemu_prologue(TCGContext *s)
2015
{
2016
    int frame_size;
2017

    
2018
    /* Calling convention requires us to save r4-r11 and lr.  */
2019
    /* stmdb sp!, { r4 - r11, lr } */
2020
    tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
2021

    
2022
    /* Allocate the local stack frame.  */
2023
    frame_size = TCG_STATIC_CALL_ARGS_SIZE;
2024
    frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long);
2025
    /* We saved an odd number of registers above; keep an 8 aligned stack.  */
2026
    frame_size = ((frame_size + TCG_TARGET_STACK_ALIGN - 1)
2027
                  & -TCG_TARGET_STACK_ALIGN) + 4;
2028

    
2029
    tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
2030
                   TCG_REG_CALL_STACK, frame_size, 1);
2031
    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2032
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
2033

    
2034
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2035

    
2036
    tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
2037
    tb_ret_addr = s->code_ptr;
2038

    
2039
    /* Epilogue.  We branch here via tb_ret_addr.  */
2040
    tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
2041
                   TCG_REG_CALL_STACK, frame_size, 1);
2042

    
2043
    /* ldmia sp!, { r4 - r11, pc } */
2044
    tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
2045
}