diff --git a/target-arm/translate.c b/target-arm/translate.c index 788c4f2bc5..baca14f245 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -181,19 +181,9 @@ static void store_reg(DisasContext *s, int reg, TCGv var) /* Basic operations. */ -#define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1]) -#define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im) #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im) #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im) -#define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1]) - -#define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]) -#define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1]) -#define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1]) - -#define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im) -#define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im) /* Value extensions. */ #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var) @@ -440,11 +430,6 @@ static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1) tcg_gen_and_i32(dest, t0, tmp); dead_tmp(tmp); } -static inline void gen_op_bicl_T0_T1(void) -{ - gen_op_notl_T1(); - gen_op_andl_T0_T1(); -} /* FIXME: Implement this natively. */ #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1) @@ -838,11 +823,6 @@ static inline void gen_st32(TCGv val, TCGv addr, int index) dead_tmp(val); } -static inline void gen_movl_T0_reg(DisasContext *s, int reg) -{ - load_reg_var(s, cpu_T[0], reg); -} - static inline void gen_movl_T1_reg(DisasContext *s, int reg) { load_reg_var(s, cpu_T[1], reg); @@ -869,11 +849,6 @@ static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t) } } -static inline void gen_movl_reg_T0(DisasContext *s, int reg) -{ - gen_movl_reg_TN(s, reg, 0); -} - static inline void gen_movl_reg_T1(DisasContext *s, int reg) { gen_movl_reg_TN(s, reg, 1); @@ -1176,19 +1151,16 @@ static inline void iwmmxt_store_reg(TCGv_i64 var, int reg) tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg])); } -static inline void gen_op_iwmmxt_movl_wCx_T0(int reg) +static inline TCGv iwmmxt_load_creg(int reg) { - tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); + TCGv var = new_tmp(); + tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); + return var; } -static inline void gen_op_iwmmxt_movl_T0_wCx(int reg) +static inline void iwmmxt_store_creg(int reg, TCGv var) { - tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); -} - -static inline void gen_op_iwmmxt_movl_T1_wCx(int reg) -{ - tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); + tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, iwmmxt.cregs[reg])); } static inline void gen_op_iwmmxt_movq_wRn_M0(int rn) @@ -1301,40 +1273,6 @@ IWMMXT_OP_ENV(packsw) IWMMXT_OP_ENV(packsl) IWMMXT_OP_ENV(packsq) -static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V1, rn); - gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]); -} - -static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift) -{ - TCGv tmp = tcg_const_i32(shift); - gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp); -} - -static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift) -{ - tcg_gen_shri_i64(cpu_M0, cpu_M0, shift); - tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0); - tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]); -} - -static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift) -{ - tcg_gen_shri_i64(cpu_M0, cpu_M0, shift); - tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0); - tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]); -} - -static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask) -{ - tcg_gen_shri_i64(cpu_M0, cpu_M0, shift); - tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0); - if (mask != ~0u) - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask); -} - static void gen_op_iwmmxt_set_mup(void) { TCGv tmp; @@ -1365,65 +1303,59 @@ static inline void gen_op_iwmmxt_addl_M0_wRn(int rn) tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); } -static void gen_iwmmxt_movl_T0_T1_wRn(int rn) -{ - iwmmxt_load_reg(cpu_V0, rn); - tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0); - tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); - tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0); -} - -static void gen_iwmmxt_movl_wRn_T0_T1(int rn) -{ - tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]); - iwmmxt_store_reg(cpu_V0, rn); -} - -static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn) +static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest) { int rd; uint32_t offset; + TCGv tmp; rd = (insn >> 16) & 0xf; - gen_movl_T1_reg(s, rd); + tmp = load_reg(s, rd); offset = (insn & 0xff) << ((insn >> 7) & 2); if (insn & (1 << 24)) { /* Pre indexed */ if (insn & (1 << 23)) - gen_op_addl_T1_im(offset); + tcg_gen_addi_i32(tmp, tmp, offset); else - gen_op_addl_T1_im(-offset); - + tcg_gen_addi_i32(tmp, tmp, -offset); + tcg_gen_mov_i32(dest, tmp); if (insn & (1 << 21)) - gen_movl_reg_T1(s, rd); + store_reg(s, rd, tmp); + else + dead_tmp(tmp); } else if (insn & (1 << 21)) { /* Post indexed */ + tcg_gen_mov_i32(dest, tmp); if (insn & (1 << 23)) - gen_op_movl_T0_im(offset); + tcg_gen_addi_i32(tmp, tmp, offset); else - gen_op_movl_T0_im(- offset); - gen_op_addl_T0_T1(); - gen_movl_reg_T0(s, rd); + tcg_gen_addi_i32(tmp, tmp, -offset); + store_reg(s, rd, tmp); } else if (!(insn & (1 << 23))) return 1; return 0; } -static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask) +static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest) { int rd = (insn >> 0) & 0xf; + TCGv tmp; - if (insn & (1 << 8)) - if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) + if (insn & (1 << 8)) { + if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) { return 1; - else - gen_op_iwmmxt_movl_T0_wCx(rd); - else - gen_iwmmxt_movl_T0_T1_wRn(rd); - - gen_op_movl_T1_im(mask); - gen_op_andl_T0_T1(); + } else { + tmp = iwmmxt_load_creg(rd); + } + } else { + tmp = new_tmp(); + iwmmxt_load_reg(cpu_V0, rd); + tcg_gen_trunc_i64_i32(tmp, cpu_V0); + } + tcg_gen_andi_i32(tmp, tmp, mask); + tcg_gen_mov_i32(dest, tmp); + dead_tmp(tmp); return 0; } @@ -1433,7 +1365,8 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) { int rd, wrd; int rdhi, rdlo, rd0, rd1, i; - TCGv tmp; + TCGv addr; + TCGv tmp, tmp2, tmp3; if ((insn & 0x0e000e00) == 0x0c000000) { if ((insn & 0x0fe00ff0) == 0x0c400000) { @@ -1441,41 +1374,43 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) rdlo = (insn >> 12) & 0xf; rdhi = (insn >> 16) & 0xf; if (insn & ARM_CP_RW_BIT) { /* TMRRC */ - gen_iwmmxt_movl_T0_T1_wRn(wrd); - gen_movl_reg_T0(s, rdlo); - gen_movl_reg_T1(s, rdhi); + iwmmxt_load_reg(cpu_V0, wrd); + tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0); + tcg_gen_shri_i64(cpu_V0, cpu_V0, 32); + tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0); } else { /* TMCRR */ - gen_movl_T0_reg(s, rdlo); - gen_movl_T1_reg(s, rdhi); - gen_iwmmxt_movl_wRn_T0_T1(wrd); + tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]); + iwmmxt_store_reg(cpu_V0, wrd); gen_op_iwmmxt_set_mup(); } return 0; } wrd = (insn >> 12) & 0xf; - if (gen_iwmmxt_address(s, insn)) + addr = new_tmp(); + if (gen_iwmmxt_address(s, insn, addr)) { + dead_tmp(addr); return 1; + } if (insn & ARM_CP_RW_BIT) { if ((insn >> 28) == 0xf) { /* WLDRW wCx */ - tmp = gen_ld32(cpu_T[1], IS_USER(s)); - tcg_gen_mov_i32(cpu_T[0], tmp); - dead_tmp(tmp); - gen_op_iwmmxt_movl_wCx_T0(wrd); + tmp = new_tmp(); + tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); + iwmmxt_store_creg(wrd, tmp); } else { i = 1; if (insn & (1 << 8)) { if (insn & (1 << 22)) { /* WLDRD */ - tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s)); + tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s)); i = 0; } else { /* WLDRW wRd */ - tmp = gen_ld32(cpu_T[1], IS_USER(s)); + tmp = gen_ld32(addr, IS_USER(s)); } } else { if (insn & (1 << 22)) { /* WLDRH */ - tmp = gen_ld16u(cpu_T[1], IS_USER(s)); + tmp = gen_ld16u(addr, IS_USER(s)); } else { /* WLDRB */ - tmp = gen_ld8u(cpu_T[1], IS_USER(s)); + tmp = gen_ld8u(addr, IS_USER(s)); } } if (i) { @@ -1486,28 +1421,26 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) } } else { if ((insn >> 28) == 0xf) { /* WSTRW wCx */ - gen_op_iwmmxt_movl_T0_wCx(wrd); - tmp = new_tmp(); - tcg_gen_mov_i32(tmp, cpu_T[0]); - gen_st32(tmp, cpu_T[1], IS_USER(s)); + tmp = iwmmxt_load_creg(wrd); + gen_st32(tmp, addr, IS_USER(s)); } else { gen_op_iwmmxt_movq_M0_wRn(wrd); tmp = new_tmp(); if (insn & (1 << 8)) { if (insn & (1 << 22)) { /* WSTRD */ dead_tmp(tmp); - tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s)); + tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s)); } else { /* WSTRW wRd */ tcg_gen_trunc_i64_i32(tmp, cpu_M0); - gen_st32(tmp, cpu_T[1], IS_USER(s)); + gen_st32(tmp, addr, IS_USER(s)); } } else { if (insn & (1 << 22)) { /* WSTRH */ tcg_gen_trunc_i64_i32(tmp, cpu_M0); - gen_st16(tmp, cpu_T[1], IS_USER(s)); + gen_st16(tmp, addr, IS_USER(s)); } else { /* WSTRB */ tcg_gen_trunc_i64_i32(tmp, cpu_M0); - gen_st8(tmp, cpu_T[1], IS_USER(s)); + gen_st8(tmp, addr, IS_USER(s)); } } } @@ -1543,18 +1476,19 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_op_iwmmxt_set_cup(); /* Fall through. */ case ARM_IWMMXT_wCSSF: - gen_op_iwmmxt_movl_T0_wCx(wrd); - gen_movl_T1_reg(s, rd); - gen_op_bicl_T0_T1(); - gen_op_iwmmxt_movl_wCx_T0(wrd); + tmp = iwmmxt_load_creg(wrd); + tmp2 = load_reg(s, rd); + tcg_gen_bic_i32(tmp, tmp, tmp2); + dead_tmp(tmp2); + iwmmxt_store_creg(wrd, tmp); break; case ARM_IWMMXT_wCGR0: case ARM_IWMMXT_wCGR1: case ARM_IWMMXT_wCGR2: case ARM_IWMMXT_wCGR3: gen_op_iwmmxt_set_cup(); - gen_movl_reg_T0(s, rd); - gen_op_iwmmxt_movl_wCx_T0(wrd); + tmp = load_reg(s, rd); + iwmmxt_store_creg(wrd, tmp); break; default: return 1; @@ -1576,8 +1510,8 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) return 1; rd = (insn >> 12) & 0xf; wrd = (insn >> 16) & 0xf; - gen_op_iwmmxt_movl_T0_wCx(wrd); - gen_movl_reg_T0(s, rd); + tmp = iwmmxt_load_creg(wrd); + store_reg(s, rd, tmp); break; case 0x300: /* WANDN */ wrd = (insn >> 12) & 0xf; @@ -1754,132 +1688,145 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) rd0 = (insn >> 16) & 0xf; rd1 = (insn >> 0) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3)); - gen_op_movl_T1_im(7); - gen_op_andl_T0_T1(); - gen_op_iwmmxt_align_M0_T0_wRn(rd1); + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3)); + tcg_gen_andi_i32(tmp, tmp, 7); + iwmmxt_load_reg(cpu_V1, rd1); + gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */ + if (((insn >> 6) & 3) == 3) + return 1; rd = (insn >> 12) & 0xf; wrd = (insn >> 16) & 0xf; - gen_movl_T0_reg(s, rd); + tmp = load_reg(s, rd); gen_op_iwmmxt_movq_M0_wRn(wrd); switch ((insn >> 6) & 3) { case 0: - gen_op_movl_T1_im(0xff); - gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3); + tmp2 = tcg_const_i32(0xff); + tmp3 = tcg_const_i32((insn & 7) << 3); break; case 1: - gen_op_movl_T1_im(0xffff); - gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4); + tmp2 = tcg_const_i32(0xffff); + tmp3 = tcg_const_i32((insn & 3) << 4); break; case 2: - gen_op_movl_T1_im(0xffffffff); - gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5); + tmp2 = tcg_const_i32(0xffffffff); + tmp3 = tcg_const_i32((insn & 1) << 5); break; - case 3: - return 1; + default: + TCGV_UNUSED(tmp2); + TCGV_UNUSED(tmp3); } + gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3); + tcg_temp_free(tmp3); + tcg_temp_free(tmp2); + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */ rd = (insn >> 12) & 0xf; wrd = (insn >> 16) & 0xf; - if (rd == 15) + if (rd == 15 || ((insn >> 22) & 3) == 3) return 1; gen_op_iwmmxt_movq_M0_wRn(wrd); + tmp = new_tmp(); switch ((insn >> 22) & 3) { case 0: - if (insn & 8) - gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3); - else { - gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff); + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3); + tcg_gen_trunc_i64_i32(tmp, cpu_M0); + if (insn & 8) { + tcg_gen_ext8s_i32(tmp, tmp); + } else { + tcg_gen_andi_i32(tmp, tmp, 0xff); } break; case 1: - if (insn & 8) - gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4); - else { - gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff); + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4); + tcg_gen_trunc_i64_i32(tmp, cpu_M0); + if (insn & 8) { + tcg_gen_ext16s_i32(tmp, tmp); + } else { + tcg_gen_andi_i32(tmp, tmp, 0xffff); } break; case 2: - gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u); + tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5); + tcg_gen_trunc_i64_i32(tmp, cpu_M0); break; - case 3: - return 1; } - gen_movl_reg_T0(s, rd); + store_reg(s, rd, tmp); break; case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */ - if ((insn & 0x000ff008) != 0x0003f000) + if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3) return 1; - gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF); + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); switch ((insn >> 22) & 3) { case 0: - gen_op_shrl_T1_im(((insn & 7) << 2) + 0); + tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0); break; case 1: - gen_op_shrl_T1_im(((insn & 3) << 3) + 4); + tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4); break; case 2: - gen_op_shrl_T1_im(((insn & 1) << 4) + 12); + tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12); break; - case 3: - return 1; } - gen_op_shll_T1_im(28); - gen_set_nzcv(cpu_T[1]); + tcg_gen_shli_i32(tmp, tmp, 28); + gen_set_nzcv(tmp); + dead_tmp(tmp); break; case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */ + if (((insn >> 6) & 3) == 3) + return 1; rd = (insn >> 12) & 0xf; wrd = (insn >> 16) & 0xf; - gen_movl_T0_reg(s, rd); + tmp = load_reg(s, rd); switch ((insn >> 6) & 3) { case 0: - gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_bcstb(cpu_M0, tmp); break; case 1: - gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_bcstw(cpu_M0, tmp); break; case 2: - gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_bcstl(cpu_M0, tmp); break; - case 3: - return 1; } + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */ - if ((insn & 0x000ff00f) != 0x0003f000) + if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) return 1; - gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF); - gen_op_movl_T0_T1(); + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); + tmp2 = new_tmp(); + tcg_gen_mov_i32(tmp2, tmp); switch ((insn >> 22) & 3) { case 0: for (i = 0; i < 7; i ++) { - gen_op_shll_T1_im(4); - gen_op_andl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 4); + tcg_gen_and_i32(tmp, tmp, tmp2); } break; case 1: for (i = 0; i < 3; i ++) { - gen_op_shll_T1_im(8); - gen_op_andl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 8); + tcg_gen_and_i32(tmp, tmp, tmp2); } break; case 2: - gen_op_shll_T1_im(16); - gen_op_andl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_and_i32(tmp, tmp, tmp2); break; - case 3: - return 1; } - gen_set_nzcv(cpu_T[0]); + gen_set_nzcv(tmp); + dead_tmp(tmp2); + dead_tmp(tmp); break; case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */ wrd = (insn >> 12) & 0xf; @@ -1902,52 +1849,52 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) gen_op_iwmmxt_set_mup(); break; case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */ - if ((insn & 0x000ff00f) != 0x0003f000) + if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3) return 1; - gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF); - gen_op_movl_T0_T1(); + tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF); + tmp2 = new_tmp(); + tcg_gen_mov_i32(tmp2, tmp); switch ((insn >> 22) & 3) { case 0: for (i = 0; i < 7; i ++) { - gen_op_shll_T1_im(4); - gen_op_orl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 4); + tcg_gen_or_i32(tmp, tmp, tmp2); } break; case 1: for (i = 0; i < 3; i ++) { - gen_op_shll_T1_im(8); - gen_op_orl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 8); + tcg_gen_or_i32(tmp, tmp, tmp2); } break; case 2: - gen_op_shll_T1_im(16); - gen_op_orl_T0_T1(); + tcg_gen_shli_i32(tmp2, tmp2, 16); + tcg_gen_or_i32(tmp, tmp, tmp2); break; - case 3: - return 1; } - gen_set_nzcv(cpu_T[0]); + gen_set_nzcv(tmp); + dead_tmp(tmp2); + dead_tmp(tmp); break; case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */ rd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; - if ((insn & 0xf) != 0) + if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3) return 1; gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = new_tmp(); switch ((insn >> 22) & 3) { case 0: - gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0); + gen_helper_iwmmxt_msbb(tmp, cpu_M0); break; case 1: - gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0); + gen_helper_iwmmxt_msbw(tmp, cpu_M0); break; case 2: - gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0); + gen_helper_iwmmxt_msbl(tmp, cpu_M0); break; - case 3: - return 1; } - gen_movl_reg_T0(s, rd); + store_reg(s, rd, tmp); break; case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */ case 0x906: case 0xb06: case 0xd06: case 0xf06: @@ -2045,100 +1992,120 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) break; case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */ case 0x214: case 0x614: case 0xa14: case 0xe14: + if (((insn >> 22) & 3) == 0) + return 1; wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - if (gen_iwmmxt_shift(insn, 0xff)) + tmp = new_tmp(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + dead_tmp(tmp); return 1; + } switch ((insn >> 22) & 3) { - case 0: - return 1; case 1: - gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp); break; case 2: - gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp); break; case 3: - gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp); break; } + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); break; case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */ case 0x014: case 0x414: case 0x814: case 0xc14: + if (((insn >> 22) & 3) == 0) + return 1; wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - if (gen_iwmmxt_shift(insn, 0xff)) + tmp = new_tmp(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + dead_tmp(tmp); return 1; + } switch ((insn >> 22) & 3) { - case 0: - return 1; case 1: - gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp); break; case 2: - gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp); break; case 3: - gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp); break; } + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); break; case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */ case 0x114: case 0x514: case 0x914: case 0xd14: + if (((insn >> 22) & 3) == 0) + return 1; wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - if (gen_iwmmxt_shift(insn, 0xff)) + tmp = new_tmp(); + if (gen_iwmmxt_shift(insn, 0xff, tmp)) { + dead_tmp(tmp); return 1; + } switch ((insn >> 22) & 3) { - case 0: - return 1; case 1: - gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp); break; case 2: - gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp); break; case 3: - gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp); break; } + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); break; case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */ case 0x314: case 0x714: case 0xb14: case 0xf14: + if (((insn >> 22) & 3) == 0) + return 1; wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); + tmp = new_tmp(); switch ((insn >> 22) & 3) { - case 0: - return 1; case 1: - if (gen_iwmmxt_shift(insn, 0xf)) + if (gen_iwmmxt_shift(insn, 0xf, tmp)) { + dead_tmp(tmp); return 1; - gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + } + gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp); break; case 2: - if (gen_iwmmxt_shift(insn, 0x1f)) + if (gen_iwmmxt_shift(insn, 0x1f, tmp)) { + dead_tmp(tmp); return 1; - gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + } + gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp); break; case 3: - if (gen_iwmmxt_shift(insn, 0x3f)) + if (gen_iwmmxt_shift(insn, 0x3f, tmp)) { + dead_tmp(tmp); return 1; - gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + } + gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp); break; } + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2211,8 +2178,10 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) rd0 = (insn >> 16) & 0xf; rd1 = (insn >> 0) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_movl_T0_im((insn >> 20) & 3); - gen_op_iwmmxt_align_M0_T0_wRn(rd1); + tmp = tcg_const_i32((insn >> 20) & 3); + iwmmxt_load_reg(cpu_V1, rd1); + gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp); + tcg_temp_free(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break; @@ -2266,8 +2235,9 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f)); - gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]); + tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f)); + gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp); + tcg_temp_free(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); gen_op_iwmmxt_set_cup(); @@ -2319,15 +2289,13 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) case 0x408: case 0x508: case 0x608: case 0x708: case 0x808: case 0x908: case 0xa08: case 0xb08: case 0xc08: case 0xd08: case 0xe08: case 0xf08: + if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0) + return 1; wrd = (insn >> 12) & 0xf; rd0 = (insn >> 16) & 0xf; rd1 = (insn >> 0) & 0xf; gen_op_iwmmxt_movq_M0_wRn(rd0); - if (!(insn & (1 << 20))) - return 1; switch ((insn >> 22) & 3) { - case 0: - return 1; case 1: if (insn & (1 << 21)) gen_op_iwmmxt_packsw_M0_wRn(rd1); @@ -2361,30 +2329,29 @@ static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn) if (rd0 == 0xf || rd1 == 0xf) return 1; gen_op_iwmmxt_movq_M0_wRn(wrd); + tmp = load_reg(s, rd0); + tmp2 = load_reg(s, rd1); switch ((insn >> 16) & 0xf) { case 0x0: /* TMIA */ - gen_movl_T0_reg(s, rd0); - gen_movl_T1_reg(s, rd1); - gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]); + gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2); break; case 0x8: /* TMIAPH */ - gen_movl_T0_reg(s, rd0); - gen_movl_T1_reg(s, rd1); - gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]); + gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2); break; case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */ - gen_movl_T1_reg(s, rd0); if (insn & (1 << 16)) - gen_op_shrl_T1_im(16); - gen_op_movl_T0_T1(); - gen_movl_T1_reg(s, rd1); + tcg_gen_shri_i32(tmp, tmp, 16); if (insn & (1 << 17)) - gen_op_shrl_T1_im(16); - gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]); + tcg_gen_shri_i32(tmp2, tmp2, 16); + gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2); break; default: + dead_tmp(tmp2); + dead_tmp(tmp); return 1; } + dead_tmp(tmp2); + dead_tmp(tmp); gen_op_iwmmxt_movq_wRn_M0(wrd); gen_op_iwmmxt_set_mup(); break;