All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support
@ 2018-08-27 14:38 Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I Craig Janeczek
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

This patch set begins to add MXU instruction support for mips
emulation.

Craig Janeczek (6):
  target/mips: Add MXU instructions S32I2M and S32M2I
  target/mips: Add MXU instruction S8LDD
  target/mips: Add MXU instruction D16MUL
  target/mips: Add MXU instruction D16MAC
  target/mips: Add MXU instructions Q8MUL and Q8MULSU
  target/mips: Add MXU instructions S32LDD and S32LDDR

 target/mips/cpu.h       |   1 +
 target/mips/translate.c | 345 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 342 insertions(+), 4 deletions(-)

-- 
2.18.0

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  2018-08-27 18:13   ` Aleksandar Markovic
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 2/6] target/mips: Add MXU instruction S8LDD Craig Janeczek
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

This commit makes the MXU registers and the utility functions for
reading/writing to them. This is required for full MXU instruction
support.

Adds support for emulating the S32I2M and S32M2I MXU instructions.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - Fix checkpatch.pl errors
    - remove mips64 ifdef
    - changed bitfield usage to extract32
    - squashed register addition patch into this one

 target/mips/cpu.h       |  1 +
 target/mips/translate.c | 71 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 009202cf64..4b2948a2c8 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -170,6 +170,7 @@ struct TCState {
         MSACSR_FS_MASK)
 
     float_status msa_fp_status;
+    target_ulong mxu_gpr[16];
 };
 
 typedef struct CPUMIPSState CPUMIPSState;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index bdd880bb77..ef819d67e0 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -364,6 +364,9 @@ enum {
     OPC_CLO      = 0x21 | OPC_SPECIAL2,
     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
+    /* MXU */
+    OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
+    OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
     /* Special */
     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 };
@@ -1398,6 +1401,9 @@ static TCGv_i32 fpu_fcr0, fpu_fcr31;
 static TCGv_i64 fpu_f64[32];
 static TCGv_i64 msa_wr_d[64];
 
+/* MXU registers */
+static TCGv mxu_gpr[16];
+
 #include "exec/gen-icount.h"
 
 #define gen_helper_0e0i(name, arg) do {                           \
@@ -1517,6 +1523,13 @@ static const char * const msaregnames[] = {
     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
 };
 
+static const char * const mxuregnames[] = {
+    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",
+    "XR6",  "XR7",  "XR8",  "XR9",  "XR10",
+    "XR11", "XR12", "XR13", "XR14", "XR15",
+    "XR16",
+};
+
 #define LOG_DISAS(...)                                                        \
     do {                                                                      \
         if (MIPS_DEBUG_DISAS) {                                               \
@@ -1550,6 +1563,23 @@ static inline void gen_store_gpr (TCGv t, int reg)
         tcg_gen_mov_tl(cpu_gpr[reg], t);
 }
 
+/* MXU General purpose registers moves. */
+static inline void gen_load_mxu_gpr(TCGv t, int reg)
+{
+    if (reg == 0) {
+        tcg_gen_movi_tl(t, 0);
+    } else {
+        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
+    }
+}
+
+static inline void gen_store_mxu_gpr(TCGv t, int reg)
+{
+    if (reg != 0) {
+        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
+    }
+}
+
 /* Moves to/from shadow registers. */
 static inline void gen_load_srsgpr (int from, int to)
 {
@@ -3738,6 +3768,35 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
     }
 }
 
+/* MXU Instructions */
+static void gen_mxu(DisasContext *ctx, uint32_t opc)
+{
+    TCGv t0;
+    uint32_t xra, rb;
+
+    t0 = tcg_temp_new();
+
+    switch (opc) {
+    case OPC_MXU_S32I2M:
+        xra = extract32(ctx->opcode, 6, 5);
+        rb = extract32(ctx->opcode, 16, 5);
+
+        gen_load_gpr(t0, rb);
+        gen_store_mxu_gpr(t0, xra);
+        break;
+
+    case OPC_MXU_S32M2I:
+        xra = extract32(ctx->opcode, 6, 5);
+        rb = extract32(ctx->opcode, 16, 5);
+
+        gen_load_mxu_gpr(t0, xra);
+        gen_store_gpr(t0, rb);
+        break;
+    }
+
+    tcg_temp_free(t0);
+}
+
 /* Godson integer instructions */
 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
                                  int rd, int rs, int rt)
@@ -17818,6 +17877,12 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
         check_insn(ctx, INSN_LOONGSON2F);
         gen_loongson_integer(ctx, op1, rd, rs, rt);
         break;
+
+    case OPC_MXU_S32I2M:
+    case OPC_MXU_S32M2I:
+        gen_mxu(ctx, op1);
+        break;
+
     case OPC_CLO:
     case OPC_CLZ:
         check_insn(ctx, ISA_MIPS32);
@@ -20742,6 +20807,12 @@ void mips_tcg_init(void)
     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
                                        offsetof(CPUMIPSState, active_fpu.fcr31),
                                        "fcr31");
+
+    for (i = 0; i < 16; i++)
+        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
+                                        offsetof(CPUMIPSState,
+                                                 active_tc.mxu_gpr[i]),
+                                        mxuregnames[i]);
 }
 
 #include "translate_init.inc.c"
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 2/6] target/mips: Add MXU instruction S8LDD
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 3/6] target/mips: Add MXU instruction D16MUL Craig Janeczek
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

Adds support for emulating the S8LDD MXU instruction.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - changed bitfield usage to extract32
    - used deposit_tl instructions instead of shift and bitmask

 target/mips/translate.c | 62 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index ef819d67e0..f5725d8eda 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -365,6 +365,7 @@ enum {
     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
     /* MXU */
+    OPC_MXU_S8LDD  = 0x22 | OPC_SPECIAL2,
     OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
     OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
     /* Special */
@@ -3771,10 +3772,11 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 /* MXU Instructions */
 static void gen_mxu(DisasContext *ctx, uint32_t opc)
 {
-    TCGv t0;
-    uint32_t xra, rb;
+    TCGv t0, t1;
+    uint32_t xra, rb, s8, optn3;
 
     t0 = tcg_temp_new();
+    t1 = tcg_temp_new();
 
     switch (opc) {
     case OPC_MXU_S32I2M:
@@ -3792,9 +3794,64 @@ static void gen_mxu(DisasContext *ctx, uint32_t opc)
         gen_load_mxu_gpr(t0, xra);
         gen_store_gpr(t0, rb);
         break;
+
+    case OPC_MXU_S8LDD:
+        xra = extract32(ctx->opcode, 6, 4);
+        s8 = extract32(ctx->opcode, 10, 8);
+        optn3 = extract32(ctx->opcode, 18, 3);
+        rb = extract32(ctx->opcode, 21, 5);
+
+        gen_load_gpr(t0, rb);
+        tcg_gen_addi_tl(t0, t0, (int8_t)s8);
+        switch (optn3) {
+        case 0: /*XRa[7:0] = tmp8 */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            gen_load_mxu_gpr(t0, xra);
+            tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
+            break;
+        case 1: /* XRa[15:8] = tmp8 */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            gen_load_mxu_gpr(t0, xra);
+            tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
+            break;
+        case 2: /* XRa[23:16] = tmp8 */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            gen_load_mxu_gpr(t0, xra);
+            tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
+            break;
+        case 3: /* XRa[31:24] = tmp8 */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            gen_load_mxu_gpr(t0, xra);
+            tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
+            break;
+        case 4: /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+            break;
+        case 5: /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            tcg_gen_shli_tl(t1, t1, 8);
+            tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+            break;
+        case 6: /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
+            tcg_gen_mov_tl(t0, t1);
+            tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
+            tcg_gen_shli_tl(t1, t1, 16);
+            tcg_gen_or_tl(t0, t0, t1);
+            break;
+        case 7: /* XRa = {tmp8, tmp8, tmp8, tmp8} */
+            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+            tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
+            tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
+            break;
+        }
+        gen_store_mxu_gpr(t0, xra);
+        break;
     }
 
     tcg_temp_free(t0);
+    tcg_temp_free(t1);
 }
 
 /* Godson integer instructions */
@@ -17880,6 +17937,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
 
     case OPC_MXU_S32I2M:
     case OPC_MXU_S32M2I:
+    case OPC_MXU_S8LDD:
         gen_mxu(ctx, op1);
         break;
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 3/6] target/mips: Add MXU instruction D16MUL
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 2/6] target/mips: Add MXU instruction S8LDD Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 4/6] target/mips: Add MXU instruction D16MAC Craig Janeczek
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

Adds support for emulating the D16MUL instruction.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - changed bitfield usage to extract32
    - used sextract_tl instructions instead of shift and ext

 target/mips/translate.c | 51 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index f5725d8eda..8a6b4f2899 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -365,6 +365,7 @@ enum {
     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
     /* MXU */
+    OPC_MXU_D16MUL = 0x08 | OPC_SPECIAL2,
     OPC_MXU_S8LDD  = 0x22 | OPC_SPECIAL2,
     OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
     OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
@@ -3772,11 +3773,13 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 /* MXU Instructions */
 static void gen_mxu(DisasContext *ctx, uint32_t opc)
 {
-    TCGv t0, t1;
-    uint32_t xra, rb, s8, optn3;
+    TCGv t0, t1, t2, t3;
+    uint32_t rb, xra, xrb, xrc, xrd, s8, sel, optn2, optn3;
 
     t0 = tcg_temp_new();
     t1 = tcg_temp_new();
+    t2 = tcg_temp_new();
+    t3 = tcg_temp_new();
 
     switch (opc) {
     case OPC_MXU_S32I2M:
@@ -3848,10 +3851,53 @@ static void gen_mxu(DisasContext *ctx, uint32_t opc)
         }
         gen_store_mxu_gpr(t0, xra);
         break;
+
+    case OPC_MXU_D16MUL:
+        xra = extract32(ctx->opcode, 6, 4);
+        xrb = extract32(ctx->opcode, 10, 4);
+        xrc = extract32(ctx->opcode, 14, 4);
+        xrd = extract32(ctx->opcode, 18, 4);
+        optn2 = extract32(ctx->opcode, 22, 2);
+        sel = extract32(ctx->opcode, 24, 2);
+
+        if (sel == 1) {
+            /* D16MULE is not supported */
+            generate_exception_end(ctx, EXCP_RI);
+        }
+        gen_load_mxu_gpr(t1, xrb);
+        tcg_gen_sextract_tl(t0, t1, 0, 16);
+        tcg_gen_sextract_tl(t1, t1, 16, 16);
+        gen_load_mxu_gpr(t3, xrc);
+        tcg_gen_sextract_tl(t2, t3, 0, 16);
+        tcg_gen_sextract_tl(t3, t3, 16, 16);
+
+        switch (optn2) {
+        case 0: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t1, t3);
+            tcg_gen_mul_tl(t2, t0, t2);
+            break;
+        case 1: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t0, t3);
+            tcg_gen_mul_tl(t2, t0, t2);
+            break;
+        case 2: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t1, t3);
+            tcg_gen_mul_tl(t2, t1, t2);
+            break;
+        case 3: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t0, t3);
+            tcg_gen_mul_tl(t2, t1, t2);
+            break;
+        }
+        gen_store_mxu_gpr(t3, xra);
+        gen_store_mxu_gpr(t2, xrd);
+        break;
     }
 
     tcg_temp_free(t0);
     tcg_temp_free(t1);
+    tcg_temp_free(t2);
+    tcg_temp_free(t3);
 }
 
 /* Godson integer instructions */
@@ -17938,6 +17984,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
     case OPC_MXU_S32I2M:
     case OPC_MXU_S32M2I:
     case OPC_MXU_S8LDD:
+    case OPC_MXU_D16MUL:
         gen_mxu(ctx, op1);
         break;
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 4/6] target/mips: Add MXU instruction D16MAC
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
                   ` (2 preceding siblings ...)
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 3/6] target/mips: Add MXU instruction D16MUL Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 5/6] target/mips: Add MXU instructions Q8MUL and Q8MULSU Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 6/6] target/mips: Add MXU instructions S32LDD and S32LDDR Craig Janeczek
  5 siblings, 0 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

