diff mbox series

[RFC,v2,43/44] target/loongarch: Implement vldi

Message ID 20230328030631.3117129-44-gaosong@loongson.cn
State New
Headers show
Series Add LoongArch LSX instructions | expand

Commit Message

gaosong March 28, 2023, 3:06 a.m. UTC
This patch includes:
- VLDI.

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/disas.c                    |   7 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 142 ++++++++++++++++++++
 target/loongarch/insns.decode               |   4 +
 3 files changed, 153 insertions(+)

Comments

Richard Henderson April 4, 2023, 3:39 a.m. UTC | #1
On 3/27/23 20:06, Song Gao wrote:
> +static bool trans_vldi(DisasContext *ctx, arg_vldi *a)
> +{
> +    int sel, vece;
> +    uint64_t value;
> +    CHECK_SXE;
> +
> +    sel = (a->imm >> 12) & 0x1;
> +
> +    if (sel) {
> +        /* VSETI.D */
> +        value = vldi_get_value(ctx, a->imm);
> +        vece = MO_64;
> +    } else {
> +       /*
> +        * VLDI.B/H/W/D
> +        *  a->imm bit [11:10] is vece.
> +        *  a->imm bit [9:0] is value;
> +        */
> +       value = ((int32_t)(a->imm << 22)) >> 22;
> +       vece = (a->imm >> 10) & 0x3;
> +    }
> +
> +    tcg_gen_gvec_dup_i64(vece, vreg_full_offset(a->vd), 16, 16,
> +                         tcg_constant_i64(value));
> +    return true;
> +}

I think you should finish this decode in insns.decode,
especially since we are using that for disassembly.


r~
gaosong April 18, 2023, 9:03 a.m. UTC | #2
Hi, Richard

在 2023/4/4 上午11:39, Richard Henderson 写道:
> On 3/27/23 20:06, Song Gao wrote:
>> +static bool trans_vldi(DisasContext *ctx, arg_vldi *a)
>> +{
>> +    int sel, vece;
>> +    uint64_t value;
>> +    CHECK_SXE;
>> +
>> +    sel = (a->imm >> 12) & 0x1;
>> +
>> +    if (sel) {
>> +        /* VSETI.D */
>> +        value = vldi_get_value(ctx, a->imm);
>> +        vece = MO_64;
>> +    } else {
>> +       /*
>> +        * VLDI.B/H/W/D
>> +        *  a->imm bit [11:10] is vece.
>> +        *  a->imm bit [9:0] is value;
>> +        */
>> +       value = ((int32_t)(a->imm << 22)) >> 22;
>> +       vece = (a->imm >> 10) & 0x3;
>> +    }
>> +
>> +    tcg_gen_gvec_dup_i64(vece, vreg_full_offset(a->vd), 16, 16,
>> +                         tcg_constant_i64(value));
>> +    return true;
>> +}
>
> I think you should finish this decode in insns.decode,
> especially since we are using that for disassembly.
>
You can ignore these comments, I will drop them. We only have vldi, no 
vseti.d, vldi.xxx insns.

Thanks.
Song Gao
diff mbox series

Patch

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 8627908fc9..5c402d944d 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -858,6 +858,11 @@  static void output_vrr(DisasContext *ctx, arg_vrr *a, const char *mnemonic)
     output(ctx, mnemonic, "v%d, r%d, r%d", a->vd, a->rj, a->rk);
 }
 
+static void output_v_i(DisasContext *ctx, arg_v_i *a, const char *mnemonic)
+{
+    output(ctx, mnemonic, "v%d, 0x%x", a->vd, a->imm);
+}
+
 INSN_LSX(vadd_b,           vvv)
 INSN_LSX(vadd_h,           vvv)
 INSN_LSX(vadd_w,           vvv)
@@ -1143,6 +1148,8 @@  INSN_LSX(vmskltz_d,        vv)
 INSN_LSX(vmskgez_b,        vv)
 INSN_LSX(vmsknz_b,         vv)
 
