diff mbox series

[v2,10/32] target/mips: Convert MSA BIT instruction format to decodetree

Message ID 20211027180730.1551932-11-f4bug@amsat.org
State New
Headers show
Series target/mips: Fully convert MSA opcodes to decodetree | expand

Commit Message

Philippe Mathieu-Daudé Oct. 27, 2021, 6:07 p.m. UTC
Convert instructions with an immediate bit index and
data format df/m to decodetree.

Since the 'data format' field is a constant value, use
tcg_constant_i32() instead of a TCG temporary.

Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
v2:
- dfm field in decodetree format
- index array by CPUMIPSMSADataFormat to avoid dup
- TCG tm is constant
---
 target/mips/tcg/msa.decode      |  19 ++++
 target/mips/tcg/msa_translate.c | 177 ++++++++++++++------------------
 2 files changed, 98 insertions(+), 98 deletions(-)

Comments

Richard Henderson Oct. 27, 2021, 9:20 p.m. UTC | #1
On 10/27/21 11:07 AM, Philippe Mathieu-Daudé wrote:
> +static bool trans_msa_bit(DisasContext *ctx, arg_msa_bit *a,
> +                          gen_helper_piiii *gen_msa_bit)
>  {
> +    if (a->df < 0) {
> +        return false;
>      }

This test should happen before the msa check...
>   
> +    gen_msa_bit(cpu_env,
> +                tcg_constant_i32(a->df),
> +                tcg_constant_i32(a->wd),
> +                tcg_constant_i32(a->ws),
> +                tcg_constant_i32(a->m));
>   
> +    return true;
>   }
>   
> +TRANS_MSA(SLLI,     trans_msa_bit, gen_helper_msa_slli_df);

... currently being hidden in here.

This is the reason why I suggest TRANS_MSA be dispensed with.  You won't have over-many 
explicit trans_* functions in which you need to place the msa check, I think.


r~
Philippe Mathieu-Daudé Oct. 28, 2021, 11:04 a.m. UTC | #2
On 10/27/21 23:20, Richard Henderson wrote:
> On 10/27/21 11:07 AM, Philippe Mathieu-Daudé wrote:
>> +static bool trans_msa_bit(DisasContext *ctx, arg_msa_bit *a,
>> +                          gen_helper_piiii *gen_msa_bit)
>>  {
>> +    if (a->df < 0) {
>> +        return false;
>>      }
> 
> This test should happen before the msa check...
>>   +    gen_msa_bit(cpu_env,
>> +                tcg_constant_i32(a->df),
>> +                tcg_constant_i32(a->wd),
>> +                tcg_constant_i32(a->ws),
>> +                tcg_constant_i32(a->m));
>>   +    return true;
>>   }
>>   +TRANS_MSA(SLLI,     trans_msa_bit, gen_helper_msa_slli_df);
> 
> ... currently being hidden in here.
> 
> This is the reason why I suggest TRANS_MSA be dispensed with.  You won't
> have over-many explicit trans_* functions in which you need to place the
> msa check, I think.

Yes, you are right.
diff mbox series

Patch

diff --git a/target/mips/tcg/msa.decode b/target/mips/tcg/msa.decode
index 115e90b4fce..c4699b9d4b7 100644
--- a/target/mips/tcg/msa.decode
+++ b/target/mips/tcg/msa.decode
@@ -16,6 +16,10 @@ 
 &msa_bz             df        wt sa
 &msa_ldi            df  wd       sa
 &msa_i5             df  wd ws    sa
+&msa_bit            df  wd ws       m
+
+%dfm_df             16:7 !function=msa_bit_df
+%dfm_m              16:7 !function=msa_bit_m
 
 @lsa                ...... rs:5 rt:5 rd:5 ... sa:2 ......   &r
 @bz_v               ...... ... ..    wt:5 sa:16             &msa_bz df=3
@@ -23,6 +27,7 @@ 
 @u5                 ...... ... df:2 sa:5  ws:5 wd:5 ......  &msa_i5
 @s5                 ...... ... df:2 sa:s5 ws:5 wd:5 ......  &msa_i5
 @ldi                ...... ... df:2 sa:s10     wd:5 ......  &msa_ldi