Adds support for emulating the D16MAC instruction.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - changed bitfield usage to extract32
    - used sextract_tl instructions instead of shift and ext

 target/mips/translate.c | 62 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 8a6b4f2899..7d37567652 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -366,6 +366,7 @@ enum {
     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
     /* MXU */
     OPC_MXU_D16MUL = 0x08 | OPC_SPECIAL2,
+    OPC_MXU_D16MAC = 0x0A | OPC_SPECIAL2,
     OPC_MXU_S8LDD  = 0x22 | OPC_SPECIAL2,
     OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
     OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
@@ -3774,7 +3775,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 static void gen_mxu(DisasContext *ctx, uint32_t opc)
 {
     TCGv t0, t1, t2, t3;
-    uint32_t rb, xra, xrb, xrc, xrd, s8, sel, optn2, optn3;
+    uint32_t rb, xra, xrb, xrc, xrd, s8, sel, optn2, optn3, aptn2;
 
     t0 = tcg_temp_new();
     t1 = tcg_temp_new();
@@ -3892,6 +3893,64 @@ static void gen_mxu(DisasContext *ctx, uint32_t opc)
         gen_store_mxu_gpr(t3, xra);
         gen_store_mxu_gpr(t2, xrd);
         break;
+
+    case OPC_MXU_D16MAC:
+        xra = extract32(ctx->opcode, 6, 4);
+        xrb = extract32(ctx->opcode, 10, 4);
+        xrc = extract32(ctx->opcode, 14, 4);
+        xrd = extract32(ctx->opcode, 18, 4);
+        optn2 = extract32(ctx->opcode, 22, 2);
+        aptn2 = extract32(ctx->opcode, 24, 2);
+
+        gen_load_mxu_gpr(t1, xrb);
+        tcg_gen_sextract_tl(t0, t1, 0, 16);
+        tcg_gen_sextract_tl(t1, t1, 16, 16);
+        gen_load_mxu_gpr(t3, xrc);
+        tcg_gen_sextract_tl(t2, t3, 0, 16);
+        tcg_gen_sextract_tl(t3, t3, 16, 16);
+
+        switch (optn2) {
+        case 0: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t1, t3);
+            tcg_gen_mul_tl(t2, t0, t2);
+            break;
+        case 1: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t0, t3);
+            tcg_gen_mul_tl(t2, t0, t2);
+            break;
+        case 2: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t1, t3);
+            tcg_gen_mul_tl(t2, t1, t2);
+            break;
+        case 3: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
+            tcg_gen_mul_tl(t3, t0, t3);
+            tcg_gen_mul_tl(t2, t1, t2);
+            break;
+        }
+        gen_load_mxu_gpr(t0, xra);
+        gen_load_mxu_gpr(t1, xrd);
+
+        switch (aptn2) {
+        case 0:
+            tcg_gen_add_tl(t3, t0, t3);
+            tcg_gen_add_tl(t2, t1, t2);
+            break;
+        case 1:
+            tcg_gen_add_tl(t3, t0, t3);
+            tcg_gen_sub_tl(t2, t1, t2);
+            break;
+        case 2:
+            tcg_gen_sub_tl(t3, t0, t3);
+            tcg_gen_add_tl(t2, t1, t2);
+            break;
+        case 3:
+            tcg_gen_sub_tl(t3, t0, t3);
+            tcg_gen_sub_tl(t2, t1, t2);
+            break;
+        }
+        gen_store_mxu_gpr(t3, xra);
+        gen_store_mxu_gpr(t2, xrd);
+        break;
     }
 
     tcg_temp_free(t0);
