Revision b0109805 target-arm/translate.c

b/target-arm/translate.c
222 222

  
223 223
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
224 224
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
225
#define gen_op_rev_T0() tcg_gen_bswap_i32(cpu_T[0], cpu_T[0])
226 225

  
227 226
#define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
228 227

  
......
804 803
        gen_op_##name##_kernel(); \
805 804
    } while (0)
806 805
#endif
806
static inline TCGv gen_ld8s(TCGv addr, int index)
807
{
808
    TCGv tmp = new_tmp();
809
    tcg_gen_qemu_ld8s(tmp, addr, index);
810
    return tmp;
811
}
812
static inline TCGv gen_ld8u(TCGv addr, int index)
813
{
814
    TCGv tmp = new_tmp();
815
    tcg_gen_qemu_ld8u(tmp, addr, index);
816
    return tmp;
817
}
818
static inline TCGv gen_ld16s(TCGv addr, int index)
819
{
820
    TCGv tmp = new_tmp();
821
    tcg_gen_qemu_ld16s(tmp, addr, index);
822
    return tmp;
823
}
824
static inline TCGv gen_ld16u(TCGv addr, int index)
825
{
826
    TCGv tmp = new_tmp();
827
    tcg_gen_qemu_ld16u(tmp, addr, index);
828
    return tmp;
829
}
830
static inline TCGv gen_ld32(TCGv addr, int index)
831
{
832
    TCGv tmp = new_tmp();
833
    tcg_gen_qemu_ld32u(tmp, addr, index);
834
    return tmp;
835
}
836
static inline void gen_st8(TCGv val, TCGv addr, int index)
837
{
838
    tcg_gen_qemu_st8(val, addr, index);
839
    dead_tmp(val);
840
}
841
static inline void gen_st16(TCGv val, TCGv addr, int index)
842
{
843
    tcg_gen_qemu_st16(val, addr, index);
844
    dead_tmp(val);
845
}
846
static inline void gen_st32(TCGv val, TCGv addr, int index)
847
{
848
    tcg_gen_qemu_st32(val, addr, index);
849
    dead_tmp(val);
850
}
807 851

  
808 852
static inline void gen_movl_T0_reg(DisasContext *s, int reg)
809 853
{
......
859 903
    s->is_jmp = DISAS_UPDATE;
860 904
}
861 905

  
862
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn)
906
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
907
                                       TCGv var)
863 908
{
864 909
    int val, rm, shift, shiftop;
865 910
    TCGv offset;
......
870 915
        if (!(insn & (1 << 23)))
871 916
            val = -val;
872 917
        if (val != 0)
873
            gen_op_addl_T1_im(val);
918
            tcg_gen_addi_i32(var, var, val);
874 919
    } else {
875 920
        /* shift/register */
876 921
        rm = (insn) & 0xf;
......
879 924
        offset = load_reg(s, rm);
880 925
        gen_arm_shift_im(offset, shiftop, shift, 0);
881 926
        if (!(insn & (1 << 23)))
882
            tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset);
927
            tcg_gen_sub_i32(var, var, offset);
883 928
        else
884
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset);
929
            tcg_gen_add_i32(var, var, offset);
885 930
        dead_tmp(offset);
886 931
    }
887 932
}
888 933

  
889 934
static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
890
                                        int extra)
935
                                        int extra, TCGv var)
891 936
{
892 937
    int val, rm;
893 938
    TCGv offset;
......
899 944
            val = -val;
900 945
        val += extra;
901 946
        if (val != 0)
902
            gen_op_addl_T1_im(val);
947
            tcg_gen_addi_i32(var, var, val);
903 948
    } else {
904 949
        /* register */
905 950
        if (extra)
906
            gen_op_addl_T1_im(extra);
951
            tcg_gen_addi_i32(var, var, extra);
907 952
        rm = (insn) & 0xf;
908 953
        offset = load_reg(s, rm);
909 954
        if (!(insn & (1 << 23)))
910
            tcg_gen_sub_i32(cpu_T[1], cpu_T[1], offset);
955
            tcg_gen_sub_i32(var, var, offset);
911 956
        else
912
            tcg_gen_add_i32(cpu_T[1], cpu_T[1], offset);
957
            tcg_gen_add_i32(var, var, offset);
913 958
        dead_tmp(offset);
914 959
    }
