qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 43/43] target/loongarch: Implement vldi


From: Song Gao
Subject: [RFC PATCH 43/43] target/loongarch: Implement vldi
Date: Sat, 24 Dec 2022 16:16:33 +0800

This patch includes:
- VLDI.

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/disas.c                    |   7 +
 target/loongarch/helper.h                   |   2 +
 target/loongarch/insn_trans/trans_lsx.c.inc |  10 ++
 target/loongarch/insns.decode               |   4 +
 target/loongarch/lsx_helper.c               | 134 ++++++++++++++++++++
 5 files changed, 157 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index e8dc0644bb..0c5cc313e0 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -829,6 +829,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)
@@ -1114,6 +1119,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/helper.h b/target/loongarch/helper.h
index a92bcfffe8..cc28ecadd9 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -418,6 +418,8 @@ DEF_HELPER_3(vmskltz_d, void, env, i32, i32)
 DEF_HELPER_3(vmskgez_b, void, env, i32, i32)
 DEF_HELPER_3(vmsknz_b, void, env, i32,i32)
 
+DEF_HELPER_3(vldi, void, env, i32, i32)
+
 DEF_HELPER_4(vand_v, void, env, i32, i32, i32)
 DEF_HELPER_4(vor_v, void, env, i32, i32, i32)
 DEF_HELPER_4(vxor_v, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 308cba12f2..97969d7138 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -406,6 +406,16 @@ 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)
 
+static bool trans_vldi(DisasContext *ctx, arg_vldi *a)
+{
+    TCGv_i32 twd = tcg_constant_i32(a->vd);
+    TCGv_i32 tui = tcg_constant_i32(a->imm);
+
+    CHECK_SXE;
+    gen_helper_vldi(cpu_env, twd, tui);
+    return true;
+}
+
 TRANS(vand_v, gen_vvv, gen_helper_vand_v)
 TRANS(vor_v, gen_vvv, gen_helper_vor_v)
 TRANS(vxor_v, gen_vvv, gen_helper_vxor_v)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index f786a9a9ee..b1608fd86e 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -512,6 +512,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
@@ -549,6 +550,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
@@ -836,6 +838,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
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index 9058230975..fcaee16394 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -5239,3 +5239,137 @@ void helper_vstelm_d(CPULoongArchState *env,
     cpu_stq_data(env, addr, Vd->D[sel]);
 #endif
 }
+
+#define EXPAND_BYTE(bit)  ((uint64_t)(bit ? 0xff : 0))
+
+void helper_vldi(CPULoongArchState *env, uint32_t vd, uint32_t ui)
+{
+    int sel = (ui >> 12) & 0x1;
+    uint32_t i;
+
+    vec_t *Vd = &(env->fpr[vd].vec);
+    if (sel) {
+        /* VSETI.D */
+        int mode = (ui >> 8) & 0xf;
+        uint64_t imm = (ui & 0xff);
+        for (i = 0; i < 2; i++) {
+            switch (mode) {
+            case 0:
+                Vd->D[i] = (imm << 32) | imm;
+                break;
+            case 1:
+                Vd->D[i] = (imm << 24) | (imm << 8);
+                break;
+            case 2:
+                Vd->D[i] = (imm << 48) | (imm << 16);
+                break;
+            case 3:
+                Vd->D[i] = (imm << 56) | (imm << 24);
+                break;
+            case 4:
+                Vd->D[i] = (imm << 48) | (imm << 32) |
+                           (imm << 16) | imm;
+                break;
+            case 5:
+                Vd->D[i] = (imm << 56) | (imm << 40) |
+                           (imm << 24) | (imm << 8);
+                break;
+            case 6:
+                Vd->D[i] = (imm << 40) | ((uint64_t)0xff << 32) |
+                           (imm << 8) | 0xff;
+                break;
+            case 7:
+                Vd->D[i] = (imm << 48) | ((uint64_t)0xffff << 32) |
+                           (imm << 16) | 0xffff;
+                break;
+            case 8:
+                Vd->D[i] = (imm << 56) | (imm << 48) | (imm << 40) |
+                           (imm << 32) | (imm << 24) | (imm << 16) |
+                           (imm << 8) | imm;
+                break;
+            case 9: {
+                uint64_t b0,b1,b2,b3,b4,b5,b6,b7;
+                b0 = imm & 0x1;
+                b1 = (imm & 0x2) >> 1;
+                b2 = (imm & 0x4) >> 2;
+                b3 = (imm & 0x8) >> 3;
+                b4 = (imm & 0x10) >> 4;
+                b5 = (imm & 0x20) >> 5;
+                b6 = (imm & 0x40) >> 6;
+                b7 = (imm & 0x80) >> 7;
+                Vd->D[i] = (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: {
+                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);
+                Vd->D[i] = (t1 << 57) | (t0 << 51) |
+                           (t1 << 25) | (t0 << 19);
+                break;
+            }
+            case 11: {
+                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);
+                Vd->D[i] = (t1 << 25) | (t0 << 19);
+                break;
+            }
+            case 12: {
+                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);
+                Vd->D[i] = (t1 << 54) | (t0 << 48);
+                break;
+            }
+            default:
+                assert(0);
+            }
+        }
+    } else {
+        /* LDI.df */
+        uint32_t df = (ui >> 10) & 0x3;
+        int32_t s10 = ((int32_t)(ui << 22)) >> 22;
+
+        switch (df) {
+        case 0:
+            for (i = 0; i < LSX_LEN/8; i++) {
+                Vd->B[i] = (int8_t)s10;
+            }
+            break;
+        case 1:
+            for (i = 0; i < LSX_LEN/16; i++) {
+                Vd->H[i] = (int16_t)s10;
+            }
+            break;
+        case 2:
+            for (i = 0; i < LSX_LEN/32; i++) {
+                Vd->W[i] = (int32_t)s10;
+            }
+            break;
+        case 3:
+            for (i = 0; i < LSX_LEN/64; i++) {
+                Vd->D[i] = (int64_t)s10;
+            }
+           break;
+        default:
+            assert(0);
+        }
+    }
+}
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]