Skip to content

Commit

Permalink
Partially support CSRRW where source and destination register is zero
Browse files Browse the repository at this point in the history
  • Loading branch information
mininny committed Jan 13, 2025
1 parent 4f45fbd commit 02f4b12
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
14 changes: 12 additions & 2 deletions rvgo/fast/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -866,8 +866,18 @@ func (inst *InstrumentedState) riscvStep() (outErr error) {
default: // imm12 = 000000000001 EBREAK
setPC(add64(pc, toU64(4))) // ignore breakpoint
}
default: // CSR instructions
setRegister(rd, 0) // ignore CSR instructions
case 1:
// CSRRW
rs1Value := getRegister(rs1)
rdValue := add64(pc, toU64(4))
// no source or destination registers must be specified
if or64(rs1Value, rdValue) != 0 {
revertWithCode(riscv.ErrIllegalInstruction, fmt.Errorf("only no-op CSRRW instruction are supported"))
}
setRegister(rd, 0)
setPC(add64(pc, toU64(4)))
default:
setRegister(rd, 0) // ignore other CSR instructions
setPC(add64(pc, toU64(4)))
}
case 0x2F: // 010_1111: RV32A and RV32A atomic operations extension
Expand Down
1 change: 1 addition & 0 deletions rvgo/riscv/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const (
ErrUnexpectedRProofLoad = uint64(0xbad22220)
ErrUnexpectedRProofStoreUnaligned = uint64(0xbad22221)
ErrUnexpectedRProofStore = uint64(0xbad2222f)
ErrIllegalInstruction = uint64(0xbadc0de)
ErrBadAMOSize = uint64(0xbada70)
ErrFailToReadPreimage = uint64(0xbadf00d0)
ErrBadMemoryProof = uint64(0xbadf00d1)
Expand Down
12 changes: 11 additions & 1 deletion rvgo/slow/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,17 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err
default: // imm12 = 000000000001 EBREAK
setPC(add64(pc, toU64(4))) // ignore breakpoint
}
default: // ignore CSR instructions
case 1:
// CSRRW
rs1Value := getRegister(rs1)
rdValue := getRegister(rd)
// no source or destination registers must be specified
if or64(rs1Value, rdValue) != (U64{}) {
revertWithCode(riscv.ErrIllegalInstruction, fmt.Errorf("only no-op CSRRW instruction are supported"))
}
setRegister(rd, toU64(0))
setPC(add64(pc, toU64(4)))
default: // ignore other CSR instructions
setRegister(rd, toU64(0)) // ignore CSR instructions
setPC(add64(pc, toU64(4)))
}
Expand Down
11 changes: 11 additions & 0 deletions rvsol/src/RISCV.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,17 @@ contract RISCV is IBigStepper {
setPC(add64(_pc, toU64(4))) // ignore breakpoint
}
}
case 1 {
// CSRRW
let rs1Value := getRegister(rs1)
let rdValue := getRegister(rd)

// no source or destination registers must be specified
if or64(rs1Value, rdValue) { revertWithCode(0xbadc0de) }

setRegister(rd, toU64(0))
setPC(add64(_pc, toU64(4)))
}
default {
// CSR instructions
setRegister(rd, toU64(0)) // ignore CSR instructions
Expand Down
2 changes: 1 addition & 1 deletion rvsol/test/RISCV.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1801,7 +1801,7 @@ contract RISCV_Test is CommonTest {

function test_csrrw_succeeds() public {
uint16 imm = 0x29a;
uint32 insn = encodeIType(0x73, 13, 1, 2, imm); // csrrw x13, 0x29a, x2
uint32 insn = encodeIType(0x73, 0x0, 0x1, 0x0, imm); // csrrw 0x0, 0x29a, 0x0
(State memory state, bytes memory proof) = constructRISCVState(0, insn);
state.registers[2] = 0x4797;
bytes memory encodedState = encodeState(state);
Expand Down

0 comments on commit 02f4b12

Please sign in to comment.