Revision 5e3f878a target-arm/translate.c

b/target-arm/translate.c
226 226

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

  
229
#define gen_op_addl_T0_T1_setq() \
230
    gen_helper_add_setq(cpu_T[0], cpu_T[0], cpu_T[1])
231
#define gen_op_addl_T0_T1_saturate() \
232
    gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
233
#define gen_op_subl_T0_T1_saturate() \
234
    gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1])
235
#define gen_op_addl_T0_T1_usaturate() \
236
    gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
237
#define gen_op_subl_T0_T1_usaturate() \
238
    gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1])
239

  
240
/* Copy the most significant bit of T0 to all bits of T1.  */
241
#define gen_op_signbit_T1_T0() tcg_gen_sari_i32(cpu_T[1], cpu_T[0], 31)
242

  
243 229
#define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
244 230
/* Set NZCV flags from the high 4 bits of var.  */
245 231
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
......
332 318

  
333 319
/* FIXME: Most targets have native widening multiplication.
334 320
   It would be good to use that instead of a full wide multiply.  */
321
/* 32x32->64 multiply.  Marks inputs as dead.  */
322
static TCGv gen_mulu_i64_i32(TCGv a, TCGv b)
323
{
324
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
325
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
326

  
327
    tcg_gen_extu_i32_i64(tmp1, a);
328
    dead_tmp(a);
329
    tcg_gen_extu_i32_i64(tmp2, b);
330
    dead_tmp(b);
331
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
332
    return tmp1;
333
}
334

  
335
static TCGv gen_muls_i64_i32(TCGv a, TCGv b)
336
{
337
    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
338
    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
339

  
340
    tcg_gen_ext_i32_i64(tmp1, a);
341
    dead_tmp(a);
342
    tcg_gen_ext_i32_i64(tmp2, b);
343
    dead_tmp(b);
344
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
345
    return tmp1;
346
}
347

  
335 348
/* Unsigned 32x32->64 multiply.  */
336 349
static void gen_op_mull_T0_T1(void)
337 350
{
......
361 374
}
362 375
#define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
363 376

  
364
/* Signed 32x16 multiply, top 32 bits.  */
365
static void gen_imulw(TCGv a, TCGv b)
366
{
367
  gen_imull(a, b);
368
  tcg_gen_shri_i32(a, a, 16);
369
  tcg_gen_shli_i32(b, b, 16);
370
  tcg_gen_or_i32(a, a, b);
371
}
372

  
373 377
/* Swap low and high halfwords.  */
374 378
static void gen_swap_half(TCGv var)
375 379
{
......
865 869
    load_reg_var(s, cpu_T[2], reg);
866 870
}
867 871

  
872
static inline void gen_set_pc_im(uint32_t val)
873
{
874
    TCGv tmp = new_tmp();
875
    tcg_gen_movi_i32(tmp, val);
876
    store_cpu_field(tmp, regs[15]);
877
}
878

  
868 879
static inline void gen_set_pc_T0(void)
869 880
{
870 881
    tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15]));
......
3818 3829
            case 1: gen_op_neon_qadd_u8(); break;
3819 3830
            case 2: gen_op_neon_qadd_s16(); break;
3820 3831
            case 3: gen_op_neon_qadd_u16(); break;
3821
            case 4: gen_op_addl_T0_T1_saturate(); break;
3822
            case 5: gen_op_addl_T0_T1_usaturate(); break;
3832
            case 4:
3833
                gen_helper_add_saturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3834
                break;
3835
            case 5:
3836
                gen_helper_add_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3837
                break;
3823 3838
            default: abort();
3824 3839
            }
3825 3840
            break;
......
3867 3882
            case 1: gen_op_neon_qsub_u8(); break;
3868 3883
            case 2: gen_op_neon_qsub_s16(); break;
3869 3884
            case 3: gen_op_neon_qsub_u16(); break;
3870
            case 4: gen_op_subl_T0_T1_saturate(); break;
3871
            case 5: gen_op_subl_T0_T1_usaturate(); break;
3885
            case 4:
3886
                gen_helper_sub_saturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3887
                break;
3888
            case 5:
3889
                gen_helper_sub_usaturate(cpu_T[0], cpu_T[0], cpu_T[1]);
3890
                break;
3872 3891
            default: abort();
3873 3892
            }
3874 3893
            break;
......
5291 5310
    }