+@bit                ...... ... .......    ws:5 wd:5 ......  &msa_bit df=%dfm_df m=%dfm_m
 
 LSA                 000000 ..... ..... ..... 000 .. 000101  @lsa
 DLSA                000000 ..... ..... ..... 000 .. 010101  @lsa
@@ -48,5 +53,19 @@  BNZ                 010001 111 .. ..... ................    @bz
 
   LDI               011110 110 .. ..........  ..... 000111  @ldi
 
+  SLLI              011110 000 ....... ..... .....  001001  @bit
+  SRAI              011110 001 ....... ..... .....  001001  @bit
+  SRLI              011110 010 ....... ..... .....  001001  @bit
+  BCLRI             011110 011 ....... ..... .....  001001  @bit
+  BSETI             011110 100 ....... ..... .....  001001  @bit
+  BNEGI             011110 101 ....... ..... .....  001001  @bit
+  BINSLI            011110 110 ....... ..... .....  001001  @bit
+  BINSRI            011110 111 ....... ..... .....  001001  @bit
+
+  SAT_S             011110 000 ....... ..... .....  001010  @bit
+  SAT_U             011110 001 ....... ..... .....  001010  @bit
+  SRARI             011110 010 ....... ..... .....  001010  @bit
+  SRLRI             011110 011 ....... ..... .....  001010  @bit
+
   MSA               011110 --------------------------
 }
diff --git a/target/mips/tcg/msa_translate.c b/target/mips/tcg/msa_translate.c
index ca70c38c866..175254c1e47 100644
--- a/target/mips/tcg/msa_translate.c
+++ b/target/mips/tcg/msa_translate.c
@@ -17,6 +17,9 @@ 
 #include "fpu_helper.h"
 #include "internal.h"
 
+static int msa_bit_m(DisasContext *ctx, int x);
+static int msa_bit_df(DisasContext *ctx, int x);
+
 /* Include the auto-generated decoder.  */
 #include "decode-msa.c.inc"
 
@@ -27,8 +30,6 @@  enum {
     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
-    OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
-    OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
@@ -222,20 +223,6 @@  enum {
     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
-
-    /* BIT instruction df(bits 22..16) = _B _H _W _D */
-    OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
-    OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
-    OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
-    OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
-    OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
-    OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
-    OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
-    OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
-    OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
-    OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
-    OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
-    OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
 };
 
 static const char msaregnames[][6] = {
@@ -257,6 +244,59 @@  static const char msaregnames[][6] = {
     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
 };
 
+/* Encoding of Operation Field (must be indexed by CPUMIPSMSADataFormat) */
+struct dfe {
+    int start;
+    int length;
+    uint32_t mask;
+};
+
+/*
+ * Extract immediate from df/{m,n} format (used by ELM & BIT instructions).
+ * Returns the immediate value, or -1 if the format does not match.
+ */
+static int msa_df_extract_val(DisasContext *ctx, int x, const struct dfe *s)
+{
+    for (unsigned i = 0; i < 4; i++) {
+        if (extract32(x, s->start, s->length) == s->mask) {
+            return extract32(x, 0, s->start);
+        }
+    }
+    return -1;
+}
+
+/*
+ * Extract DataField from df/{m,n} format (used by ELM & BIT instructions).
+ * Returns the DataField, or -1 if the format does not match.
+ */
+static int msa_df_extract_df(DisasContext *ctx, int x, const struct dfe *s)
+{
+    for (unsigned i = 0; i < 4; i++) {
+        if (extract32(x, s->start, s->length) == s->mask) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+static const struct dfe df_bit[] = {
+    /* Table 3.28 BIT Instruction Format */
+    [DF_BYTE]   = {3, 4, 0b1110},
+    [DF_HALF]   = {4, 3, 0b110},
+    [DF_WORD]   = {5, 2, 0b10},
+    [DF_DOUBLE] = {6, 1, 0b0}
+};
+
+static int msa_bit_m(DisasContext *ctx, int x)
+{
+    return msa_df_extract_val(ctx, x, df_bit);
+}
+
+static int msa_bit_df(DisasContext *ctx, int x)
+{
+    return msa_df_extract_df(ctx, x, df_bit);
+}
+
 static TCGv_i64 msa_wr_d[64];
 
 void msa_translate_init(void)
@@ -500,90 +540,35 @@  static bool trans_LDI(DisasContext *ctx, arg_msa_ldi *a)
     return true;
 }
 
-static void gen_msa_bit(DisasContext *ctx)
+static bool trans_msa_bit(DisasContext *ctx, arg_msa_bit *a,
+                          gen_helper_piiii *gen_msa_bit)
 {
-#define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
-    uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
-    uint32_t df = 0, m = 0;
-    uint8_t ws = (ctx->opcode >> 11) & 0x1f;
-    uint8_t wd = (ctx->opcode >> 6) & 0x1f;
-
-    TCGv_i32 tdf;
-    TCGv_i32 tm;
-    TCGv_i32 twd;
-    TCGv_i32 tws;
-
-    if ((dfm & 0x40) == 0x00) {
-        m = dfm & 0x3f;
-        df = DF_DOUBLE;
-    } else if ((dfm & 0x60) == 0x40) {
-        m = dfm & 0x1f;
-        df = DF_WORD;
-    } else if ((dfm & 0x70) == 0x60) {
-        m = dfm & 0x0f;
-        df = DF_HALF;
-    } else if ((dfm & 0x78) == 0x70) {
-        m = dfm & 0x7;
-        df = DF_BYTE;
-    } else {
-        gen_reserved_instruction(ctx);
-        return;
+    if (a->df < 0) {
+        return false;
     }
 
-    tdf = tcg_const_i32(df);
-    tm  = tcg_const_i32(m);
-    twd = tcg_const_i32(wd);
-    tws = tcg_const_i32(ws);
+    gen_msa_bit(cpu_env,
+                tcg_constant_i32(a->df),
+                tcg_constant_i32(a->wd),
+                tcg_constant_i32(a->ws),
+                tcg_constant_i32(a->m));
 
-    switch (MASK_MSA_BIT(ctx->opcode)) {
-    case OPC_SLLI_df:
-        gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SRAI_df:
-        gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SRLI_df:
-        gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_BCLRI_df:
-        gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_BSETI_df:
-        gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_BNEGI_df:
-        gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_BINSLI_df:
-        gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_BINSRI_df:
-        gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SAT_S_df:
-        gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SAT_U_df:
-        gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SRARI_df:
-        gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    case OPC_SRLRI_df:
-        gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
-        break;
-    default:
-        MIPS_INVAL("MSA instruction");
-        gen_reserved_instruction(ctx);
-        break;
-    }
-
-    tcg_temp_free_i32(tdf);
-    tcg_temp_free_i32(tm);
-    tcg_temp_free_i32(twd);
-    tcg_temp_free_i32(tws);
+    return true;
 }
 
+TRANS_MSA(SLLI,     trans_msa_bit, gen_helper_msa_slli_df);
+TRANS_MSA(SRAI,     trans_msa_bit, gen_helper_msa_srai_df);
+TRANS_MSA(SRLI,     trans_msa_bit, gen_helper_msa_srli_df);
+TRANS_MSA(BCLRI,    trans_msa_bit, gen_helper_msa_bclri_df);
+TRANS_MSA(BSETI,    trans_msa_bit, gen_helper_msa_bseti_df);
+TRANS_MSA(BNEGI,    trans_msa_bit, gen_helper_msa_bnegi_df);
+TRANS_MSA(BINSLI,   trans_msa_bit, gen_helper_msa_binsli_df);
+TRANS_MSA(BINSRI,   trans_msa_bit, gen_helper_msa_binsri_df);
+TRANS_MSA(SAT_S,    trans_msa_bit, gen_helper_msa_sat_u_df);
+TRANS_MSA(SAT_U,    trans_msa_bit, gen_helper_msa_sat_u_df);
+TRANS_MSA(SRARI,    trans_msa_bit, gen_helper_msa_srari_df);
+TRANS_MSA(SRLRI,    trans_msa_bit, gen_helper_msa_srlri_df);
+
 static void gen_msa_3r(DisasContext *ctx)
 {
 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
@@ -2128,10 +2113,6 @@  static bool trans_MSA(DisasContext *ctx, arg_MSA *a)
     case OPC_MSA_I8_02:
         gen_msa_i8(ctx);
         break;
-    case OPC_MSA_BIT_09:
-    case OPC_MSA_BIT_0A:
-        gen_msa_bit(ctx);
-        break;
     case OPC_MSA_3R_0D:
     case OPC_MSA_3R_0E:
     case OPC_MSA_3R_0F: