Statistics
| Branch: | Revision:

root / tcg / arm / tcg-target.c @ 66c2056f

History | View | Annotate | Download (73 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
/* The __ARM_ARCH define is provided by gcc 4.8.  Construct it otherwise.  */
26
#ifndef __ARM_ARCH
27
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
28
     || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
29
     || defined(__ARM_ARCH_7EM__)
30
#  define __ARM_ARCH 7
31
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
32
       || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
33
       || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
34
#  define __ARM_ARCH 6
35
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \
36
       || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
37
       || defined(__ARM_ARCH_5TEJ__)
38
#  define __ARM_ARCH 5
39
# else
40
#  define __ARM_ARCH 4
41
# endif
42
#endif
43

    
44
static int arm_arch = __ARM_ARCH;
45

    
46
#if defined(__ARM_ARCH_5T__) \
47
    || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
48
# define use_armv5t_instructions 1
49
#else
50
# define use_armv5t_instructions use_armv6_instructions
51
#endif
52

    
53
#define use_armv6_instructions  (__ARM_ARCH >= 6 || arm_arch >= 6)
54
#define use_armv7_instructions  (__ARM_ARCH >= 7 || arm_arch >= 7)
55

    
56
#ifndef use_idiv_instructions
57
bool use_idiv_instructions;
58
#endif
59
#ifdef CONFIG_GETAUXVAL
60
# include <sys/auxv.h>
61
#endif
62

    
63
#ifndef NDEBUG
64
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
65
    "%r0",
66
    "%r1",
67
    "%r2",
68
    "%r3",
69
    "%r4",
70
    "%r5",
71
    "%r6",
72
    "%r7",
73
    "%r8",
74
    "%r9",
75
    "%r10",
76
    "%r11",
77
    "%r12",
78
    "%r13",
79
    "%r14",
80
    "%pc",
81
};
82
#endif
83

    
84
static const int tcg_target_reg_alloc_order[] = {
85
    TCG_REG_R4,
86
    TCG_REG_R5,
87
    TCG_REG_R6,
88
    TCG_REG_R7,
89
    TCG_REG_R8,
90
    TCG_REG_R9,
91
    TCG_REG_R10,
92
    TCG_REG_R11,
93
    TCG_REG_R13,
94
    TCG_REG_R0,
95
    TCG_REG_R1,
96
    TCG_REG_R2,
97
    TCG_REG_R3,
98
    TCG_REG_R12,
99
    TCG_REG_R14,
100
};
101

    
102
static const int tcg_target_call_iarg_regs[4] = {
103
    TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3
104
};
105
static const int tcg_target_call_oarg_regs[2] = {
106
    TCG_REG_R0, TCG_REG_R1
107
};
108

    
109
#define TCG_REG_TMP  TCG_REG_R12
110

    
111
static inline void reloc_abs32(void *code_ptr, intptr_t target)
112
{
113
    *(uint32_t *) code_ptr = target;
114
}
115

    
116
static inline void reloc_pc24(void *code_ptr, intptr_t target)
117
{
118
    uint32_t offset = ((target - ((intptr_t)code_ptr + 8)) >> 2);
119

    
120
    *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
121
                             | (offset & 0xffffff);
122
}
123

    
124
static void patch_reloc(uint8_t *code_ptr, int type,
125
                        intptr_t value, intptr_t addend)
126
{
127
    switch (type) {
128
    case R_ARM_ABS32:
129
        reloc_abs32(code_ptr, value);
130
        break;
131

    
132
    case R_ARM_CALL:
133
    case R_ARM_JUMP24:
134
    default:
135
        tcg_abort();
136

    
137
    case R_ARM_PC24:
138
        reloc_pc24(code_ptr, value);
139
        break;
140
    }
141
}
142

    
143
#define TCG_CT_CONST_ARM  0x100
144
#define TCG_CT_CONST_INV  0x200
145
#define TCG_CT_CONST_NEG  0x400
146
#define TCG_CT_CONST_ZERO 0x800
147

    
148
/* parse target specific constraints */
149
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
150
{
151
    const char *ct_str;
152

    
153
    ct_str = *pct_str;
154
    switch (ct_str[0]) {
155
    case 'I':
156
        ct->ct |= TCG_CT_CONST_ARM;
157
        break;
158
    case 'K':
159
        ct->ct |= TCG_CT_CONST_INV;
160
        break;
161
    case 'N': /* The gcc constraint letter is L, already used here.  */
162
        ct->ct |= TCG_CT_CONST_NEG;
163
        break;
164
    case 'Z':
165
        ct->ct |= TCG_CT_CONST_ZERO;
166
        break;
167

    
168
    case 'r':
169
        ct->ct |= TCG_CT_REG;
170
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
171
        break;
172

    
173
    /* qemu_ld address */
174
    case 'l':
175
        ct->ct |= TCG_CT_REG;
176
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
177
#ifdef CONFIG_SOFTMMU
178
        /* r0-r2,lr will be overwritten when reading the tlb entry,
179
           so don't use these. */
180
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
181
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
182
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
183
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
184
#endif
185
        break;
186

    
187
    /* qemu_st address & data_reg */
188
    case 's':
189
        ct->ct |= TCG_CT_REG;
190
        tcg_regset_set32(ct->u.regs, 0, (1 << TCG_TARGET_NB_REGS) - 1);
191
        /* r0-r2 will be overwritten when reading the tlb entry (softmmu only)
192
           and r0-r1 doing the byte swapping, so don't use these. */
193
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
194
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
195
#if defined(CONFIG_SOFTMMU)
196
        /* Avoid clashes with registers being used for helper args */
197
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
198
#if TARGET_LONG_BITS == 64
199
        /* Avoid clashes with registers being used for helper args */
200
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
201
#endif
202
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R14);
203
#endif
204
        break;
205

    
206
    default:
207
        return -1;
208
    }
209
    ct_str++;
210
    *pct_str = ct_str;
211

    
212
    return 0;
213
}
214

    
215
static inline uint32_t rotl(uint32_t val, int n)
216
{
217
  return (val << n) | (val >> (32 - n));
218
}
219

    
220
/* ARM immediates for ALU instructions are made of an unsigned 8-bit
221
   right-rotated by an even amount between 0 and 30. */
222
static inline int encode_imm(uint32_t imm)
223
{
224
    int shift;
225

    
226
    /* simple case, only lower bits */
227
    if ((imm & ~0xff) == 0)
228
        return 0;
229
    /* then try a simple even shift */
230
    shift = ctz32(imm) & ~1;
231
    if (((imm >> shift) & ~0xff) == 0)
232
        return 32 - shift;
233
    /* now try harder with rotations */
234
    if ((rotl(imm, 2) & ~0xff) == 0)
235
        return 2;
236
    if ((rotl(imm, 4) & ~0xff) == 0)
237
        return 4;
238
    if ((rotl(imm, 6) & ~0xff) == 0)
239
        return 6;
240
    /* imm can't be encoded */
241
    return -1;
242
}
243

    
244
static inline int check_fit_imm(uint32_t imm)
245
{
246
    return encode_imm(imm) >= 0;
247
}
248

    
249
/* Test if a constant matches the constraint.
250
 * TODO: define constraints for:
251
 *
252
 * ldr/str offset:   between -0xfff and 0xfff
253
 * ldrh/strh offset: between -0xff and 0xff
254
 * mov operand2:     values represented with x << (2 * y), x < 0x100
255
 * add, sub, eor...: ditto
256
 */
257
static inline int tcg_target_const_match(tcg_target_long val,
258
                                         const TCGArgConstraint *arg_ct)
