On Sun, Jan 20, 2013 at 7:27 PM, Richard Sandiford
<rdsandif...@googlemail.com> wrote:
> Add accumulator arguments to gen_HILO and gen_muldiv, rather than
> extracting the accumulator directly from ctx->opcode.  The extraction
> was only right for the standard encoding: MIPS16 doesn't have access
> to the DSP registers, while microMIPS encodes the accumulator register
> in a different field (bits 14 and 15).
>
> Passing the accumulator register is probably an over-generalisation
> for division and 64-bit multiplication, which never access anything
> other than HI and LO, and which always pass 0 as the new argument.
> Separating them felt a bit fussy though.
>
> Signed-off-by: Richard Sandiford <rdsandif...@googlemail.com>
> ---
>  target-mips/translate.c | 135 
> ++++++++++++++++++++----------------------------
>  1 file changed, 57 insertions(+), 78 deletions(-)
>
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 206ba83..47528d7 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -2571,10 +2571,9 @@ static void gen_shift (CPUMIPSState *env, DisasContext 
> *ctx, uint32_t opc,
>  }
>
>  /* Arithmetic on HI/LO registers */
> -static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
> +static void gen_HILO (DisasContext *ctx, uint32_t opc, int acc, int reg)

Please remove the extra space between function name and '('.

