On 12/06/2015 15:02, Yongbok Kim wrote:
> add new microMIPS32 Release 6 Major opcode instructions
> 
> Signed-off-by: Yongbok Kim <yongbok....@imgtec.com>
> ---
>  target-mips/translate.c |   58 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 55 insertions(+), 3 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index 5be2a9c..3ac9632 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -14596,8 +14596,21 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>          }
>          break;
>      case ADDI32:
> -        mips32_op = OPC_ADDI;
> -        goto do_addi;
> +        /* AUI, LUI */
> +        if (ctx->insn_flags & ISA_MIPS32R6) {
> +            if (rs != 0) {
> +                /* AUI */
> +                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
> +                tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
> +            } else {
> +                /* LUI */
> +                tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
> +            }

Can't we just call gen_logic_imm(ctx, OPC_LUI, rt, rs, imm) here to avoid
duplication?

> +        } else {
> +            mips32_op = OPC_ADDI;
> +            goto do_addi;
> +        }
> +        break;
>      case ADDIU32:
>          mips32_op = OPC_ADDIU;
>      do_addi:
> @@ -14719,7 +14732,46 @@ static void decode_micromips32_opc (CPUMIPSState 
> *env, DisasContext *ctx,
>          gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
>          break;
>      case ADDIUPC:
> -        {
> +        /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
> +        if (ctx->insn_flags & ISA_MIPS32R6) {
> +            int reg = ZIMM(ctx->opcode, 21, 5);
> +            target_long offset;
> +            target_long addr;
> +            switch ((ctx->opcode >> 16) & 0x1f) {
> +            case ADDIUPC_00 ... ADDIUPC_07:
> +                if (reg != 0) {
> +                    offset = sextract32(ctx->opcode << 2, 0, 21);
> +                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case AUIPC:
> +                if (reg != 0) {
> +                    offset = imm << 16;
> +                    addr = addr_add(ctx, ctx->pc, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case ALUIPC:
> +                if (reg != 0) {
> +                    offset = imm << 16;
> +                    addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
> +                    tcg_gen_movi_tl(cpu_gpr[reg], addr);
> +                }
> +                break;
> +            case LWPC_08 ... LWPC_0F:
> +                if (reg != 0) {
> +                    target_long addr;
> +                    offset = sextract32(ctx->opcode << 2, 0, 21);
> +                    addr = addr_add(ctx, ctx->pc & ~0x3, offset);
> +                    gen_r6_ld(addr, reg, ctx->mem_idx, MO_TESL);
> +                }
> +                break;
> +            default:
> +                generate_exception(ctx, EXCP_RI);
> +                break;
> +            }

This looks very similar to equivalent MIPS R6 instructions. With relatively
small changes in gen_pcrel() we could reuse it for these instructions I think.

Leon


Reply via email to