259
{
260
    int ct;
261
    ct = arg_ct->ct;
262
    if (ct & TCG_CT_CONST) {
263
        return 1;
264
    } else if ((ct & TCG_CT_CONST_ARM) && check_fit_imm(val)) {
265
        return 1;
266
    } else if ((ct & TCG_CT_CONST_INV) && check_fit_imm(~val)) {
267
        return 1;
268
    } else if ((ct & TCG_CT_CONST_NEG) && check_fit_imm(-val)) {
269
        return 1;
270
    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
271
        return 1;
272
    } else {
273
        return 0;
274
    }
275
}
276

    
277
#define TO_CPSR (1 << 20)
278

    
279
typedef enum {
280
    ARITH_AND = 0x0 << 21,
281
    ARITH_EOR = 0x1 << 21,
282
    ARITH_SUB = 0x2 << 21,
283
    ARITH_RSB = 0x3 << 21,
284
    ARITH_ADD = 0x4 << 21,
285
    ARITH_ADC = 0x5 << 21,
286
    ARITH_SBC = 0x6 << 21,
287
    ARITH_RSC = 0x7 << 21,
288
    ARITH_TST = 0x8 << 21 | TO_CPSR,
289
    ARITH_CMP = 0xa << 21 | TO_CPSR,
290
    ARITH_CMN = 0xb << 21 | TO_CPSR,
291
    ARITH_ORR = 0xc << 21,
292
    ARITH_MOV = 0xd << 21,
293
    ARITH_BIC = 0xe << 21,
294
    ARITH_MVN = 0xf << 21,
295

    
296
    INSN_LDR_IMM   = 0x04100000,
297
    INSN_LDR_REG   = 0x06100000,
298
    INSN_STR_IMM   = 0x04000000,
299
    INSN_STR_REG   = 0x06000000,
300

    
301
    INSN_LDRH_IMM  = 0x005000b0,
302
    INSN_LDRH_REG  = 0x001000b0,
303
    INSN_LDRSH_IMM = 0x005000f0,
304
    INSN_LDRSH_REG = 0x001000f0,
305
    INSN_STRH_IMM  = 0x004000b0,
306
    INSN_STRH_REG  = 0x000000b0,
307

    
308
    INSN_LDRB_IMM  = 0x04500000,
309
    INSN_LDRB_REG  = 0x06500000,
310
    INSN_LDRSB_IMM = 0x005000d0,
311
    INSN_LDRSB_REG = 0x001000d0,
312
    INSN_STRB_IMM  = 0x04400000,
313
    INSN_STRB_REG  = 0x06400000,
314

    
315
    INSN_LDRD_IMM  = 0x004000d0,
316
    INSN_LDRD_REG  = 0x000000d0,
317
    INSN_STRD_IMM  = 0x004000f0,
318
    INSN_STRD_REG  = 0x000000f0,
319
} ARMInsn;
320

    
321
#define SHIFT_IMM_LSL(im)        (((im) << 7) | 0x00)
322
#define SHIFT_IMM_LSR(im)        (((im) << 7) | 0x20)
323
#define SHIFT_IMM_ASR(im)        (((im) << 7) | 0x40)
324
#define SHIFT_IMM_ROR(im)        (((im) << 7) | 0x60)
325
#define SHIFT_REG_LSL(rs)        (((rs) << 8) | 0x10)
326
#define SHIFT_REG_LSR(rs)        (((rs) << 8) | 0x30)
327
#define SHIFT_REG_ASR(rs)        (((rs) << 8) | 0x50)
328
#define SHIFT_REG_ROR(rs)        (((rs) << 8) | 0x70)
329

    
330
enum arm_cond_code_e {
331
    COND_EQ = 0x0,
332
    COND_NE = 0x1,
333
    COND_CS = 0x2,        /* Unsigned greater or equal */
334
    COND_CC = 0x3,        /* Unsigned less than */
335
    COND_MI = 0x4,        /* Negative */
336
    COND_PL = 0x5,        /* Zero or greater */
337
    COND_VS = 0x6,        /* Overflow */
338
    COND_VC = 0x7,        /* No overflow */
339
    COND_HI = 0x8,        /* Unsigned greater than */
340
    COND_LS = 0x9,        /* Unsigned less or equal */
341
    COND_GE = 0xa,
342
    COND_LT = 0xb,
343
    COND_GT = 0xc,
344
    COND_LE = 0xd,
345
    COND_AL = 0xe,
346
};
347

    
348
static const uint8_t tcg_cond_to_arm_cond[] = {
349
    [TCG_COND_EQ] = COND_EQ,
350
    [TCG_COND_NE] = COND_NE,
351
    [TCG_COND_LT] = COND_LT,
352
    [TCG_COND_GE] = COND_GE,
353
    [TCG_COND_LE] = COND_LE,
354
    [TCG_COND_GT] = COND_GT,
355
    /* unsigned */
356
    [TCG_COND_LTU] = COND_CC,
357
    [TCG_COND_GEU] = COND_CS,
358
    [TCG_COND_LEU] = COND_LS,
359
    [TCG_COND_GTU] = COND_HI,
360
};
361

    
362
static inline void tcg_out_bx(TCGContext *s, int cond, int rn)
363
{
364
    tcg_out32(s, (cond << 28) | 0x012fff10 | rn);
365
}
366

    
367
static inline void tcg_out_b(TCGContext *s, int cond, int32_t offset)
368
{
369
    tcg_out32(s, (cond << 28) | 0x0a000000 |
370
                    (((offset - 8) >> 2) & 0x00ffffff));
371
}
372

    
373
static inline void tcg_out_b_noaddr(TCGContext *s, int cond)
374
{
375
    /* We pay attention here to not modify the branch target by skipping
376
       the corresponding bytes. This ensure that caches and memory are
377
       kept coherent during retranslation. */
378
    s->code_ptr += 3;
379
    tcg_out8(s, (cond << 4) | 0x0a);
380
}
381

    
382
static inline void tcg_out_bl_noaddr(TCGContext *s, int cond)
383
{
384
    /* We pay attention here to not modify the branch target by skipping
385
       the corresponding bytes. This ensure that caches and memory are
386
       kept coherent during retranslation. */
387
    s->code_ptr += 3;
388
    tcg_out8(s, (cond << 4) | 0x0b);
389
}
390

    
391
static inline void tcg_out_bl(TCGContext *s, int cond, int32_t offset)
392
{
393
    tcg_out32(s, (cond << 28) | 0x0b000000 |
394
                    (((offset - 8) >> 2) & 0x00ffffff));
395
}
396

    
397
static inline void tcg_out_blx(TCGContext *s, int cond, int rn)
398
{
399
    tcg_out32(s, (cond << 28) | 0x012fff30 | rn);
400
}
401

    
402
static inline void tcg_out_blx_imm(TCGContext *s, int32_t offset)
403
{
404
    tcg_out32(s, 0xfa000000 | ((offset & 2) << 23) |
405
                (((offset - 8) >> 2) & 0x00ffffff));
406
}
407

    
408
static inline void tcg_out_dat_reg(TCGContext *s,
409
                int cond, int opc, int rd, int rn, int rm, int shift)
410
{
411
    tcg_out32(s, (cond << 28) | (0 << 25) | opc |
412
                    (rn << 16) | (rd << 12) | shift | rm);
413
}
414

    
415
static inline void tcg_out_nop(TCGContext *s)
416
{
417
    if (use_armv7_instructions) {
418
        /* Architected nop introduced in v6k.  */
419
        /* ??? This is an MSR (imm) 0,0,0 insn.  Anyone know if this
420
           also Just So Happened to do nothing on pre-v6k so that we
421
           don't need to conditionalize it?  */
422
        tcg_out32(s, 0xe320f000);
423
    } else {
424
        /* Prior to that the assembler uses mov r0, r0.  */
425
        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, 0, 0, 0, SHIFT_IMM_LSL(0));
426
    }
427
}
428

    
429
static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
430
{
431
    /* Simple reg-reg move, optimising out the 'do nothing' case */
432
    if (rd != rm) {
433
        tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
434
    }
435
}
436

    
437
static inline void tcg_out_dat_imm(TCGContext *s,
438
                int cond, int opc, int rd, int rn, int im)
439
{
440
    tcg_out32(s, (cond << 28) | (1 << 25) | opc |
441
                    (rn << 16) | (rd << 12) | im);
442
}
443

    
444
static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
445
{
446
    int rot, opc, rn;
447

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

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

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

    
495
        opc = ARITH_EOR;
496
        rn = rd;
497
    } while (arg);
498
}
499

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

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

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

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

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

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

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

    
618
static inline void tcg_out_udiv(TCGContext *s, int cond, int rd, int rn, int rm)
619
{
620
    tcg_out32(s, 0x0730f010 | (cond << 28) | (rd << 16) | rn | (rm << 8));
621
}
622

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

    
637
static inline void tcg_out_ext8u(TCGContext *s, int cond,
638
                                 int rd, int rn)
639
{
640
    tcg_out_dat_imm(s, cond, ARITH_AND, rd, rn, 0xff);
641
}
642

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

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

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

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

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

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

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

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

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

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

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

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

    
795
static inline void tcg_out_st32_12(TCGContext *s, int cond, TCGReg rt,
796
                                   TCGReg rn, int imm12)
797
{
798
    tcg_out_memop_12(s, cond, INSN_STR_IMM, rt, rn, imm12, 1, 0);
799
}
800

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

    
807
static inline void tcg_out_st32_r(TCGContext *s, int cond, TCGReg rt,
808
                                  TCGReg rn, TCGReg rm)
809
{
810
    tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 0);
811
}
812

    
813
static inline void tcg_out_ldrd_8(TCGContext *s, int cond, TCGReg rt,
814
                                   TCGReg rn, int imm8)
815
{
816
    tcg_out_memop_8(s, cond, INSN_LDRD_IMM, rt, rn, imm8, 1, 0);
817
}
818

    
819
static inline void tcg_out_ldrd_r(TCGContext *s, int cond, TCGReg rt,
820
                                  TCGReg rn, TCGReg rm)
821
{
822
    tcg_out_memop_r(s, cond, INSN_LDRD_REG, rt, rn, rm, 1, 1, 0);
823
}
824

    
825
static inline void tcg_out_strd_8(TCGContext *s, int cond, TCGReg rt,
826
                                   TCGReg rn, int imm8)
827
{
828
    tcg_out_memop_8(s, cond, INSN_STRD_IMM, rt, rn, imm8, 1, 0);
829
}
830

    
831
static inline void tcg_out_strd_r(TCGContext *s, int cond, TCGReg rt,
832
                                  TCGReg rn, TCGReg rm)
833
{
834
    tcg_out_memop_r(s, cond, INSN_STRD_REG, rt, rn, rm, 1, 1, 0);
835
}
836

    
837
/* Register pre-increment with base writeback.  */
838
static inline void tcg_out_ld32_rwb(TCGContext *s, int cond, TCGReg rt,
839
                                    TCGReg rn, TCGReg rm)
840
{
841
    tcg_out_memop_r(s, cond, INSN_LDR_REG, rt, rn, rm, 1, 1, 1);
842
}
843

    
844
static inline void tcg_out_st32_rwb(TCGContext *s, int cond, TCGReg rt,
845
                                    TCGReg rn, TCGReg rm)
846
{
847
    tcg_out_memop_r(s, cond, INSN_STR_REG, rt, rn, rm, 1, 1, 1);
848
}
849

    
850
static inline void tcg_out_ld16u_8(TCGContext *s, int cond, TCGReg rt,
851
                                   TCGReg rn, int imm8)
852
{
853
    tcg_out_memop_8(s, cond, INSN_LDRH_IMM, rt, rn, imm8, 1, 0);
854
}
855

    
856
static inline void tcg_out_st16_8(TCGContext *s, int cond, TCGReg rt,
857
                                  TCGReg rn, int imm8)