>  {
>      const char *opn = "hilo";
> -    unsigned int acc;
>
>      if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
>          /* Treat as NOP. */
> @@ -2582,12 +2581,6 @@ static void gen_HILO (DisasContext *ctx, uint32_t opc, 
> int reg)
>          return;
>      }
>
> -    if (opc == OPC_MFHI || opc == OPC_MFLO) {
> -        acc = ((ctx->opcode) >> 21) & 0x03;
> -    } else {
> -        acc = ((ctx->opcode) >> 11) & 0x03;
> -    }
> -
>      if (acc != 0) {
>          check_dsp(ctx);
>      }
> @@ -2651,11 +2644,10 @@ static void gen_HILO (DisasContext *ctx, uint32_t 
> opc, int reg)
>  }
>
>  static void gen_muldiv (DisasContext *ctx, uint32_t opc,
> -                        int rs, int rt)
> +                        int acc, int rs, int rt)
>  {
>      const char *opn = "mul/div";
>      TCGv t0, t1;
> -    unsigned int acc;
>
>      t0 = tcg_temp_new();
>      t1 = tcg_temp_new();
> @@ -2663,6 +2655,9 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>      gen_load_gpr(t0, rs);
>      gen_load_gpr(t1, rt);
>
> +    if (acc != 0)

Missing braces, please read CODING_STYLE and check the patches with
checkpatch.pl.


> +        check_dsp(ctx);
> +
>      switch (opc) {
>      case OPC_DIV:
>          {
> @@ -2677,10 +2672,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>              tcg_gen_or_tl(t2, t2, t3);
>              tcg_gen_movi_tl(t3, 0);
>              tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
> -            tcg_gen_div_tl(cpu_LO[0], t0, t1);
> -            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
> -            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
> -            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
> +            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
> +            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
> +            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
> +            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
>              tcg_temp_free(t3);
>              tcg_temp_free(t2);
>          }
> @@ -2693,10 +2688,10 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>              tcg_gen_ext32u_tl(t0, t0);
>              tcg_gen_ext32u_tl(t1, t1);
>              tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
> -            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
> -            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
> -            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
> -            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
> +            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
> +            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
> +            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
> +            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
>              tcg_temp_free(t3);
>              tcg_temp_free(t2);
>          }
> @@ -2706,10 +2701,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext_tl_i64(t2, t0);
>              tcg_gen_ext_tl_i64(t3, t1);
> @@ -2728,10 +2719,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext32u_tl(t0, t0);
>              tcg_gen_ext32u_tl(t1, t1);
> @@ -2760,8 +2747,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>              tcg_gen_or_tl(t2, t2, t3);
>              tcg_gen_movi_tl(t3, 0);
>              tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
> -            tcg_gen_div_tl(cpu_LO[0], t0, t1);
> -            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
> +            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
> +            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
>              tcg_temp_free(t3);
>              tcg_temp_free(t2);
>          }
> @@ -2772,8 +2759,8 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
>              TCGv t2 = tcg_const_tl(0);
>              TCGv t3 = tcg_const_tl(1);
>              tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
> -            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
> -            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
> +            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
> +            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
>              tcg_temp_free(t3);
>              tcg_temp_free(t2);
>          }
> @@ -2792,10 +2779,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext_tl_i64(t2, t0);
>              tcg_gen_ext_tl_i64(t3, t1);
> @@ -2816,10 +2799,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext32u_tl(t0, t0);
>              tcg_gen_ext32u_tl(t1, t1);
> @@ -2842,10 +2821,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext_tl_i64(t2, t0);
>              tcg_gen_ext_tl_i64(t3, t1);
> @@ -2866,10 +2841,6 @@ static void gen_muldiv (DisasContext *ctx, uint32_t 
> opc,
>          {
>              TCGv_i64 t2 = tcg_temp_new_i64();
>              TCGv_i64 t3 = tcg_temp_new_i64();
> -            acc = ((ctx->opcode) >> 11) & 0x03;
> -            if (acc != 0) {
> -                check_dsp(ctx);
> -            }
>
>              tcg_gen_ext32u_tl(t0, t0);
>              tcg_gen_ext32u_tl(t1, t1);
> @@ -10134,7 +10105,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx,
>              gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
>              break;
>          case RR_MFHI:
> -            gen_HILO(ctx, OPC_MFHI, rx);
> +            gen_HILO(ctx, OPC_MFHI, 0, rx);
>              break;
>          case RR_CNVT:
>              switch (cnvt_op) {
> @@ -10166,7 +10137,7 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx,
>              }
>              break;
>          case RR_MFLO:
> -            gen_HILO(ctx, OPC_MFLO, rx);
> +            gen_HILO(ctx, OPC_MFLO, 0, rx);
>              break;
>  #if defined (TARGET_MIPS64)
>          case RR_DSRA:
> @@ -10187,33 +10158,33 @@ static int decode_mips16_opc (CPUMIPSState *env, 
> DisasContext *ctx,
>              break;
>  #endif
>          case RR_MULT:
> -            gen_muldiv(ctx, OPC_MULT, rx, ry);
> +            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
>              break;
>          case RR_MULTU:
> -            gen_muldiv(ctx, OPC_MULTU, rx, ry);
> +            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
>              break;
>          case RR_DIV:
> -            gen_muldiv(ctx, OPC_DIV, rx, ry);
> +            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
>              break;
>          case RR_DIVU:
> -            gen_muldiv(ctx, OPC_DIVU, rx, ry);
> +            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
>              break;
>  #if defined (TARGET_MIPS64)
>          case RR_DMULT:
>              check_mips_64(ctx);
> -            gen_muldiv(ctx, OPC_DMULT, rx, ry);
> +            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
>              break;
>          case RR_DMULTU:
>              check_mips_64(ctx);
> -            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
> +            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
>              break;
>          case RR_DDIV:
>              check_mips_64(ctx);
> -            gen_muldiv(ctx, OPC_DDIV, rx, ry);
> +            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
>              break;
>          case RR_DDIVU:
>              check_mips_64(ctx);
> -            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
> +            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
>              break;
>  #endif
>          default:
> @@ -10922,11 +10893,11 @@ static void gen_pool16c_insn (CPUMIPSState *env, 
> DisasContext *ctx, int *is_bran
>          break;
>      case MFHI16 + 0:
>      case MFHI16 + 1:
> -        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
> +        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
>          break;
>      case MFLO16 + 0:
>      case MFLO16 + 1:
> -        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
> +        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
>          break;
>      case BREAK16:
>          generate_exception(ctx, EXCP_BREAK);
> @@ -11124,30 +11095,33 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs,
>              break;
>          case MULT:
>              mips32_op = OPC_MULT;
> -            goto do_muldiv;
> +            goto do_mul;
>          case MULTU:
>              mips32_op = OPC_MULTU;
> -            goto do_muldiv;
> +            goto do_mul;
>          case DIV:
>              mips32_op = OPC_DIV;
> -            goto do_muldiv;
> +            goto do_div;
>          case DIVU:
>              mips32_op = OPC_DIVU;
> -            goto do_muldiv;
> +        do_div:
> +            check_insn(env, ctx, ISA_MIPS32);
> +            gen_muldiv(ctx, mips32_op, 0, rs, rt);
> +            break;
>          case MADD:
>              mips32_op = OPC_MADD;
> -            goto do_muldiv;
> +            goto do_mul;
>          case MADDU:
>              mips32_op = OPC_MADDU;
> -            goto do_muldiv;
> +            goto do_mul;
>          case MSUB:
>              mips32_op = OPC_MSUB;
> -            goto do_muldiv;
> +            goto do_mul;
>          case MSUBU:
>              mips32_op = OPC_MSUBU;
> -        do_muldiv:
> +        do_mul:
>              check_insn(env, ctx, ISA_MIPS32);
> -            gen_muldiv(ctx, mips32_op, rs, rt);
> +            gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);
>              break;
>          default:
>              goto pool32axf_invalid;
> @@ -11284,18 +11258,18 @@ static void gen_pool32axf (CPUMIPSState *env, 
> DisasContext *ctx, int rt, int rs,
>          }
>          break;
>      case 0x35:
> -        switch (minor) {
> +        switch (minor & 3) {
>          case MFHI32:
> -            gen_HILO(ctx, OPC_MFHI, rs);
> +            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
>              break;
>          case MFLO32:
> -            gen_HILO(ctx, OPC_MFLO, rs);
> +            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
>              break;
>          case MTHI32:
> -            gen_HILO(ctx, OPC_MTHI, rs);
> +            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
>              break;
>          case MTLO32:
> -            gen_HILO(ctx, OPC_MTLO, rs);
> +            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
>              break;
>          default:
>              goto pool32axf_invalid;
> @@ -14429,13 +14403,18 @@ static void decode_opc (CPUMIPSState *env, 
> DisasContext *ctx, int *is_branch)
>          case OPC_XOR:
>              gen_logic(env, ctx, op1, rd, rs, rt);
>              break;
> -        case OPC_MULT ... OPC_DIVU:
> +        case OPC_MULT:
> +        case OPC_MULTU:
>              if (sa) {
>                  check_insn(env, ctx, INSN_VR54XX);
>                  op1 = MASK_MUL_VR54XX(ctx->opcode);
>                  gen_mul_vr54xx(ctx, op1, rd, rs, rt);
>              } else
> -                gen_muldiv(ctx, op1, rs, rt);
> +                gen_muldiv(ctx, op1, rd & 3, rs, rt);
> +            break;
> +        case OPC_DIV:
> +        case OPC_DIVU:
> +            gen_muldiv(ctx, op1, 0, rs, rt);
>              break;
>          case OPC_JR ... OPC_JALR:
>              gen_compute_branch(ctx, op1, 4, rs, rd, sa);
> @@ -14447,11 +14426,11 @@ static void decode_opc (CPUMIPSState *env, 
> DisasContext *ctx, int *is_branch)
>              break;
>          case OPC_MFHI:          /* Move from HI/LO */
>          case OPC_MFLO:
> -            gen_HILO(ctx, op1, rd);
> +            gen_HILO(ctx, op1, rs & 3, rd);
>              break;
>          case OPC_MTHI:
>          case OPC_MTLO:          /* Move to HI/LO */
> -            gen_HILO(ctx, op1, rs);
> +            gen_HILO(ctx, op1, rd & 3, rs);
>              break;
>          case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
>  #ifdef MIPS_STRICT_STANDARD
> @@ -14571,7 +14550,7 @@ static void decode_opc (CPUMIPSState *env, 
> DisasContext *ctx, int *is_branch)
>          case OPC_DMULT ... OPC_DDIVU:
>              check_insn(env, ctx, ISA_MIPS3);
>              check_mips_64(ctx);
> -            gen_muldiv(ctx, op1, rs, rt);
> +            gen_muldiv(ctx, op1, 0, rs, rt);
>              break;
>  #endif
>          default:            /* Invalid */
> @@ -14586,7 +14565,7 @@ static void decode_opc (CPUMIPSState *env, 
> DisasContext *ctx, int *is_branch)
>          case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
>          case OPC_MSUB ... OPC_MSUBU:
>              check_insn(env, ctx, ISA_MIPS32);
> -            gen_muldiv(ctx, op1, rs, rt);
> +            gen_muldiv(ctx, op1, rd & 3, rs, rt);
>              break;
>          case OPC_MUL:
>              gen_arith(env, ctx, op1, rd, rs, rt);
> --
> 1.7.11.7
>
>

Reply via email to