5292 5311
}
5293 5312

  
5313

  
5314
/* Store a 64-bit value to a register pair.  Clobbers val.  */
5315
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv val)
5316
{
5317
    TCGv tmp;
5318
    tmp = new_tmp();
5319
    tcg_gen_trunc_i64_i32(tmp, val);
5320
    store_reg(s, rlow, tmp);
5321
    tmp = new_tmp();
5322
    tcg_gen_shri_i64(val, val, 32);
5323
    tcg_gen_trunc_i64_i32(tmp, val);
5324
    store_reg(s, rhigh, tmp);
5325
}
5326

  
5327
/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
5328
static void gen_addq_lo(DisasContext *s, TCGv val, int rlow)
5329
{
5330
    TCGv tmp;
5331
    TCGv tmp2;
5332

  
5333
    /* Load 64-bit value rd:rn.  */
5334
    tmp = tcg_temp_new(TCG_TYPE_I64);
5335
    tmp2 = load_reg(s, rlow);
5336
    tcg_gen_extu_i32_i64(tmp, tmp2);
5337
    dead_tmp(tmp2);
5338
    tcg_gen_add_i64(val, val, tmp);
5339
}
5340

  
5341
/* load and add a 64-bit value from a register pair.  */
5342
static void gen_addq(DisasContext *s, TCGv val, int rlow, int rhigh)
5343
{
5344
    TCGv tmp;
5345
    TCGv tmp2;
5346

  
5347
    /* Load 64-bit value rd:rn.  */
5348
    tmp = tcg_temp_new(TCG_TYPE_I64);
5349
    tmp2 = load_reg(s, rhigh);
5350
    tcg_gen_extu_i32_i64(tmp, tmp2);
5351
    dead_tmp(tmp2);
5352
    tcg_gen_shli_i64(tmp, tmp, 32);
5353
    tcg_gen_add_i64(val, val, tmp);
5354

  
5355
    tmp2 = load_reg(s, rlow);
5356
    tcg_gen_extu_i32_i64(tmp, tmp2);
5357
    dead_tmp(tmp2);
5358
    tcg_gen_add_i64(val, val, tmp);
5359
}
5360

  
5361
/* Set N and Z flags from a 64-bit value.  */
5362
static void gen_logicq_cc(TCGv val)
5363
{
5364
    TCGv tmp = new_tmp();
5365
    gen_helper_logicq_cc(tmp, val);
5366
    store_cpu_field(tmp, NZF);
5367
}
5368

  
5294 5369
static void disas_arm_insn(CPUState * env, DisasContext *s)
5295 5370
{
5296 5371
    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
......
5507 5582
            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
5508 5583
            if ((insn & (1 << 22)) == 0) {
5509 5584
                /* MOVW */
5510
                gen_op_movl_T0_im(val);
5585
                tmp = new_tmp();
5586
                tcg_gen_movi_i32(tmp, val);
5511 5587
            } else {
5512 5588
                /* MOVT */
5513
                gen_movl_T0_reg(s, rd);
5514
                gen_op_movl_T1_im(0xffff);
5515
                gen_op_andl_T0_T1();
5516
                gen_op_movl_T1_im(val << 16);
5517
                gen_op_orl_T0_T1();
5589
                tmp = load_reg(s, rd);
5590
                tcg_gen_andi_i32(tmp, tmp, 0xffff);
5591
                tcg_gen_ori_i32(tmp, tmp, val << 16);
5518 5592
            }
5519
            gen_movl_reg_T0(s, rd);
5593
            store_reg(s, rd, tmp);
5520 5594
        } else {
5521 5595
            if (((insn >> 12) & 0xf) != 0xf)
5522 5596
                goto illegal_op;
......
5601 5675
        case 0x5: /* saturating add/subtract */
5602 5676
            rd = (insn >> 12) & 0xf;
5603 5677
            rn = (insn >> 16) & 0xf;
5604
            gen_movl_T0_reg(s, rm);
5605
            gen_movl_T1_reg(s, rn);
5678
            tmp = load_reg(s, rn);
5679
            tmp2 = load_reg(s, rn);
5606 5680
            if (op1 & 2)
5607
                gen_helper_double_saturate(cpu_T[1], cpu_T[1]);
5681
                gen_helper_double_saturate(tmp2, tmp2);
5608 5682
            if (op1 & 1)
5609
                gen_op_subl_T0_T1_saturate();
5683
                gen_helper_sub_saturate(tmp, tmp, tmp2);
5610 5684
            else
5611
                gen_op_addl_T0_T1_saturate();
5612
            gen_movl_reg_T0(s, rd);
5685
                gen_helper_add_saturate(tmp, tmp, tmp2);
5686
            dead_tmp(tmp2);
5687
            store_reg(s, rd, tmp);
5613 5688
            break;
5614 5689
        case 7: /* bkpt */
5615 5690
            gen_set_condexec(s);
5616
            gen_op_movl_T0_im((long)s->pc - 4);
5617
            gen_set_pc_T0();
5691
            gen_set_pc_im(s->pc - 4);
5618 5692
            gen_exception(EXCP_BKPT);
5619 5693
            s->is_jmp = DISAS_JUMP;
5620 5694
            break;
......
5627 5701
            rd = (insn >> 16) & 0xf;
5628 5702
            if (op1 == 1) {
5629 5703
                /* (32 * 16) >> 16 */
5630
                gen_movl_T0_reg(s, rm);
5631
                gen_movl_T1_reg(s, rs);
5704
                tmp = load_reg(s, rm);
5705
                tmp2 = load_reg(s, rs);
5632 5706
                if (sh & 4)
5633
                    gen_op_sarl_T1_im(16);
5707
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
5634 5708
                else
5635
                    gen_sxth(cpu_T[1]);
5636
                gen_imulw(cpu_T[0], cpu_T[1]);
5709
                    gen_sxth(tmp2);
5710
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
5711
                tcg_gen_shri_i64(tmp2, tmp2, 16);
5712
                tmp = new_tmp();
5713
                tcg_gen_trunc_i64_i32(tmp, tmp2);
5637 5714
                if ((sh & 2) == 0) {
5638
                    gen_movl_T1_reg(s, rn);
5639
                    gen_op_addl_T0_T1_setq();
5715
                    tmp2 = load_reg(s, rn);
5716
                    gen_helper_add_setq(tmp, tmp, tmp2);
5717
                    dead_tmp(tmp2);
5640 5718
                }
5641
                gen_movl_reg_T0(s, rd);
5719
                store_reg(s, rd, tmp);
5642 5720
            } else {
5643 5721
                /* 16 * 16 */
5644
                gen_movl_T0_reg(s, rm);
5645
                gen_movl_T1_reg(s, rs);
5646
                gen_mulxy(cpu_T[0], cpu_T[1], sh & 2, sh & 4);
5722
                tmp = load_reg(s, rm);
5723
                tmp2 = load_reg(s, rs);
5724
                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
5725
                dead_tmp(tmp2);
5647 5726
                if (op1 == 2) {
5648
                    gen_op_signbit_T1_T0();
5649
                    gen_op_addq_T0_T1(rn, rd);
5650
                    gen_movl_reg_T0(s, rn);
5651
                    gen_movl_reg_T1(s, rd);
5727
                    tmp = tcg_temp_new(TCG_TYPE_I64);
5728
                    tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
5729
                    gen_addq(s, tmp, rn, rd);
5730
                    gen_storeq_reg(s, rn, rd, tmp);
5652 5731
                } else {
5653 5732
                    if (op1 == 0) {
5654
                        gen_movl_T1_reg(s, rn);
5655
                        gen_op_addl_T0_T1_setq();
5733
                        tmp2 = load_reg(s, rn);
5734
                        gen_helper_add_setq(tmp, tmp, tmp2);
5735
                        dead_tmp(tmp2);
5656 5736
                    }
5657
                    gen_movl_reg_T0(s, rd);
5737
                    store_reg(s, rd, tmp);
5658 5738
                }
5659 5739
            }
5660 5740
            break;
......
5839 5919
                    switch (op1) {
5840 5920
                    case 0: case 1: case 2: case 3: case 6:
5841 5921
                        /* 32 bit mul */
5842
                        gen_movl_T0_reg(s, rs);
5843
                        gen_movl_T1_reg(s, rm);
5844
                        gen_op_mul_T0_T1();
5922
                        tmp = load_reg(s, rs);
5923
                        tmp2 = load_reg(s, rm);
5924
                        tcg_gen_mul_i32(tmp, tmp, tmp2);
5925
                        dead_tmp(tmp2);
5845 5926
                        if (insn & (1 << 22)) {
5846 5927
                            /* Subtract (mls) */
5847 5928
                            ARCH(6T2);
5848
                            gen_movl_T1_reg(s, rn);
5849
                            gen_op_rsbl_T0_T1();
5929
                            tmp2 = load_reg(s, rn);
5930
                            tcg_gen_sub_i32(tmp, tmp2, tmp);
5931
                            dead_tmp(tmp2);
5850 5932
                        } else if (insn & (1 << 21)) {
5851 5933
                            /* Add */
5852
                            gen_movl_T1_reg(s, rn);
5853
                            gen_op_addl_T0_T1();
5934
                            tmp2 = load_reg(s, rn);
5935
                            tcg_gen_add_i32(tmp, tmp, tmp2);
5936
                            dead_tmp(tmp2);
5854 5937
                        }
5855 5938
                        if (insn & (1 << 20))
5856
                            gen_op_logic_T0_cc();
5857
                        gen_movl_reg_T0(s, rd);
5939
                            gen_logic_CC(tmp);
5940
                        store_reg(s, rd, tmp);
5858 5941
                        break;
5859 5942
                    default:
5860 5943
                        /* 64 bit mul */
5861
                        gen_movl_T0_reg(s, rs);
5862
                        gen_movl_T1_reg(s, rm);
5944
                        tmp = load_reg(s, rs);
5945
                        tmp2 = load_reg(s, rm);
5863 5946
                        if (insn & (1 << 22))
5864
                            gen_op_imull_T0_T1();
5947
                            tmp = gen_muls_i64_i32(tmp, tmp2);
5865 5948
                        else
5866
                            gen_op_mull_T0_T1();
5949
                            tmp = gen_mulu_i64_i32(tmp, tmp2);
5867 5950
                        if (insn & (1 << 21)) /* mult accumulate */
5868
                            gen_op_addq_T0_T1(rn, rd);
5951
                            gen_addq(s, tmp, rn, rd);
5869 5952
                        if (!(insn & (1 << 23))) { /* double accumulate */
5870 5953
                            ARCH(6);
5871
                            gen_op_addq_lo_T0_T1(rn);
5872
                            gen_op_addq_lo_T0_T1(rd);
5954
                            gen_addq_lo(s, tmp, rn);
5955
                            gen_addq_lo(s, tmp, rd);
5873 5956
                        }
5874 5957
                        if (insn & (1 << 20))
5875
                            gen_op_logicq_cc();
5876
                        gen_movl_reg_T0(s, rn);
5877
                        gen_movl_reg_T1(s, rd);
5958
                            gen_logicq_cc(tmp);
5959
                        gen_storeq_reg(s, rn, rd, tmp);
5878 5960
                        break;
5879 5961
                    }
5880 5962
                } else {
......
6060 6142
                        dead_tmp(tmp2);
6061 6143
                        store_reg(s, rd, tmp);
6062 6144
                    } else if ((insn & 0x000003e0) == 0x00000060) {
6063
                        gen_movl_T1_reg(s, rm);
6145
                        tmp = load_reg(s, rm);
6064 6146
                        shift = (insn >> 10) & 3;
6065 6147
                        /* ??? In many cases it's not neccessary to do a
6066 6148
                           rotate, a shift is sufficient.  */
6067 6149
                        if (shift != 0)
6068
                            gen_op_rorl_T1_im(shift * 8);
6150
                            tcg_gen_rori_i32(tmp, tmp, shift * 8);
6069 6151
                        op1 = (insn >> 20) & 7;
6070 6152
                        switch (op1) {
6071
                        case 0: gen_sxtb16(cpu_T[1]); break;
6072
                        case 2: gen_sxtb(cpu_T[1]);   break;
6073
                        case 3: gen_sxth(cpu_T[1]);   break;
6074
                        case 4: gen_uxtb16(cpu_T[1]); break;
6075
                        case 6: gen_uxtb(cpu_T[1]);   break;
6076
                        case 7: gen_uxth(cpu_T[1]);   break;
6153
                        case 0: gen_sxtb16(tmp);  break;
6154
                        case 2: gen_sxtb(tmp);    break;
6155
                        case 3: gen_sxth(tmp);    break;
6156
                        case 4: gen_uxtb16(tmp);  break;
6157
                        case 6: gen_uxtb(tmp);    break;
6158
                        case 7: gen_uxth(tmp);    break;
6077 6159
                        default: goto illegal_op;
6078 6160
                        }
6079 6161
                        if (rn != 15) {
6080
                            tmp = load_reg(s, rn);
6162
                            tmp2 = load_reg(s, rn);
6081 6163
                            if ((op1 & 3) == 0) {
6082
                                gen_add16(cpu_T[1], tmp);
6164
                                gen_add16(tmp, tmp2);
6083 6165
                            } else {
6084
                                tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
6085
                                dead_tmp(tmp);
6166
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6167
                                dead_tmp(tmp2);
6086 6168
                            }
6087 6169
                        }
6088
                        gen_movl_reg_T1(s, rd);
6170
                        store_reg(s, rd, tmp2);
6089 6171
                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
6090 6172
                        /* rev */
6091 6173
                        tmp = load_reg(s, rm);
......
6108 6190
                    }