858
{
859
    tcg_out_memop_8(s, cond, INSN_STRH_IMM, rt, rn, imm8, 1, 0);
860
}
861

    
862
static inline void tcg_out_ld16u_r(TCGContext *s, int cond, TCGReg rt,
863
                                   TCGReg rn, TCGReg rm)
864
{
865
    tcg_out_memop_r(s, cond, INSN_LDRH_REG, rt, rn, rm, 1, 1, 0);
866
}
867

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

    
874
static inline void tcg_out_ld16s_8(TCGContext *s, int cond, TCGReg rt,
875
                                   TCGReg rn, int imm8)
876
{
877
    tcg_out_memop_8(s, cond, INSN_LDRSH_IMM, rt, rn, imm8, 1, 0);
878
}
879

    
880
static inline void tcg_out_ld16s_r(TCGContext *s, int cond, TCGReg rt,
881
                                   TCGReg rn, TCGReg rm)
882
{
883
    tcg_out_memop_r(s, cond, INSN_LDRSH_REG, rt, rn, rm, 1, 1, 0);
884
}
885

    
886
static inline void tcg_out_ld8_12(TCGContext *s, int cond, TCGReg rt,
887
                                  TCGReg rn, int imm12)
888
{
889
    tcg_out_memop_12(s, cond, INSN_LDRB_IMM, rt, rn, imm12, 1, 0);
890
}
891

    
892
static inline void tcg_out_st8_12(TCGContext *s, int cond, TCGReg rt,
893
                                  TCGReg rn, int imm12)
894
{
895
    tcg_out_memop_12(s, cond, INSN_STRB_IMM, rt, rn, imm12, 1, 0);
896
}
897

    
898
static inline void tcg_out_ld8_r(TCGContext *s, int cond, TCGReg rt,
899
                                 TCGReg rn, TCGReg rm)
900
{
901
    tcg_out_memop_r(s, cond, INSN_LDRB_REG, rt, rn, rm, 1, 1, 0);
902
}
903

    
904
static inline void tcg_out_st8_r(TCGContext *s, int cond, TCGReg rt,
905
                                 TCGReg rn, TCGReg rm)
906
{
907
    tcg_out_memop_r(s, cond, INSN_STRB_REG, rt, rn, rm, 1, 1, 0);
908
}
909

    
910
static inline void tcg_out_ld8s_8(TCGContext *s, int cond, TCGReg rt,
911
                                  TCGReg rn, int imm8)
912
{
913
    tcg_out_memop_8(s, cond, INSN_LDRSB_IMM, rt, rn, imm8, 1, 0);
914
}
915

    
916
static inline void tcg_out_ld8s_r(TCGContext *s, int cond, TCGReg rt,
917
                                  TCGReg rn, TCGReg rm)
918
{
919
    tcg_out_memop_r(s, cond, INSN_LDRSB_REG, rt, rn, rm, 1, 1, 0);
920
}
921

    
922
static inline void tcg_out_ld32u(TCGContext *s, int cond,
923
                int rd, int rn, int32_t offset)
924
{
925
    if (offset > 0xfff || offset < -0xfff) {
926
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
927
        tcg_out_ld32_r(s, cond, rd, rn, TCG_REG_TMP);
928
    } else
929
        tcg_out_ld32_12(s, cond, rd, rn, offset);
930
}
931

    
932
static inline void tcg_out_st32(TCGContext *s, int cond,
933
                int rd, int rn, int32_t offset)
934
{
935
    if (offset > 0xfff || offset < -0xfff) {
936
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
937
        tcg_out_st32_r(s, cond, rd, rn, TCG_REG_TMP);
938
    } else
939
        tcg_out_st32_12(s, cond, rd, rn, offset);
940
}
941

    
942
static inline void tcg_out_ld16u(TCGContext *s, int cond,
943
                int rd, int rn, int32_t offset)
944
{
945
    if (offset > 0xff || offset < -0xff) {
946
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
947
        tcg_out_ld16u_r(s, cond, rd, rn, TCG_REG_TMP);
948
    } else
949
        tcg_out_ld16u_8(s, cond, rd, rn, offset);
950
}
951

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

    
962
static inline void tcg_out_st16(TCGContext *s, int cond,
963
                int rd, int rn, int32_t offset)
964
{
965
    if (offset > 0xff || offset < -0xff) {
966
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
967
        tcg_out_st16_r(s, cond, rd, rn, TCG_REG_TMP);
968
    } else
969
        tcg_out_st16_8(s, cond, rd, rn, offset);
970
}
971

    
972
static inline void tcg_out_ld8u(TCGContext *s, int cond,
973
                int rd, int rn, int32_t offset)
974
{
975
    if (offset > 0xfff || offset < -0xfff) {
976
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
977
        tcg_out_ld8_r(s, cond, rd, rn, TCG_REG_TMP);
978
    } else
979
        tcg_out_ld8_12(s, cond, rd, rn, offset);
980
}
981

    
982
static inline void tcg_out_ld8s(TCGContext *s, int cond,
983
                int rd, int rn, int32_t offset)
984
{
985
    if (offset > 0xff || offset < -0xff) {
986
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
987
        tcg_out_ld8s_r(s, cond, rd, rn, TCG_REG_TMP);
988
    } else
989
        tcg_out_ld8s_8(s, cond, rd, rn, offset);
990
}
991

    
992
static inline void tcg_out_st8(TCGContext *s, int cond,
993
                int rd, int rn, int32_t offset)
994
{
995
    if (offset > 0xfff || offset < -0xfff) {
996
        tcg_out_movi32(s, cond, TCG_REG_TMP, offset);
997
        tcg_out_st8_r(s, cond, rd, rn, TCG_REG_TMP);
998
    } else
999
        tcg_out_st8_12(s, cond, rd, rn, offset);
1000
}
1001

    
1002
/* The _goto case is normally between TBs within the same code buffer, and
1003
 * with the code buffer limited to 16MB we wouldn't need the long case.
1004
 * But we also use it for the tail-call to the qemu_ld/st helpers, which does.
1005
 */
1006
static inline void tcg_out_goto(TCGContext *s, int cond, uint32_t addr)
1007
{
1008
    int32_t disp = addr - (tcg_target_long) s->code_ptr;
1009

    
1010
    if ((addr & 1) == 0 && disp - 8 < 0x01fffffd && disp - 8 > -0x01fffffd) {
1011
        tcg_out_b(s, cond, disp);
1012
        return;
1013
    }
1014

    
1015
    tcg_out_movi32(s, cond, TCG_REG_TMP, addr);
1016
    if (use_armv5t_instructions) {
1017
        tcg_out_bx(s, cond, TCG_REG_TMP);
1018
    } else {
1019
        if (addr & 1) {
1020
            tcg_abort();
1021
        }
1022
        tcg_out_mov_reg(s, cond, TCG_REG_PC, TCG_REG_TMP);
1023
    }
1024
}
1025

    
1026
/* The call case is mostly used for helpers - so it's not unreasonable
1027
 * for them to be beyond branch range */
1028
static inline void tcg_out_call(TCGContext *s, uint32_t addr)
1029
{
1030
    int32_t val;
1031

    
1032
    val = addr - (tcg_target_long) s->code_ptr;
1033
    if (val - 8 < 0x02000000 && val - 8 >= -0x02000000) {
1034
        if (addr & 1) {
1035
            /* Use BLX if the target is in Thumb mode */
1036
            if (!use_armv5t_instructions) {
1037
                tcg_abort();
1038
            }
1039
            tcg_out_blx_imm(s, val);
1040
        } else {
1041
            tcg_out_bl(s, COND_AL, val);
1042
        }
1043
    } else if (use_armv7_instructions) {
1044
        tcg_out_movi32(s, COND_AL, TCG_REG_TMP, addr);
1045
        tcg_out_blx(s, COND_AL, TCG_REG_TMP);
1046
    } else {
1047
        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R14, TCG_REG_PC, 4);
1048
        tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1049
        tcg_out32(s, addr);
1050
    }
1051
}
1052

    
1053
static inline void tcg_out_callr(TCGContext *s, int cond, int arg)
1054
{
1055
    if (use_armv5t_instructions) {
1056
        tcg_out_blx(s, cond, arg);
1057
    } else {
1058
        tcg_out_dat_reg(s, cond, ARITH_MOV, TCG_REG_R14, 0,
1059
                        TCG_REG_PC, SHIFT_IMM_LSL(0));
1060
        tcg_out_bx(s, cond, arg);
1061
    }
1062
}
1063

    
1064
static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
1065
{
1066
    TCGLabel *l = &s->labels[label_index];
1067

    
1068
    if (l->has_value) {
1069
        tcg_out_goto(s, cond, l->u.value);
1070
    } else {
1071
        tcg_out_reloc(s, s->code_ptr, R_ARM_PC24, label_index, 31337);
1072
        tcg_out_b_noaddr(s, cond);
1073
    }
1074
}
1075

    
1076
#ifdef CONFIG_SOFTMMU
1077
/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
1078
 *                                     int mmu_idx, uintptr_t ra)
1079
 */
1080
static const void * const qemu_ld_helpers[8] = {
1081
    helper_ret_ldub_mmu,
1082
    helper_ret_lduw_mmu,
1083
    helper_ret_ldul_mmu,
1084
    helper_ret_ldq_mmu,
1085

    
1086
    helper_ret_ldsb_mmu,
1087
    helper_ret_ldsw_mmu,
1088
    helper_ret_ldul_mmu,
1089
    helper_ret_ldq_mmu,
1090
};
1091

    
1092
/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
1093
 *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
