diff --git a/riscv/decode.h b/riscv/decode.h index e6d0e8a4..a49137a3 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -199,10 +199,12 @@ private: softfloat_exceptionFlags = 0; }) #define require_rvc if(!(sr & SR_EC)) throw trap_illegal_instruction +#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4) #define sext32(x) ((sreg_t)(int32_t)(x)) -#define insn_length(x) (((x).bits & 0x3) < 0x3 ? 2 : 4) +#define zext32(x) ((reg_t)(uint32_t)(x)) #define sext_xprlen(x) ((sreg_t(x) << (64-xprlen)) >> (64-xprlen)) +#define zext_xprlen(x) ((reg_t(x) << (64-xprlen)) >> (64-xprlen)) // RVC stuff diff --git a/riscv/insns/div.h b/riscv/insns/div.h index 96d9e10e..82a40666 100644 --- a/riscv/insns/div.h +++ b/riscv/insns/div.h @@ -3,4 +3,4 @@ if(RS2 == 0) else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = RS1; else - RD = sext_xprlen(sreg_t(RS1) / sreg_t(RS2)); + RD = sext_xprlen(sext_xprlen(RS1) / sext_xprlen(RS2)); diff --git a/riscv/insns/divu.h b/riscv/insns/divu.h index d4a4eca0..681afd21 100644 --- a/riscv/insns/divu.h +++ b/riscv/insns/divu.h @@ -1,4 +1,4 @@ if(RS2 == 0) RD = UINT64_MAX; else - RD = sext_xprlen(RS1 / RS2); + RD = sext_xprlen(zext_xprlen(RS1) / zext_xprlen(RS2)); diff --git a/riscv/insns/divuw.h b/riscv/insns/divuw.h index 4d64be3b..0ceb0402 100644 --- a/riscv/insns/divuw.h +++ b/riscv/insns/divuw.h @@ -2,4 +2,4 @@ require_xpr64; if(RS2 == 0) RD = UINT64_MAX; else - RD = sext32(RS1 / RS2); + RD = sext32(zext32(RS1) / zext32(RS2)); diff --git a/riscv/insns/divw.h b/riscv/insns/divw.h index ee940da8..5bf4db0a 100644 --- a/riscv/insns/divw.h +++ b/riscv/insns/divw.h @@ -6,4 +6,4 @@ if(RS2 == 0) else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = RS1; else - RD = sext32(sreg_t(RS1) / sreg_t(RS2)); + RD = sext32(int32_t(RS1) / int32_t(RS2)); diff --git a/riscv/insns/mulh.h b/riscv/insns/mulh.h index ceefccd9..f771a621 100644 --- a/riscv/insns/mulh.h +++ b/riscv/insns/mulh.h @@ -5,4 +5,4 @@ if(xpr64) RD = (int128_t(a) * int128_t(b)) >> 64; } else - RD = sext32((sreg_t(RS1) * sreg_t(RS2)) >> 32); + RD = sext32((sext32(RS1) * sext32(RS2)) >> 32); diff --git a/riscv/insns/mulhsu.h b/riscv/insns/mulhsu.h index e5f1c951..c832657e 100644 --- a/riscv/insns/mulhsu.h +++ b/riscv/insns/mulhsu.h @@ -5,4 +5,4 @@ if(xpr64) RD = (int128_t(a) * uint128_t(b)) >> 64; } else - RD = sext32((sreg_t(RS1) * reg_t((uint32_t)RS2)) >> 32); + RD = sext32((sext32(RS1) * reg_t((uint32_t)RS2)) >> 32); diff --git a/riscv/insns/rem.h b/riscv/insns/rem.h index db7e0a96..ac82a56f 100644 --- a/riscv/insns/rem.h +++ b/riscv/insns/rem.h @@ -3,4 +3,4 @@ if(RS2 == 0) else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = 0; else - RD = sext_xprlen(sreg_t(RS1) % sreg_t(RS2)); + RD = sext_xprlen(sext_xprlen(RS1) % sext_xprlen(RS2)); diff --git a/riscv/insns/remu.h b/riscv/insns/remu.h index 04499ab3..c698aca2 100644 --- a/riscv/insns/remu.h +++ b/riscv/insns/remu.h @@ -1,4 +1,4 @@ if(RS2 == 0) RD = RS1; else - RD = sext_xprlen(RS1 % RS2); + RD = sext_xprlen(zext_xprlen(RS1) % zext_xprlen(RS2)); diff --git a/riscv/insns/remuw.h b/riscv/insns/remuw.h index ae28fa56..8234af38 100644 --- a/riscv/insns/remuw.h +++ b/riscv/insns/remuw.h @@ -2,4 +2,4 @@ require_xpr64; if(RS2 == 0) RD = RS1; else - RD = sext32(RS1 % RS2); + RD = sext32(zext_xprlen(RS1) % zext_xprlen(RS2)); diff --git a/riscv/insns/remw.h b/riscv/insns/remw.h index 784baa39..c338516c 100644 --- a/riscv/insns/remw.h +++ b/riscv/insns/remw.h @@ -6,4 +6,4 @@ if(RS2 == 0) else if(sreg_t(RS1) == INT64_MIN && sreg_t(RS2) == -1) RD = 0; else - RD = sext32(sreg_t(RS1) % sreg_t(RS2)); + RD = sext32(int32_t(RS1) % int32_t(RS2)); diff --git a/riscv/insns/sra.h b/riscv/insns/sra.h index 8bbdc097..7102da0c 100644 --- a/riscv/insns/sra.h +++ b/riscv/insns/sra.h @@ -1 +1 @@ -RD = sext_xprlen(sreg_t(RS1) >> (RS2 & (xprlen-1))); +RD = sext_xprlen(sext_xprlen(RS1) >> (RS2 & (xprlen-1))); diff --git a/riscv/insns/sraw.h b/riscv/insns/sraw.h index 103f03a3..d1783741 100644 --- a/riscv/insns/sraw.h +++ b/riscv/insns/sraw.h @@ -1,2 +1,2 @@ require_xpr64; -RD = sext32(sreg_t(RS1) >> (RS2 & 0x1F)); +RD = sext32(int32_t(RS1) >> (RS2 & 0x1F));