915 960
}
......
1090 1135
{
1091 1136
    int rd, wrd;
1092 1137
    int rdhi, rdlo, rd0, rd1, i;
1138
    TCGv tmp;
1093 1139

  
1094 1140
    if ((insn & 0x0e000e00) == 0x0c000000) {
1095 1141
        if ((insn & 0x0fe00ff0) == 0x0c400000) {
......
1114 1160
            return 1;
1115 1161
        if (insn & ARM_CP_RW_BIT) {
1116 1162
            if ((insn >> 28) == 0xf) {			/* WLDRW wCx */
1117
                gen_ldst(ldl, s);
1163
                tmp = gen_ld32(cpu_T[1], IS_USER(s));
1164
                tcg_gen_mov_i32(cpu_T[0], tmp);
1165
                dead_tmp(tmp);
1118 1166
                gen_op_iwmmxt_movl_wCx_T0(wrd);
1119 1167
            } else {
1120 1168
                if (insn & (1 << 8))
......
1132 1180
        } else {
1133 1181
            if ((insn >> 28) == 0xf) {			/* WSTRW wCx */
1134 1182
                gen_op_iwmmxt_movl_T0_wCx(wrd);
1135
                gen_ldst(stl, s);
1183
                tmp = new_tmp();
1184
                tcg_gen_mov_i32(tmp, cpu_T[0]);
1185
                gen_st32(tmp, cpu_T[1], IS_USER(s));
1136 1186
            } else {
1137 1187
                gen_op_iwmmxt_movq_M0_wRn(wrd);
1138 1188
                if (insn & (1 << 8))
......
2970 3020
    s->is_jmp = DISAS_UPDATE;
2971 3021
}
2972 3022

  
2973
/* Generate a v6 exception return.  */
2974
static void gen_rfe(DisasContext *s)
3023
/* Generate a v6 exception return.  Marks both values as dead.  */
3024
static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
2975 3025
{
2976
    gen_set_cpsr(cpu_T[0], 0xffffffff);
2977
    gen_op_movl_T0_T2();
2978
    gen_set_pc_T0();
3026
    gen_set_cpsr(cpsr, 0xffffffff);
3027
    dead_tmp(cpsr);
3028
    store_reg(s, 15, pc);
2979 3029
    s->is_jmp = DISAS_UPDATE;
2980 3030
}
2981 3031

  
......
3288 3338
    int shift;
3289 3339
    uint32_t mask;
3290 3340
    int n;
3341
    TCGv tmp;
3291 3342

  
3292 3343
    if (!vfp_enabled(env))
3293 3344
      return 1;
......
3316 3367
            for (pass = 0; pass < 2; pass++) {
3317 3368
                if (size == 2) {
3318 3369
                    if (load) {
3319
                        gen_ldst(ldl, s);
3370
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3371
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3372
                        dead_tmp(tmp);
3320 3373
                        NEON_SET_REG(T0, rd, pass);
3321 3374
                    } else {
3322 3375
                        NEON_GET_REG(T0, rd, pass);
3323
                        gen_ldst(stl, s);
3376
                        tmp = new_tmp();
3377
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3378
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3324 3379
                    }
3325 3380
                    gen_op_addl_T1_im(stride);
3326 3381
                } else if (size == 1) {
3327 3382
                    if (load) {
3328
                        gen_ldst(lduw, s);
3383
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3384
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3385
                        dead_tmp(tmp);
3329 3386
                        gen_op_addl_T1_im(stride);
3330 3387
                        gen_op_movl_T2_T0();
3331
                        gen_ldst(lduw, s);
3388
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3389
                        tcg_gen_mov_i32(cpu_T[0], tmp);
3390
                        dead_tmp(tmp);
3332 3391
                        gen_op_addl_T1_im(stride);
3333 3392
                        gen_op_neon_insert_elt(16, 0xffff);
3334 3393
                        NEON_SET_REG(T2, rd, pass);
3335 3394
                    } else {
3336 3395
                        NEON_GET_REG(T2, rd, pass);
3337 3396
                        gen_op_movl_T0_T2();
3338
                        gen_ldst(stw, s);
3397
                        tmp = new_tmp();
3398
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3399
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3339 3400
                        gen_op_addl_T1_im(stride);
3340 3401
                        gen_op_neon_extract_elt(16, 0xffff0000);
3341
                        gen_ldst(stw, s);
3402
                        tmp = new_tmp();
3403
                        tcg_gen_mov_i32(tmp, cpu_T[0]);
3404
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3342 3405
                        gen_op_addl_T1_im(stride);
3343 3406
                    }
3344 3407
                } else /* size == 0 */ {
3345 3408
                    if (load) {
3346 3409
                        mask = 0xff;
3347 3410
                        for (n = 0; n < 4; n++) {
3348
                            gen_ldst(ldub, s);
3411
                            tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3412
                            tcg_gen_mov_i32(cpu_T[0], tmp);
3413
                            dead_tmp(tmp);
3349 3414
                            gen_op_addl_T1_im(stride);
3350 3415
                            if (n == 0) {
3351 3416
                                gen_op_movl_T2_T0();
......
3364 3429
                            } else {
3365 3430
                                gen_op_neon_extract_elt(n * 8, mask);
3366 3431
                            }
3367
                            gen_ldst(stb, s);
3432
                            tmp = new_tmp();
3433
                            tcg_gen_mov_i32(tmp, cpu_T[0]);
3434
                            gen_st8(tmp, cpu_T[1], IS_USER(s));
3368 3435
                            gen_op_addl_T1_im(stride);
3369 3436
                            mask <<= 8;
3370 3437
                        }
......
3387 3454
            for (reg = 0; reg < nregs; reg++) {
3388 3455
                switch (size) {
3389 3456
                case 0:
3390
                    gen_ldst(ldub, s);
3457
                    tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3458
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3459
                    dead_tmp(tmp);
3391 3460
                    gen_op_neon_dup_u8(0);
3392 3461
                    break;
3393 3462
                case 1:
3394
                    gen_ldst(lduw, s);
3463
                    tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3464
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3465
                    dead_tmp(tmp);
3395 3466
                    gen_op_neon_dup_low16();
3396 3467
                    break;
3397 3468
                case 2:
3398
                    gen_ldst(ldl, s);
3469
                    tmp = gen_ld32(cpu_T[0], IS_USER(s));
3470
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3471
                    dead_tmp(tmp);
3399 3472
                    break;
3400 3473
                case 3:
3401 3474
                    return 1;
......
3437 3510
                    }
3438 3511
                    switch (size) {
3439 3512
                    case 0:
3440
                        gen_ldst(ldub, s);
3513
                        tmp = gen_ld8u(cpu_T[1], IS_USER(s));
3441 3514
                        break;
3442 3515
                    case 1:
3443
                        gen_ldst(lduw, s);
3516
                        tmp = gen_ld16u(cpu_T[1], IS_USER(s));
3444 3517
                        break;
3445 3518
                    case 2:
3446
                        gen_ldst(ldl, s);
3447
                        NEON_SET_REG(T0, rd, pass);
3519
                        tmp = gen_ld32(cpu_T[1], IS_USER(s));
3448 3520
                        break;
3449 3521
                    }
3522
                    tcg_gen_mov_i32(cpu_T[0], tmp);
3523
                    dead_tmp(tmp);
3450 3524
                    if (size != 2) {
3451 3525
                        gen_op_neon_insert_elt(shift, ~mask);
3452 3526
                        NEON_SET_REG(T0, rd, pass);
3527
                    } else {
3528
                        NEON_SET_REG(T0, rd, pass);
3453 3529
                    }
3454 3530
                } else { /* Store */
3455 3531
                    if (size == 2) {
......
3458 3534
                        NEON_GET_REG(T2, rd, pass);
3459 3535
                        gen_op_neon_extract_elt(shift, mask);
3460 3536
                    }
3537
                    tmp = new_tmp();
3538
                    tcg_gen_mov_i32(tmp, cpu_T[0]);
3461 3539
                    switch (size) {
3462 3540
                    case 0:
3463
                        gen_ldst(stb, s);
3541
                        gen_st8(tmp, cpu_T[1], IS_USER(s));
3464 3542
                        break;
3465 3543
                    case 1:
3466
                        gen_ldst(stw, s);
3544
                        gen_st16(tmp, cpu_T[1], IS_USER(s));
3467 3545
                        break;
3468 3546
                    case 2:
3469
                        gen_ldst(stl, s);
3547
                        gen_st32(tmp, cpu_T[1], IS_USER(s));
3470 3548
                        break;
3471 3549
                    }
3472 3550
                }
......
4647 4725
                        NEON_GET_REG(T0, rm, pass * 2);
4648 4726
                        NEON_GET_REG(T1, rm, pass * 2 + 1);
4649 4727
                        switch (size) {
4650
                        case 0: gen_op_rev_T0(); break;
4728
                        case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4651 4729
                        case 1: gen_swap_half(cpu_T[0]); break;
4652 4730
                        case 2: /* no-op */ break;
4653 4731
                        default: abort();
......
4658 4736
                        } else {
4659 4737
                            gen_op_movl_T0_T1();
4660 4738
                            switch (size) {
4661
                            case 0: gen_op_rev_T0(); break;
4739
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4662 4740
                            case 1: gen_swap_half(cpu_T[0]); break;
4663 4741
                            default: abort();
4664 4742
                            }
......
4827 4905
                        switch (op) {
4828 4906
                        case 1: /* VREV32 */
4829 4907
                            switch (size) {
4830
                            case 0: gen_op_rev_T0(); break;
4908
                            case 0: tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]); break;
4831 4909
                            case 1: gen_swap_half(cpu_T[0]); break;
4832 4910
                            default: return 1;
4833 4911
                            }
......
5099 5177
    TCGv tmp;
5100 5178
    TCGv tmp2;
5101 5179
    TCGv tmp3;
5180
    TCGv addr;
5102 5181

  
5103 5182
    insn = ldl_code(s->pc);
5104 5183
    s->pc += 4;
......
5160 5239
            ARCH(6);
5161 5240
            op1 = (insn & 0x1f);
5162 5241
            if (op1 == (env->uncached_cpsr & CPSR_M)) {
5163
                gen_movl_T1_reg(s, 13);
5242
                addr = load_reg(s, 13);
5164 5243
            } else {
5165
                gen_op_movl_T1_r13_banked(op1);
5244
                addr = new_tmp();
5245
                gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
5166 5246
            }
5167 5247
            i = (insn >> 23) & 3;
5168 5248
            switch (i) {
......
5173 5253
            default: abort();
5174 5254
            }
5175 5255
            if (offset)
5176
                gen_op_addl_T1_im(offset);
5177
            gen_movl_T0_reg(s, 14);
5178
            gen_ldst(stl, s);
5179
            gen_helper_cpsr_read(cpu_T[0]);
5180
            gen_op_addl_T1_im(4);
5181
            gen_ldst(stl, s);
5256
                tcg_gen_addi_i32(addr, addr, offset);
5257
            tmp = load_reg(s, 14);
5258
            gen_st32(tmp, addr, 0);
5259
            tmp = new_tmp();
5260
            gen_helper_cpsr_read(tmp);
5261
            tcg_gen_addi_i32(addr, addr, 4);
5262
            gen_st32(tmp, addr, 0);
5182 5263
            if (insn & (1 << 21)) {
5183 5264
                /* Base writeback.  */
5184 5265
                switch (i) {
......
5189 5270
                default: abort();
5190 5271
                }
5191 5272
                if (offset)
5192
                    gen_op_addl_T1_im(offset);
5273
                    tcg_gen_addi_i32(addr, tmp, offset);
5193 5274
                if (op1 == (env->uncached_cpsr & CPSR_M)) {
5194 5275
                    gen_movl_reg_T1(s, 13);
5195 5276
                } else {
5196
                    gen_op_movl_r13_T1_banked(op1);
5277
                    gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
5197 5278
                }
5279
            } else {
5280
                dead_tmp(addr);
5198 5281
            }
5199 5282
        } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
5200 5283
            /* rfe */
......
5203 5286
                goto illegal_op;
5204 5287
            ARCH(6);
5205 5288
            rn = (insn >> 16) & 0xf;
5206
            gen_movl_T1_reg(s, rn);
5289
            addr = load_reg(s, rn);
5207 5290
            i = (insn >> 23) & 3;
5208 5291
            switch (i) {
5209
            case 0: offset = 0; break; /* DA */
5210
            case 1: offset = -4; break; /* DB */
5211
            case 2: offset = 4; break; /* IA */
5212
            case 3: offset = 8; break; /* IB */
5292
            case 0: offset = -4; break; /* DA */
5293
            case 1: offset = -8; break; /* DB */
5294
            case 2: offset = 0; break; /* IA */
5295
            case 3: offset = 4; break; /* IB */
5213 5296
            default: abort();
5214 5297
            }
5215 5298
            if (offset)
5216
                gen_op_addl_T1_im(offset);
5217
            /* Load CPSR into T2 and PC into T0.  */
5218
            gen_ldst(ldl, s);
5219
            gen_op_movl_T2_T0();
5220
            gen_op_addl_T1_im(-4);
5221
            gen_ldst(ldl, s);
5299
                tcg_gen_addi_i32(addr, addr, offset);
5300
            /* Load PC into tmp and CPSR into tmp2.  */
5301
            tmp = gen_ld32(addr, 0);
5302
            tcg_gen_addi_i32(addr, addr, 4);
5303
            tmp2 = gen_ld32(addr, 0);
5222 5304
            if (insn & (1 << 21)) {
5223 5305
                /* Base writeback.  */
5224 5306
                switch (i) {
5225
                case 0: offset = -4; break;
5226
                case 1: offset = 0; break;
5227
                case 2: offset = 8; break;
5228
                case 3: offset = 4; break;
5307
                case 0: offset = -8; break;
5308
                case 1: offset = -4; break;
5309
                case 2: offset = 4; break;
5310
                case 3: offset = 0; break;
5229 5311
                default: abort();
5230 5312
                }
5231 5313
                if (offset)
5232
                    gen_op_addl_T1_im(offset);
5233
                gen_movl_reg_T1(s, rn);
5314
                    tcg_gen_addi_i32(addr, addr, offset);
5315
                store_reg(s, rn, addr);
5316
            } else {
5317
                dead_tmp(addr);
5234 5318
            }
5235
            gen_rfe(s);
5319
            gen_rfe(s, tmp, tmp2);
5236 5320
        } else if ((insn & 0x0e000000) == 0x0a000000) {
5237 5321
            /* branch link and change to thumb (blx <offset>) */
5238 5322
            int32_t offset;
......
5707 5791
                /* Misc load/store */
5708 5792
                rn = (insn >> 16) & 0xf;
5709 5793
                rd = (insn >> 12) & 0xf;
5710
                gen_movl_T1_reg(s, rn);
5794
                addr = load_reg(s, rn);
5711 5795
                if (insn & (1 << 24))
5712
                    gen_add_datah_offset(s, insn, 0);
5796
                    gen_add_datah_offset(s, insn, 0, addr);
5713 5797
                address_offset = 0;
5714 5798
                if (insn & (1 << 20)) {
5715 5799
                    /* load */
5716 5800
                    switch(sh) {
5717 5801
                    case 1:
5718
                        gen_ldst(lduw, s);
5802
                        tmp = gen_ld16u(addr, IS_USER(s));
5719 5803
                        break;
5720 5804
                    case 2:
5721
                        gen_ldst(ldsb, s);
5805
                        tmp = gen_ld8s(addr, IS_USER(s));
5722 5806
                        break;
5723 5807
                    default:
5724 5808
                    case 3:
5725
                        gen_ldst(ldsw, s);
5809
                        tmp = gen_ld16s(addr, IS_USER(s));
5726 5810
                        break;
5727 5811
                    }
5728 5812
                    load = 1;
......
5730 5814
                    /* doubleword */
5731 5815
                    if (sh & 1) {
5732 5816
                        /* store */
5733
                        gen_movl_T0_reg(s, rd);
5734
                        gen_ldst(stl, s);
5735
                        gen_op_addl_T1_im(4);
5736
                        gen_movl_T0_reg(s, rd + 1);
5737
                        gen_ldst(stl, s);
5817
                        tmp = load_reg(s, rd);
5818
                        gen_st32(tmp, addr, IS_USER(s));
5819
                        tcg_gen_addi_i32(addr, addr, 4);
5820
                        tmp = load_reg(s, rd + 1);
5821
                        gen_st32(tmp, addr, IS_USER(s));
5738 5822
                        load = 0;
5739 5823
                    } else {
5740 5824
                        /* load */
5741
                        gen_ldst(ldl, s);
5742
                        gen_movl_reg_T0(s, rd);
5743
                        gen_op_addl_T1_im(4);
5744
                        gen_ldst(ldl, s);
5825
                        tmp = gen_ld32(addr, IS_USER(s));
5826
                        store_reg(s, rd, tmp);
5827
                        tcg_gen_addi_i32(addr, addr, 4);
5828
                        tmp = gen_ld32(addr, IS_USER(s));
5745 5829
                        rd++;
5746 5830
                        load = 1;
5747 5831
                    }
5748 5832
                    address_offset = -4;
5749 5833
                } else {
5750 5834
                    /* store */
5751
                    gen_movl_T0_reg(s, rd);
5752
                    gen_ldst(stw, s);
5835
                    tmp = load_reg(s, rd);
5836
                    gen_st16(tmp, addr, IS_USER(s));
5753 5837
                    load = 0;
5754 5838
                }
5755 5839
                /* Perform base writeback before the loaded value to
......
5757 5841
                   ldrd with base writeback is is undefined if the
5758 5842
                   destination and index registers overlap.  */
5759 5843
                if (!(insn & (1 << 24))) {
5760
                    gen_add_datah_offset(s, insn, address_offset);
5761
                    gen_movl_reg_T1(s, rn);
5844
                    gen_add_datah_offset(s, insn, address_offset, addr);
5845
                    store_reg(s, rn, addr);
5762 5846
                } else if (insn & (1 << 21)) {
5763 5847
                    if (address_offset)
5764
                        gen_op_addl_T1_im(address_offset);
5765
                    gen_movl_reg_T1(s, rn);
5848
                        tcg_gen_addi_i32(addr, addr, address_offset);
5849
                    store_reg(s, rn, addr);
5850
                } else {
5851
                    dead_tmp(addr);
5766 5852
                }
5767 5853
                if (load) {
5768 5854
                    /* Complete the load.  */
5769
                    gen_movl_reg_T0(s, rd);
5855
                    store_reg(s, rd, tmp);
5770 5856
                }
5771 5857
            }
5772 5858
            break;
......
5882 5968
                        gen_movl_reg_T1(s, rd);
5883 5969
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
5884 5970
                        /* rev */
5885
                        gen_movl_T0_reg(s, rm);
5971
                        tmp = load_reg(s, rm);
5886 5972
                        if (insn & (1 << 22)) {
5887 5973
                            if (insn & (1 << 7)) {
5888
                                gen_revsh(cpu_T[0]);
5974
                                gen_revsh(tmp);
5889 5975
                            } else {
5890 5976
                                ARCH(6T2);
5891
                                gen_helper_rbit(cpu_T[0], cpu_T[0]);
5977
                                gen_helper_rbit(tmp, tmp);
5892 5978
                            }
5893 5979
                        } else {
5894 5980
                            if (insn & (1 << 7))
5895
                                gen_rev16(cpu_T[0]);
5981
                                gen_rev16(tmp);
5896 5982
                            else
5897
                                gen_op_rev_T0();
5983
                                tcg_gen_bswap_i32(tmp, tmp);
5898 5984
                        }
5899
                        gen_movl_reg_T0(s, rd);
5985
                        store_reg(s, rd, tmp);
5900 5986
                    } else {
5901 5987
                        goto illegal_op;
5902 5988
                    }
......
6020 6106
            /* load/store byte/word */
6021 6107
            rn = (insn >> 16) & 0xf;
6022 6108
            rd = (insn >> 12) & 0xf;
6023
            gen_movl_T1_reg(s, rn);
6109
            tmp2 = load_reg(s, rn);
6024 6110
            i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
6025 6111
            if (insn & (1 << 24))
6026
                gen_add_data_offset(s, insn);
6112
                gen_add_data_offset(s, insn, tmp2);
6027 6113
            if (insn & (1 << 20)) {
6028 6114
                /* load */
6029 6115
                s->is_mem = 1;
6030
#if defined(CONFIG_USER_ONLY)
6031
                if (insn & (1 << 22))
6032
                    gen_op_ldub_raw();
6033
                else
6034
                    gen_op_ldl_raw();
6035
#else
6036 6116
                if (insn & (1 << 22)) {
6037
                    if (i)
6038
                        gen_op_ldub_user();
6039
                    else
6040
                        gen_op_ldub_kernel();
6117
                    tmp = gen_ld8u(tmp2, i);
6041 6118
                } else {
6042
                    if (i)
6043
                        gen_op_ldl_user();
6044
                    else
6045
                        gen_op_ldl_kernel();
6119
                    tmp = gen_ld32(tmp2, i);
6046 6120
                }
6047
#endif
6048 6121
            } else {
6049 6122
                /* store */
6050
                gen_movl_T0_reg(s, rd);
6051
#if defined(CONFIG_USER_ONLY)
6123
                tmp = load_reg(s, rd);
6052 6124
                if (insn & (1 << 22))
6053
                    gen_op_stb_raw();
6125
                    gen_st8(tmp, tmp2, i);
6054 6126
                else
6055
                    gen_op_stl_raw();
6056
#else
6057
                if (insn & (1 << 22)) {
6058
                    if (i)
6059
                        gen_op_stb_user();
6060
                    else
6061
                        gen_op_stb_kernel();
6062
                } else {
6063
                    if (i)
6064
                        gen_op_stl_user();
6065
                    else
6066
                        gen_op_stl_kernel();
6067
                }
6068
#endif
6127
                    gen_st32(tmp, tmp2, i);
6069 6128
            }
6070 6129
            if (!(insn & (1 << 24))) {
6071
                gen_add_data_offset(s, insn);
6072
                gen_movl_reg_T1(s, rn);
6073
            } else if (insn & (1 << 21))
6074
                gen_movl_reg_T1(s, rn); {
6130
                gen_add_data_offset(s, insn, tmp2);
6131
                store_reg(s, rn, tmp2);
6132
            } else if (insn & (1 << 21)) {
6133
                store_reg(s, rn, tmp2);
6134
            } else {
6135
                dead_tmp(tmp2);
6075 6136
            }
6076 6137
            if (insn & (1 << 20)) {
6077 6138
                /* Complete the load.  */
6078 6139
                if (rd == 15)
6079
                    gen_bx_T0(s);
6140
                    gen_bx(s, tmp);
6080 6141
                else
6081
                    gen_movl_reg_T0(s, rd);
6142
                    store_reg(s, rd, tmp);
6082 6143
            }
6083 6144
            break;
6084 6145
        case 0x08:
6085 6146
        case 0x09:
6086 6147
            {
6087 6148
                int j, n, user, loaded_base;
6149
                TCGv loaded_var;
6088 6150
                /* load/store multiple words */
6089 6151
                /* XXX: store correct base if write back */
6090 6152
                user = 0;
......
6096 6158
                        user = 1;
6097 6159
                }
6098 6160
                rn = (insn >> 16) & 0xf;
6099
                gen_movl_T1_reg(s, rn);
6161
                addr = load_reg(s, rn);
6100 6162

  
6101 6163
                /* compute total size */
6102 6164
                loaded_base = 0;
......
6109 6171
                if (insn & (1 << 23)) {
6110 6172
                    if (insn & (1 << 24)) {
6111 6173
                        /* pre increment */
6112
                        gen_op_addl_T1_im(4);
6174
                        tcg_gen_addi_i32(addr, addr, 4);
6113 6175
                    } else {
6114 6176
                        /* post increment */
6115 6177
                    }
6116 6178
                } else {
6117 6179
                    if (insn & (1 << 24)) {
6118 6180
                        /* pre decrement */
6119
                        gen_op_addl_T1_im(-(n * 4));
6181
                        tcg_gen_addi_i32(addr, addr, -(n * 4));
6120 6182
                    } else {
6121 6183
                        /* post decrement */
6122 6184
                        if (n != 1)
6123
                            gen_op_addl_T1_im(-((n - 1) * 4));
6185
                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6124 6186
                    }
6125 6187
                }
6126 6188
                j = 0;
......
6128 6190
                    if (insn & (1 << i)) {
6129 6191
                        if (insn & (1 << 20)) {
6130 6192
                            /* load */
6131
                            gen_ldst(ldl, s);
6193
                            tmp = gen_ld32(addr, IS_USER(s));
6132 6194
                            if (i == 15) {
6133
                                gen_bx_T0(s);
6195
                                gen_bx(s, tmp);
6134 6196
                            } else if (user) {
6135
                                gen_op_movl_user_T0(i);
6197
                                gen_helper_set_user_reg(tcg_const_i32(i), tmp);
6198
                                dead_tmp(tmp);
6136 6199
                            } else if (i == rn) {
6137
                                gen_op_movl_T2_T0();
6200
                                loaded_var = tmp;
6138 6201
                                loaded_base = 1;
6139 6202
                            } else {
6140
                                gen_movl_reg_T0(s, i);
6203
                                store_reg(s, i, tmp);
6141 6204
                            }
6142 6205
                        } else {
6143 6206
                            /* store */
6144 6207
                            if (i == 15) {
6145 6208
                                /* special case: r15 = PC + 8 */
6146 6209
                                val = (long)s->pc + 4;
6147
                                gen_op_movl_T0_im(val);
6210
                                tmp = new_tmp();
6211
                                tcg_gen_movi_i32(tmp, val);
6148 6212
                            } else if (user) {
6149
                                gen_op_movl_T0_user(i);
6213
                                tmp = new_tmp();
6214
                                gen_helper_get_user_reg(tmp, tcg_const_i32(i));
6150 6215
                            } else {
6151
                                gen_movl_T0_reg(s, i);
6216
                                tmp = load_reg(s, i);
6152 6217
                            }
6153
                            gen_ldst(stl, s);
6218
                            gen_st32(tmp, addr, IS_USER(s));
6154 6219
                        }
6155 6220
                        j++;
6156 6221
                        /* no need to add after the last transfer */
6157 6222
                        if (j != n)
6158
                            gen_op_addl_T1_im(4);
6223
                            tcg_gen_addi_i32(addr, addr, 4);
6159 6224
                    }
6160 6225
                }
6161 6226
                if (insn & (1 << 21)) {
......
6165 6230
                            /* pre increment */
6166 6231
                        } else {
6167 6232
                            /* post increment */
6168
                            gen_op_addl_T1_im(4);
6233
                            tcg_gen_addi_i32(addr, addr, 4);
6169 6234
                        }
6170 6235
                    } else {
6171 6236
                        if (insn & (1 << 24)) {
6172 6237
                            /* pre decrement */
6173 6238
                            if (n != 1)
6174
                                gen_op_addl_T1_im(-((n - 1) * 4));
6239
                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
6175 6240
                        } else {
6176 6241
                            /* post decrement */
6177
                            gen_op_addl_T1_im(-(n * 4));
6242
                            tcg_gen_addi_i32(addr, addr, -(n * 4));
6178 6243
                        }
6179 6244
                    }
6180
                    gen_movl_reg_T1(s, rn);
6245
                    store_reg(s, rn, addr);
6246
                } else {
6247
                    dead_tmp(addr);
6181 6248
                }
6182 6249
                if (loaded_base) {
6183
                    gen_op_movl_T0_T2();
6184
                    gen_movl_reg_T0(s, rn);
6250
                    store_reg(s, rn, loaded_var);
6185 6251
                }
6186 6252
                if ((insn & (1 << 22)) && !user) {
6187 6253
                    /* Restore CPSR from SPSR.  */
......
6319 6385
   is not legal.  */
6320 6386
static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
6321 6387
{
6322
    uint32_t insn, imm, shift, offset, addr;
6388
    uint32_t insn, imm, shift, offset;
6323 6389
    uint32_t rd, rn, rm, rs;
6324 6390
    TCGv tmp;
6325 6391
    TCGv tmp2;
6326 6392
    TCGv tmp3;
6393
    TCGv addr;
6327 6394
    int op;
6328 6395
    int shiftop;
6329 6396
    int conds;
......
6341 6408
            tcg_gen_addi_i32(tmp, tmp, offset);
6342 6409
            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
6343 6410

  
6344
            addr = (uint32_t)s->pc;
6345 6411
            tmp2 = new_tmp();
6346
            tcg_gen_movi_i32(tmp2, addr | 1);
6412
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6347 6413
            store_reg(s, 14, tmp2);
6348 6414
            gen_bx(s, tmp);
6349 6415
            return 0;
......
6354 6420
            tmp = load_reg(s, 14);
6355 6421
            tcg_gen_addi_i32(tmp, tmp, 14);
6356 6422

  
6357
            addr = (uint32_t)s->pc;
6358 6423
            tmp2 = new_tmp();
6359
            tcg_gen_movi_i32(tmp2, addr | 1);
6424
            tcg_gen_movi_i32(tmp2, s->pc | 1);
6360 6425
            store_reg(s, 14, tmp2);
6361 6426
            gen_bx(s, tmp);
6362 6427
            return 0;
......
6366 6431
               16-bit instructions in case the second half causes an
6367 6432
               prefetch abort.  */
6368 6433
            offset = ((int32_t)insn << 21) >> 9;
6369
            addr = s->pc + 2 + offset;
6370
            gen_op_movl_T0_im(addr);
6434
            gen_op_movl_T0_im(s->pc + 2 + offset);
6371 6435
            gen_movl_reg_T0(s, 14);
6372 6436
            return 0;
6373 6437
        }
......
6396 6460
            if (insn & 0x01200000) {
6397 6461
                /* Load/store doubleword.  */
6398 6462
                if (rn == 15) {
6399
                    gen_op_movl_T1_im(s->pc & ~3);
6463
                    addr = new_tmp();
6464
                    tcg_gen_movi_i32(addr, s->pc & ~3);
6400 6465
                } else {
6401
                    gen_movl_T1_reg(s, rn);
6466
                    addr = load_reg(s, rn);
6402 6467
                }
6403 6468
                offset = (insn & 0xff) * 4;
6404 6469
                if ((insn & (1 << 23)) == 0)
6405 6470
                    offset = -offset;
6406 6471
                if (insn & (1 << 24)) {
6407
                    gen_op_addl_T1_im(offset);
6472
                    tcg_gen_addi_i32(addr, addr, offset);
6408 6473
                    offset = 0;
6409 6474
                }
6410 6475
                if (insn & (1 << 20)) {
6411 6476
                    /* ldrd */
6412
                    gen_ldst(ldl, s);
6413
                    gen_movl_reg_T0(s, rs);
6414
                    gen_op_addl_T1_im(4);
6415
                    gen_ldst(ldl, s);
6416
                    gen_movl_reg_T0(s, rd);
6477
                    tmp = gen_ld32(addr, IS_USER(s));
6478
                    store_reg(s, rs, tmp);
6479
                    tcg_gen_addi_i32(addr, addr, 4);
6480
                    tmp = gen_ld32(addr, IS_USER(s));
6481
                    store_reg(s, rd, tmp);
6417 6482
                } else {
6418 6483
                    /* strd */
6419
                    gen_movl_T0_reg(s, rs);
6420
                    gen_ldst(stl, s);
6421
                    gen_op_addl_T1_im(4);
6422
                    gen_movl_T0_reg(s, rd);
6423
                    gen_ldst(stl, s);
6484
                    tmp = load_reg(s, rs);
6485
                    gen_st32(tmp, addr, IS_USER(s));
6486
                    tcg_gen_addi_i32(addr, addr, 4);
6487
                    tmp = load_reg(s, rd);
6488
                    gen_st32(tmp, addr, IS_USER(s));
6424 6489
                }
6425 6490
                if (insn & (1 << 21)) {
6426 6491
                    /* Base writeback.  */
6427 6492
                    if (rn == 15)
6428 6493
                        goto illegal_op;
6429
                    gen_op_addl_T1_im(offset - 4);
6430
                    gen_movl_reg_T1(s, rn);
6494
                    tcg_gen_addi_i32(addr, addr, offset - 4);
6495
                    store_reg(s, rn, addr);
6496
                } else {
6497
                    dead_tmp(addr);
6431 6498
                }
6432 6499
            } else if ((insn & (1 << 23)) == 0) {
6433 6500
                /* Load/store exclusive word.  */
......
6442 6509
            } else if ((insn & (1 << 6)) == 0) {
6443 6510
                /* Table Branch.  */
6444 6511
                if (rn == 15) {
6445
                    gen_op_movl_T1_im(s->pc);
6512
                    addr = new_tmp();
6513
                    tcg_gen_movi_i32(addr, s->pc);
6446 6514
                } else {
6447
                    gen_movl_T1_reg(s, rn);
6515
                    addr = load_reg(s, rn);
6448 6516
                }
6449 6517
                tmp = load_reg(s, rm);
6450
                tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
6518
                tcg_gen_add_i32(addr, addr, tmp);
6451 6519
                if (insn & (1 << 4)) {
6452 6520
                    /* tbh */
6453
                    tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
6521
                    tcg_gen_add_i32(addr, addr, tmp);
6454 6522
                    dead_tmp(tmp);
6455
                    gen_ldst(lduw, s);
6523
                    tmp = gen_ld16u(addr, IS_USER(s));
6456 6524
                } else { /* tbb */
6457 6525
                    dead_tmp(tmp);
6458
                    gen_ldst(ldub, s);
6526
                    tmp = gen_ld8u(addr, IS_USER(s));
6459 6527
                }
6460
                tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 1);
6461
                tcg_gen_addi_i32(cpu_T[0], cpu_T[0], s->pc);
6462
                gen_movl_reg_T0(s, 15);
6528
                dead_tmp(addr);
6529
                tcg_gen_shli_i32(tmp, tmp, 1);
6530
                tcg_gen_addi_i32(tmp, tmp, s->pc);
6531
                store_reg(s, 15, tmp);
6463 6532
            } else {
6464 6533
                /* Load/store exclusive byte/halfword/doubleword.  */
6465 6534
                op = (insn >> 4) & 0x3;
......
6503 6572
            /* Load/store multiple, RFE, SRS.  */
6504 6573
            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
6505 6574
                /* Not available in user mode.  */
6506
                if (!IS_USER(s))
6575
                if (IS_USER(s))
6507 6576
                    goto illegal_op;
6508 6577
                if (insn & (1 << 20)) {
6509 6578
                    /* rfe */
6510
                    gen_movl_T1_reg(s, rn);
6511
                    if (insn & (1 << 24)) {
6512
                        gen_op_addl_T1_im(4);
6513
                    } else {
6514
                        gen_op_addl_T1_im(-4);
6515
                    }
6516
                    /* Load CPSR into T2 and PC into T0.  */
6517
                    gen_ldst(ldl, s);
6518
                    gen_op_movl_T2_T0();
6519
                    gen_op_addl_T1_im(-4);
6520
                    gen_ldst(ldl, s);
6579
                    addr = load_reg(s, rn);
6580
                    if ((insn & (1 << 24)) == 0)
6581
                        tcg_gen_addi_i32(addr, addr, -8);
6582
                    /* Load PC into tmp and CPSR into tmp2.  */
6583
                    tmp = gen_ld32(addr, 0);
6584
                    tcg_gen_addi_i32(addr, addr, 4);
6585
                    tmp2 = gen_ld32(addr, 0);
6521 6586
                    if (insn & (1 << 21)) {
6522 6587
                        /* Base writeback.  */
6523
                        if (insn & (1 << 24))
6524
                            gen_op_addl_T1_im(8);
6525
                        gen_movl_reg_T1(s, rn);
6588
                        if (insn & (1 << 24)) {
6589
                            tcg_gen_addi_i32(addr, addr, 4);
6590
                        } else {
6591
                            tcg_gen_addi_i32(addr, addr, -4);
6592
                        }
6593
                        store_reg(s, rn, addr);
6594
                    } else {
6595
                        dead_tmp(addr);
6526 6596
                    }
6527
                    gen_rfe(s);
6597
                    gen_rfe(s, tmp, tmp2);
6528 6598
                } else {
6529 6599
                    /* srs */
6530 6600
                    op = (insn & 0x1f);
6531 6601
                    if (op == (env->uncached_cpsr & CPSR_M)) {
6532
                        gen_movl_T1_reg(s, 13);
6602
                        addr = load_reg(s, 13);
6533 6603
                    } else {
6534
                        gen_op_movl_T1_r13_banked(op);
6604
                        addr = new_tmp();
6605
                        gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
6535 6606
                    }
6536 6607
                    if ((insn & (1 << 24)) == 0) {
6537
                        gen_op_addl_T1_im(-8);
6608
                        tcg_gen_addi_i32(addr, addr, -8);
6538 6609
                    }
6539
                    gen_movl_T0_reg(s, 14);
6540
                    gen_ldst(stl, s);
6541
                    gen_helper_cpsr_read(cpu_T[0]);
6542
                    gen_op_addl_T1_im(4);
6543
                    gen_ldst(stl, s);
6610
                    tmp = load_reg(s, 14);
6611
                    gen_st32(tmp, addr, 0);
6612
                    tcg_gen_addi_i32(addr, addr, 4);
6613
                    tmp = new_tmp();
6614
                    gen_helper_cpsr_read(tmp);
6615
                    gen_st32(tmp, addr, 0);
6544 6616
                    if (insn & (1 << 21)) {
6545 6617
                        if ((insn & (1 << 24)) == 0) {
6546
                            gen_op_addl_T1_im(-4);
6618
                            tcg_gen_addi_i32(addr, addr, -4);
6547 6619
                        } else {
6548
                            gen_op_addl_T1_im(4);
6620
                            tcg_gen_addi_i32(addr, addr, 4);
6549 6621
                        }
6550 6622
                        if (op == (env->uncached_cpsr & CPSR_M)) {
6551
                            gen_movl_reg_T1(s, 13);
6623
                            store_reg(s, 13, addr);
6552 6624
                        } else {
6553
                            gen_op_movl_r13_T1_banked(op);
6625
                            gen_helper_set_r13_banked(cpu_env,
6626
                                tcg_const_i32(op), addr);
6554 6627
                        }
6628
                    } else {
6629
                        dead_tmp(addr);
6555 6630
                    }
6556 6631
                }
6557 6632
            } else {
6558 6633
                int i;
6559 6634
                /* Load/store multiple.  */
6560
                gen_movl_T1_reg(s, rn);
6635
                addr = load_reg(s, rn);
6561 6636
                offset = 0;
6562 6637
                for (i = 0; i < 16; i++) {
6563 6638
                    if (insn & (1 << i))
6564 6639
                        offset += 4;
6565 6640
                }
6566 6641
                if (insn & (1 << 24)) {
6567
                    gen_op_addl_T1_im(-offset);
6642
                    tcg_gen_addi_i32(addr, addr, -offset);
6568 6643
                }
6569 6644

  
6570 6645
                for (i = 0; i < 16; i++) {
......
6572 6647
                        continue;
6573 6648
                    if (insn & (1 << 20)) {
6574 6649
                        /* Load.  */
6575
                        gen_ldst(ldl, s);
6650
                        tmp = gen_ld32(addr, IS_USER(s));
6576 6651
                        if (i == 15) {
6577
                            gen_bx_T0(s);
6652
                            gen_bx(s, tmp);
6578 6653
                        } else {
6579
                            gen_movl_reg_T0(s, i);
6654
                            store_reg(s, i, tmp);
6580 6655
                        }
6581 6656
                    } else {
6582 6657
                        /* Store.  */
6583
                        gen_movl_T0_reg(s, i);
6584
                        gen_ldst(stl, s);
6658
                        tmp = load_reg(s, i);
6659
                        gen_st32(tmp, addr, IS_USER(s));
6585 6660
                    }
6586
                    gen_op_addl_T1_im(4);
6661
                    tcg_gen_addi_i32(addr, addr, 4);
6587 6662
                }
6588 6663
                if (insn & (1 << 21)) {
6589 6664
                    /* Base register writeback.  */
6590 6665
                    if (insn & (1 << 24)) {
6591
                        gen_op_addl_T1_im(-offset);
6666
                        tcg_gen_addi_i32(addr, addr, -offset);
6592 6667
                    }
6593 6668
                    /* Fault if writeback register is in register list.  */
6594 6669
                    if (insn & (1 << rn))
6595 6670
                        goto illegal_op;
6596
                    gen_movl_reg_T1(s, rn);
6671
                    store_reg(s, rn, addr);
6672
                } else {
6673
                    dead_tmp(addr);
6597 6674
                }
6598 6675
            }
6599 6676
        }
......
6892 6969
                offset ^= ((~insn) & (1 << 13)) << 10;
6893 6970
                offset ^= ((~insn) & (1 << 11)) << 11;
6894 6971

  
6895
                addr = s->pc;
6896 6972
                if (insn & (1 << 14)) {
6897 6973
                    /* Branch and link.  */
6898
                    gen_op_movl_T1_im(addr | 1);
6974
                    gen_op_movl_T1_im(s->pc | 1);
6899 6975
                    gen_movl_reg_T1(s, 14);
6900 6976
                }
6901 6977

  
6902
                addr += offset;
6978
                offset += s->pc;
6903 6979
                if (insn & (1 << 12)) {
6904 6980
                    /* b/bl */
6905
                    gen_jmp(s, addr);
6981
                    gen_jmp(s, offset);
6906 6982
                } else {
6907 6983
                    /* blx */
6908
                    addr &= ~(uint32_t)2;
6909
                    gen_bx_im(s, addr);
6984
                    offset &= ~(uint32_t)2;
6985
                    gen_bx_im(s, offset);
6910 6986
                }
6911 6987
            } else if (((insn >> 23) & 7) == 7) {
6912 6988
                /* Misc control */
......
7025 7101
                offset |= (insn & (1 << 11)) << 8;
7026 7102

  
7027 7103
                /* jump to the offset */
7028
                addr = s->pc + offset;
7029
                gen_jmp(s, addr);
7104
                gen_jmp(s, s->pc + offset);
7030 7105
            }