1094
 */
1095
static const void * const qemu_st_helpers[4] = {
1096
    helper_ret_stb_mmu,
1097
    helper_ret_stw_mmu,
1098
    helper_ret_stl_mmu,
1099
    helper_ret_stq_mmu,
1100
};
1101

    
1102
/* Helper routines for marshalling helper function arguments into
1103
 * the correct registers and stack.
1104
 * argreg is where we want to put this argument, arg is the argument itself.
1105
 * Return value is the updated argreg ready for the next call.
1106
 * Note that argreg 0..3 is real registers, 4+ on stack.
1107
 *
1108
 * We provide routines for arguments which are: immediate, 32 bit
1109
 * value in register, 16 and 8 bit values in register (which must be zero
1110
 * extended before use) and 64 bit value in a lo:hi register pair.
1111
 */
1112
#define DEFINE_TCG_OUT_ARG(NAME, ARGTYPE, MOV_ARG, EXT_ARG)                \
1113
static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGTYPE arg)              \
1114
{                                                                          \
1115
    if (argreg < 4) {                                                      \
1116
        MOV_ARG(s, COND_AL, argreg, arg);                                  \
1117
    } else {                                                               \
1118
        int ofs = (argreg - 4) * 4;                                        \
1119
        EXT_ARG;                                                           \
1120
        assert(ofs + 4 <= TCG_STATIC_CALL_ARGS_SIZE);                      \
1121
        tcg_out_st32_12(s, COND_AL, arg, TCG_REG_CALL_STACK, ofs);         \
1122
    }                                                                      \
1123
    return argreg + 1;                                                     \
1124
}
1125

    
1126
DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t, tcg_out_movi32,
1127
    (tcg_out_movi32(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1128
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg, tcg_out_ext8u,
1129
    (tcg_out_ext8u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1130
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg, tcg_out_ext16u,
1131
    (tcg_out_ext16u(s, COND_AL, TCG_REG_TMP, arg), arg = TCG_REG_TMP))
1132
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg32, TCGReg, tcg_out_mov_reg, )
1133

    
1134
static TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
1135
                                TCGReg arglo, TCGReg arghi)
1136
{
1137
    /* 64 bit arguments must go in even/odd register pairs
1138
     * and in 8-aligned stack slots.
1139
     */
1140
    if (argreg & 1) {
1141
        argreg++;
1142
    }
1143
    if (use_armv6_instructions && argreg >= 4
1144
        && (arglo & 1) == 0 && arghi == arglo + 1) {
1145
        tcg_out_strd_8(s, COND_AL, arglo,
1146
                       TCG_REG_CALL_STACK, (argreg - 4) * 4);
1147
        return argreg + 2;
1148
    } else {
1149
        argreg = tcg_out_arg_reg32(s, argreg, arglo);
1150
        argreg = tcg_out_arg_reg32(s, argreg, arghi);
1151
        return argreg;
1152
    }
1153
}
1154

    
1155
#define TLB_SHIFT        (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
1156

    
1157
/* We're expecting to use an 8-bit immediate and to mask.  */
1158
QEMU_BUILD_BUG_ON(CPU_TLB_BITS > 8);
1159

    
1160
/* We're expecting to use an 8-bit immediate add + 8-bit ldrd offset.
1161
   Using the offset of the second entry in the last tlb table ensures
1162
   that we can index all of the elements of the first entry.  */
1163
QEMU_BUILD_BUG_ON(offsetof(CPUArchState, tlb_table[NB_MMU_MODES - 1][1])
1164
                  > 0xffff);
1165

    
1166
/* Load and compare a TLB entry, leaving the flags set.  Returns the register
1167
   containing the addend of the tlb entry.  Clobbers R0, R1, R2, TMP.  */
1168

    
1169
static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
1170
                               int s_bits, int mem_index, bool is_load)
1171
{
1172
    TCGReg base = TCG_AREG0;
1173
    int cmp_off =
1174
        (is_load
1175
         ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1176
         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1177
    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1178

    
1179
    /* Should generate something like the following:
1180
     *   shr    tmp, addr_reg, #TARGET_PAGE_BITS                  (1)
1181
     *   add    r2, env, #high
1182
     *   and    r0, tmp, #(CPU_TLB_SIZE - 1)                      (2)
1183
     *   add    r2, r2, r0, lsl #CPU_TLB_ENTRY_BITS               (3)
1184
     *   ldr    r0, [r2, #cmp]                                    (4)
1185
     *   tst    addr_reg, #s_mask
1186
     *   cmpeq  r0, tmp, lsl #TARGET_PAGE_BITS                    (5)
1187
     *   ldr    r1, [r2, #add]
1188
     */
1189
    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,
1190
                    0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));
1191

    
1192
    /* We checked that the offset is contained within 16 bits above.  */
1193
    if (add_off > 0xfff || (use_armv6_instructions && cmp_off > 0xff)) {
1194
        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1195
                        (24 << 7) | (cmp_off >> 8));
1196
        base = TCG_REG_R2;
1197
        add_off -= cmp_off & 0xff00;
1198
        cmp_off &= 0xff;
1199
    }
1200

    
1201
    tcg_out_dat_imm(s, COND_AL, ARITH_AND,
1202
                    TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);
1203
    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
1204
                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
1205

    
1206
    /* Load the tlb comparator.  Use ldrd if needed and available,
1207
       but due to how the pointer needs setting up, ldm isn't useful.
1208
       Base arm5 doesn't have ldrd, but armv5te does.  */
1209
    if (use_armv6_instructions && TARGET_LONG_BITS == 64) {
1210
        tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);
1211
    } else {
1212
        tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);
1213
        if (TARGET_LONG_BITS == 64) {
1214
            tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, cmp_off + 4);
1215
        }
1216
    }
1217

    
1218
    /* Check alignment.  */
1219
    if (s_bits) {
1220
        tcg_out_dat_imm(s, COND_AL, ARITH_TST,
1221
                        0, addrlo, (1 << s_bits) - 1);
1222
    }
1223

    
1224
    tcg_out_dat_reg(s, (s_bits ? COND_EQ : COND_AL), ARITH_CMP, 0,
1225
                    TCG_REG_R0, TCG_REG_TMP, SHIFT_IMM_LSL(TARGET_PAGE_BITS));
1226

    
1227
    if (TARGET_LONG_BITS == 64) {
1228
        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,
1229
                        TCG_REG_R1, addrhi, SHIFT_IMM_LSL(0));
1230
    }
1231

    
1232
    /* Load the tlb addend.  */
1233
    tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, add_off);
1234
    return TCG_REG_R1;
1235
}
1236

    
1237
/* Record the context of a call to the out of line helper code for the slow
1238
   path for a load or store, so that we can later generate the correct
1239
   helper code.  */
1240
static void add_qemu_ldst_label(TCGContext *s, int is_ld, int opc,
1241
                                int data_reg, int data_reg2, int addrlo_reg,
1242
                                int addrhi_reg, int mem_index,
1243
                                uint8_t *raddr, uint8_t *label_ptr)
1244
{
1245
    int idx;
1246
    TCGLabelQemuLdst *label;
1247

    
1248
    if (s->nb_qemu_ldst_labels >= TCG_MAX_QEMU_LDST) {
1249
        tcg_abort();
1250
    }
1251

    
1252
    idx = s->nb_qemu_ldst_labels++;
1253
    label = (TCGLabelQemuLdst *)&s->qemu_ldst_labels[idx];
1254
    label->is_ld = is_ld;
1255
    label->opc = opc;
1256
    label->datalo_reg = data_reg;
1257
    label->datahi_reg = data_reg2;
1258
    label->addrlo_reg = addrlo_reg;
1259
    label->addrhi_reg = addrhi_reg;
1260
    label->mem_index = mem_index;
1261
    label->raddr = raddr;
1262
    label->label_ptr[0] = label_ptr;
1263
}
1264

    
1265
static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1266
{
1267
    TCGReg argreg, data_reg, data_reg2;
1268
    int opc = lb->opc;
1269
    uintptr_t func;
1270

    
1271
    reloc_pc24(lb->label_ptr[0], (tcg_target_long)s->code_ptr);
1272

    
1273
    argreg = tcg_out_arg_reg32(s, TCG_REG_R0, TCG_AREG0);
1274
    if (TARGET_LONG_BITS == 64) {
1275
        argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1276
    } else {
1277
        argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1278
    }
1279
    argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index);
1280
    argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1281

    
1282
    /* For armv6 we can use the canonical unsigned helpers and minimize
1283
       icache usage.  For pre-armv6, use the signed helpers since we do
1284
       not have a single insn sign-extend.  */
1285
    if (use_armv6_instructions) {
1286
        func = (uintptr_t)qemu_ld_helpers[opc & 3];
1287
    } else {
1288
        func = (uintptr_t)qemu_ld_helpers[opc];
1289
        if (opc & 4) {
1290
            opc = 2;
1291
        }
1292
    }
1293
    tcg_out_call(s, func);
1294

    
1295
    data_reg = lb->datalo_reg;
1296
    data_reg2 = lb->datahi_reg;
1297
    switch (opc) {
1298
    case 0 | 4:
1299
        tcg_out_ext8s(s, COND_AL, data_reg, TCG_REG_R0);
1300
        break;
1301
    case 1 | 4:
1302
        tcg_out_ext16s(s, COND_AL, data_reg, TCG_REG_R0);
1303
        break;
1304
    default:
1305
        tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1306
        break;
1307
    case 3:
1308
        if (data_reg != TCG_REG_R1) {
1309
            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1310
            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1311
        } else if (data_reg2 != TCG_REG_R0) {
1312
            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1313
            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_R0);
1314
        } else {
1315
            tcg_out_mov_reg(s, COND_AL, TCG_REG_TMP, TCG_REG_R0);
1316
            tcg_out_mov_reg(s, COND_AL, data_reg2, TCG_REG_R1);
1317
            tcg_out_mov_reg(s, COND_AL, data_reg, TCG_REG_TMP);
1318
        }
1319
        break;
1320
    }
1321

    
1322
    tcg_out_goto(s, COND_AL, (tcg_target_long)lb->raddr);
1323
}
1324

    
1325
static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1326
{
1327
    TCGReg argreg, data_reg, data_reg2;
1328

    
1329
    reloc_pc24(lb->label_ptr[0], (tcg_target_long)s->code_ptr);
1330

    
1331
    argreg = TCG_REG_R0;
1332
    argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
1333
    if (TARGET_LONG_BITS == 64) {
1334
        argreg = tcg_out_arg_reg64(s, argreg, lb->addrlo_reg, lb->addrhi_reg);
1335
    } else {
1336
        argreg = tcg_out_arg_reg32(s, argreg, lb->addrlo_reg);
1337
    }
1338

    
1339
    data_reg = lb->datalo_reg;
1340
    data_reg2 = lb->datahi_reg;
1341
    switch (lb->opc) {
1342
    case 0:
1343
        argreg = tcg_out_arg_reg8(s, argreg, data_reg);
1344
        break;
1345
    case 1:
1346
        argreg = tcg_out_arg_reg16(s, argreg, data_reg);
1347
        break;
1348
    case 2:
1349
        argreg = tcg_out_arg_reg32(s, argreg, data_reg);
1350
        break;
1351
    case 3:
1352
        argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2);
1353
        break;
1354
    }
1355

    
1356
    argreg = tcg_out_arg_imm32(s, argreg, lb->mem_index);
1357
    argreg = tcg_out_arg_reg32(s, argreg, TCG_REG_R14);
1358

    
1359
    /* Tail-call to the helper, which will return to the fast path.  */
1360
    tcg_out_goto(s, COND_AL, (tcg_target_long) qemu_st_helpers[lb->opc & 3]);
1361
}
1362
#endif /* SOFTMMU */
1363

    
1364
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
1365
{
1366
    TCGReg addr_reg, data_reg, data_reg2;
1367
    bool bswap;
1368
#ifdef CONFIG_SOFTMMU
1369
    int mem_index, s_bits;
1370
    TCGReg addr_reg2, addend;
1371
    uint8_t *label_ptr;
1372
#endif
1373
#ifdef TARGET_WORDS_BIGENDIAN
1374
    bswap = 1;
1375
#else
1376
    bswap = 0;
1377
#endif
1378

    
1379
    data_reg = *args++;
1380
    data_reg2 = (opc == 3 ? *args++ : 0);
1381
    addr_reg = *args++;
1382
#ifdef CONFIG_SOFTMMU
1383
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1384
    mem_index = *args;
1385
    s_bits = opc & 3;
1386

    
1387
    addend = tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits, mem_index, 1);
1388

    
1389
    /* This a conditional BL only to load a pointer within this opcode into LR
1390
       for the slow path.  We will not be using the value for a tail call.  */
1391
    label_ptr = s->code_ptr;
1392
    tcg_out_bl_noaddr(s, COND_NE);
1393

    
1394
    switch (opc) {
1395
    case 0:
1396
        tcg_out_ld8_r(s, COND_AL, data_reg, addr_reg, addend);
1397
        break;
1398
    case 0 | 4:
1399
        tcg_out_ld8s_r(s, COND_AL, data_reg, addr_reg, addend);
1400
        break;
1401
    case 1:
1402
        tcg_out_ld16u_r(s, COND_AL, data_reg, addr_reg, addend);
1403
        if (bswap) {
1404
            tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1405
        }
1406
        break;
1407
    case 1 | 4:
1408
        if (bswap) {
1409
            tcg_out_ld16u_r(s, COND_AL, data_reg, addr_reg, addend);
1410
            tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1411
        } else {
1412
            tcg_out_ld16s_r(s, COND_AL, data_reg, addr_reg, addend);
1413
        }
1414
        break;
1415
    case 2:
1416
    default:
1417
        tcg_out_ld32_r(s, COND_AL, data_reg, addr_reg, addend);
1418
        if (bswap) {
1419
            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1420
        }
1421
        break;
1422
    case 3:
1423
        {
1424
            /* Be careful not to modify data_reg and data_reg2
1425
               for the slow path below.  */
1426
            TCGReg dl = (bswap ? data_reg2 : data_reg);
1427
            TCGReg dh = (bswap ? data_reg : data_reg2);
1428

    
1429
            if (use_armv6_instructions && (dl & 1) == 0 && dh == dl + 1) {
1430
                tcg_out_ldrd_r(s, COND_AL, dl, addr_reg, addend);
1431
            } else if (dl != addend) {
1432
                tcg_out_ld32_rwb(s, COND_AL, dl, addend, addr_reg);
1433
                tcg_out_ld32_12(s, COND_AL, dh, addend, 4);
1434
            } else {
1435
                tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_TMP,
1436
                                addend, addr_reg, SHIFT_IMM_LSL(0));
1437
                tcg_out_ld32_12(s, COND_AL, dl, TCG_REG_TMP, 0);
1438
                tcg_out_ld32_12(s, COND_AL, dh, TCG_REG_TMP, 4);
1439
            }
1440
            if (bswap) {
1441
                tcg_out_bswap32(s, COND_AL, dh, dh);
1442
                tcg_out_bswap32(s, COND_AL, dl, dl);
1443
            }
1444
        }
1445
        break;
1446
    }
1447

    
1448
    add_qemu_ldst_label(s, 1, opc, data_reg, data_reg2, addr_reg, addr_reg2,
1449
                        mem_index, s->code_ptr, label_ptr);
1450
#else /* !CONFIG_SOFTMMU */
1451
    if (GUEST_BASE) {
1452
        uint32_t offset = GUEST_BASE;
1453
        int i, rot;
1454

    
1455
        while (offset) {
1456
            i = ctz32(offset) & ~1;
1457
            rot = ((32 - i) << 7) & 0xf00;
1458

    
1459
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_TMP, addr_reg,
1460
                            ((offset >> i) & 0xff) | rot);
1461
            addr_reg = TCG_REG_TMP;
1462
            offset &= ~(0xff << i);
1463
        }
1464
    }
1465
    switch (opc) {
1466
    case 0:
1467
        tcg_out_ld8_12(s, COND_AL, data_reg, addr_reg, 0);
1468
        break;
1469
    case 0 | 4:
1470
        tcg_out_ld8s_8(s, COND_AL, data_reg, addr_reg, 0);
1471
        break;
1472
    case 1:
1473
        tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1474
        if (bswap) {
1475
            tcg_out_bswap16(s, COND_AL, data_reg, data_reg);
1476
        }
1477
        break;
1478
    case 1 | 4:
1479
        if (bswap) {
1480
            tcg_out_ld16u_8(s, COND_AL, data_reg, addr_reg, 0);
1481
            tcg_out_bswap16s(s, COND_AL, data_reg, data_reg);
1482
        } else {
1483
            tcg_out_ld16s_8(s, COND_AL, data_reg, addr_reg, 0);
1484
        }
1485
        break;
1486
    case 2:
1487
    default:
1488
        tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, 0);
1489
        if (bswap) {
1490
            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1491
        }
1492
        break;
1493
    case 3:
1494
        if (use_armv6_instructions && !bswap
1495
            && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1496
            tcg_out_ldrd_8(s, COND_AL, data_reg, addr_reg, 0);
1497
        } else if (use_armv6_instructions && bswap
1498
                   && (data_reg2 & 1) == 0 && data_reg == data_reg2 + 1) {
1499
            tcg_out_ldrd_8(s, COND_AL, data_reg2, addr_reg, 0);
1500
        } else if (data_reg == addr_reg) {
1501
            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1502
            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1503
        } else {
1504
            tcg_out_ld32_12(s, COND_AL, data_reg, addr_reg, bswap ? 4 : 0);
1505
            tcg_out_ld32_12(s, COND_AL, data_reg2, addr_reg, bswap ? 0 : 4);
1506
        }
1507
        if (bswap) {
1508
            tcg_out_bswap32(s, COND_AL, data_reg, data_reg);
1509
            tcg_out_bswap32(s, COND_AL, data_reg2, data_reg2);
1510
        }
1511
        break;
1512
    }
1513
#endif
1514
}
1515

    
1516
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1517
{
1518
    TCGReg addr_reg, data_reg, data_reg2;
1519
    bool bswap;
1520
#ifdef CONFIG_SOFTMMU
1521
    int mem_index, s_bits;
1522
    TCGReg addr_reg2, addend;
1523
    uint8_t *label_ptr;
1524
#endif
1525
#ifdef TARGET_WORDS_BIGENDIAN
1526
    bswap = 1;
1527
#else
1528
    bswap = 0;
1529
#endif
1530

    
1531
    data_reg = *args++;
1532
    data_reg2 = (opc == 3 ? *args++ : 0);
1533
    addr_reg = *args++;
1534
#ifdef CONFIG_SOFTMMU
1535
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1536
    mem_index = *args;
1537
    s_bits = opc & 3;
1538

    
1539
    addend = tcg_out_tlb_read(s, addr_reg, addr_reg2, s_bits, mem_index, 0);
1540

    
1541
    switch (opc) {
1542
    case 0:
1543
        tcg_out_st8_r(s, COND_EQ, data_reg, addr_reg, addend);
1544
        break;
1545
    case 1:
1546
        if (bswap) {
1547
            tcg_out_bswap16st(s, COND_EQ, TCG_REG_R0, data_reg);
1548
            tcg_out_st16_r(s, COND_EQ, TCG_REG_R0, addr_reg, addend);
1549
        } else {
1550
            tcg_out_st16_r(s, COND_EQ, data_reg, addr_reg, addend);
1551
        }
1552
        break;
1553
    case 2:
1554
    default:
1555
        if (bswap) {
1556
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1557
            tcg_out_st32_r(s, COND_EQ, TCG_REG_R0, addr_reg, addend);
1558
        } else {
1559
            tcg_out_st32_r(s, COND_EQ, data_reg, addr_reg, addend);
1560
        }
1561
        break;
1562
    case 3:
1563
        if (bswap) {
1564
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg2);
1565
            tcg_out_st32_rwb(s, COND_EQ, TCG_REG_R0, addend, addr_reg);
1566
            tcg_out_bswap32(s, COND_EQ, TCG_REG_R0, data_reg);
1567
            tcg_out_st32_12(s, COND_EQ, TCG_REG_R0, addend, 4);
1568
        } else if (use_armv6_instructions
1569
                   && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1570
            tcg_out_strd_r(s, COND_EQ, data_reg, addr_reg, addend);
1571
        } else {
1572
            tcg_out_st32_rwb(s, COND_EQ, data_reg, addend, addr_reg);
1573
            tcg_out_st32_12(s, COND_EQ, data_reg2, addend, 4);
1574
        }
1575
        break;
1576
    }
1577

    
1578
    /* The conditional call must come last, as we're going to return here.  */
1579
    label_ptr = s->code_ptr;
1580
    tcg_out_bl_noaddr(s, COND_NE);
1581

    
1582
    add_qemu_ldst_label(s, 0, opc, data_reg, data_reg2, addr_reg, addr_reg2,
1583
                        mem_index, s->code_ptr, label_ptr);
1584
#else /* !CONFIG_SOFTMMU */
1585
    if (GUEST_BASE) {
1586
        uint32_t offset = GUEST_BASE;
1587
        int i;
1588
        int rot;
1589

    
1590
        while (offset) {
1591
            i = ctz32(offset) & ~1;
1592
            rot = ((32 - i) << 7) & 0xf00;
1593

    
1594
            tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R1, addr_reg,
1595
                            ((offset >> i) & 0xff) | rot);
1596
            addr_reg = TCG_REG_R1;
1597
            offset &= ~(0xff << i);
1598
        }
1599
    }
1600
    switch (opc) {
1601
    case 0:
1602
        tcg_out_st8_12(s, COND_AL, data_reg, addr_reg, 0);
1603
        break;
1604
    case 1:
1605
        if (bswap) {
1606
            tcg_out_bswap16st(s, COND_AL, TCG_REG_R0, data_reg);
1607
            tcg_out_st16_8(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1608
        } else {
1609
            tcg_out_st16_8(s, COND_AL, data_reg, addr_reg, 0);
1610
        }
1611
        break;
1612
    case 2:
1613
    default:
1614
        if (bswap) {
1615
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1616
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1617
        } else {
1618
            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1619
        }
1620
        break;
1621
    case 3:
1622
        if (bswap) {
1623
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg2);
1624
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 0);
1625
            tcg_out_bswap32(s, COND_AL, TCG_REG_R0, data_reg);
1626
            tcg_out_st32_12(s, COND_AL, TCG_REG_R0, addr_reg, 4);
1627
        } else if (use_armv6_instructions
1628
                   && (data_reg & 1) == 0 && data_reg2 == data_reg + 1) {
1629
            tcg_out_strd_8(s, COND_AL, data_reg, addr_reg, 0);
1630
        } else {
1631
            tcg_out_st32_12(s, COND_AL, data_reg, addr_reg, 0);
1632
            tcg_out_st32_12(s, COND_AL, data_reg2, addr_reg, 4);
1633
        }
1634
        break;
1635
    }
1636
#endif
1637
}
1638

    
1639
static uint8_t *tb_ret_addr;
1640

    
1641
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1642
                const TCGArg *args, const int *const_args)
1643
{
1644
    TCGArg a0, a1, a2, a3, a4, a5;
1645
    int c;
1646

    
1647
    switch (opc) {
1648
    case INDEX_op_exit_tb:
1649
        if (use_armv7_instructions || check_fit_imm(args[0])) {
1650
            tcg_out_movi32(s, COND_AL, TCG_REG_R0, args[0]);
1651
            tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1652
        } else {
1653
            uint8_t *ld_ptr = s->code_ptr;
1654
            tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1655
            tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);
1656
            *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;
1657
            tcg_out32(s, args[0]);
1658
        }
1659
        break;
1660
    case INDEX_op_goto_tb:
1661
        if (s->tb_jmp_offset) {
1662
            /* Direct jump method */
1663
#if defined(USE_DIRECT_JUMP)
1664
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1665
            tcg_out_b_noaddr(s, COND_AL);
1666
#else
1667
            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);
1668
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1669
            tcg_out32(s, 0);
1670
#endif
1671
        } else {
1672
            /* Indirect jump method */
1673
#if 1
1674
            c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);
1675
            if (c > 0xfff || c < -0xfff) {
1676
                tcg_out_movi32(s, COND_AL, TCG_REG_R0,
1677
                                (tcg_target_long) (s->tb_next + args[0]));
1678
                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1679
            } else
1680
                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);
1681
#else
1682
            tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);
1683
            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);
1684
            tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));
1685
#endif
1686
        }
1687
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1688
        break;
1689
    case INDEX_op_call:
1690
        if (const_args[0])
1691
            tcg_out_call(s, args[0]);
1692
        else
1693
            tcg_out_callr(s, COND_AL, args[0]);
1694
        break;
1695
    case INDEX_op_br:
1696
        tcg_out_goto_label(s, COND_AL, args[0]);
1697
        break;
1698

    
1699
    case INDEX_op_ld8u_i32:
1700
        tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);
1701
        break;
1702
    case INDEX_op_ld8s_i32:
1703
        tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);
1704
        break;
1705
    case INDEX_op_ld16u_i32:
1706
        tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);
1707
        break;
1708
    case INDEX_op_ld16s_i32:
1709
        tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);
1710
        break;
1711
    case INDEX_op_ld_i32:
1712
        tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);
1713
        break;
1714
    case INDEX_op_st8_i32:
1715
        tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);
1716
        break;
1717
    case INDEX_op_st16_i32:
1718
        tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);
1719
        break;
1720
    case INDEX_op_st_i32:
1721
        tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);
1722
        break;
1723

    
1724
    case INDEX_op_mov_i32:
1725
        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
1726
                        args[0], 0, args[1], SHIFT_IMM_LSL(0));
1727
        break;
1728
    case INDEX_op_movi_i32:
1729
        tcg_out_movi32(s, COND_AL, args[0], args[1]);
1730
        break;
1731
    case INDEX_op_movcond_i32:
1732
        /* Constraints mean that v2 is always in the same register as dest,
1733
         * so we only need to do "if condition passed, move v1 to dest".
1734
         */
1735
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1736
                        args[1], args[2], const_args[2]);
1737
        tcg_out_dat_rIK(s, tcg_cond_to_arm_cond[args[5]], ARITH_MOV,
1738
                        ARITH_MVN, args[0], 0, args[3], const_args[3]);
1739
        break;
1740
    case INDEX_op_add_i32:
1741
        tcg_out_dat_rIN(s, COND_AL, ARITH_ADD, ARITH_SUB,
1742
                        args[0], args[1], args[2], const_args[2]);
1743
        break;
1744
    case INDEX_op_sub_i32:
1745
        if (const_args[1]) {
1746
            if (const_args[2]) {
1747
                tcg_out_movi32(s, COND_AL, args[0], args[1] - args[2]);
1748
            } else {
1749
                tcg_out_dat_rI(s, COND_AL, ARITH_RSB,
1750
                               args[0], args[2], args[1], 1);
1751
            }
1752
        } else {
1753
            tcg_out_dat_rIN(s, COND_AL, ARITH_SUB, ARITH_ADD,
1754
                            args[0], args[1], args[2], const_args[2]);
1755
        }
1756
        break;
1757
    case INDEX_op_and_i32:
1758
        tcg_out_dat_rIK(s, COND_AL, ARITH_AND, ARITH_BIC,
1759
                        args[0], args[1], args[2], const_args[2]);
1760
        break;
1761
    case INDEX_op_andc_i32:
1762
        tcg_out_dat_rIK(s, COND_AL, ARITH_BIC, ARITH_AND,
1763
                        args[0], args[1], args[2], const_args[2]);
1764
        break;
1765
    case INDEX_op_or_i32:
1766
        c = ARITH_ORR;
1767
        goto gen_arith;
1768
    case INDEX_op_xor_i32:
1769
        c = ARITH_EOR;
1770
        /* Fall through.  */
1771
    gen_arith:
1772
        tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);
1773
        break;
1774
    case INDEX_op_add2_i32:
1775
        a0 = args[0], a1 = args[1], a2 = args[2];
1776
        a3 = args[3], a4 = args[4], a5 = args[5];
1777
        if (a0 == a3 || (a0 == a5 && !const_args[5])) {
1778
            a0 = TCG_REG_TMP;
1779
        }
1780
        tcg_out_dat_rIN(s, COND_AL, ARITH_ADD | TO_CPSR, ARITH_SUB | TO_CPSR,
1781
                        a0, a2, a4, const_args[4]);
1782
        tcg_out_dat_rIK(s, COND_AL, ARITH_ADC, ARITH_SBC,
1783
                        a1, a3, a5, const_args[5]);
1784
        tcg_out_mov_reg(s, COND_AL, args[0], a0);
1785
        break;
1786
    case INDEX_op_sub2_i32:
1787
        a0 = args[0], a1 = args[1], a2 = args[2];
1788
        a3 = args[3], a4 = args[4], a5 = args[5];
1789
        if ((a0 == a3 && !const_args[3]) || (a0 == a5 && !const_args[5])) {
1790
            a0 = TCG_REG_TMP;
1791
        }
1792
        if (const_args[2]) {
1793
            if (const_args[4]) {
1794
                tcg_out_movi32(s, COND_AL, a0, a4);
1795
                a4 = a0;
1796
            }
1797
            tcg_out_dat_rI(s, COND_AL, ARITH_RSB | TO_CPSR, a0, a4, a2, 1);
1798
        } else {
1799
            tcg_out_dat_rIN(s, COND_AL, ARITH_SUB | TO_CPSR,
1800
                            ARITH_ADD | TO_CPSR, a0, a2, a4, const_args[4]);
1801
        }
1802
        if (const_args[3]) {
1803
            if (const_args[5]) {
1804
                tcg_out_movi32(s, COND_AL, a1, a5);
1805
                a5 = a1;
1806
            }
1807
            tcg_out_dat_rI(s, COND_AL, ARITH_RSC, a1, a5, a3, 1);
1808
        } else {
1809
            tcg_out_dat_rIK(s, COND_AL, ARITH_SBC, ARITH_ADC,
1810
                            a1, a3, a5, const_args[5]);
1811
        }
1812
        tcg_out_mov_reg(s, COND_AL, args[0], a0);
1813
        break;
1814
    case INDEX_op_neg_i32:
1815
        tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);
1816
        break;
1817
    case INDEX_op_not_i32:
1818
        tcg_out_dat_reg(s, COND_AL,
1819
                        ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));
1820
        break;
1821
    case INDEX_op_mul_i32:
1822
        tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);
1823
        break;
1824
    case INDEX_op_mulu2_i32:
1825
        tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1826
        break;
1827
    case INDEX_op_muls2_i32:
1828
        tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);
1829
        break;
1830
    /* XXX: Perhaps args[2] & 0x1f is wrong */
1831
    case INDEX_op_shl_i32:
1832
        c = const_args[2] ?
1833
                SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);
1834
        goto gen_shift32;
1835
    case INDEX_op_shr_i32:
1836
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :
1837
                SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);
1838
        goto gen_shift32;
1839
    case INDEX_op_sar_i32:
1840
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :
1841
                SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);
1842
        goto gen_shift32;
1843
    case INDEX_op_rotr_i32:
1844
        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :
1845
                SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);
1846
        /* Fall through.  */
1847
    gen_shift32:
1848
        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);
1849
        break;
1850

    
1851
    case INDEX_op_rotl_i32:
1852
        if (const_args[2]) {
1853
            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1854
                            ((0x20 - args[2]) & 0x1f) ?
1855
                            SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :
1856
                            SHIFT_IMM_LSL(0));
1857
        } else {
1858
            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_TMP, args[1], 0x20);
1859
            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],
1860
                            SHIFT_REG_ROR(TCG_REG_TMP));
1861
        }
1862
        break;
1863

    
1864
    case INDEX_op_brcond_i32:
1865
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1866
                       args[0], args[1], const_args[1]);
1867
        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);
1868
        break;
1869
    case INDEX_op_brcond2_i32:
1870
        /* The resulting conditions are:
1871
         * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,
1872
         * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,
1873
         * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,
1874
         * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),
1875
         * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),
1876
         * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,
1877
         */
1878
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1879
                        args[1], args[3], const_args[3]);
1880
        tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1881
                        args[0], args[2], const_args[2]);
1882
        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);
1883
        break;
1884
    case INDEX_op_setcond_i32:
1885
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1886
                        args[1], args[2], const_args[2]);
1887
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],
1888
                        ARITH_MOV, args[0], 0, 1);
1889
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],
1890
                        ARITH_MOV, args[0], 0, 0);
1891
        break;
1892
    case INDEX_op_setcond2_i32:
1893
        /* See brcond2_i32 comment */
1894
        tcg_out_dat_rIN(s, COND_AL, ARITH_CMP, ARITH_CMN, 0,
1895
                        args[2], args[4], const_args[4]);
1896
        tcg_out_dat_rIN(s, COND_EQ, ARITH_CMP, ARITH_CMN, 0,
1897
                        args[1], args[3], const_args[3]);
1898
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],
1899
                        ARITH_MOV, args[0], 0, 1);
1900
        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],
1901
                        ARITH_MOV, args[0], 0, 0);
1902
        break;
1903

    
1904
    case INDEX_op_qemu_ld8u:
1905
        tcg_out_qemu_ld(s, args, 0);
1906
        break;
1907
    case INDEX_op_qemu_ld8s:
1908
        tcg_out_qemu_ld(s, args, 0 | 4);
1909
        break;
1910
    case INDEX_op_qemu_ld16u:
1911
        tcg_out_qemu_ld(s, args, 1);
1912
        break;
1913
    case INDEX_op_qemu_ld16s:
1914
        tcg_out_qemu_ld(s, args, 1 | 4);
1915
        break;
1916
    case INDEX_op_qemu_ld32:
1917
        tcg_out_qemu_ld(s, args, 2);
1918
        break;
1919
    case INDEX_op_qemu_ld64:
1920
        tcg_out_qemu_ld(s, args, 3);
1921
        break;
1922

    
1923
    case INDEX_op_qemu_st8:
1924
        tcg_out_qemu_st(s, args, 0);
1925
        break;
1926
    case INDEX_op_qemu_st16:
1927
        tcg_out_qemu_st(s, args, 1);
1928
        break;
1929
    case INDEX_op_qemu_st32:
1930
        tcg_out_qemu_st(s, args, 2);
1931
        break;
1932
    case INDEX_op_qemu_st64:
1933
        tcg_out_qemu_st(s, args, 3);
1934
        break;
1935

    
1936
    case INDEX_op_bswap16_i32:
1937
        tcg_out_bswap16(s, COND_AL, args[0], args[1]);
1938
        break;
1939
    case INDEX_op_bswap32_i32:
1940
        tcg_out_bswap32(s, COND_AL, args[0], args[1]);
1941
        break;
1942

    
1943
    case INDEX_op_ext8s_i32:
1944
        tcg_out_ext8s(s, COND_AL, args[0], args[1]);
1945
        break;
1946
    case INDEX_op_ext16s_i32:
1947
        tcg_out_ext16s(s, COND_AL, args[0], args[1]);
1948
        break;
1949
    case INDEX_op_ext16u_i32:
1950
        tcg_out_ext16u(s, COND_AL, args[0], args[1]);
1951
        break;
1952

    
1953
    case INDEX_op_deposit_i32:
1954
        tcg_out_deposit(s, COND_AL, args[0], args[2],
1955
                        args[3], args[4], const_args[2]);
1956
        break;
1957

    
1958
    case INDEX_op_div_i32:
1959
        tcg_out_sdiv(s, COND_AL, args[0], args[1], args[2]);
1960
        break;
1961
    case INDEX_op_divu_i32:
1962
        tcg_out_udiv(s, COND_AL, args[0], args[1], args[2]);
1963
        break;
1964

    
1965
    default:
1966
        tcg_abort();
1967
    }
1968
}
1969

    
1970
#ifdef CONFIG_SOFTMMU
1971
/* Generate TB finalization at the end of block.  */
1972
void tcg_out_tb_finalize(TCGContext *s)
1973
{
1974
    int i;
1975
    for (i = 0; i < s->nb_qemu_ldst_labels; i++) {
1976
        TCGLabelQemuLdst *label = &s->qemu_ldst_labels[i];
1977
        if (label->is_ld) {
1978
            tcg_out_qemu_ld_slow_path(s, label);
1979
        } else {
1980
            tcg_out_qemu_st_slow_path(s, label);
1981
        }
1982
    }
1983
}
1984
#endif /* SOFTMMU */
1985

    
1986
static const TCGTargetOpDef arm_op_defs[] = {
1987
    { INDEX_op_exit_tb, { } },
1988
    { INDEX_op_goto_tb, { } },
1989
    { INDEX_op_call, { "ri" } },
1990
    { INDEX_op_br, { } },
1991

    
1992
    { INDEX_op_mov_i32, { "r", "r" } },
1993
    { INDEX_op_movi_i32, { "r" } },
1994

    
1995
    { INDEX_op_ld8u_i32, { "r", "r" } },
1996
    { INDEX_op_ld8s_i32, { "r", "r" } },
1997
    { INDEX_op_ld16u_i32, { "r", "r" } },
1998
    { INDEX_op_ld16s_i32, { "r", "r" } },
1999
    { INDEX_op_ld_i32, { "r", "r" } },
2000
    { INDEX_op_st8_i32, { "r", "r" } },
2001
    { INDEX_op_st16_i32, { "r", "r" } },
2002
    { INDEX_op_st_i32, { "r", "r" } },
2003

    
2004
    /* TODO: "r", "r", "ri" */
2005
    { INDEX_op_add_i32, { "r", "r", "rIN" } },
2006
    { INDEX_op_sub_i32, { "r", "rI", "rIN" } },
2007
    { INDEX_op_mul_i32, { "r", "r", "r" } },
2008
    { INDEX_op_mulu2_i32, { "r", "r", "r", "r" } },
2009
    { INDEX_op_muls2_i32, { "r", "r", "r", "r" } },
2010
    { INDEX_op_and_i32, { "r", "r", "rIK" } },
2011
    { INDEX_op_andc_i32, { "r", "r", "rIK" } },
2012
    { INDEX_op_or_i32, { "r", "r", "rI" } },
2013
    { INDEX_op_xor_i32, { "r", "r", "rI" } },
2014
    { INDEX_op_neg_i32, { "r", "r" } },
2015
    { INDEX_op_not_i32, { "r", "r" } },
2016

    
2017
    { INDEX_op_shl_i32, { "r", "r", "ri" } },
2018
    { INDEX_op_shr_i32, { "r", "r", "ri" } },
2019
    { INDEX_op_sar_i32, { "r", "r", "ri" } },
2020
    { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2021
    { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2022

    
2023
    { INDEX_op_brcond_i32, { "r", "rIN" } },
2024
    { INDEX_op_setcond_i32, { "r", "r", "rIN" } },
2025
    { INDEX_op_movcond_i32, { "r", "r", "rIN", "rIK", "0" } },
2026

    
2027
    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rIN", "rIK" } },
2028
    { INDEX_op_sub2_i32, { "r", "r", "rI", "rI", "rIN", "rIK" } },
2029
    { INDEX_op_brcond2_i32, { "r", "r", "rIN", "rIN" } },
2030
    { INDEX_op_setcond2_i32, { "r", "r", "r", "rIN", "rIN" } },
2031

    
2032
#if TARGET_LONG_BITS == 32
2033
    { INDEX_op_qemu_ld8u, { "r", "l" } },
2034
    { INDEX_op_qemu_ld8s, { "r", "l" } },
2035
    { INDEX_op_qemu_ld16u, { "r", "l" } },
2036
    { INDEX_op_qemu_ld16s, { "r", "l" } },
2037
    { INDEX_op_qemu_ld32, { "r", "l" } },
2038
    { INDEX_op_qemu_ld64, { "r", "r", "l" } },
2039

    
2040
    { INDEX_op_qemu_st8, { "s", "s" } },
2041
    { INDEX_op_qemu_st16, { "s", "s" } },
2042
    { INDEX_op_qemu_st32, { "s", "s" } },
2043
    { INDEX_op_qemu_st64, { "s", "s", "s" } },
2044
#else
2045
    { INDEX_op_qemu_ld8u, { "r", "l", "l" } },
2046
    { INDEX_op_qemu_ld8s, { "r", "l", "l" } },
2047
    { INDEX_op_qemu_ld16u, { "r", "l", "l" } },
2048
    { INDEX_op_qemu_ld16s, { "r", "l", "l" } },
2049
    { INDEX_op_qemu_ld32, { "r", "l", "l" } },
2050
    { INDEX_op_qemu_ld64, { "r", "r", "l", "l" } },
2051

    
2052
    { INDEX_op_qemu_st8, { "s", "s", "s" } },
2053
    { INDEX_op_qemu_st16, { "s", "s", "s" } },
2054
    { INDEX_op_qemu_st32, { "s", "s", "s" } },
2055
    { INDEX_op_qemu_st64, { "s", "s", "s", "s" } },
2056
#endif
2057

    
2058
    { INDEX_op_bswap16_i32, { "r", "r" } },
2059
    { INDEX_op_bswap32_i32, { "r", "r" } },
2060

    
2061
    { INDEX_op_ext8s_i32, { "r", "r" } },
2062
    { INDEX_op_ext16s_i32, { "r", "r" } },
2063
    { INDEX_op_ext16u_i32, { "r", "r" } },
2064

    
2065
    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2066

    
2067
    { INDEX_op_div_i32, { "r", "r", "r" } },
2068
    { INDEX_op_divu_i32, { "r", "r", "r" } },
2069

    
2070
    { -1 },
2071
};
2072

    
2073
static void tcg_target_init(TCGContext *s)
2074
{
2075
#if defined(CONFIG_GETAUXVAL)
2076
    /* Only probe for the platform and capabilities if we havn't already
2077
       determined maximum values at compile time.  */
2078
# if !defined(use_idiv_instructions)
2079
    {
2080
        unsigned long hwcap = getauxval(AT_HWCAP);
2081
        use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
2082
    }
2083
# endif
2084
    if (__ARM_ARCH < 7) {
2085
        const char *pl = (const char *)getauxval(AT_PLATFORM);
2086
        if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
2087
            arm_arch = pl[1] - '0';
2088
        }
2089
    }
2090
#endif /* GETAUXVAL */
2091

    
2092
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
2093
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2094
                     (1 << TCG_REG_R0) |
2095
                     (1 << TCG_REG_R1) |
2096
                     (1 << TCG_REG_R2) |
2097
                     (1 << TCG_REG_R3) |
2098
                     (1 << TCG_REG_R12) |
2099
                     (1 << TCG_REG_R14));
2100

    
2101
    tcg_regset_clear(s->reserved_regs);
2102
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
2103
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP);
2104
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
2105

    
2106
    tcg_add_target_add_op_defs(arm_op_defs);
2107
}
2108

    
2109
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
2110
                              TCGReg arg1, intptr_t arg2)
2111
{
2112
    tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
2113
}
2114

    
2115
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
2116
                              TCGReg arg1, intptr_t arg2)
2117
{
2118
    tcg_out_st32(s, COND_AL, arg, arg1, arg2);
2119
}
2120

    
2121
static inline void tcg_out_mov(TCGContext *s, TCGType type,
2122
                               TCGReg ret, TCGReg arg)
2123
{
2124
    tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
2125
}
2126

    
2127
static inline void tcg_out_movi(TCGContext *s, TCGType type,
2128
                                TCGReg ret, tcg_target_long arg)
2129
{
2130
    tcg_out_movi32(s, COND_AL, ret, arg);
2131
}
2132

    
2133
/* Compute frame size via macros, to share between tcg_target_qemu_prologue
2134
   and tcg_register_jit.  */
2135

    
2136
#define PUSH_SIZE  ((11 - 4 + 1 + 1) * sizeof(tcg_target_long))
2137

    
2138
#define FRAME_SIZE \
2139
    ((PUSH_SIZE \
2140
      + TCG_STATIC_CALL_ARGS_SIZE \
2141
      + CPU_TEMP_BUF_NLONGS * sizeof(long) \
2142
      + TCG_TARGET_STACK_ALIGN - 1) \
2143
     & -TCG_TARGET_STACK_ALIGN)
2144

    
2145
static void tcg_target_qemu_prologue(TCGContext *s)
2146
{
2147
    int stack_addend;
2148

    
2149
    /* Calling convention requires us to save r4-r11 and lr.  */
2150
    /* stmdb sp!, { r4 - r11, lr } */
2151
    tcg_out32(s, (COND_AL << 28) | 0x092d4ff0);
2152

    
2153
    /* Reserve callee argument and tcg temp space.  */
2154
    stack_addend = FRAME_SIZE - PUSH_SIZE;
2155

    
2156
    tcg_out_dat_rI(s, COND_AL, ARITH_SUB, TCG_REG_CALL_STACK,
2157
                   TCG_REG_CALL_STACK, stack_addend, 1);
2158
    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
2159
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
2160

    
2161
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2162

    
2163
    tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
2164
    tb_ret_addr = s->code_ptr;
2165

    
2166
    /* Epilogue.  We branch here via tb_ret_addr.  */
2167
    tcg_out_dat_rI(s, COND_AL, ARITH_ADD, TCG_REG_CALL_STACK,
2168
                   TCG_REG_CALL_STACK, stack_addend, 1);
2169

    
2170
    /* ldmia sp!, { r4 - r11, pc } */
2171
    tcg_out32(s, (COND_AL << 28) | 0x08bd8ff0);
2172
}
2173

    
2174
typedef struct {
2175
    DebugFrameCIE cie;
2176
    DebugFrameFDEHeader fde;
2177
    uint8_t fde_def_cfa[4];
2178
    uint8_t fde_reg_ofs[18];
2179
} DebugFrame;
2180

    
2181
#define ELF_HOST_MACHINE EM_ARM
2182

    
2183
/* We're expecting a 2 byte uleb128 encoded value.  */
2184
QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2185

    
2186
static DebugFrame debug_frame = {
2187
    .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2188
    .cie.id = -1,
2189
    .cie.version = 1,
2190
    .cie.code_align = 1,
2191
    .cie.data_align = 0x7c,             /* sleb128 -4 */
2192
    .cie.return_column = 14,
2193

    
2194
    /* Total FDE size does not include the "len" member.  */
2195
    .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2196

    
2197
    .fde_def_cfa = {
2198
        12, 13,                         /* DW_CFA_def_cfa sp, ... */
2199
        (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2200
        (FRAME_SIZE >> 7)
2201
    },
2202
    .fde_reg_ofs = {
2203
        /* The following must match the stmdb in the prologue.  */
2204
        0x8e, 1,                        /* DW_CFA_offset, lr, -4 */
2205
        0x8b, 2,                        /* DW_CFA_offset, r11, -8 */
2206
        0x8a, 3,                        /* DW_CFA_offset, r10, -12 */
2207
        0x89, 4,                        /* DW_CFA_offset, r9, -16 */
2208
        0x88, 5,                        /* DW_CFA_offset, r8, -20 */
2209
        0x87, 6,                        /* DW_CFA_offset, r7, -24 */
2210
        0x86, 7,                        /* DW_CFA_offset, r6, -28 */
2211
        0x85, 8,                        /* DW_CFA_offset, r5, -32 */
2212
        0x84, 9,                        /* DW_CFA_offset, r4, -36 */
2213
    }
2214
};
2215

    
2216
void tcg_register_jit(void *buf, size_t buf_size)
2217
{
2218
    debug_frame.fde.func_start = (tcg_target_long) buf;
2219
    debug_frame.fde.func_len = buf_size;
2220

    
2221
    tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2222
}