[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH V12 5/8] target/mips: Add loongson-ext lsdc2 group of instruction
From: |
Huacai Chen |
Subject: |
[PATCH V12 5/8] target/mips: Add loongson-ext lsdc2 group of instructions |
Date: |
Mon, 28 Sep 2020 17:49:43 +0800 |
From: Jiaxun Yang <jiaxun.yang@flygoat.com>
LDC2/SDC2 opcodes have been rewritten as "load & store with offset"
group of instructions by loongson-ext ASE.
This patch add implementation of these instructions:
gslbx: load 1 bytes to GPR
gslhx: load 2 bytes to GPR
gslwx: load 4 bytes to GPR
gsldx: load 8 bytes to GPR
gslwxc1: load 4 bytes to FPR
gsldxc1: load 8 bytes to FPR
gssbx: store 1 bytes from GPR
gsshx: store 2 bytes from GPR
gsswx: store 4 bytes from GPR
gssdx: store 8 bytes from GPR
gsswxc1: store 4 bytes from FPR
gssdxc1: store 8 bytes from FPR
Details of Loongson-EXT is here:
https://github.com/FlyGoat/loongson-insn/blob/master/loongson-ext.md
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
target/mips/translate.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 179 insertions(+)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 916b57f..4d42cfc 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -484,6 +484,24 @@ enum {
OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
};
+/* Loongson EXT LDC2/SDC2 opcodes */
+#define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
+
+enum {
+ OPC_GSLBX = 0x0 | OPC_LDC2,
+ OPC_GSLHX = 0x1 | OPC_LDC2,
+ OPC_GSLWX = 0x2 | OPC_LDC2,
+ OPC_GSLDX = 0x3 | OPC_LDC2,
+ OPC_GSLWXC1 = 0x6 | OPC_LDC2,
+ OPC_GSLDXC1 = 0x7 | OPC_LDC2,
+ OPC_GSSBX = 0x0 | OPC_SDC2,
+ OPC_GSSHX = 0x1 | OPC_SDC2,
+ OPC_GSSWX = 0x2 | OPC_SDC2,
+ OPC_GSSDX = 0x3 | OPC_SDC2,
+ OPC_GSSWXC1 = 0x6 | OPC_SDC2,
+ OPC_GSSDXC1 = 0x7 | OPC_SDC2,
+};
+
/* BSHFL opcodes */
#define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
@@ -6172,6 +6190,165 @@ static void gen_loongson_lswc2(DisasContext *ctx, int
rt,
tcg_temp_free(t0);
}
+/* Loongson EXT LDC2/SDC2 */
+static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
+ int rs, int rd)
+{
+ int offset = (int8_t)(ctx->opcode >> 3);
+ uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
+ TCGv t0, t1;
+ TCGv_i32 fp0;
+
+ /* Pre-conditions */
+ switch (opc) {
+ case OPC_GSLBX:
+ case OPC_GSLHX:
+ case OPC_GSLWX:
+ case OPC_GSLDX:
+ /* prefetch, implement as NOP */
+ if (rt == 0) {
+ return;
+ }
+ break;
+ case OPC_GSSBX:
+ case OPC_GSSHX:
+ case OPC_GSSWX:
+ case OPC_GSSDX:
+ break;
+ case OPC_GSLWXC1:
+#if defined(TARGET_MIPS64)
+ case OPC_GSLDXC1:
+#endif
+ check_cp1_enabled(ctx);
+ /* prefetch, implement as NOP */
+ if (rt == 0) {
+ return;
+ }
+ break;
+ case OPC_GSSWXC1:
+#if defined(TARGET_MIPS64)
+ case OPC_GSSDXC1:
+#endif
+ check_cp1_enabled(ctx);
+ break;
+ default:
+ MIPS_INVAL("loongson_lsdc2");
+ generate_exception_end(ctx, EXCP_RI);
+ return;
+ break;
+ }
+
+ t0 = tcg_temp_new();
+
+ gen_base_offset_addr(ctx, t0, rs, offset);
+ gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
+
+ switch (opc) {
+ case OPC_GSLBX:
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
+ gen_store_gpr(t0, rt);
+ break;
+ case OPC_GSLHX:
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, rt);
+ break;
+ case OPC_GSLWX:
+ gen_base_offset_addr(ctx, t0, rs, offset);
+ if (rd) {
+ gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
+ }
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, rt);
+ break;
+#if defined(TARGET_MIPS64)
+ case OPC_GSLDX:
+ gen_base_offset_addr(ctx, t0, rs, offset);
+ if (rd) {
+ gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
+ }
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_gpr(t0, rt);
+ break;
+#endif
+ case OPC_GSLWXC1:
+ check_cp1_enabled(ctx);
+ gen_base_offset_addr(ctx, t0, rs, offset);
+ if (rd) {
+ gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
+ }
+ fp0 = tcg_temp_new_i32();
+ tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
+ ctx->default_tcg_memop_mask);
+ gen_store_fpr32(ctx, fp0, rt);
+ tcg_temp_free_i32(fp0);
+ break;
+#if defined(TARGET_MIPS64)
+ case OPC_GSLDXC1:
+ check_cp1_enabled(ctx);
+ gen_base_offset_addr(ctx, t0, rs, offset);
+ if (rd) {
+ gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
+ }
+ tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+ ctx->default_tcg_memop_mask);
+ gen_store_fpr64(ctx, t0, rt);
+ break;
+#endif
+ case OPC_GSSBX:
+ t1 = tcg_temp_new();
+ gen_load_gpr(t1, rt);
+ tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
+ tcg_temp_free(t1);
+ break;
+ case OPC_GSSHX:
+ t1 = tcg_temp_new();
+ gen_load_gpr(t1, rt);
+ tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
+ ctx->default_tcg_memop_mask);
+ tcg_temp_free(t1);
+ break;
+ case OPC_GSSWX:
+ t1 = tcg_temp_new();
+ gen_load_gpr(t1, rt);
+ tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ tcg_temp_free(t1);
+ break;
+#if defined(TARGET_MIPS64)
+ case OPC_GSSDX:
+ t1 = tcg_temp_new();
+ gen_load_gpr(t1, rt);
+ tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+ ctx->default_tcg_memop_mask);
+ tcg_temp_free(t1);
+ break;
+#endif
+ case OPC_GSSWXC1:
+ fp0 = tcg_temp_new_i32();
+ gen_load_fpr32(ctx, fp0, rt);
+ tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
+ ctx->default_tcg_memop_mask);
+ tcg_temp_free_i32(fp0);
+ break;
+#if defined(TARGET_MIPS64)
+ case OPC_GSSDXC1:
+ t1 = tcg_temp_new();
+ gen_load_fpr64(ctx, t1, rt);
+ tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
+ ctx->default_tcg_memop_mask);
+ tcg_temp_free(t1);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ tcg_temp_free(t0);
+}
+
/* Traps */
static void gen_trap(DisasContext *ctx, uint32_t opc,
int rs, int rt, int16_t imm)
@@ -31055,6 +31232,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext
*ctx)
/* OPC_JIC, OPC_JIALC */
gen_compute_compact_branch(ctx, op, 0, rt, imm);
}
+ } else if (ctx->insn_flags & ASE_LEXT) {
+ gen_loongson_lsdc2(ctx, rt, rs, rd);
} else {
/* OPC_LWC2, OPC_SWC2 */
/* COP2: Not implemented. */
--
2.7.0
- [PATCH V12 0/8] mips: Add Loongson-3 machine support, Huacai Chen, 2020/09/28
- [PATCH V12 1/8] linux-headers: Update MIPS KVM type defintition, Huacai Chen, 2020/09/28
- [PATCH V12 2/8] target/mips: Fix PageMask with variable page size, Huacai Chen, 2020/09/28
- [PATCH V12 3/8] target/mips: Add loongson-ext lswc2 group of instructions (Part 1), Huacai Chen, 2020/09/28
- [PATCH V12 4/8] target/mips: Add loongson-ext lswc2 group of instructions (Part 2), Huacai Chen, 2020/09/28
- [PATCH V12 5/8] target/mips: Add loongson-ext lsdc2 group of instructions,
Huacai Chen <=
- [PATCH V12 6/8] hw/mips: Implement fw_cfg_arch_key_name(), Huacai Chen, 2020/09/28
- [PATCH V12 7/8] hw/mips: Add Loongson-3 machine support, Huacai Chen, 2020/09/28
- [PATCH V12 8/8] docs/system: Update MIPS machine documentation, Huacai Chen, 2020/09/28