7031 7106
        } else {
7032 7107
            /* Data processing immediate.  */
......
7114 7189
                    } else {
7115 7190
                        /* Add/sub 12-bit immediate.  */
7116 7191
                        if (rn == 15) {
7117
                            addr = s->pc & ~(uint32_t)3;
7192
                            offset = s->pc & ~(uint32_t)3;
7118 7193
                            if (insn & (1 << 23))
7119
                                addr -= imm;
7194
                                offset -= imm;
7120 7195
                            else
7121
                                addr += imm;
7122
                            gen_op_movl_T0_im(addr);
7196
                                offset += imm;
7197
                            gen_op_movl_T0_im(offset);
7123 7198
                        } else {
7124 7199
                            gen_movl_T0_reg(s, rn);
7125 7200
                            gen_op_movl_T1_im(imm);
......
7179 7254
        {
7180 7255
        int postinc = 0;
7181 7256
        int writeback = 0;
7257
        int user;
7182 7258
        if ((insn & 0x01100000) == 0x01000000) {
7183 7259
            if (disas_neon_ls_insn(env, s, insn))
7184 7260
                goto illegal_op;
7185 7261
            break;
7186 7262
        }
7263
        user = IS_USER(s);
7187 7264
        if (rn == 15) {
7265
            addr = new_tmp();
7188 7266
            /* PC relative.  */
7189 7267
            /* s->pc has already been incremented by 4.  */
7190 7268
            imm = s->pc & 0xfffffffc;
......
7192 7270
                imm += insn & 0xfff;
7193 7271
            else
7194 7272
                imm -= insn & 0xfff;
7195
            gen_op_movl_T1_im(imm);
7273
            tcg_gen_movi_i32(addr, imm);
7196 7274
        } else {
7197
            gen_movl_T1_reg(s, rn);
7275
            addr = load_reg(s, rn);
7198 7276
            if (insn & (1 << 23)) {
7199 7277
                /* Positive offset.  */
7200 7278
                imm = insn & 0xfff;
7201
                gen_op_addl_T1_im(imm);
7279
                tcg_gen_addi_i32(addr, addr, imm);
7202 7280
            } else {
7203 7281
                op = (insn >> 8) & 7;
7204 7282
                imm = insn & 0xff;
......
7210 7288
                    tmp = load_reg(s, rm);
7211 7289
                    if (shift)
7212 7290
                        tcg_gen_shli_i32(tmp, tmp, shift);
7213
                    tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
7291
                    tcg_gen_add_i32(addr, addr, tmp);
7214 7292
                    dead_tmp(tmp);
7215 7293
                    break;
7216 7294
                case 4: /* Negative offset.  */
7217
                    gen_op_addl_T1_im(-imm);
7295
                    tcg_gen_addi_i32(addr, addr, -imm);
7218 7296
                    break;
7219 7297
                case 6: /* User privilege.  */
7220
                    gen_op_addl_T1_im(imm);
7298
                    tcg_gen_addi_i32(addr, addr, imm);
7299
                    user = 1;
7221 7300
                    break;
7222 7301
                case 1: /* Post-decrement.  */
7223 7302
                    imm = -imm;
......
7230 7309
                    imm = -imm;
7231 7310
                    /* Fall through.  */
7232 7311
                case 7: /* Pre-increment.  */
7233
                    gen_op_addl_T1_im(imm);
7312
                    tcg_gen_addi_i32(addr, addr, imm);
7234 7313
                    writeback = 1;
7235 7314
                    break;
7236 7315
                default:
......
7247 7326
                /* Memory hint.  Implemented as NOP.  */
7248 7327
            } else {
7249 7328
                switch (op) {
7250
                case 0: gen_ldst(ldub, s); break;
7251
                case 4: gen_ldst(ldsb, s); break;
7252
                case 1: gen_ldst(lduw, s); break;
7253
                case 5: gen_ldst(ldsw, s); break;
7254
                case 2: gen_ldst(ldl, s); break;
7329
                case 0: tmp = gen_ld8u(addr, user); break;
7330
                case 4: tmp = gen_ld8s(addr, user); break;
7331
                case 1: tmp = gen_ld16u(addr, user); break;
7332
                case 5: tmp = gen_ld16s(addr, user); break;
7333
                case 2: tmp = gen_ld32(addr, user); break;
7255 7334
                default: goto illegal_op;
7256 7335
                }
7257 7336
                if (rs == 15) {
7258
                    gen_bx_T0(s);
7337
                    gen_bx(s, tmp);
7259 7338
                } else {
7260
                    gen_movl_reg_T0(s, rs);
7339
                    store_reg(s, rs, tmp);
7261 7340
                }
7262 7341
            }
7263 7342
        } else {
7264 7343
            /* Store.  */
7265 7344
            if (rs == 15)
7266 7345
                goto illegal_op;
7267
            gen_movl_T0_reg(s, rs);
7346
            tmp = load_reg(s, rs);
7268 7347
            switch (op) {
7269
            case 0: gen_ldst(stb, s); break;
7270
            case 1: gen_ldst(stw, s); break;
7271
            case 2: gen_ldst(stl, s); break;
7348
            case 0: gen_st8(tmp, addr, user); break;
7349
            case 1: gen_st16(tmp, addr, user); break;
7350
            case 2: gen_st32(tmp, addr, user); break;
7272 7351
            default: goto illegal_op;
7273 7352
            }
7274 7353
        }
7275 7354
        if (postinc)
7276
            gen_op_addl_T1_im(imm);
7277
        if (writeback)
7278
            gen_movl_reg_T1(s, rn);
7355
            tcg_gen_addi_i32(addr, addr, imm);
7356
        if (writeback) {
7357
            store_reg(s, rn, addr);
7358
        } else {
7359
            dead_tmp(addr);
7360
        }
7279 7361
        }
7280 7362
        break;
7281 7363
    default:
......
7293 7375
    int i;
7294 7376
    TCGv tmp;
7295 7377
    TCGv tmp2;
7378
    TCGv addr;
7296 7379

  
7297 7380
    if (s->condexec_mask) {
7298 7381
        cond = s->condexec_cond;
......
7383 7466
            /* load pc-relative.  Bit 1 of PC is ignored.  */
7384 7467
            val = s->pc + 2 + ((insn & 0xff) * 4);
7385 7468
            val &= ~(uint32_t)2;
7386
            gen_op_movl_T1_im(val);
7387
            gen_ldst(ldl, s);
7388
            gen_movl_reg_T0(s, rd);
7469
            addr = new_tmp();
7470
            tcg_gen_movi_i32(addr, val);
7471
            tmp = gen_ld32(addr, IS_USER(s));
7472
            dead_tmp(addr);
7473
            store_reg(s, rd, tmp);
7389 7474
            break;
7390 7475
        }
7391 7476
        if (insn & (1 << 10)) {
......
7410 7495
                gen_movl_reg_T0(s, rd);
7411 7496
                break;
7412 7497
            case 3:/* branch [and link] exchange thumb register */
7498
                tmp = load_reg(s, rm);
7413 7499
                if (insn & (1 << 7)) {
7414 7500
                    val = (uint32_t)s->pc | 1;
7415
                    gen_op_movl_T1_im(val);
7416
                    gen_movl_reg_T1(s, 14);
7501
                    tmp2 = new_tmp();
7502
                    tcg_gen_movi_i32(tmp2, val);
7503
                    store_reg(s, 14, tmp2);
7417 7504
                }
7418
                tmp = load_reg(s, rm);
7419 7505
                gen_bx(s, tmp);
7420 7506
                break;
7421 7507
            }
......
7553 7639
        rn = (insn >> 3) & 7;
7554 7640
        rm = (insn >> 6) & 7;
7555 7641
        op = (insn >> 9) & 7;
7556
        gen_movl_T1_reg(s, rn);
7642
        addr = load_reg(s, rn);
7557 7643
        tmp = load_reg(s, rm);
7558
        tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
7644
        tcg_gen_add_i32(addr, addr, tmp);
7559 7645
        dead_tmp(tmp);
7560 7646

  
7561 7647
        if (op < 3) /* store */
7562
            gen_movl_T0_reg(s, rd);
7648
            tmp = load_reg(s, rd);
7563 7649

  
7564 7650
        switch (op) {
7565 7651
        case 0: /* str */
7566
            gen_ldst(stl, s);
7652
            gen_st32(tmp, addr, IS_USER(s));
7567 7653
            break;
7568 7654
        case 1: /* strh */
7569
            gen_ldst(stw, s);
7655
            gen_st16(tmp, addr, IS_USER(s));
7570 7656
            break;
7571 7657
        case 2: /* strb */
7572
            gen_ldst(stb, s);
7658
            gen_st8(tmp, addr, IS_USER(s));
7573 7659
            break;
7574 7660
        case 3: /* ldrsb */
7575
            gen_ldst(ldsb, s);
7661
            tmp = gen_ld8s(addr, IS_USER(s));
7576 7662
            break;
7577 7663
        case 4: /* ldr */
7578
            gen_ldst(ldl, s);
7664
            tmp = gen_ld32(addr, IS_USER(s));
7579 7665
            break;
7580 7666
        case 5: /* ldrh */
7581
            gen_ldst(lduw, s);
7667
            tmp = gen_ld16u(addr, IS_USER(s));
7582 7668
            break;
7583 7669
        case 6: /* ldrb */
7584
            gen_ldst(ldub, s);
7670
            tmp = gen_ld8u(addr, IS_USER(s));
7585 7671
            break;
7586 7672
        case 7: /* ldrsh */
7587
            gen_ldst(ldsw, s);
7673
            tmp = gen_ld16s(addr, IS_USER(s));
7588 7674
            break;
7589 7675
        }
7590 7676
        if (op >= 3) /* load */
7591
            gen_movl_reg_T0(s, rd);
7677
            store_reg(s, rd, tmp);
7678
        dead_tmp(addr);
7592 7679
        break;
7593 7680

  
7594 7681
    case 6:
7595 7682
        /* load/store word immediate offset */
7596 7683
        rd = insn & 7;
7597 7684
        rn = (insn >> 3) & 7;
7598
        gen_movl_T1_reg(s, rn);
7685
        addr = load_reg(s, rn);
7599 7686
        val = (insn >> 4) & 0x7c;
7600
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val);
7687
        tcg_gen_addi_i32(addr, addr, val);
7601 7688

  
7602 7689
        if (insn & (1 << 11)) {
7603 7690
            /* load */
7604
            gen_ldst(ldl, s);
7605
            gen_movl_reg_T0(s, rd);
7691
            tmp = gen_ld32(addr, IS_USER(s));
7692
            store_reg(s, rd, tmp);
7606 7693
        } else {
7607 7694
            /* store */
7608
            gen_movl_T0_reg(s, rd);
7609
            gen_ldst(stl, s);
7695
            tmp = load_reg(s, rd);
7696
            gen_st32(tmp, addr, IS_USER(s));
7610 7697
        }
7698
        dead_tmp(addr);
7611 7699
        break;
7612 7700

  
7613 7701
    case 7:
7614 7702
        /* load/store byte immediate offset */
7615 7703
        rd = insn & 7;
7616 7704
        rn = (insn >> 3) & 7;
7617
        gen_movl_T1_reg(s, rn);
7705
        addr = load_reg(s, rn);
7618 7706
        val = (insn >> 6) & 0x1f;
7619
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val);
7707
        tcg_gen_addi_i32(addr, addr, val);
