Add MIPS P8700 ldp, lwp, sdp, swp instructions.

Signed-off-by: Chao-ying Fu <c...@mips.com>
Signed-off-by: Djordje Todorovic <djordje.todoro...@htecgroup.com>
---
 target/riscv/cpu.c                        |  3 +
 target/riscv/cpu_cfg.h                    |  3 +-
 target/riscv/insn_trans/trans_xmips.c.inc | 84 +++++++++++++++++++++++
 target/riscv/xmips.decode                 | 12 ++++
 4 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d201a0dd02..39872cfec5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -238,6 +238,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
     ISA_EXT_DATA_ENTRY(xmipscbop, PRIV_VERSION_1_12_0, ext_xmipscbop),
     ISA_EXT_DATA_ENTRY(xmipscmov, PRIV_VERSION_1_12_0, ext_xmipscmov),
+    ISA_EXT_DATA_ENTRY(xmipslsp, PRIV_VERSION_1_12_0, ext_xmipslsp),
 
     { },
 };
@@ -544,6 +545,7 @@ static void rv64_mips_p8700_cpu_init(Object *obj)
     cpu->cfg.ext_zbb = true;
     cpu->cfg.ext_xmipscbop = true;
     cpu->cfg.ext_xmipscmov = true;
+    cpu->cfg.ext_xmipslsp = true;
     cpu->cfg.marchid = 0x8000000000000201;
 }
 
@@ -1762,6 +1764,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
     MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
     MULTI_EXT_CFG_BOOL("xmipscbop", ext_xmipscbop, false),
     MULTI_EXT_CFG_BOOL("xmipscmov", ext_xmipscmov, false),
+    MULTI_EXT_CFG_BOOL("xmipslsp", ext_xmipslsp, false),
 
     { },
 };
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 9643625018..68634c49e7 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -184,6 +184,7 @@ struct RISCVCPUConfig {
     bool ext_XVentanaCondOps;
     bool ext_xmipscbop;
     bool ext_xmipscmov;
+    bool ext_xmipslsp;
 
     uint32_t pmu_mask;
     uint16_t vlenb;
@@ -214,7 +215,7 @@ static inline bool always_true_p(const RISCVCPUConfig *cfg 
__attribute__((__unus
 
 static inline bool has_xmips_p(const RISCVCPUConfig *cfg)
 {
-    return cfg->ext_xmipscbop || cfg->ext_xmipscmov;
+    return cfg->ext_xmipscbop || cfg->ext_xmipscmov || cfg->ext_xmipslsp;
 }
 
 static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
diff --git a/target/riscv/insn_trans/trans_xmips.c.inc 
b/target/riscv/insn_trans/trans_xmips.c.inc
index 375970defc..8f6d485a52 100644
--- a/target/riscv/insn_trans/trans_xmips.c.inc
+++ b/target/riscv/insn_trans/trans_xmips.c.inc
@@ -28,6 +28,12 @@
     }                                            \
 } while (0)
 
+#define REQUIRE_XMIPSLSP(ctx) do {               \
+    if (!ctx->cfg_ptr->ext_xmipslsp) {           \
+        return false;                            \
+    }                                            \
+} while (0)
+
 static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
 {
     REQUIRE_XMIPSCMOV(ctx);
@@ -43,6 +49,84 @@ static bool trans_ccmov(DisasContext *ctx, arg_ccmov *a)
     return true;
 }
 
+static bool trans_ldp(DisasContext *ctx, arg_ldp *a)
+{
+    REQUIRE_XMIPSLSP(ctx);
+    REQUIRE_64_OR_128BIT(ctx);
+
+    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv dest0 = dest_gpr(ctx, a->rd);
+    TCGv dest1 = dest_gpr(ctx, a->rs3);
+    TCGv addr = tcg_temp_new();
+
+    tcg_gen_addi_tl(addr, src, a->imm_y);
+    tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESQ);
+    gen_set_gpr(ctx, a->rd, dest0);
+
+    tcg_gen_addi_tl(addr, addr, 8);
+    tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESQ);
+    gen_set_gpr(ctx, a->rs3, dest1);
+
+    return true;
+}
+
+static bool trans_lwp(DisasContext *ctx, arg_lwp *a)
+{
+    REQUIRE_XMIPSLSP(ctx);
+
+    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv dest0 = dest_gpr(ctx, a->rd);
+    TCGv dest1 = dest_gpr(ctx, a->rs3);
+    TCGv addr = tcg_temp_new();
+
+    tcg_gen_addi_tl(addr, src, a->imm_x);
+    tcg_gen_qemu_ld_tl(dest0, addr, ctx->mem_idx, MO_TESL);
+    gen_set_gpr(ctx, a->rd, dest0);
+
+    tcg_gen_addi_tl(addr, addr, 4);
+    tcg_gen_qemu_ld_tl(dest1, addr, ctx->mem_idx, MO_TESL);
+    gen_set_gpr(ctx, a->rs3, dest1);
+
+    return true;
+}
+
+static bool trans_sdp(DisasContext *ctx, arg_sdp *a)
+{
+    REQUIRE_XMIPSLSP(ctx);
+    REQUIRE_64_OR_128BIT(ctx);
+
+    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv data0 = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv data1 = get_gpr(ctx, a->rs3, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    tcg_gen_addi_tl(addr, src, a->imm_w);
+    tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TEUQ);
+
+    tcg_gen_addi_tl(addr, addr, 8);
+    tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TEUQ);
+
+    return true;
+}
+
+static bool trans_swp(DisasContext *ctx, arg_swp *a)
+{
+    REQUIRE_XMIPSLSP(ctx);
+
+    TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv data0 = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv data1 = get_gpr(ctx, a->rs3, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    tcg_gen_addi_tl(addr, src, a->imm_v);
+    tcg_gen_qemu_st_tl(data0, addr, ctx->mem_idx, MO_TESL);
+
+    tcg_gen_addi_tl(addr, addr, 4);
+    tcg_gen_qemu_st_tl(data1, addr, ctx->mem_idx, MO_TESL);
+
+    return true;
+}
+
 static bool trans_pref(DisasContext *ctx, arg_pref *a)
 {
     REQUIRE_XMIPSCBOP(ctx);
diff --git a/target/riscv/xmips.decode b/target/riscv/xmips.decode
index 56237fe610..07802bf30e 100644
--- a/target/riscv/xmips.decode
+++ b/target/riscv/xmips.decode
@@ -15,13 +15,25 @@
 %rd        7:5
 %imm_9     20:9
 %imm_hint  7:5
+%imm_v     25:2 9:3               !function=ex_shift_2
+%imm_w     25:2 10:2              !function=ex_shift_3
+%imm_x     22:5                   !function=ex_shift_2
+%imm_y     23:4                   !function=ex_shift_3
 
 # Argument sets
 
 # Formats
 @r1_pref ...   ......... ..... ... ..... ....... %imm_9 %rs1 %imm_hint
 @r4      ..... ..  ..... ..... ... ..... ....... %rs3 %rs2 %rs1 %rd
+@r4_immv ..... .. ..... ..... ... ... .. ....... %rs2 %rs3 %imm_v %rs1
+@r4_immw ..... .. ..... ..... ... .. ... ....... %rs2 %rs3 %imm_w %rs1
+@r4_immx ..... .....  .. ..... ... ..... ....... %rs3 %imm_x %rs1 %rd
+@r4_immy ..... ....  ... ..... ... ..... ....... %rs3 %imm_y %rs1 %rd
 
 # *** RV64 MIPS Extension ***
 ccmov       .....11  ..... ..... 011 .....  0001011 @r4
+ldp         ..... .... 000 ..... 100 .....  0001011 @r4_immy
+lwp         ..... ..... 01 ..... 100 .....  0001011 @r4_immx
+sdp         ..... .. ..... ..... 101 ..  0000001011 @r4_immw
+swp         ..... .. ..... ..... 101 ...  010001011 @r4_immv
 pref        000  ......... ..... 000 .....  0001011 @r1_pref
-- 
2.34.1

Reply via email to