sim/riscv: fix JALR instruction simulation
authorJaydeep Patil <Jaydeep.Patil@imgtec.com>
Wed, 18 Oct 2023 16:37:59 +0000 (17:37 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Wed, 18 Oct 2023 16:55:31 +0000 (17:55 +0100)
Fix 32bit 'jalr rd,ra,imm' integer instruction, where RD was written
before using it to calculate destination address.

This commit also improves testutils.inc for riscv; make use of
pushsection and popsection when adding things to .data, and setup the
%gp global pointer register within the 'start' macro.

Approved-By: Andrew Burgess <aburgess@redhat.com>
sim/riscv/sim-main.c
sim/testsuite/riscv/jalr.s [new file with mode: 0644]
sim/testsuite/riscv/testutils.inc

index 250791634a19f079f85f459cce322879284e12ba..afdfcf506566973f1f27d63ba6ed895f6226d48f 100644 (file)
@@ -449,8 +449,8 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op)
       break;
     case MATCH_JALR:
       TRACE_INSN (cpu, "jalr %s, %s, %" PRIiTW ";", rd_name, rs1_name, i_imm);
-      store_rd (cpu, rd, riscv_cpu->pc + 4);
       pc = riscv_cpu->regs[rs1] + i_imm;
+      store_rd (cpu, rd, riscv_cpu->pc + 4);
       TRACE_BRANCH (cpu, "to %#" PRIxTW, pc);
       break;
 
diff --git a/sim/testsuite/riscv/jalr.s b/sim/testsuite/riscv/jalr.s
new file mode 100644 (file)
index 0000000..daccf4f
--- /dev/null
@@ -0,0 +1,22 @@
+# Basic jalr tests.
+# mach: riscv
+
+.include "testutils.inc"
+
+       start
+
+       # Load desination into register a0.
+       la      a0, good_dest
+
+       # Jump to the destination in a0.
+       jalr    a0, a0, 0
+
+       # If we write destination into a0 before reading it in order
+       # to jump, we might end up here.
+bad_dest:
+       fail
+
+       # We should end up here.
+good_dest:
+       pass
+       fail
index b9680b9c22e09c3591d82408c3bc47d314e2feb7..c5e09eb5ea329f5d9d88ad36e45188ce9b928f7a 100644 (file)
@@ -21,8 +21,9 @@
        # Trigger OS trap.
        ecall;
        exit 0;
-       .data
+       .pushsection .data
        1: .asciz "pass\n"
+       .popsection
        .endm
 
 # MACRO: fail
        # Use stdout.
        li a0, 1;
        # Point to the string.
-       lla a1, 1f;
+       la a1, 1f;
        # Number of bytes to write.
        li a2, 5;
        # Trigger OS trap.
        ecall;
        exit 0;
-       .data
+       .pushsection .data
        1: .asciz "fail\n"
+       .popsection
        .endm
 
 # MACRO: start
@@ -49,4 +51,8 @@
        .text
 .global _start
 _start:
+       .option push
+       .option norelax
+       lla gp, __global_pointer$
+       .option pop
        .endm