diff --git a/rvgo/fast/vm.go b/rvgo/fast/vm.go index 3e1755d6..6d10faa5 100644 --- a/rvgo/fast/vm.go +++ b/rvgo/fast/vm.go @@ -670,8 +670,16 @@ func (inst *InstrumentedState) riscvStep() (outErr error) { case 0: // 000 = ADDIW rdValue = mask32Signed64(add64(rs1Value, imm)) case 1: // 001 = SLLIW + // SLLIW where imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) != 0 { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } rdValue = mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value)) case 5: // 101 = SR~ + // SRLIW and SRAIW where imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) != 0 { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } shamt := and64(imm, toU64(0x1F)) switch shr64(toU64(5), imm) { // top 7 bits select the shift type case 0x00: // 0000000 = SRLIW diff --git a/rvgo/slow/vm.go b/rvgo/slow/vm.go index 458f00c6..e7a0317e 100644 --- a/rvgo/slow/vm.go +++ b/rvgo/slow/vm.go @@ -843,8 +843,16 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err case 0: // 000 = ADDIW rdValue = mask32Signed64(add64(rs1Value, imm)) case 1: // 001 = SLLIW + // SLLIW where imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) != (U64{}) { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } rdValue = mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value)) case 5: // 101 = SR~ + // SRLIW and SRAIW imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) != (U64{}) { + revertWithCode(riscv.ErrInvalidSyscall, fmt.Errorf("illegal instruction %d: reserved instruction encoding", instr)) + } shamt := and64(imm, toU64(0x1F)) switch shr64(toU64(5), imm).val() { // top 7 bits select the shift type case 0x00: // 0000000 = SRLIW diff --git a/rvsol/src/RISCV.sol b/rvsol/src/RISCV.sol index 1bbb681e..1bac7d30 100644 --- a/rvsol/src/RISCV.sol +++ b/rvsol/src/RISCV.sol @@ -1271,9 +1271,19 @@ contract RISCV is IBigStepper { } case 1 { // 001 = SLLIW + + // SLLIW where imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) { + revertWithCode(0xf001ca11) + } rdValue := mask32Signed64(shl64(and64(imm, toU64(0x1F)), rs1Value)) } case 5 { + // SRLIW and SRAIW where imm[5] != 0 is reserved + if and64(imm, toU64(0x20)) { + revertWithCode(0xf001ca11) + } + // 101 = SR~ let shamt := and64(imm, toU64(0x1F)) switch shr64(toU64(5), imm)