@@ -17985,6 +18044,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
     case OPC_MXU_S32M2I:
     case OPC_MXU_S8LDD:
     case OPC_MXU_D16MUL:
+    case OPC_MXU_D16MAC:
         gen_mxu(ctx, op1);
         break;
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 5/6] target/mips: Add MXU instructions Q8MUL and Q8MULSU
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
                   ` (3 preceding siblings ...)
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 4/6] target/mips: Add MXU instruction D16MAC Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 6/6] target/mips: Add MXU instructions S32LDD and S32LDDR Craig Janeczek
  5 siblings, 0 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

Adds support for emulating the Q8MUL and Q8MULSU instructions.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - changed bitfield usage to extract32

 target/mips/translate.c | 70 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 7d37567652..e2def36b03 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -370,6 +370,7 @@ enum {
     OPC_MXU_S8LDD  = 0x22 | OPC_SPECIAL2,
     OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
     OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
+    OPC_MXU_Q8MUL  = 0x38 | OPC_SPECIAL2,
     /* Special */
     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 };
@@ -3774,13 +3775,17 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 /* MXU Instructions */
 static void gen_mxu(DisasContext *ctx, uint32_t opc)
 {
-    TCGv t0, t1, t2, t3;
+    TCGv t0, t1, t2, t3, t4, t5, t6, t7;
     uint32_t rb, xra, xrb, xrc, xrd, s8, sel, optn2, optn3, aptn2;
 
     t0 = tcg_temp_new();
     t1 = tcg_temp_new();
     t2 = tcg_temp_new();
     t3 = tcg_temp_new();
+    t4 = tcg_temp_new();
+    t5 = tcg_temp_new();
+    t6 = tcg_temp_new();
+    t7 = tcg_temp_new();
 
     switch (opc) {
     case OPC_MXU_S32I2M:
@@ -3951,12 +3956,74 @@ static void gen_mxu(DisasContext *ctx, uint32_t opc)
         gen_store_mxu_gpr(t3, xra);
         gen_store_mxu_gpr(t2, xrd);
         break;
+
+    case OPC_MXU_Q8MUL:
+        xra = extract32(ctx->opcode, 6, 4);
+        xrb = extract32(ctx->opcode, 10, 4);
+        xrc = extract32(ctx->opcode, 14, 4);
+        xrd = extract32(ctx->opcode, 18, 4);
+        sel = extract32(ctx->opcode, 22, 4);
+
+        gen_load_mxu_gpr(t3, xrb);
+        gen_load_mxu_gpr(t7, xrc);
+
+        if (sel == 0x2) {
+            /* Q8MULSU */
+            tcg_gen_ext8s_tl(t0, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8s_tl(t1, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8s_tl(t2, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8s_tl(t3, t3);
+        } else {
+            /* Q8MUL */
+            tcg_gen_ext8u_tl(t0, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8u_tl(t1, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8u_tl(t2, t3);
+            tcg_gen_shri_tl(t3, t3, 8);
+            tcg_gen_ext8u_tl(t3, t3);
+        }
+
+        tcg_gen_ext8u_tl(t4, t7);
+        tcg_gen_shri_tl(t7, t7, 8);
+        tcg_gen_ext8u_tl(t5, t7);
+        tcg_gen_shri_tl(t7, t7, 8);
+        tcg_gen_ext8u_tl(t6, t7);
+        tcg_gen_shri_tl(t7, t7, 8);
+        tcg_gen_ext8u_tl(t7, t7);
+
+        tcg_gen_mul_tl(t0, t0, t4);
+        tcg_gen_mul_tl(t1, t1, t5);
+        tcg_gen_mul_tl(t2, t2, t6);
+        tcg_gen_mul_tl(t3, t3, t7);
+
+        tcg_gen_andi_tl(t0, t0, 0xFFFF);
+        tcg_gen_andi_tl(t1, t1, 0xFFFF);
+        tcg_gen_andi_tl(t2, t2, 0xFFFF);
+        tcg_gen_andi_tl(t3, t3, 0xFFFF);
+
+        tcg_gen_shli_tl(t1, t1, 16);
+        tcg_gen_shli_tl(t3, t3, 16);
+
+        tcg_gen_or_tl(t0, t0, t1);
+        tcg_gen_or_tl(t1, t2, t3);
+
+        gen_store_mxu_gpr(t0, xrd);
+        gen_store_mxu_gpr(t1, xra);
+        break;
     }
 
     tcg_temp_free(t0);
     tcg_temp_free(t1);
     tcg_temp_free(t2);
     tcg_temp_free(t3);
+    tcg_temp_free(t4);
+    tcg_temp_free(t5);
+    tcg_temp_free(t6);
+    tcg_temp_free(t7);
 }
 
 /* Godson integer instructions */
@@ -18045,6 +18112,7 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
     case OPC_MXU_S8LDD:
     case OPC_MXU_D16MUL:
     case OPC_MXU_D16MAC:
+    case OPC_MXU_Q8MUL:
         gen_mxu(ctx, op1);
         break;
 
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH v2 6/6] target/mips: Add MXU instructions S32LDD and S32LDDR
  2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
                   ` (4 preceding siblings ...)
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 5/6] target/mips: Add MXU instructions Q8MUL and Q8MULSU Craig Janeczek
@ 2018-08-27 14:38 ` Craig Janeczek
  5 siblings, 0 replies; 8+ messages in thread
From: Craig Janeczek @ 2018-08-27 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: amarkovic, aurelien, Craig Janeczek

Adds support for emulating the S32LDD and S32LDDR MXU instructions.

Signed-off-by: Craig Janeczek <jancraig@amazon.com>
---
 v1
    - initial patch
 v2
    - changed bitfield usage to extract32

 target/mips/translate.c | 43 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index e2def36b03..2eb7c02741 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -347,7 +347,8 @@ enum {
     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
     /* Loongson 2F */
-    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
+    /* opcode 0x10 overlaps loongson and MXU command */
+    OPC_MULT_G_2F_MXU_S32LDD   = 0x10 | OPC_SPECIAL2,
     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
@@ -3776,7 +3777,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
 static void gen_mxu(DisasContext *ctx, uint32_t opc)
 {
     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
-    uint32_t rb, xra, xrb, xrc, xrd, s8, sel, optn2, optn3, aptn2;
+    uint32_t rb, xra, xrb, xrc, xrd, s8, s12, sel, optn2, optn3, aptn2;
 
     t0 = tcg_temp_new();
     t1 = tcg_temp_new();
@@ -3858,6 +3859,29 @@ static void gen_mxu(DisasContext *ctx, uint32_t opc)
         gen_store_mxu_gpr(t0, xra);
         break;
 
+    case OPC_MULT_G_2F_MXU_S32LDD:
+        xra = extract32(ctx->opcode, 6, 4);
+        s12 = extract32(ctx->opcode, 10, 10);
+        sel = extract32(ctx->opcode, 20, 1);
+        rb = extract32(ctx->opcode, 21, 5);
+
+        gen_load_gpr(t0, rb);
+
+        tcg_gen_movi_tl(t1, s12);
+        tcg_gen_shli_tl(t1, t1, 2);
+        if (s12 & 0x200) {
+            tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
+        }
+        tcg_gen_add_tl(t1, t0, t1);
+        tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
+
+        if (sel == 1) {
+            /* S32LDDR */
+            tcg_gen_bswap32_tl(t1, t1);
+        }
+        gen_store_mxu_gpr(t1, xra);
+        break;
+
     case OPC_MXU_D16MUL:
         xra = extract32(ctx->opcode, 6, 4);
         xrb = extract32(ctx->opcode, 10, 4);
@@ -4039,7 +4063,7 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
 
     switch (opc) {
     case OPC_MULT_G_2E:
-    case OPC_MULT_G_2F:
+    case OPC_MULT_G_2F_MXU_S32LDD:
     case OPC_MULTU_G_2E:
     case OPC_MULTU_G_2F:
 #if defined(TARGET_MIPS64)
@@ -4062,7 +4086,7 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
 
     switch (opc) {
     case OPC_MULT_G_2E:
-    case OPC_MULT_G_2F:
+    case OPC_MULT_G_2F_MXU_S32LDD:
         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
         break;
@@ -18099,7 +18123,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
         break;
     case OPC_DIV_G_2F:
     case OPC_DIVU_G_2F:
-    case OPC_MULT_G_2F:
     case OPC_MULTU_G_2F:
     case OPC_MOD_G_2F:
     case OPC_MODU_G_2F:
@@ -18116,6 +18139,16 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
         gen_mxu(ctx, op1);
         break;
 
+    case OPC_MULT_G_2F_MXU_S32LDD:
+        /* There is an overlap of opcodes between Loongson2F and MXU */
+        if (ctx->insn_flags & INSN_LOONGSON2F) {
+            check_insn(ctx, INSN_LOONGSON2F);
+            gen_loongson_integer(ctx, op1, rd, rs, rt);
+        } else {
+            gen_mxu(ctx, op1);
+        }
+        break;
+
     case OPC_CLO:
     case OPC_CLZ:
         check_insn(ctx, ISA_MIPS32);
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I
  2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I Craig Janeczek
@ 2018-08-27 18:13   ` Aleksandar Markovic
  0 siblings, 0 replies; 8+ messages in thread
