[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 07/18] target-riscv: Add Loads/Stores, FP Loads/Stor
From: |
Sagar Karandikar |
Subject: |
[Qemu-devel] [PATCH 07/18] target-riscv: Add Loads/Stores, FP Loads/Stores |
Date: |
Mon, 26 Sep 2016 03:56:37 -0700 |
Signed-off-by: Sagar Karandikar <address@hidden>
---
target-riscv/translate.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/target-riscv/translate.c b/target-riscv/translate.c
index d8044cf..767cdbe 100644
--- a/target-riscv/translate.c
+++ b/target-riscv/translate.c
@@ -72,6 +72,10 @@ static const char * const fpr_regnames[] = {
"fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
};
+/* convert riscv funct3 to qemu memop for load/store */
+static int tcg_memop_lookup[] = { MO_SB, MO_TESW, MO_TESL, MO_TEQ, MO_UB,
+ MO_TEUW, MO_TEUL };
+
static inline void generate_exception(DisasContext *ctx, int excp)
{
tcg_gen_movi_tl(cpu_PC, ctx->pc);
@@ -538,6 +542,105 @@ static inline void gen_branch(DisasContext *ctx, uint32_t
opc, int rs1, int rs2,
ctx->bstate = BS_BRANCH;
}
+static inline void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+ int16_t imm)
+{
+ target_long uimm = (target_long)imm; /* sign ext 16->64 bits */
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ gen_get_gpr(t0, rs1);
+ tcg_gen_addi_tl(t0, t0, uimm); /* */
+ int memop = (opc >> 12) & 0x7;
+
+#if defined(TARGET_RISCV64)
+ if (memop == 0x7) {
+#else
+ if (memop == 0x7 || memop == 0x3 || memop == 0x6) {
+#endif
+ kill_unknown(ctx, RISCV_EXCP_ILLEGAL_INST);
+ } else {
+ tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, tcg_memop_lookup[memop]);
+ }
+
+ gen_set_gpr(rd, t1);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
+static inline void gen_store(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+ int16_t imm)
+{
+ target_long uimm = (target_long)imm; /* sign ext 16->64 bits */
+
+ TCGv t0 = tcg_temp_new();
+ TCGv dat = tcg_temp_new();
+ gen_get_gpr(t0, rs1);
+ tcg_gen_addi_tl(t0, t0, uimm);
+ gen_get_gpr(dat, rs2);
+ int memop = (opc >> 12) & 0x7;
+
+#if defined(TARGET_RISCV64)
+ if (memop > 0x3) {
+#else
+ if (memop > 0x2) {
+#endif
+ kill_unknown(ctx, RISCV_EXCP_ILLEGAL_INST);
+ } else {
+ tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, tcg_memop_lookup[memop]);
+ }
+
+ tcg_temp_free(t0);
+ tcg_temp_free(dat);
+}
+
+static inline void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
+ int rs1, int16_t imm)
+{
+ target_long uimm = (target_long)imm; /* sign ext 16->64 bits */
+ TCGv t0 = tcg_temp_new();
+ gen_get_gpr(t0, rs1);
+ tcg_gen_addi_tl(t0, t0, uimm);
+
+ switch (opc) {
+ case OPC_RISC_FLW:
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
+ break;
+ case OPC_RISC_FLD:
+ tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
+ break;
+ default:
+ kill_unknown(ctx, RISCV_EXCP_ILLEGAL_INST);
+ break;
+ }
+ tcg_temp_free(t0);
+}
+
+static inline void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
+ int rs2, int16_t imm)
+{
+ target_long uimm = (target_long)imm; /* sign ext 16->64 bits */
+
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ gen_get_gpr(t0, rs1);
+ tcg_gen_addi_tl(t0, t0, uimm);
+
+ switch (opc) {
+ case OPC_RISC_FSW:
+ tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
+ break;
+ case OPC_RISC_FSD:
+ tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
+ break;
+ default:
+ kill_unknown(ctx, RISCV_EXCP_ILLEGAL_INST);
+ break;
+ }
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
static void decode_opc(CPURISCVState *env, DisasContext *ctx)
{
int rs1;
@@ -611,6 +714,13 @@ static void decode_opc(CPURISCVState *env, DisasContext
*ctx)
gen_branch(ctx, MASK_OP_BRANCH(ctx->opcode), rs1, rs2,
GET_B_IMM(ctx->opcode));
break;
+ case OPC_RISC_LOAD:
+ gen_load(ctx, MASK_OP_LOAD(ctx->opcode), rd, rs1, imm);
+ break;
+ case OPC_RISC_STORE:
+ gen_store(ctx, MASK_OP_STORE(ctx->opcode), rs1, rs2,
+ GET_STORE_IMM(ctx->opcode));
+ break;
case OPC_RISC_ARITH_IMM:
#if defined(TARGET_RISCV64)
case OPC_RISC_ARITH_IMM_W:
@@ -629,6 +739,13 @@ static void decode_opc(CPURISCVState *env, DisasContext
*ctx)
}
gen_arith(ctx, MASK_OP_ARITH(ctx->opcode), rd, rs1, rs2);
break;
+ case OPC_RISC_FP_LOAD:
+ gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
+ break;
+ case OPC_RISC_FP_STORE:
+ gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
+ GET_STORE_IMM(ctx->opcode));
+ break;
default:
kill_unknown(ctx, RISCV_EXCP_ILLEGAL_INST);
break;
--
2.9.3
- [Qemu-devel] [PATCH 00/18] target-riscv: Add full-system emulation support for the RISC-V Instruction Set Architecture (RV64G, RV32G), Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 06/18] target-riscv: Add JALR, Branch Instructions, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 01/18] target-riscv: Add RISC-V target stubs and Maintainer, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 15/18] target-riscv: Interrupt Handling, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 07/18] target-riscv: Add Loads/Stores, FP Loads/Stores,
Sagar Karandikar <=
- [Qemu-devel] [PATCH 08/18] target-riscv: Add Atomic Instructions, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 03/18] target-riscv: Add initialization for translation, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 14/18] target-riscv: softmmu/address translation support, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 16/18] target-riscv: Timer Support, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 12/18] target-riscv: Add system instructions, Sagar Karandikar, 2016/09/26