7620 7708

  
7621 7709
        if (insn & (1 << 11)) {
7622 7710
            /* load */
7623
            gen_ldst(ldub, s);
7624
            gen_movl_reg_T0(s, rd);
7711
            tmp = gen_ld8u(addr, IS_USER(s));
7712
            store_reg(s, rd, tmp);
7625 7713
        } else {
7626 7714
            /* store */
7627
            gen_movl_T0_reg(s, rd);
7628
            gen_ldst(stb, s);
7715
            tmp = load_reg(s, rd);
7716
            gen_st8(tmp, addr, IS_USER(s));
7629 7717
        }
7718
        dead_tmp(addr);
7630 7719
        break;
7631 7720

  
7632 7721
    case 8:
7633 7722
        /* load/store halfword immediate offset */
7634 7723
        rd = insn & 7;
7635 7724
        rn = (insn >> 3) & 7;
7636
        gen_movl_T1_reg(s, rn);
7725
        addr = load_reg(s, rn);
7637 7726
        val = (insn >> 5) & 0x3e;
7638
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val);
7727
        tcg_gen_addi_i32(addr, addr, val);
7639 7728

  
7640 7729
        if (insn & (1 << 11)) {
7641 7730
            /* load */
7642
            gen_ldst(lduw, s);
7643
            gen_movl_reg_T0(s, rd);
7731
            tmp = gen_ld16u(addr, IS_USER(s));
7732
            store_reg(s, rd, tmp);
7644 7733
        } else {
7645 7734
            /* store */
7646
            gen_movl_T0_reg(s, rd);
7647
            gen_ldst(stw, s);
7735
            tmp = load_reg(s, rd);
7736
            gen_st16(tmp, addr, IS_USER(s));
7648 7737
        }
7738
        dead_tmp(addr);
7649 7739
        break;
7650 7740

  
7651 7741
    case 9:
7652 7742
        /* load/store from stack */
7653 7743
        rd = (insn >> 8) & 7;
7654
        gen_movl_T1_reg(s, 13);
7744
        addr = load_reg(s, 13);
7655 7745
        val = (insn & 0xff) * 4;
7656
        tcg_gen_addi_i32(cpu_T[1], cpu_T[1], val);
7746
        tcg_gen_addi_i32(addr, addr, val);
7657 7747

  
7658 7748
        if (insn & (1 << 11)) {
7659 7749
            /* load */
7660
            gen_ldst(ldl, s);
7661
            gen_movl_reg_T0(s, rd);
7750
            tmp = gen_ld32(addr, IS_USER(s));
7751
            store_reg(s, rd, tmp);
7662 7752
        } else {
7663 7753
            /* store */
7664
            gen_movl_T0_reg(s, rd);
7665
            gen_ldst(stl, s);
7754
            tmp = load_reg(s, rd);
7755
            gen_st32(tmp, addr, IS_USER(s));
7666 7756
        }
7757
        dead_tmp(addr);
7667 7758
        break;
7668 7759

  
7669 7760
    case 10:
......
7700 7791
            ARCH(6);