From: Aleksandar Markovic @ 2018-08-27 18:13 UTC (permalink / raw)
  To: Craig Janeczek, qemu-devel; +Cc: aurelien, Petar Jovanovic, Richard Henderson

> From: Craig Janeczek <jancraig@amazon.com>
> Sent: Monday, August 27, 2018 4:38 PM
> Subject: [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I
> 
> This commit makes the MXU registers and the utility functions for
> reading/writing to them. This is required for full MXU instruction
> support.
> 
> Adds support for emulating the S32I2M and S32M2I MXU instructions.
> 
> Signed-off-by: Craig Janeczek <jancraig@amazon.com>
> ---
>  v1
>     - initial patch
>  v2
>     - Fix checkpatch.pl errors
>     - remove mips64 ifdef
>     - changed bitfield usage to extract32
>     - squashed register addition patch into this one
> 
>  target/mips/cpu.h       |  1 +
>  target/mips/translate.c | 71 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 72 insertions(+)
> 

Hi, Craig,

So far it is going well. You respond well to the reviews. I encourage you to persevere, this is a nice addition to QEMU's MIPS functionality, we want it.

Just something about overall patch organization:

This (1/7) patch should be split/refactored in this way:

PATCH 1: Introduce MXU registers (16 fields and their names, plus initialization)

PATCH 2: Add MXU opcodes (if possible, add ALL MXU opcodes, there are 50 to 60 ones, if I am not mistaken)

PATCH 3: The rest of this patch (so, S32I2M and S32M2I emulation)

... and further patches as you already organized.

However, there is more. We plan to significantly revamp translate.c in near future, and this series, even though it is consistent with the rest of code in the same file, would not fit in its present state well into the new organization of translate.c. I am asking you, therefore, to reorganize code in the following fashion:

- implementation of emulation of each instruction should be in a separate function (baring some exceptions); for this patch functions gen_mxu_s32i2m() and gen_mxu_s32m2i() should be created; the only arguments of these function should be "DisasContext *ctx" and "uint32_t opc";

- each such function should be preceded by a comment similar to this:

/*
 * S32M2I XRa, rb - Register move from XRF to GRF
 */

- gen_mxu() would disappear;

- decode_opc_special2_legacy() should call various gen_mxu_XXX() directly, in separate "case" sections for each instruction.

Please rearrange the code this way.

Thanks,
Aleksandar

> diff --git a/target/mips/cpu.h b/target/mips/cpu.h
> index 009202cf64..4b2948a2c8 100644
> --- a/target/mips/cpu.h
> +++ b/target/mips/cpu.h
> @@ -170,6 +170,7 @@ struct TCState {
>          MSACSR_FS_MASK)
> 
>      float_status msa_fp_status;
> +    target_ulong mxu_gpr[16];
>  };
> 
>  typedef struct CPUMIPSState CPUMIPSState;
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index bdd880bb77..ef819d67e0 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -364,6 +364,9 @@ enum {
>      OPC_CLO      = 0x21 | OPC_SPECIAL2,
>      OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
>      OPC_DCLO     = 0x25 | OPC_SPECIAL2,
> +    /* MXU */
> +    OPC_MXU_S32I2M = 0x2F | OPC_SPECIAL2,
> +    OPC_MXU_S32M2I = 0x2E | OPC_SPECIAL2,
>      /* Special */
>      OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
>  };
> @@ -1398,6 +1401,9 @@ static TCGv_i32 fpu_fcr0, fpu_fcr31;
>  static TCGv_i64 fpu_f64[32];
>  static TCGv_i64 msa_wr_d[64];
> 
> +/* MXU registers */
> +static TCGv mxu_gpr[16];
> +
>  #include "exec/gen-icount.h"
> 
>  #define gen_helper_0e0i(name, arg) do {                           \
> @@ -1517,6 +1523,13 @@ static const char * const msaregnames[] = {
>      "w30.d0", "w30.d1", "w31.d0", "w31.d1",
>  };
> 
> +static const char * const mxuregnames[] = {
> +    "XR1",  "XR2",  "XR3",  "XR4",  "XR5",
> +    "XR6",  "XR7",  "XR8",  "XR9",  "XR10",
> +    "XR11", "XR12", "XR13", "XR14", "XR15",
> +    "XR16",
> +};
> +
>  #define LOG_DISAS(...)                                                        \
>      do {                                                                      \
>          if (MIPS_DEBUG_DISAS) {                                               \
> @@ -1550,6 +1563,23 @@ static inline void gen_store_gpr (TCGv t, int reg)
>          tcg_gen_mov_tl(cpu_gpr[reg], t);
>  }
> 
> +/* MXU General purpose registers moves. */
> +static inline void gen_load_mxu_gpr(TCGv t, int reg)
> +{
> +    if (reg == 0) {
> +        tcg_gen_movi_tl(t, 0);
> +    } else {
> +        tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
> +    }
> +}
> +
> +static inline void gen_store_mxu_gpr(TCGv t, int reg)
> +{
> +    if (reg != 0) {
> +        tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
> +    }
> +}
> +
>  /* Moves to/from shadow registers. */
>  static inline void gen_load_srsgpr (int from, int to)
>  {
> @@ -3738,6 +3768,35 @@ static void gen_cl (DisasContext *ctx, uint32_t opc,
>      }
>  }
> 
> +/* MXU Instructions */
> +static void gen_mxu(DisasContext *ctx, uint32_t opc)
> +{
> +    TCGv t0;
> +    uint32_t xra, rb;
> +
> +    t0 = tcg_temp_new();
> +
> +    switch (opc) {
> +    case OPC_MXU_S32I2M:
> +        xra = extract32(ctx->opcode, 6, 5);
> +        rb = extract32(ctx->opcode, 16, 5);
> +
> +        gen_load_gpr(t0, rb);
> +        gen_store_mxu_gpr(t0, xra);
> +        break;
> +
> +    case OPC_MXU_S32M2I:
> +        xra = extract32(ctx->opcode, 6, 5);
> +        rb = extract32(ctx->opcode, 16, 5);
> +
> +        gen_load_mxu_gpr(t0, xra);
> +        gen_store_gpr(t0, rb);
> +        break;
> +    }
> +
> +    tcg_temp_free(t0);
> +}
> +
>  /* Godson integer instructions */
>  static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
>                                   int rd, int rs, int rt)
> @@ -17818,6 +17877,12 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
>          check_insn(ctx, INSN_LOONGSON2F);
>          gen_loongson_integer(ctx, op1, rd, rs, rt);
>          break;
> +
> +    case OPC_MXU_S32I2M:
> +    case OPC_MXU_S32M2I:
> +        gen_mxu(ctx, op1);
> +        break;
> +
>      case OPC_CLO:
>      case OPC_CLZ:
>          check_insn(ctx, ISA_MIPS32);
> @@ -20742,6 +20807,12 @@ void mips_tcg_init(void)
>      fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
>                                         offsetof(CPUMIPSState, active_fpu.fcr31),
>                                         "fcr31");
> +
> +    for (i = 0; i < 16; i++)
> +        mxu_gpr[i] = tcg_global_mem_new(cpu_env,
> +                                        offsetof(CPUMIPSState,
> +                                                 active_tc.mxu_gpr[i]),
> +                                        mxuregnames[i]);
>  }
> 
>  #include "translate_init.inc.c"
> --
> 2.18.0
> 
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-08-27 18:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-27 14:38 [Qemu-devel] [PATCH v2 0/6] Add limited MXU instruction support Craig Janeczek
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 1/6] target/mips: Add MXU instructions S32I2M and S32M2I Craig Janeczek
2018-08-27 18:13   ` Aleksandar Markovic
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 2/6] target/mips: Add MXU instruction S8LDD Craig Janeczek
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 3/6] target/mips: Add MXU instruction D16MUL Craig Janeczek
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 4/6] target/mips: Add MXU instruction D16MAC Craig Janeczek
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 5/6] target/mips: Add MXU instructions Q8MUL and Q8MULSU Craig Janeczek
2018-08-27 14:38 ` [Qemu-devel] [PATCH v2 6/6] target/mips: Add MXU instructions S32LDD and S32LDDR Craig Janeczek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.