6109 6191
                    break;
6110 6192
                case 2: /* Multiplies (Type 3).  */
6111
                    gen_movl_T0_reg(s, rm);
6112
                    gen_movl_T1_reg(s, rs);
6193
                    tmp = load_reg(s, rm);
6194
                    tmp2 = load_reg(s, rs);
6113 6195
                    if (insn & (1 << 20)) {
6114 6196
                        /* Signed multiply most significant [accumulate].  */
6115
                        gen_op_imull_T0_T1();
6197
                        tmp2 = gen_muls_i64_i32(tmp, tmp2);
6116 6198
                        if (insn & (1 << 5))
6117
                            gen_roundqd(cpu_T[0], cpu_T[1]);
6118
                        else
6119
                            gen_op_movl_T0_T1();
6199
                            tcg_gen_addi_i64(tmp2, tmp2, 0x80000000u);
6200
                        tcg_gen_shri_i64(tmp2, tmp2, 32);
6201
                        tmp = new_tmp();
6202
                        tcg_gen_trunc_i64_i32(tmp, tmp2);
6120 6203
                        if (rn != 15) {
6121
                            gen_movl_T1_reg(s, rn);
6204
                            tmp2 = load_reg(s, rn);
6122 6205
                            if (insn & (1 << 6)) {
6123
                                gen_op_addl_T0_T1();
6206
                                tcg_gen_sub_i32(tmp, tmp, tmp2);
6124 6207
                            } else {
6125
                                gen_op_rsbl_T0_T1();
6208
                                tcg_gen_add_i32(tmp, tmp, tmp2);
6126 6209
                            }
6210
                            dead_tmp(tmp2);
6127 6211
                        }
6128
                        gen_movl_reg_T0(s, rd);
6212
                        store_reg(s, rd, tmp);
6129 6213
                    } else {
6130 6214
                        if (insn & (1 << 5))
6131
                            gen_swap_half(cpu_T[1]);
6132
                        gen_smul_dual(cpu_T[0], cpu_T[1]);
6215
                            gen_swap_half(tmp2);
6216
                        gen_smul_dual(tmp, tmp2);
6217
                        /* This addition cannot overflow.  */
6218
                        if (insn & (1 << 6)) {
6219
                            tcg_gen_sub_i32(tmp, tmp, tmp2);
6220
                        } else {
6221
                            tcg_gen_add_i32(tmp, tmp, tmp2);
6222
                        }
6223
                        dead_tmp(tmp2);
6133 6224
                        if (insn & (1 << 22)) {
6134
                            if (insn & (1 << 6)) {
6135
                                /* smlald */
6136
                                gen_op_addq_T0_T1_dual(rn, rd);
6137
                            } else {
6138
                                /* smlsld */
6139
                                gen_op_subq_T0_T1_dual(rn, rd);
6140
                            }
6225
                            /* smlald, smlsld */
6226
                            tmp2 = tcg_temp_new(TCG_TYPE_I64);
6227
                            tcg_gen_ext_i32_i64(tmp2, tmp);
6228
                            dead_tmp(tmp);
6229
                            gen_addq(s, tmp2, rn, rd);
6230
                            gen_storeq_reg(s, rn, rd, tmp2);
6141 6231
                        } else {
6142
                            /* This addition cannot overflow.  */
6143
                            if (insn & (1 << 6)) {
6144
                                /* sm[ul]sd */
6145
                                gen_op_subl_T0_T1();
6146
                            } else {
6147
                                /* sm[ul]ad */
6148
                                gen_op_addl_T0_T1();
6149
                            }
6232
                            /* smuad, smusd, smlad, smlsd */
6150 6233
                            if (rn != 15)
6151 6234
                              {
6152
                                gen_movl_T1_reg(s, rn);
6153
                                gen_op_addl_T0_T1_setq();
6235
                                tmp2 = load_reg(s, rn);
6236
                                gen_helper_add_setq(tmp, tmp, tmp2);
6237
                                dead_tmp(tmp2);
6154 6238
                              }
6155
                            gen_movl_reg_T0(s, rd);
6239
                            store_reg(s, rd, tmp);
6156 6240
                        }
6157 6241
                    }
