diff mbox

[11/13] target-mips: microMIPS32 R6 Major instructions

Message ID 1434117743-53520-12-git-send-email-yongbok.kim@imgtec.com
State New
Headers show

Commit Message

Yongbok Kim June 12, 2015, 2:02 p.m. UTC
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(-)

Comments

Leon Alrae June 16, 2015, 1:07 p.m. UTC | #1
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 mbox

Patch

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;