Message ID | 1434117743-53520-12-git-send-email-yongbok.kim@imgtec.com |
---|---|
State | New |
Headers | show |
On 12/06/2015 15:02, Yongbok Kim wrote: > add new microMIPS32 Release 6 Major opcode instructions > > Signed-off-by: Yongbok Kim <yongbok.kim@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
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); + } + } 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; + } + } else { int reg = mmreg(ZIMM(ctx->opcode, 23, 3)); int offset = SIMM(ctx->opcode, 0, 23) << 2;
add new microMIPS32 Release 6 Major opcode instructions Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com> --- target-mips/translate.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 55 insertions(+), 3 deletions(-)