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 |