+INSN_LSX(vldi,             v_i)
+
 INSN_LSX(vand_v,           vvv)
 INSN_LSX(vor_v,            vvv)
 INSN_LSX(vxor_v,           vvv)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc b/target/loongarch/insn_trans/trans_lsx.c.inc
index ab896f8a9e..cb5aa9e4a9 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2606,6 +2606,148 @@  TRANS(vmskltz_d, gen_vv, gen_helper_vmskltz_d)
 TRANS(vmskgez_b, gen_vv, gen_helper_vmskgez_b)
 TRANS(vmsknz_b, gen_vv, gen_helper_vmsknz_b)
 
+#define EXPAND_BYTE(bit)  ((uint64_t)(bit ? 0xff : 0))
+
+static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
+{
+    int mode;
+    uint64_t data, t;
+
+    /*
+     * imm bit [11:8] is mode, mode value is 0-12.
+     * other values are invalid.
+     */
+    mode = (imm >> 8) & 0xf;
+    t =  imm & 0xff;
+    switch (mode) {
+    case 0:
+        /* data: {2{24'0, imm[7:0]}} */
+        data =  (t << 32) | t ;
+        break;
+    case 1:
+        /* data: {2{16'0, imm[7:0], 8'0}} */
+        data = (t << 24) | (t << 8);
+        break;
+    case 2:
+        /* data: {2{8'0, imm[7:0], 16'0}} */
+        data = (t << 48) | (t << 16);
+        break;
+    case 3:
+        /* data: {2{imm[7:0], 24'0}} */
+        data = (t << 56) | (t << 24);
+        break;
+    case 4:
+        /* data: {4{8'0, imm[7:0]}} */
+        data = (t << 48) | (t << 32) | (t << 16) | t;
+        break;
+    case 5:
+        /* data: {4{imm[7:0], 8'0}} */
+        data = (t << 56) |(t << 40) | (t << 24) | (t << 8);
+        break;
+    case 6:
+        /* data: {2{16'0, imm[7:0], 8'1}} */
+        data = (t << 40) | ((uint64_t)0xff << 32) | (t << 8) | 0xff;
+        break;
+    case 7:
+        /* data: {2{8'0, imm[7:0], 16'1}} */
+        data = (t << 48) | ((uint64_t)0xffff << 32) | (t << 16) | 0xffff;
+        break;
+    case 8:
+        /* data: {8{imm[7:0]}} */
+        data =(t << 56) | (t << 48) | (t << 40) | (t << 32) |
+              (t << 24) | (t << 16) | (t << 8) | t;
+        break;
+    case 9:
+        /* data: {{8{imm[7]}, ..., 8{imm[0]}}} */
+        {
+            uint64_t b0,b1,b2,b3,b4,b5,b6,b7;
+            b0 = t& 0x1;
+            b1 = (t & 0x2) >> 1;
+            b2 = (t & 0x4) >> 2;
+            b3 = (t & 0x8) >> 3;
+            b4 = (t & 0x10) >> 4;
+            b5 = (t & 0x20) >> 5;
+            b6 = (t & 0x40) >> 6;
+            b7 = (t & 0x80) >> 7;
+            data = (EXPAND_BYTE(b7) << 56) |
+                   (EXPAND_BYTE(b6) << 48) |
+                   (EXPAND_BYTE(b5) << 40) |
+                   (EXPAND_BYTE(b4) << 32) |
+                   (EXPAND_BYTE(b3) << 24) |
+                   (EXPAND_BYTE(b2) << 16) |
+                   (EXPAND_BYTE(b1) <<  8) |
+                   EXPAND_BYTE(b0);
+        }
+        break;
+    case 10:
+        /* data: {2{imm[7], ~imm[6], {5{imm[6]}}, imm[5:0], 19'0}} */
+        {
+            uint64_t b6, b7;
+            uint64_t t0, t1;
+            b6 = (imm & 0x40) >> 6;
+            b7 = (imm & 0x80) >> 7;
+            t0 = (imm & 0x3f);
+            t1 = (b7 << 6) | ((1-b6) << 5) | (uint64_t)(b6 ? 0x1f : 0);
+            data  = (t1 << 57) | (t0 << 51) | (t1 << 25) | (t0 << 19);
+        }
+        break;
+    case 11:
+        /* data: {32'0, imm[7], ~{imm[6]}, 5{imm[6]}, imm[5:0], 19'0} */
+        {
+            uint64_t b6,b7;
+            uint64_t t0, t1;
+            b6 = (imm & 0x40) >> 6;
+            b7 = (imm & 0x80) >> 7;
+            t0 = (imm & 0x3f);
+            t1 = (b7 << 6) | ((1-b6) << 5) | (b6 ? 0x1f : 0);
+            data = (t1 << 25) | (t0 << 19);
+        }
+        break;
+    case 12:
+        /* data: {imm[7], ~imm[6], 8{imm[6]}, imm[5:0], 48'0} */
+        {
+            uint64_t b6,b7;
+            uint64_t t0, t1;
+            b6 = (imm & 0x40) >> 6;
+            b7 = (imm & 0x80) >> 7;
+            t0 = (imm & 0x3f);
+            t1 = (b7 << 9) | ((1-b6) << 8) | (b6 ? 0xff : 0);
+            data = (t1 << 54) | (t0 << 48);
+        }
+        break;
+    default:
+        assert(0);
+    }
+    return data;
+}
+
+static bool trans_vldi(DisasContext *ctx, arg_vldi *a)
+{
+    int sel, vece;
+    uint64_t value;
+    CHECK_SXE;
+
+    sel = (a->imm >> 12) & 0x1;
+
+    if (sel) {
+        /* VSETI.D */
+        value = vldi_get_value(ctx, a->imm);
+        vece = MO_64;
+    } else {
+       /*
+        * VLDI.B/H/W/D
+        *  a->imm bit [11:10] is vece.
+        *  a->imm bit [9:0] is value;
+        */
+       value = ((int32_t)(a->imm << 22)) >> 22;
+       vece = (a->imm >> 10) & 0x3;
+    }
+
+    tcg_gen_gvec_dup_i64(vece, vreg_full_offset(a->vd), 16, 16,
+                         tcg_constant_i64(value));
+    return true;
+}
+
 TRANS(vand_v, gvec_vvv, MO_64, tcg_gen_gvec_and)
 TRANS(vor_v, gvec_vvv, MO_64, tcg_gen_gvec_or)
 TRANS(vxor_v, gvec_vvv, MO_64, tcg_gen_gvec_xor)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index ea6eedb7a9..c9c3bc2c73 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -513,6 +513,7 @@  dbcl             0000 00000010 10101 ...............      @i15
 &vvr          vd vj rk
 &vrr          vd rj rk
 &vr_ii        vd rj imm imm2
+&v_i          vd imm
 
 #
 # LSX Formats
@@ -550,6 +551,7 @@  dbcl             0000 00000010 10101 ...............      @i15
 @vr_i8i3       .... ....... imm2:3 ........ rj:5 vd:5    &vr_ii imm=%i8s1
 @vr_i8i4          .... ...... imm2:4 imm:s8 rj:5 vd:5    &vr_ii
 @vrr               .... ........ ..... rk:5 rj:5 vd:5    &vrr
+@v_i13                   .... ........ .. imm:13 vd:5    &v_i
 
 vadd_b           0111 00000000 10100 ..... ..... .....    @vvv
 vadd_h           0111 00000000 10101 ..... ..... .....    @vvv
@@ -837,6 +839,8 @@  vmskltz_d        0111 00101001 11000 10011 ..... .....    @vv
 vmskgez_b        0111 00101001 11000 10100 ..... .....    @vv
 vmsknz_b         0111 00101001 11000 11000 ..... .....    @vv
 
+vldi             0111 00111110 00 ............. .....     @v_i13
+
 vand_v           0111 00010010 01100 ..... ..... .....    @vvv
 vor_v            0111 00010010 01101 ..... ..... .....    @vvv
 vxor_v           0111 00010010 01110 ..... ..... .....    @vvv