7701 7792
            rd = insn & 7;
7702 7793
            rm = (insn >> 3) & 7;
7703
            gen_movl_T1_reg(s, rm);
7794
            tmp = load_reg(s, rm);
7704 7795
            switch ((insn >> 6) & 3) {
7705
            case 0: gen_sxth(cpu_T[1]); break;
7706
            case 1: gen_sxtb(cpu_T[1]); break;
7707
            case 2: gen_uxth(cpu_T[1]); break;
7708
            case 3: gen_uxtb(cpu_T[1]); break;
7796
            case 0: gen_sxth(tmp); break;
7797
            case 1: gen_sxtb(tmp); break;
7798
            case 2: gen_uxth(tmp); break;
7799
            case 3: gen_uxtb(tmp); break;
7709 7800
            }
7710
            gen_movl_reg_T1(s, rd);
7801
            store_reg(s, rd, tmp);
7711 7802
            break;
7712 7803
        case 4: case 5: case 0xc: case 0xd:
7713 7804
            /* push/pop */
7714
            gen_movl_T1_reg(s, 13);
7805
            addr = load_reg(s, 13);
7715 7806
            if (insn & (1 << 8))
7716 7807
                offset = 4;
7717 7808
            else
......
7721 7812
                    offset += 4;
7722 7813
            }
