commit 91a9bce7e95e6fc5cadee33299c25e47ba0ecba0
parent 09a30ddcb38024ba70fe616cc6669f2a448bf2fa
Author: Brian Swetland <swetland@frotz.net>
Date: Mon, 21 Oct 2019 22:13:30 -0700
rvsim: fix branch bugs
- incorrect sign expansion in get_ib()
- incorrect multiplication by two (constant already works like that)
- incorrect decodes
- passing 35 tests
Diffstat:
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/riscv.h b/riscv.h
@@ -25,7 +25,7 @@ static inline uint32_t get_ib(uint32_t ins) {
return ((ins >> 7) & 0x1e) |
((ins >> 20) & 0x7e0) |
((ins << 4) & 0x800) |
- (((int32_t)ins) >> 19);
+ (((int32_t)(ins & 0x80000000)) >> 20);
}
static inline uint32_t get_iu(uint32_t ins) {
return ins & 0xFFFFF000;
diff --git a/rvdis.c b/rvdis.c
@@ -71,7 +71,7 @@ void rvdis(uint32_t pc, uint32_t ins, char *out) {
case 'j': out = append_i32(out, get_ij(ins)); break;
case 'J': out = append_u32(out, pc + get_ij(ins)); break;
case 'b': out = append_i32(out, get_ib(ins)); break;
- case 'B': out = append_u32(out, pc + (2 * get_ib(ins))); break;
+ case 'B': out = append_u32(out, pc + get_ib(ins)); break;
case 's': out = append_i32(out, get_is(ins)); break;
case 'u': out = append_i32(out, get_iu(ins)); break;
case 'U': out = append_u32(out, get_iu(ins)); break;
diff --git a/rvsim.c b/rvsim.c
@@ -207,14 +207,14 @@ void rvsim(rvstate_t* s) {
switch (get_fn3(ins)) {
case F3_BEQ: p = (a == b); break;
case F3_BNE: p = (a != b); break;
- case F3_BLT: p = (((int32_t)a) == ((int32_t)b)); break;
- case F3_BGE: p = (((int32_t)a) == ((int32_t)b)); break;
- case F3_BLTU: p = (a <= b); break;
+ case F3_BLT: p = (((int32_t)a) < ((int32_t)b)); break;
+ case F3_BGE: p = (((int32_t)a) >= ((int32_t)b)); break;
+ case F3_BLTU: p = (a < b); break;
case F3_BGEU: p = (a >= b); break;
default:
goto inval;
}
- if (p) next = pc + (get_ib(ins) << 1);
+ if (p) next = pc + get_ib(ins);
break;
}
case OC_JALR: