qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 06/18] target-riscv: Add JALR, Branch Instructio


From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH 06/18] target-riscv: Add JALR, Branch Instructions
Date: Mon, 26 Sep 2016 11:28:24 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0

On 09/26/2016 03:56 AM, Sagar Karandikar wrote:
Signed-off-by: Sagar Karandikar <address@hidden>
---
 target-riscv/translate.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/target-riscv/translate.c b/target-riscv/translate.c
index ccfb795..d8044cf 100644
--- a/target-riscv/translate.c
+++ b/target-riscv/translate.c
@@ -438,6 +438,106 @@ static inline void gen_arith_imm(DisasContext *ctx, 
uint32_t opc, int rd,
     tcg_temp_free(source1);
 }

+static inline void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+        int16_t imm)
+{
+    /* no chaining with JALR */
+    TCGLabel *misaligned = gen_new_label();
+    TCGLabel *done = gen_new_label();
+    target_long uimm = (target_long)imm; /* sign ext 16->64 bits */
+    TCGv t0, t1, t2, t3;
+    t0 = tcg_temp_local_new();
+    t1 = tcg_temp_local_new();
+    t2 = tcg_temp_local_new(); /* old_pc */
+    t3 = tcg_temp_local_new();
+
+    switch (opc) {
+    case OPC_RISC_JALR:
+        gen_get_gpr(t0, rs1);
+        tcg_gen_addi_tl(t0, t0, uimm);
+        tcg_gen_andi_tl(t0, t0, (target_ulong)0xFFFFFFFFFFFFFFFEll);

-2.

+        tcg_gen_andi_tl(t3, t0, 0x2);
+        tcg_gen_movi_tl(t2, ctx->pc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, t3, 0x0, misaligned);
+        tcg_gen_mov_tl(cpu_PC, t0);
+        tcg_gen_addi_tl(t1, t2, 4);
+        gen_set_gpr(rd, t1);
+        tcg_gen_br(done);
+        gen_set_label(misaligned);
+        generate_exception_mbadaddr(ctx, RISCV_EXCP_INST_ADDR_MIS);
+        gen_set_label(done);
+        tcg_gen_exit_tb(0);
+        ctx->bstate = BS_BRANCH;

You don't need any temp_local, which will significantly clean up the generated code. Try

  gen_get_gpr(cpu_PC, rs1);
  tcg_gen_addi_tl(cpu_PC, cpu_PC, imm);
  tcg_gen_andi_tl(cpu_PC, cpu_PC, -2);
  tcg_gen_andi_tl(tmp, cpu_PC, 2);
  tcg_gen_brcondi_tl(TCG_COND_NE, tmp, 0, misaligned);

  if (rd != 0) {
    tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc + 4);
  }
  tcg_gen_exit_tb(0);

  tcg_set_label(misaligned);
  generate_exception_mbadaddr(ctx, ...);

Note that cpu_PC will be reset in generate_exception, so we can initialize it early, before the branch.

+static inline void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int 
rs2,
+        int16_t bimm)

Drop the inline markers and let the compiler decide.


r~



reply via email to

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