Commit 5e3f878ad65a3a3e50200dd40feac23c9f77b9b7

Authored by pbrook
1 parent 4373f3ce

ARM TCG conversion 11/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4148 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/helper.c
... ... @@ -2167,6 +2167,10 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
2167 2167 return (a & mask) | (b & ~mask);
2168 2168 }
2169 2169  
  2170 +uint32_t HELPER(logicq_cc)(uint64_t val)
  2171 +{
  2172 + return (val >> 32) | (val != 0);
  2173 +}
2170 2174  
2171 2175 /* VFP support. We follow the convention used for VFP instrunctions:
2172 2176 Single precition routines have a "s" suffix, double precision a
... ... @@ -2529,4 +2533,3 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
2529 2533 tmp = float32_scalbn(tmp, 31, s);
2530 2534 return float32_to_int32(tmp, s);
2531 2535 }
2532   -
... ...
target-arm/helpers.h
... ... @@ -109,6 +109,8 @@ DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t))
109 109  
110 110 DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t))
111 111  
  112 +DEF_HELPER_1_1(logicq_cc, uint32_t, (uint64_t))
  113 +
112 114 DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t))
113 115 DEF_HELPER_0_1(exception, void, (uint32_t))
114 116 DEF_HELPER_0_0(wfi, void, (void))
... ...
target-arm/op.c
... ... @@ -80,51 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1)
80 80  
81 81 OPSUB(rsb, rsc, T0, T1, T0)
82 82  
83   -void OPPROTO op_addq_T0_T1(void)
84   -{
85   - uint64_t res;
86   - res = ((uint64_t)T1 << 32) | T0;
87   - res += ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
88   - T1 = res >> 32;
89   - T0 = res;
90   -}
91   -
92   -void OPPROTO op_addq_lo_T0_T1(void)
93   -{
94   - uint64_t res;
95   - res = ((uint64_t)T1 << 32) | T0;
96   - res += (uint64_t)(env->regs[PARAM1]);
97   - T1 = res >> 32;
98   - T0 = res;
99   -}
100   -
101   -/* Dual 16-bit accumulate. */
102   -void OPPROTO op_addq_T0_T1_dual(void)
103   -{
104   - uint64_t res;
105   - res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
106   - res += (int32_t)T0;
107   - res += (int32_t)T1;
108   - env->regs[PARAM1] = (uint32_t)res;
109   - env->regs[PARAM2] = res >> 32;
110   -}
111   -
112   -/* Dual 16-bit subtract accumulate. */
113   -void OPPROTO op_subq_T0_T1_dual(void)
114   -{
115   - uint64_t res;
116   - res = ((uint64_t)(env->regs[PARAM2]) << 32) | (env->regs[PARAM1]);
117   - res += (int32_t)T0;
118   - res -= (int32_t)T1;
119   - env->regs[PARAM1] = (uint32_t)res;
120   - env->regs[PARAM2] = res >> 32;
121   -}
122   -
123   -void OPPROTO op_logicq_cc(void)
124   -{
125   - env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
126   -}
127   -
128 83 /* memory access */
129 84  
130 85 #define MEMSUFFIX _raw
... ...
target-arm/translate.c
... ... @@ -226,20 +226,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
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,6 +318,33 @@ static void gen_roundqd(TCGv a, TCGv b)
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,15 +374,6 @@ static void gen_imull(TCGv a, TCGv b)
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,6 +869,13 @@ static inline void gen_movl_T2_reg(DisasContext *s, int reg)
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,8 +3829,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
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,8 +3882,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
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,6 +5310,62 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
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,16 +5582,15 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,20 +5675,20 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,34 +5701,40 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,42 +5919,44 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,32 +6142,32 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,51 +6190,53 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,32 +6263,34 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,8 +6472,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,15 +6490,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
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,32 +6917,32 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
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,8 +7050,10 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
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,55 +7094,59 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
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,12 +7390,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
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,17 +7406,17 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
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,15 +7974,15 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
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,8 +8094,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
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,9 +8181,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
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,16 +8219,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s)
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,8 +8296,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
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,8 +8369,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
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,6 +8489,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
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,5 +8502,6 @@ void cpu_dump_state(CPUState *env, FILE *f,
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  
... ...