6158 6242
                    break;
......
6179 6263
                        i = (insn >> 16) & 0x1f;
6180 6264
                        i = i + 1 - shift;
6181 6265
                        if (rm == 15) {
6182
                            gen_op_movl_T1_im(0);
6266
                            tmp = new_tmp();
6267
                            tcg_gen_movi_i32(tmp, 0);
6183 6268
                        } else {
6184
                            gen_movl_T1_reg(s, rm);
6269
                            tmp = load_reg(s, rm);
6185 6270
                        }
6186 6271
                        if (i != 32) {
6187
                            gen_movl_T0_reg(s, rd);
6188
                            gen_bfi(cpu_T[1], cpu_T[0], cpu_T[1],
6272
                            tmp2 = load_reg(s, rd);
6273
                            gen_bfi(tmp, tmp2, tmp,
6189 6274
                                    shift, ((1u << i) - 1) << shift);
6275
                            dead_tmp(tmp2);
6190 6276
                        }
6191
                        gen_movl_reg_T1(s, rd);
6277
                        store_reg(s, rd, tmp);
6192 6278
                        break;
6193 6279
                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
6194 6280
                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
6195
                        gen_movl_T1_reg(s, rm);
6281
                        tmp = load_reg(s, rm);
6196 6282
                        shift = (insn >> 7) & 0x1f;
6197 6283
                        i = ((insn >> 16) & 0x1f) + 1;
6198 6284
                        if (shift + i > 32)
6199 6285
                            goto illegal_op;
6200 6286
                        if (i < 32) {
6201 6287
                            if (op1 & 0x20) {
6202
                                gen_ubfx(cpu_T[1], shift, (1u << i) - 1);
6288
                                gen_ubfx(tmp, shift, (1u << i) - 1);
6203 6289
                            } else {
6204
                                gen_sbfx(cpu_T[1], shift, i);
6290
                                gen_sbfx(tmp, shift, i);
6205 6291
                            }
6206 6292
                        }
6207
                        gen_movl_reg_T1(s, rd);
6293
                        store_reg(s, rd, tmp);
6208 6294
                        break;
6209 6295
                    default:
6210 6296
                        goto illegal_op;
......
6386 6472
                /* branch (and link) */
6387 6473
                val = (int32_t)s->pc;
6388 6474
                if (insn & (1 << 24)) {
6389
                    gen_op_movl_T0_im(val);
6390
                    gen_movl_reg_T0(s, 14);
6475
                    tmp = new_tmp();
6476
                    tcg_gen_movi_i32(tmp, val);
6477
                    store_reg(s, 14, tmp);
6391 6478
                }
6392 6479
                offset = (((int32_t)insn << 8) >> 8);
6393 6480
                val += (offset << 2) + 4;
......
6403 6490
            break;
6404 6491
        case 0xf:
6405 6492
            /* swi */
6406
            gen_op_movl_T0_im((long)s->pc);
6407
            gen_set_pc_T0();
6493
            gen_set_pc_im(s->pc);
6408 6494
            s->is_jmp = DISAS_SWI;
6409 6495
            break;
6410 6496
        default:
6411 6497
        illegal_op:
6412 6498
            gen_set_condexec(s);
6413
            gen_op_movl_T0_im((long)s->pc - 4);
6414
            gen_set_pc_T0();
6499
            gen_set_pc_im(s->pc - 4);
6415 6500
            gen_exception(EXCP_UDEF);
6416 6501
            s->is_jmp = DISAS_JUMP;
6417 6502
            break;
......
6832 6917
            gen_movl_reg_T1(s, rd);
6833 6918
            break;
6834 6919
        case 1: /* Sign/zero extend.  */
6835
            gen_movl_T1_reg(s, rm);
6920
            tmp = load_reg(s, rm);
6836 6921
            shift = (insn >> 4) & 3;
6837 6922
            /* ??? In many cases it's not neccessary to do a
6838 6923
               rotate, a shift is sufficient.  */
6839 6924
            if (shift != 0)
6840
                gen_op_rorl_T1_im(shift * 8);
6925
                tcg_gen_rori_i32(tmp, tmp, shift * 8);
6841 6926
            op = (insn >> 20) & 7;
6842 6927
            switch (op) {
6843
            case 0: gen_sxth(cpu_T[1]);   break;
6844
            case 1: gen_uxth(cpu_T[1]);   break;
6845
            case 2: gen_sxtb16(cpu_T[1]); break;
6846
            case 3: gen_uxtb16(cpu_T[1]); break;
6847
            case 4: gen_sxtb(cpu_T[1]);   break;
6848
            case 5: gen_uxtb(cpu_T[1]);   break;
6928
            case 0: gen_sxth(tmp);   break;
6929
            case 1: gen_uxth(tmp);   break;
6930
            case 2: gen_sxtb16(tmp); break;
6931
            case 3: gen_uxtb16(tmp); break;
6932
            case 4: gen_sxtb(tmp);   break;
6933
            case 5: gen_uxtb(tmp);   break;
6849 6934
            default: goto illegal_op;
6850 6935
            }
6851 6936
            if (rn != 15) {
6852
                tmp = load_reg(s, rn);
6937
                tmp2 = load_reg(s, rn);
6853 6938
                if ((op >> 1) == 1) {
6854
                    gen_add16(cpu_T[1], tmp);
6939
                    gen_add16(tmp, tmp2);
6855 6940
                } else {
6856
                    tcg_gen_add_i32(cpu_T[1], cpu_T[1], tmp);
6857
                    dead_tmp(tmp);
6941
                    tcg_gen_add_i32(tmp, tmp, tmp2);
6942
                    dead_tmp(tmp2);
6858 6943
                }
6859 6944
            }
6860
            gen_movl_reg_T1(s, rd);
6945
            store_reg(s, rd, tmp);
6861 6946
            break;
6862 6947
        case 2: /* SIMD add/subtract.  */
6863 6948
            op = (insn >> 20) & 7;
......
6965 7050
                    tcg_gen_sari_i32(tmp2, tmp2, 16);
6966 7051
                else
6967 7052
                    gen_sxth(tmp2);
6968
                gen_imulw(tmp, tmp2);
6969
                dead_tmp(tmp2);
7053
                tmp2 = gen_muls_i64_i32(tmp, tmp2);
7054
                tcg_gen_shri_i64(tmp2, tmp2, 16);
7055
                tmp = new_tmp();
7056
                tcg_gen_trunc_i64_i32(tmp, tmp2);
6970 7057
                if (rs != 15)
6971 7058
                  {
6972 7059
                    tmp2 = load_reg(s, rs);
......
7007 7094
            break;
7008 7095
        case 6: case 7: /* 64-bit multiply, Divide.  */
7009 7096
            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
7010
            gen_movl_T0_reg(s, rn);
7011
            gen_movl_T1_reg(s, rm);
7097
            tmp = load_reg(s, rn);
7098
            tmp2 = load_reg(s, rm);
7012 7099
            if ((op & 0x50) == 0x10) {
7013 7100
                /* sdiv, udiv */
7014 7101
                if (!arm_feature(env, ARM_FEATURE_DIV))
7015 7102
                    goto illegal_op;
7016 7103
                if (op & 0x20)
7017
                    gen_helper_udiv(cpu_T[0], cpu_T[0], cpu_T[1]);
7104
                    gen_helper_udiv(tmp, tmp, tmp2);
7018 7105
                else
7019
                    gen_helper_sdiv(cpu_T[0], cpu_T[0], cpu_T[1]);
7020
                gen_movl_reg_T0(s, rd);
7106
                    gen_helper_sdiv(tmp, tmp, tmp2);
7107
                dead_tmp(tmp2);
7108
                store_reg(s, rd, tmp);
7021 7109
            } else if ((op & 0xe) == 0xc) {
7022 7110
                /* Dual multiply accumulate long.  */
7023 7111
                if (op & 1)
7024
                    gen_swap_half(cpu_T[1]);
7025
                gen_smul_dual(cpu_T[0], cpu_T[1]);
7112
                    gen_swap_half(tmp2);
7113
                gen_smul_dual(tmp, tmp2);
7026 7114
                if (op & 0x10) {
7027
                    gen_op_subl_T0_T1();
7115
                    tcg_gen_sub_i32(tmp, tmp, tmp2);
7028 7116
                } else {
7029
                    gen_op_addl_T0_T1();
7117
                    tcg_gen_add_i32(tmp, tmp, tmp2);
7030 7118
                }
7031
                gen_op_signbit_T1_T0();
7032
                gen_op_addq_T0_T1(rs, rd);
7033
                gen_movl_reg_T0(s, rs);
7034
                gen_movl_reg_T1(s, rd);
7119
                dead_tmp(tmp2);
7120
                tmp2 = tcg_temp_new(TCG_TYPE_I64);
7121
                gen_addq(s, tmp, rs, rd);
7122
                gen_storeq_reg(s, rs, rd, tmp);
7035 7123
            } else {
7036 7124
                if (op & 0x20) {
7037 7125
                    /* Unsigned 64-bit multiply  */
7038
                    gen_op_mull_T0_T1();
7126
                    tmp = gen_mulu_i64_i32(tmp, tmp2);
7039 7127
                } else {
7040 7128
                    if (op & 8) {
7041 7129
                        /* smlalxy */
7042
                        gen_mulxy(cpu_T[0], cpu_T[1], op & 2, op & 1);
7043
                        gen_op_signbit_T1_T0();
7130
                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
7131
                        dead_tmp(tmp2);
7132
                        tmp2 = tcg_temp_new(TCG_TYPE_I64);
7133
                        tcg_gen_ext_i32_i64(tmp2, tmp);
7134
                        dead_tmp(tmp);
7135
                        tmp = tmp2;
7044 7136
                    } else {
7045 7137
                        /* Signed 64-bit multiply  */
7046
                        gen_op_imull_T0_T1();
7138
                        tmp = gen_muls_i64_i32(tmp, tmp2);
7047 7139
                    }
7048 7140
                }
7049 7141
                if (op & 4) {
7050 7142
                    /* umaal */
7051
                    gen_op_addq_lo_T0_T1(rs);
7052
                    gen_op_addq_lo_T0_T1(rd);
7143
                    gen_addq_lo(s, tmp, rs);
7144
                    gen_addq_lo(s, tmp, rd);
7053 7145
                } else if (op & 0x40) {
7054 7146
                    /* 64-bit accumulate.  */
7055
                    gen_op_addq_T0_T1(rs, rd);
7147
                    gen_addq(s, tmp, rs, rd);
7056 7148
                }
7057
                gen_movl_reg_T0(s, rs);
7058
                gen_movl_reg_T1(s, rd);
7149
                gen_storeq_reg(s, rs, rd, tmp);
7059 7150
            }
7060 7151
            break;
7061 7152
        }
......
7299 7390
                        imm |= (insn >> 4) & 0xf000;
7300 7391
                        if (insn & (1 << 23)) {
7301 7392
                            /* movt */
7302
                            gen_movl_T0_reg(s, rd);
7303
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
7304
                            tcg_gen_ori_i32(cpu_T[0], cpu_T[0], imm << 16);
7393
                            tmp = load_reg(s, rd);
7394
                            tcg_gen_andi_i32(tmp, tmp, 0xffff);
7395
                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
7305 7396
                        } else {
7306 7397
                            /* movw */
7307
                            gen_op_movl_T0_im(imm);
7398
                            tmp = new_tmp();
7399
                            tcg_gen_movi_i32(tmp, imm);
7308 7400
                        }
7309 7401
                    } else {
7310 7402
                        /* Add/sub 12-bit immediate.  */
......
7314 7406
                                offset -= imm;
7315 7407
                            else
7316 7408
                                offset += imm;
7317
                            gen_op_movl_T0_im(offset);
7409
                            tmp = new_tmp();
7410
                            tcg_gen_movi_i32(tmp, offset);
7318 7411
                        } else {
7319
                            gen_movl_T0_reg(s, rn);
7320
                            gen_op_movl_T1_im(imm);
7412
                            tmp = load_reg(s, rn);
7321 7413
                            if (insn & (1 << 23))
7322
                                gen_op_subl_T0_T1();
7414
                                tcg_gen_subi_i32(tmp, tmp, imm);
7323 7415
                            else
7324
                                gen_op_addl_T0_T1();
7416
                                tcg_gen_addi_i32(tmp, tmp, imm);
7325 7417
                        }
7326 7418
                    }
7327
                    gen_movl_reg_T0(s, rd);
7419
                    store_reg(s, rd, tmp);
7328 7420
                }
7329 7421
            } else {
7330 7422
                int shifter_out = 0;
......
7882 7974
        rd = (insn >> 8) & 7;
7883 7975
        if (insn & (1 << 11)) {
7884 7976
            /* SP */
7885
            gen_movl_T0_reg(s, 13);
7977
            tmp = load_reg(s, 13);
7886 7978
        } else {
7887 7979
            /* PC. bit 1 is ignored.  */
7888
            gen_op_movl_T0_im((s->pc + 2) & ~(uint32_t)2);
7980
            tmp = new_tmp();
7981
            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
7889 7982
        }
7890 7983
        val = (insn & 0xff) * 4;
7891
        gen_op_movl_T1_im(val);
7892
        gen_op_addl_T0_T1();
7893
        gen_movl_reg_T0(s, rd);
7984
        tcg_gen_addi_i32(tmp, tmp, val);
7985
        store_reg(s, rd, tmp);
7894 7986
        break;
7895 7987

  
7896 7988
    case 11:
......
8002 8094

  
8003 8095
        case 0xe: /* bkpt */
8004 8096
            gen_set_condexec(s);
8005
            gen_op_movl_T0_im((long)s->pc - 2);
8006
            gen_set_pc_T0();
8097
            gen_set_pc_im(s->pc - 2);
8007 8098
            gen_exception(EXCP_BKPT);
8008 8099
            s->is_jmp = DISAS_JUMP;
8009 8100
            break;
......
8090 8181
        if (cond == 0xf) {
8091 8182
            /* swi */
8092 8183
            gen_set_condexec(s);
8093
            gen_op_movl_T0_im((long)s->pc | 1);
8094
            /* Don't set r15.  */
8095
            gen_set_pc_T0();
8184
            gen_set_pc_im(s->pc | 1);
8096 8185
            s->is_jmp = DISAS_SWI;
8097 8186
            break;
8098 8187
        }
......
8130 8219
    return;
8131 8220
undef32:
8132 8221
    gen_set_condexec(s);
8133
    gen_op_movl_T0_im((long)s->pc - 4);
8134
    gen_set_pc_T0();
8222
    gen_set_pc_im(s->pc - 4);
8135 8223
    gen_exception(EXCP_UDEF);
8136 8224
    s->is_jmp = DISAS_JUMP;
8137 8225
    return;
8138 8226
illegal_op:
8139 8227
undef:
8140 8228
    gen_set_condexec(s);
8141
    gen_op_movl_T0_im((long)s->pc - 2);
8142
    gen_set_pc_T0();
8229
    gen_set_pc_im(s->pc - 2);
8143 8230
    gen_exception(EXCP_UDEF);
8144 8231
    s->is_jmp = DISAS_JUMP;
8145 8232
}
......
8209 8296
            for(j = 0; j < env->nb_breakpoints; j++) {
8210 8297
                if (env->breakpoints[j] == dc->pc) {
8211 8298
                    gen_set_condexec(dc);
8212
                    gen_op_movl_T0_im((long)dc->pc);
8213
                    gen_set_pc_T0();
8299
                    gen_set_pc_im(dc->pc);
8214 8300
                    gen_exception(EXCP_DEBUG);
8215 8301
                    dc->is_jmp = DISAS_JUMP;
8216 8302
                    /* Advance PC so that clearing the breakpoint will
......
8283 8369
            gen_set_label(dc->condlabel);
8284 8370
        }
8285 8371
        if (dc->condjmp || !dc->is_jmp) {
8286
            gen_op_movl_T0_im((long)dc->pc);
8287
            gen_set_pc_T0();
8372
            gen_set_pc_im(dc->pc);
8288 8373
            dc->condjmp = 0;
8289 8374
        }
8290 8375
        gen_set_condexec(dc);
......
8404 8489
                psr & CPSR_T ? 'T' : 'A',
8405 8490
                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
8406 8491

  
8492
#if 0
8407 8493
    for (i = 0; i < 16; i++) {
8408 8494
        d.d = env->vfp.regs[i];
8409 8495
        s0.i = d.l.lower;
......
8416 8502
                    d0.d);
8417 8503
    }
8418 8504
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
8505
#endif
8419 8506
}
8420 8507

  

Also available in: Unified diff