Skip to content

Commit

Permalink
cannon: Add tests for lld, scd ops
Browse files Browse the repository at this point in the history
  • Loading branch information
mbaxter committed Oct 14, 2024
1 parent 54a4d6c commit 4b307c3
Showing 1 changed file with 183 additions and 1 deletion.
184 changes: 183 additions & 1 deletion cannon/mipsevm/tests/evm_multithreaded64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestEVM_MT64_LL(t *testing.T) {
}{
{name: "8-byte-aligned addr", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memVal, retVal: 0x11223344, retReg: 5},
{name: "8-byte-aligned addr, neg value", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memValNeg, retVal: 0xFFFFFFFF_F1223344, retReg: 5},
{name: "8-byte-aligned addr, extra bits", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memVal, retVal: 0x11223344, retReg: 5},
{name: "8-byte-aligned addr, extra bits", base: 0x01, offset: 0x0109, addr: 0x010A, memVal: memVal, retVal: 0x11223344, retReg: 5},
{name: "8-byte-aligned addr, signed extended", base: 0x01, offset: 0xFF37, addr: 0xFFFF_FFFF_FFFF_FF38, memVal: memVal, retVal: 0x11223344, retReg: 5},
{name: "8-byte-aligned addr, signed extended w overflow", base: 0x1000_0001, offset: 0xFF07, addr: 0x0000_0000_0FFF_FF08, memVal: memVal, retVal: 0x11223344, retReg: 5},
{name: "4-byte-aligned addr", base: 0x01, offset: 0x0103, addr: 0x0104, memVal: memVal, retVal: 0x55667788, retReg: 5},
Expand Down Expand Up @@ -197,3 +197,185 @@ func TestEVM_MT64_SC(t *testing.T) {
}
}
}

func TestEVM_MT64_LLD(t *testing.T) {
var tracer *tracing.Hooks

memVal := Word(0x11223344_55667788)
memValNeg := Word(0xF1223344_F5667788)
cases := []struct {
name string
base Word
offset int
addr Word
memVal Word
retReg int
}{
{name: "Aligned addr", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memVal, retReg: 5},
{name: "Aligned addr, neg value", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memValNeg, retReg: 5},
{name: "Unaligned addr, offset=1", base: 0x01, offset: 0x0100, addr: 0x0101, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=2", base: 0x02, offset: 0x0100, addr: 0x0102, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=3", base: 0x03, offset: 0x0100, addr: 0x0103, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=4", base: 0x04, offset: 0x0100, addr: 0x0104, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=5", base: 0x05, offset: 0x0100, addr: 0x0105, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=6", base: 0x06, offset: 0x0100, addr: 0x0106, memVal: memVal, retReg: 5},
{name: "Unaligned addr, offset=7", base: 0x07, offset: 0x0100, addr: 0x0107, memVal: memVal, retReg: 5},
{name: "Aligned addr, signed extended", base: 0x01, offset: 0xFF37, addr: 0xFFFF_FFFF_FFFF_FF38, memVal: memVal, retReg: 5},
{name: "Aligned addr, signed extended w overflow", base: 0x1000_0001, offset: 0xFF07, addr: 0x0000_0000_0FFF_FF08, memVal: memVal, retReg: 5},
{name: "Return register set to 0", base: 0x01, offset: 0x0107, addr: 0x0108, memVal: memVal, retReg: 0},
}
for i, c := range cases {
for _, withExistingReservation := range []bool{true, false} {
tName := fmt.Sprintf("%v (withExistingReservation = %v)", c.name, withExistingReservation)
t.Run(tName, func(t *testing.T) {
effAddr := arch.AddressMask & c.addr

retReg := c.retReg
baseReg := 6
pc := Word(0x44)
insn := uint32((0b11_0100 << 26) | (baseReg & 0x1F << 21) | (retReg & 0x1F << 16) | (0xFFFF & c.offset))
goVm, state, contracts := setup(t, i, nil)
step := state.GetStep()

// Set up state
state.GetCurrentThread().Cpu.PC = pc
state.GetCurrentThread().Cpu.NextPC = pc + 4
state.GetMemory().SetUint32(pc, insn)
state.GetMemory().SetWord(effAddr, c.memVal)
state.GetRegistersRef()[baseReg] = c.base
if withExistingReservation {
state.LLReservationActive = true
state.LLAddress = c.addr + 1
state.LLOwnerThread = 123
} else {
state.LLReservationActive = false
state.LLAddress = 0
state.LLOwnerThread = 0
}

// Set up expectations
expected := mttestutil.NewExpectedMTState(state)
expected.ExpectStep()
expected.LLReservationActive = true
expected.LLAddress = c.addr
expected.LLOwnerThread = state.GetCurrentThread().ThreadId
if retReg != 0 {
expected.ActiveThread().Registers[retReg] = c.memVal
}

stepWitness, err := goVm.Step(true)
require.NoError(t, err)

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer)
})
}
}
}

func TestEVM_MT64_SCD(t *testing.T) {
var tracer *tracing.Hooks

value := Word(0x11223344_55667788)
llVariations := []struct {
name string
llReservationActive bool
matchThreadId bool
matchAddr bool
shouldSucceed bool
}{
{name: "should succeed", llReservationActive: true, matchThreadId: true, matchAddr: true, shouldSucceed: true},
{name: "mismatch addr", llReservationActive: true, matchThreadId: false, matchAddr: true, shouldSucceed: false},
{name: "mismatched thread", llReservationActive: true, matchThreadId: true, matchAddr: false, shouldSucceed: false},
{name: "mismatched addr & thread", llReservationActive: true, matchThreadId: false, matchAddr: false, shouldSucceed: false},
{name: "no active reservation", llReservationActive: false, matchThreadId: true, matchAddr: true, shouldSucceed: false},
}

cases := []struct {
name string
base Word
offset int
addr Word
rtReg int
threadId Word
}{
{name: "Aligned addr", base: 0x01, offset: 0x0137, addr: 0x0138, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=1", base: 0x01, offset: 0x0100, addr: 0x0101, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=2", base: 0x02, offset: 0x0100, addr: 0x0102, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=3", base: 0x03, offset: 0x0100, addr: 0x0103, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=4", base: 0x04, offset: 0x0100, addr: 0x0104, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=5", base: 0x05, offset: 0x0100, addr: 0x0105, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=6", base: 0x06, offset: 0x0100, addr: 0x0106, rtReg: 5, threadId: 4},
{name: "Unaligned addr, offset=7", base: 0x07, offset: 0x0100, addr: 0x0107, rtReg: 5, threadId: 4},
{name: "Aligned addr, signed extended", base: 0x01, offset: 0xFF37, addr: 0xFFFF_FFFF_FFFF_FF38, rtReg: 5, threadId: 4},
{name: "Aligned addr, signed extended w overflow", base: 0x1000_0001, offset: 0xFF37, addr: 0x0FFF_FF38, rtReg: 5, threadId: 4},
{name: "Return register set to 0", base: 0x01, offset: 0x0138, addr: 0x0139, rtReg: 0, threadId: 4},
{name: "Zero valued ll args", base: 0x0, offset: 0x0, rtReg: 5, threadId: 0},
}
for i, c := range cases {
for _, v := range llVariations {
tName := fmt.Sprintf("%v (%v)", c.name, v.name)
t.Run(tName, func(t *testing.T) {
effAddr := arch.AddressMask & c.addr

// Setup
rtReg := c.rtReg
baseReg := 6
pc := Word(0x44)
insn := uint32((0b11_1100 << 26) | (baseReg & 0x1F << 21) | (rtReg & 0x1F << 16) | (0xFFFF & c.offset))
goVm, state, contracts := setup(t, i, nil)
mttestutil.InitializeSingleThread(i*23456, state, i%2 == 1)
step := state.GetStep()

// Define LL-related params
var llAddress, llOwnerThread Word
if v.matchAddr {
llAddress = c.addr
} else {
llAddress = c.addr + 1
}
if v.matchThreadId {
llOwnerThread = c.threadId
} else {
llOwnerThread = c.threadId + 1
}

// Setup state
state.GetCurrentThread().ThreadId = c.threadId
state.GetCurrentThread().Cpu.PC = pc
state.GetCurrentThread().Cpu.NextPC = pc + 4
state.GetMemory().SetUint32(pc, insn)
state.GetRegistersRef()[baseReg] = c.base
state.GetRegistersRef()[rtReg] = value
state.LLReservationActive = v.llReservationActive
state.LLAddress = llAddress
state.LLOwnerThread = llOwnerThread

// Setup expectations
expected := mttestutil.NewExpectedMTState(state)
expected.ExpectStep()
var retVal Word
if v.shouldSucceed {
retVal = 1
expected.ExpectMemoryWordWrite(effAddr, value)
expected.LLReservationActive = false
expected.LLAddress = 0
expected.LLOwnerThread = 0
} else {
retVal = 0
}
if rtReg != 0 {
expected.ActiveThread().Registers[rtReg] = retVal
}

stepWitness, err := goVm.Step(true)
require.NoError(t, err)

// Check expectations
expected.Validate(t, state)
testutil.ValidateEVM(t, stepWitness, step, goVm, multithreaded.GetStateHashFn(), contracts, tracer)
})
}
}
}

0 comments on commit 4b307c3

Please sign in to comment.