7723 7814
            if ((insn & (1 << 11)) == 0) {
7724
                gen_op_addl_T1_im(-offset);
7815
                tcg_gen_addi_i32(addr, addr, -offset);
7725 7816
            }
7726 7817
            for (i = 0; i < 8; i++) {
7727 7818
                if (insn & (1 << i)) {
7728 7819
                    if (insn & (1 << 11)) {
7729 7820
                        /* pop */
7730
                        gen_ldst(ldl, s);
7731
                        gen_movl_reg_T0(s, i);
7821
                        tmp = gen_ld32(addr, IS_USER(s));
7822
                        store_reg(s, i, tmp);
7732 7823
                    } else {
7733 7824
                        /* push */
7734
                        gen_movl_T0_reg(s, i);
7735
                        gen_ldst(stl, s);
7825
                        tmp = load_reg(s, i);
7826
                        gen_st32(tmp, addr, IS_USER(s));
7736 7827
                    }
7737 7828
                    /* advance to the next address.  */
7738
                    gen_op_addl_T1_im(4);
7829
                    tcg_gen_addi_i32(addr, addr, 4);
7739 7830
                }
7740 7831
            }
7741 7832
            if (insn & (1 << 8)) {
7742 7833
                if (insn & (1 << 11)) {
7743 7834
                    /* pop pc */
7744
                    gen_ldst(ldl, s);
7835
                    tmp = gen_ld32(addr, IS_USER(s));
7745 7836
                    /* don't set the pc until the rest of the instruction
7746 7837
                       has completed */
7747 7838
                } else {
7748 7839
                    /* push lr */
7749
                    gen_movl_T0_reg(s, 14);
7750
                    gen_ldst(stl, s);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff