Commit 5e3f878ad65a3a3e50200dd40feac23c9f77b9b7
1 parent
4373f3ce
ARM TCG conversion 11/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4148 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
295 additions
and
248 deletions
target-arm/helper.c
@@ -2167,6 +2167,10 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) | @@ -2167,6 +2167,10 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b) | ||
2167 | return (a & mask) | (b & ~mask); | 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 | /* VFP support. We follow the convention used for VFP instrunctions: | 2175 | /* VFP support. We follow the convention used for VFP instrunctions: |
2172 | Single precition routines have a "s" suffix, double precision a | 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,4 +2533,3 @@ uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env) | ||
2529 | tmp = float32_scalbn(tmp, 31, s); | 2533 | tmp = float32_scalbn(tmp, 31, s); |
2530 | return float32_to_int32(tmp, s); | 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,6 +109,8 @@ DEF_HELPER_1_2(usat16, uint32_t, (uint32_t, uint32_t)) | ||
109 | 109 | ||
110 | DEF_HELPER_1_2(usad8, uint32_t, (uint32_t, uint32_t)) | 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 | DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t)) | 114 | DEF_HELPER_1_3(sel_flags, uint32_t, (uint32_t, uint32_t, uint32_t)) |
113 | DEF_HELPER_0_1(exception, void, (uint32_t)) | 115 | DEF_HELPER_0_1(exception, void, (uint32_t)) |
114 | DEF_HELPER_0_0(wfi, void, (void)) | 116 | DEF_HELPER_0_0(wfi, void, (void)) |
target-arm/op.c
@@ -80,51 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1) | @@ -80,51 +80,6 @@ OPSUB(sub, sbc, T0, T0, T1) | ||
80 | 80 | ||
81 | OPSUB(rsb, rsc, T0, T1, T0) | 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 | /* memory access */ | 83 | /* memory access */ |
129 | 84 | ||
130 | #define MEMSUFFIX _raw | 85 | #define MEMSUFFIX _raw |
target-arm/translate.c
@@ -226,20 +226,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) | @@ -226,20 +226,6 @@ static void store_reg(DisasContext *s, int reg, TCGv var) | ||
226 | 226 | ||
227 | #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1]) | 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 | #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask)) | 229 | #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask)) |
244 | /* Set NZCV flags from the high 4 bits of var. */ | 230 | /* Set NZCV flags from the high 4 bits of var. */ |
245 | #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV) | 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,6 +318,33 @@ static void gen_roundqd(TCGv a, TCGv b) | ||
332 | 318 | ||
333 | /* FIXME: Most targets have native widening multiplication. | 319 | /* FIXME: Most targets have native widening multiplication. |
334 | It would be good to use that instead of a full wide multiply. */ | 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 | /* Unsigned 32x32->64 multiply. */ | 348 | /* Unsigned 32x32->64 multiply. */ |
336 | static void gen_op_mull_T0_T1(void) | 349 | static void gen_op_mull_T0_T1(void) |
337 | { | 350 | { |
@@ -361,15 +374,6 @@ static void gen_imull(TCGv a, TCGv b) | @@ -361,15 +374,6 @@ static void gen_imull(TCGv a, TCGv b) | ||
361 | } | 374 | } |
362 | #define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1]) | 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 | /* Swap low and high halfwords. */ | 377 | /* Swap low and high halfwords. */ |
374 | static void gen_swap_half(TCGv var) | 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,6 +869,13 @@ static inline void gen_movl_T2_reg(DisasContext *s, int reg) | ||
865 | load_reg_var(s, cpu_T[2], reg); | 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 | static inline void gen_set_pc_T0(void) | 879 | static inline void gen_set_pc_T0(void) |
869 | { | 880 | { |
870 | tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, regs[15])); | 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,8 +3829,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | ||
3818 | case 1: gen_op_neon_qadd_u8(); break; | 3829 | case 1: gen_op_neon_qadd_u8(); break; |
3819 | case 2: gen_op_neon_qadd_s16(); break; | 3830 | case 2: gen_op_neon_qadd_s16(); break; |
3820 | case 3: gen_op_neon_qadd_u16(); break; | 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 | default: abort(); | 3838 | default: abort(); |
3824 | } | 3839 | } |
3825 | break; | 3840 | break; |
@@ -3867,8 +3882,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | @@ -3867,8 +3882,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) | ||
3867 | case 1: gen_op_neon_qsub_u8(); break; | 3882 | case 1: gen_op_neon_qsub_u8(); break; |
3868 | case 2: gen_op_neon_qsub_s16(); break; | 3883 | case 2: gen_op_neon_qsub_s16(); break; |
3869 | case 3: gen_op_neon_qsub_u16(); break; | 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 | default: abort(); | 3891 | default: abort(); |
3873 | } | 3892 | } |
3874 | break; | 3893 | break; |
@@ -5291,6 +5310,62 @@ static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn) | @@ -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 | static void disas_arm_insn(CPUState * env, DisasContext *s) | 5369 | static void disas_arm_insn(CPUState * env, DisasContext *s) |
5295 | { | 5370 | { |
5296 | unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; | 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,16 +5582,15 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5507 | val = ((insn >> 4) & 0xf000) | (insn & 0xfff); | 5582 | val = ((insn >> 4) & 0xf000) | (insn & 0xfff); |
5508 | if ((insn & (1 << 22)) == 0) { | 5583 | if ((insn & (1 << 22)) == 0) { |
5509 | /* MOVW */ | 5584 | /* MOVW */ |
5510 | - gen_op_movl_T0_im(val); | 5585 | + tmp = new_tmp(); |
5586 | + tcg_gen_movi_i32(tmp, val); | ||
5511 | } else { | 5587 | } else { |
5512 | /* MOVT */ | 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 | } else { | 5594 | } else { |
5521 | if (((insn >> 12) & 0xf) != 0xf) | 5595 | if (((insn >> 12) & 0xf) != 0xf) |
5522 | goto illegal_op; | 5596 | goto illegal_op; |
@@ -5601,20 +5675,20 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -5601,20 +5675,20 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5601 | case 0x5: /* saturating add/subtract */ | 5675 | case 0x5: /* saturating add/subtract */ |
5602 | rd = (insn >> 12) & 0xf; | 5676 | rd = (insn >> 12) & 0xf; |
5603 | rn = (insn >> 16) & 0xf; | 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 | if (op1 & 2) | 5680 | if (op1 & 2) |
5607 | - gen_helper_double_saturate(cpu_T[1], cpu_T[1]); | 5681 | + gen_helper_double_saturate(tmp2, tmp2); |
5608 | if (op1 & 1) | 5682 | if (op1 & 1) |
5609 | - gen_op_subl_T0_T1_saturate(); | 5683 | + gen_helper_sub_saturate(tmp, tmp, tmp2); |
5610 | else | 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 | break; | 5688 | break; |
5614 | case 7: /* bkpt */ | 5689 | case 7: /* bkpt */ |
5615 | gen_set_condexec(s); | 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 | gen_exception(EXCP_BKPT); | 5692 | gen_exception(EXCP_BKPT); |
5619 | s->is_jmp = DISAS_JUMP; | 5693 | s->is_jmp = DISAS_JUMP; |
5620 | break; | 5694 | break; |
@@ -5627,34 +5701,40 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -5627,34 +5701,40 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5627 | rd = (insn >> 16) & 0xf; | 5701 | rd = (insn >> 16) & 0xf; |
5628 | if (op1 == 1) { | 5702 | if (op1 == 1) { |
5629 | /* (32 * 16) >> 16 */ | 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 | if (sh & 4) | 5706 | if (sh & 4) |
5633 | - gen_op_sarl_T1_im(16); | 5707 | + tcg_gen_sari_i32(tmp2, tmp2, 16); |
5634 | else | 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 | if ((sh & 2) == 0) { | 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 | } else { | 5720 | } else { |
5643 | /* 16 * 16 */ | 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 | if (op1 == 2) { | 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 | } else { | 5731 | } else { |
5653 | if (op1 == 0) { | 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 | break; | 5740 | break; |
@@ -5839,42 +5919,44 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -5839,42 +5919,44 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
5839 | switch (op1) { | 5919 | switch (op1) { |
5840 | case 0: case 1: case 2: case 3: case 6: | 5920 | case 0: case 1: case 2: case 3: case 6: |
5841 | /* 32 bit mul */ | 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 | if (insn & (1 << 22)) { | 5926 | if (insn & (1 << 22)) { |
5846 | /* Subtract (mls) */ | 5927 | /* Subtract (mls) */ |
5847 | ARCH(6T2); | 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 | } else if (insn & (1 << 21)) { | 5932 | } else if (insn & (1 << 21)) { |
5851 | /* Add */ | 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 | if (insn & (1 << 20)) | 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 | break; | 5941 | break; |
5859 | default: | 5942 | default: |
5860 | /* 64 bit mul */ | 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 | if (insn & (1 << 22)) | 5946 | if (insn & (1 << 22)) |
5864 | - gen_op_imull_T0_T1(); | 5947 | + tmp = gen_muls_i64_i32(tmp, tmp2); |
5865 | else | 5948 | else |
5866 | - gen_op_mull_T0_T1(); | 5949 | + tmp = gen_mulu_i64_i32(tmp, tmp2); |
5867 | if (insn & (1 << 21)) /* mult accumulate */ | 5950 | if (insn & (1 << 21)) /* mult accumulate */ |
5868 | - gen_op_addq_T0_T1(rn, rd); | 5951 | + gen_addq(s, tmp, rn, rd); |
5869 | if (!(insn & (1 << 23))) { /* double accumulate */ | 5952 | if (!(insn & (1 << 23))) { /* double accumulate */ |
5870 | ARCH(6); | 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 | if (insn & (1 << 20)) | 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 | break; | 5960 | break; |
5879 | } | 5961 | } |
5880 | } else { | 5962 | } else { |
@@ -6060,32 +6142,32 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6060,32 +6142,32 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
6060 | dead_tmp(tmp2); | 6142 | dead_tmp(tmp2); |
6061 | store_reg(s, rd, tmp); | 6143 | store_reg(s, rd, tmp); |
6062 | } else if ((insn & 0x000003e0) == 0x00000060) { | 6144 | } else if ((insn & 0x000003e0) == 0x00000060) { |
6063 | - gen_movl_T1_reg(s, rm); | 6145 | + tmp = load_reg(s, rm); |
6064 | shift = (insn >> 10) & 3; | 6146 | shift = (insn >> 10) & 3; |
6065 | /* ??? In many cases it's not neccessary to do a | 6147 | /* ??? In many cases it's not neccessary to do a |
6066 | rotate, a shift is sufficient. */ | 6148 | rotate, a shift is sufficient. */ |
6067 | if (shift != 0) | 6149 | if (shift != 0) |
6068 | - gen_op_rorl_T1_im(shift * 8); | 6150 | + tcg_gen_rori_i32(tmp, tmp, shift * 8); |
6069 | op1 = (insn >> 20) & 7; | 6151 | op1 = (insn >> 20) & 7; |
6070 | switch (op1) { | 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 | default: goto illegal_op; | 6159 | default: goto illegal_op; |
6078 | } | 6160 | } |
6079 | if (rn != 15) { | 6161 | if (rn != 15) { |
6080 | - tmp = load_reg(s, rn); | 6162 | + tmp2 = load_reg(s, rn); |
6081 | if ((op1 & 3) == 0) { | 6163 | if ((op1 & 3) == 0) { |
6082 | - gen_add16(cpu_T[1], tmp); | 6164 | + gen_add16(tmp, tmp2); |
6083 | } else { | 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 | } else if ((insn & 0x003f0f60) == 0x003f0f20) { | 6171 | } else if ((insn & 0x003f0f60) == 0x003f0f20) { |
6090 | /* rev */ | 6172 | /* rev */ |
6091 | tmp = load_reg(s, rm); | 6173 | tmp = load_reg(s, rm); |
@@ -6108,51 +6190,53 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6108,51 +6190,53 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
6108 | } | 6190 | } |
6109 | break; | 6191 | break; |
6110 | case 2: /* Multiplies (Type 3). */ | 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 | if (insn & (1 << 20)) { | 6195 | if (insn & (1 << 20)) { |
6114 | /* Signed multiply most significant [accumulate]. */ | 6196 | /* Signed multiply most significant [accumulate]. */ |
6115 | - gen_op_imull_T0_T1(); | 6197 | + tmp2 = gen_muls_i64_i32(tmp, tmp2); |
6116 | if (insn & (1 << 5)) | 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 | if (rn != 15) { | 6203 | if (rn != 15) { |
6121 | - gen_movl_T1_reg(s, rn); | 6204 | + tmp2 = load_reg(s, rn); |
6122 | if (insn & (1 << 6)) { | 6205 | if (insn & (1 << 6)) { |
6123 | - gen_op_addl_T0_T1(); | 6206 | + tcg_gen_sub_i32(tmp, tmp, tmp2); |
6124 | } else { | 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 | } else { | 6213 | } else { |
6130 | if (insn & (1 << 5)) | 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 | if (insn & (1 << 22)) { | 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 | } else { | 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 | if (rn != 15) | 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 | break; | 6242 | break; |
@@ -6179,32 +6263,34 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6179,32 +6263,34 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
6179 | i = (insn >> 16) & 0x1f; | 6263 | i = (insn >> 16) & 0x1f; |
6180 | i = i + 1 - shift; | 6264 | i = i + 1 - shift; |
6181 | if (rm == 15) { | 6265 | if (rm == 15) { |
6182 | - gen_op_movl_T1_im(0); | 6266 | + tmp = new_tmp(); |
6267 | + tcg_gen_movi_i32(tmp, 0); | ||
6183 | } else { | 6268 | } else { |
6184 | - gen_movl_T1_reg(s, rm); | 6269 | + tmp = load_reg(s, rm); |
6185 | } | 6270 | } |
6186 | if (i != 32) { | 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 | shift, ((1u << i) - 1) << shift); | 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 | break; | 6278 | break; |
6193 | case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ | 6279 | case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ |
6194 | case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ | 6280 | case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ |
6195 | - gen_movl_T1_reg(s, rm); | 6281 | + tmp = load_reg(s, rm); |
6196 | shift = (insn >> 7) & 0x1f; | 6282 | shift = (insn >> 7) & 0x1f; |
6197 | i = ((insn >> 16) & 0x1f) + 1; | 6283 | i = ((insn >> 16) & 0x1f) + 1; |
6198 | if (shift + i > 32) | 6284 | if (shift + i > 32) |
6199 | goto illegal_op; | 6285 | goto illegal_op; |
6200 | if (i < 32) { | 6286 | if (i < 32) { |
6201 | if (op1 & 0x20) { | 6287 | if (op1 & 0x20) { |
6202 | - gen_ubfx(cpu_T[1], shift, (1u << i) - 1); | 6288 | + gen_ubfx(tmp, shift, (1u << i) - 1); |
6203 | } else { | 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 | break; | 6294 | break; |
6209 | default: | 6295 | default: |
6210 | goto illegal_op; | 6296 | goto illegal_op; |
@@ -6386,8 +6472,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6386,8 +6472,9 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
6386 | /* branch (and link) */ | 6472 | /* branch (and link) */ |
6387 | val = (int32_t)s->pc; | 6473 | val = (int32_t)s->pc; |
6388 | if (insn & (1 << 24)) { | 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 | offset = (((int32_t)insn << 8) >> 8); | 6479 | offset = (((int32_t)insn << 8) >> 8); |
6393 | val += (offset << 2) + 4; | 6480 | val += (offset << 2) + 4; |
@@ -6403,15 +6490,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | @@ -6403,15 +6490,13 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) | ||
6403 | break; | 6490 | break; |
6404 | case 0xf: | 6491 | case 0xf: |
6405 | /* swi */ | 6492 | /* swi */ |
6406 | - gen_op_movl_T0_im((long)s->pc); | ||
6407 | - gen_set_pc_T0(); | 6493 | + gen_set_pc_im(s->pc); |
6408 | s->is_jmp = DISAS_SWI; | 6494 | s->is_jmp = DISAS_SWI; |
6409 | break; | 6495 | break; |
6410 | default: | 6496 | default: |
6411 | illegal_op: | 6497 | illegal_op: |
6412 | gen_set_condexec(s); | 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 | gen_exception(EXCP_UDEF); | 6500 | gen_exception(EXCP_UDEF); |
6416 | s->is_jmp = DISAS_JUMP; | 6501 | s->is_jmp = DISAS_JUMP; |
6417 | break; | 6502 | break; |
@@ -6832,32 +6917,32 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -6832,32 +6917,32 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
6832 | gen_movl_reg_T1(s, rd); | 6917 | gen_movl_reg_T1(s, rd); |
6833 | break; | 6918 | break; |
6834 | case 1: /* Sign/zero extend. */ | 6919 | case 1: /* Sign/zero extend. */ |
6835 | - gen_movl_T1_reg(s, rm); | 6920 | + tmp = load_reg(s, rm); |
6836 | shift = (insn >> 4) & 3; | 6921 | shift = (insn >> 4) & 3; |
6837 | /* ??? In many cases it's not neccessary to do a | 6922 | /* ??? In many cases it's not neccessary to do a |
6838 | rotate, a shift is sufficient. */ | 6923 | rotate, a shift is sufficient. */ |
6839 | if (shift != 0) | 6924 | if (shift != 0) |
6840 | - gen_op_rorl_T1_im(shift * 8); | 6925 | + tcg_gen_rori_i32(tmp, tmp, shift * 8); |
6841 | op = (insn >> 20) & 7; | 6926 | op = (insn >> 20) & 7; |
6842 | switch (op) { | 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 | default: goto illegal_op; | 6934 | default: goto illegal_op; |
6850 | } | 6935 | } |
6851 | if (rn != 15) { | 6936 | if (rn != 15) { |
6852 | - tmp = load_reg(s, rn); | 6937 | + tmp2 = load_reg(s, rn); |
6853 | if ((op >> 1) == 1) { | 6938 | if ((op >> 1) == 1) { |
6854 | - gen_add16(cpu_T[1], tmp); | 6939 | + gen_add16(tmp, tmp2); |
6855 | } else { | 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 | break; | 6946 | break; |
6862 | case 2: /* SIMD add/subtract. */ | 6947 | case 2: /* SIMD add/subtract. */ |
6863 | op = (insn >> 20) & 7; | 6948 | op = (insn >> 20) & 7; |
@@ -6965,8 +7050,10 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -6965,8 +7050,10 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
6965 | tcg_gen_sari_i32(tmp2, tmp2, 16); | 7050 | tcg_gen_sari_i32(tmp2, tmp2, 16); |
6966 | else | 7051 | else |
6967 | gen_sxth(tmp2); | 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 | if (rs != 15) | 7057 | if (rs != 15) |
6971 | { | 7058 | { |
6972 | tmp2 = load_reg(s, rs); | 7059 | tmp2 = load_reg(s, rs); |
@@ -7007,55 +7094,59 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -7007,55 +7094,59 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
7007 | break; | 7094 | break; |
7008 | case 6: case 7: /* 64-bit multiply, Divide. */ | 7095 | case 6: case 7: /* 64-bit multiply, Divide. */ |
7009 | op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); | 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 | if ((op & 0x50) == 0x10) { | 7099 | if ((op & 0x50) == 0x10) { |
7013 | /* sdiv, udiv */ | 7100 | /* sdiv, udiv */ |
7014 | if (!arm_feature(env, ARM_FEATURE_DIV)) | 7101 | if (!arm_feature(env, ARM_FEATURE_DIV)) |
7015 | goto illegal_op; | 7102 | goto illegal_op; |
7016 | if (op & 0x20) | 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 | else | 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 | } else if ((op & 0xe) == 0xc) { | 7109 | } else if ((op & 0xe) == 0xc) { |
7022 | /* Dual multiply accumulate long. */ | 7110 | /* Dual multiply accumulate long. */ |
7023 | if (op & 1) | 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 | if (op & 0x10) { | 7114 | if (op & 0x10) { |
7027 | - gen_op_subl_T0_T1(); | 7115 | + tcg_gen_sub_i32(tmp, tmp, tmp2); |
7028 | } else { | 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 | } else { | 7123 | } else { |
7036 | if (op & 0x20) { | 7124 | if (op & 0x20) { |
7037 | /* Unsigned 64-bit multiply */ | 7125 | /* Unsigned 64-bit multiply */ |
7038 | - gen_op_mull_T0_T1(); | 7126 | + tmp = gen_mulu_i64_i32(tmp, tmp2); |
7039 | } else { | 7127 | } else { |
7040 | if (op & 8) { | 7128 | if (op & 8) { |
7041 | /* smlalxy */ | 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 | } else { | 7136 | } else { |
7045 | /* Signed 64-bit multiply */ | 7137 | /* Signed 64-bit multiply */ |
7046 | - gen_op_imull_T0_T1(); | 7138 | + tmp = gen_muls_i64_i32(tmp, tmp2); |
7047 | } | 7139 | } |
7048 | } | 7140 | } |
7049 | if (op & 4) { | 7141 | if (op & 4) { |
7050 | /* umaal */ | 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 | } else if (op & 0x40) { | 7145 | } else if (op & 0x40) { |
7054 | /* 64-bit accumulate. */ | 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 | break; | 7151 | break; |
7061 | } | 7152 | } |
@@ -7299,12 +7390,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -7299,12 +7390,13 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
7299 | imm |= (insn >> 4) & 0xf000; | 7390 | imm |= (insn >> 4) & 0xf000; |
7300 | if (insn & (1 << 23)) { | 7391 | if (insn & (1 << 23)) { |
7301 | /* movt */ | 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 | } else { | 7396 | } else { |
7306 | /* movw */ | 7397 | /* movw */ |
7307 | - gen_op_movl_T0_im(imm); | 7398 | + tmp = new_tmp(); |
7399 | + tcg_gen_movi_i32(tmp, imm); | ||
7308 | } | 7400 | } |
7309 | } else { | 7401 | } else { |
7310 | /* Add/sub 12-bit immediate. */ | 7402 | /* Add/sub 12-bit immediate. */ |
@@ -7314,17 +7406,17 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | @@ -7314,17 +7406,17 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) | ||
7314 | offset -= imm; | 7406 | offset -= imm; |
7315 | else | 7407 | else |
7316 | offset += imm; | 7408 | offset += imm; |
7317 | - gen_op_movl_T0_im(offset); | 7409 | + tmp = new_tmp(); |
7410 | + tcg_gen_movi_i32(tmp, offset); | ||
7318 | } else { | 7411 | } else { |
7319 | - gen_movl_T0_reg(s, rn); | ||
7320 | - gen_op_movl_T1_im(imm); | 7412 | + tmp = load_reg(s, rn); |
7321 | if (insn & (1 << 23)) | 7413 | if (insn & (1 << 23)) |
7322 | - gen_op_subl_T0_T1(); | 7414 | + tcg_gen_subi_i32(tmp, tmp, imm); |
7323 | else | 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 | } else { | 7421 | } else { |
7330 | int shifter_out = 0; | 7422 | int shifter_out = 0; |
@@ -7882,15 +7974,15 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | @@ -7882,15 +7974,15 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | ||
7882 | rd = (insn >> 8) & 7; | 7974 | rd = (insn >> 8) & 7; |
7883 | if (insn & (1 << 11)) { | 7975 | if (insn & (1 << 11)) { |
7884 | /* SP */ | 7976 | /* SP */ |
7885 | - gen_movl_T0_reg(s, 13); | 7977 | + tmp = load_reg(s, 13); |
7886 | } else { | 7978 | } else { |
7887 | /* PC. bit 1 is ignored. */ | 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 | val = (insn & 0xff) * 4; | 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 | break; | 7986 | break; |
7895 | 7987 | ||
7896 | case 11: | 7988 | case 11: |
@@ -8002,8 +8094,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | @@ -8002,8 +8094,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | ||
8002 | 8094 | ||
8003 | case 0xe: /* bkpt */ | 8095 | case 0xe: /* bkpt */ |
8004 | gen_set_condexec(s); | 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 | gen_exception(EXCP_BKPT); | 8098 | gen_exception(EXCP_BKPT); |
8008 | s->is_jmp = DISAS_JUMP; | 8099 | s->is_jmp = DISAS_JUMP; |
8009 | break; | 8100 | break; |
@@ -8090,9 +8181,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | @@ -8090,9 +8181,7 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | ||
8090 | if (cond == 0xf) { | 8181 | if (cond == 0xf) { |
8091 | /* swi */ | 8182 | /* swi */ |
8092 | gen_set_condexec(s); | 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 | s->is_jmp = DISAS_SWI; | 8185 | s->is_jmp = DISAS_SWI; |
8097 | break; | 8186 | break; |
8098 | } | 8187 | } |
@@ -8130,16 +8219,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | @@ -8130,16 +8219,14 @@ static void disas_thumb_insn(CPUState *env, DisasContext *s) | ||
8130 | return; | 8219 | return; |
8131 | undef32: | 8220 | undef32: |
8132 | gen_set_condexec(s); | 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 | gen_exception(EXCP_UDEF); | 8223 | gen_exception(EXCP_UDEF); |
8136 | s->is_jmp = DISAS_JUMP; | 8224 | s->is_jmp = DISAS_JUMP; |
8137 | return; | 8225 | return; |
8138 | illegal_op: | 8226 | illegal_op: |
8139 | undef: | 8227 | undef: |
8140 | gen_set_condexec(s); | 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 | gen_exception(EXCP_UDEF); | 8230 | gen_exception(EXCP_UDEF); |
8144 | s->is_jmp = DISAS_JUMP; | 8231 | s->is_jmp = DISAS_JUMP; |
8145 | } | 8232 | } |
@@ -8209,8 +8296,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -8209,8 +8296,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
8209 | for(j = 0; j < env->nb_breakpoints; j++) { | 8296 | for(j = 0; j < env->nb_breakpoints; j++) { |
8210 | if (env->breakpoints[j] == dc->pc) { | 8297 | if (env->breakpoints[j] == dc->pc) { |
8211 | gen_set_condexec(dc); | 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 | gen_exception(EXCP_DEBUG); | 8300 | gen_exception(EXCP_DEBUG); |
8215 | dc->is_jmp = DISAS_JUMP; | 8301 | dc->is_jmp = DISAS_JUMP; |
8216 | /* Advance PC so that clearing the breakpoint will | 8302 | /* Advance PC so that clearing the breakpoint will |
@@ -8283,8 +8369,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | @@ -8283,8 +8369,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, | ||
8283 | gen_set_label(dc->condlabel); | 8369 | gen_set_label(dc->condlabel); |
8284 | } | 8370 | } |
8285 | if (dc->condjmp || !dc->is_jmp) { | 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 | dc->condjmp = 0; | 8373 | dc->condjmp = 0; |
8289 | } | 8374 | } |
8290 | gen_set_condexec(dc); | 8375 | gen_set_condexec(dc); |
@@ -8404,6 +8489,7 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -8404,6 +8489,7 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
8404 | psr & CPSR_T ? 'T' : 'A', | 8489 | psr & CPSR_T ? 'T' : 'A', |
8405 | cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); | 8490 | cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26); |
8406 | 8491 | ||
8492 | +#if 0 | ||
8407 | for (i = 0; i < 16; i++) { | 8493 | for (i = 0; i < 16; i++) { |
8408 | d.d = env->vfp.regs[i]; | 8494 | d.d = env->vfp.regs[i]; |
8409 | s0.i = d.l.lower; | 8495 | s0.i = d.l.lower; |
@@ -8416,5 +8502,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -8416,5 +8502,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
8416 | d0.d); | 8502 | d0.d); |
8417 | } | 8503 | } |
8418 | cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); | 8504 | cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]); |
8505 | +#endif | ||
8419 | } | 8506 | } |
8420 | 8507 |