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