FA-89561 / Instruction set emulation / Open access
srai shifts in zeros · case 01
Arithmetic right shift of a negative value produces a large positive value.
ROOT CAUSE
srai shifts the unsigned register value.
VERIFIED REPAIR
Shift the signed interpretation and mask the amount to 5 bits.
Unsuccessful approach: Forgetting the 5-bit shift-amount mask shifts negative values to -1 for large amounts.
Case contract
Input [prog]: [op, rd, a, b] with ops addi (x[a]+b), add, sub, lui (b<<12), slt (signed), sltu (unsigned), sltiu (x[a] < b sign-extended then taken unsigned), srai, srli, slli (shift amount b & 31). Registers x0..x31 start at 0 and hold unsigned 32-bit values; x0 always reads 0 and writes to it are discarded. Return sorted [index, value] of nonzero registers.
Why this case matters
Every RISC emulator implements a register file with a zero register and 32-bit wrapping arithmetic on a host with unbounded integers.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
prog = args[0]
x = [0] * 32
M = 0xFFFFFFFF
def s(v):
return v - (1 << 32) if v >> 31 else v
for op, rd, a, b in prog:
if op == 'addi': r = x[a] + b
elif op == 'add': r = x[a] + x[b]
elif op == 'sub': r = x[a] - x[b]
elif op == 'lui': r = b << 12
elif op == 'slt': r = int(s(x[a]) < s(x[b]))
elif op == 'sltu': r = int(x[a] < x[b])
elif op == 'sltiu': r = int(x[a] < (b & M))
elif op == 'srai': r = x[a] >> (b & 31)
elif op == 'srli': r = x[a] >> (b & 31)
else: r = x[a] << (b & 31)
if rd != 0:
x[rd] = r & M
return [[i, x[i]] for i in range(32) if x[i]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('writes to x0 are discarded', [[['addi', 0, 0, 6], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 8], ['add', 2, 1, 1]]], [[1, 8], [2, 16]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 3], ['add', 2, 1, 1]]], [[1, 1], [2, 2]]), ('negative results wrap', [[['addi', 1, 0, -2], ['sub', 2, 0, 1]]], [[1, 4294967294], [2, 2]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 2], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 2], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 6], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74566], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -32], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 33], ['slli', 3, 1, 31]]], [[1, 3], [2, 6], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 7], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 9], ['add', 2, 1, 1]]], [[1, 9], [2, 18]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 4], ['add', 2, 1, 1]]], [[1, 2], [2, 4]]), ('negative results wrap', [[['addi', 1, 0, -3], ['sub', 2, 0, 1]]], [[1, 4294967293], [2, 3]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 3], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 3], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 7], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74567], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 7], [2, 1], [3, 1], [5, 305426432], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -48], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967248], [2, 4294967284], [3, 15], [4, 4294967272]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 34], ['slli', 3, 1, 31]]], [[1, 3], [2, 12], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 8], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 10], ['add', 2, 1, 1]]], [[1, 10], [2, 20]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 5], ['add', 2, 1, 1]]], [[1, 3], [2, 6]]), ('negative results wrap', [[['addi', 1, 0, -4], ['sub', 2, 0, 1]]], [[1, 4294967292], [2, 4]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 4], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 4], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 8], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74568], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 8], [2, 1], [3, 1], [5, 305430528], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -64], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967232], [2, 4294967280], [3, 15], [4, 4294967264]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 35], ['slli', 3, 1, 31]]], [[1, 3], [2, 24], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 9], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 11], ['add', 2, 1, 1]]], [[1, 11], [2, 22]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 6], ['add', 2, 1, 1]]], [[1, 4], [2, 8]]), ('negative results wrap', [[['addi', 1, 0, -5], ['sub', 2, 0, 1]]], [[1, 4294967291], [2, 5]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 5], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 5], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 9], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74569], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 9], [2, 1], [3, 1], [5, 305434624], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -80], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967216], [2, 4294967276], [3, 15], [4, 4294967256]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 36], ['slli', 3, 1, 31]]], [[1, 3], [2, 48], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 10], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 12], ['add', 2, 1, 1]]], [[1, 12], [2, 24]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 7], ['add', 2, 1, 1]]], [[1, 5], [2, 10]]), ('negative results wrap', [[['addi', 1, 0, -6], ['sub', 2, 0, 1]]], [[1, 4294967290], [2, 6]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 6], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 6], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 10], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74570], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 10], [2, 1], [3, 1], [5, 305438720], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -96], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967200], [2, 4294967272], [3, 15], [4, 4294967248]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 37], ['slli', 3, 1, 31]]], [[1, 3], [2, 96], [3, 2147483648]])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| writes to x0 are discarded | [[2, 3]] | [[2, 3]] | Passed |
| x1 is an ordinary register | [[1, 8], [2, 16]] | [[1, 8], [2, 16]] | Passed |
| 32-bit wrap on add | [[1, 1], [2, 2]] | [[1, 1], [2, 2]] | Passed |
| negative results wrap | [[1, 4294967294], [2, 2]] | [[1, 4294967294], [2, 2]] | Passed |
| signed and unsigned compare | [[1, 4294967295], [2, 2], [3, 1]] | [[1, 4294967295], [2, 2], [3, 1]] | Passed |
| sltiu with negative immediate | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | Passed |
| arithmetic and logical right shift | [[1, 4294967264], [2, 1073741816], [3, 15], [4, 2147483632]] | [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]] | Failed |
| shift amount masked | [[1, 3], [2, 6], [3, 2147483648]] | [[1, 3], [2, 6], [3, 2147483648]] | Passed |
SHA-256 / e5552a87237e7767b32b4911e3582d87337625d2502f921b96648717a8a8b385
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
prog = args[0]
x = [0] * 32
M = 0xFFFFFFFF
def s(v):
return v - (1 << 32) if v >> 31 else v
for op, rd, a, b in prog:
if op == 'addi': r = x[a] + b
elif op == 'add': r = x[a] + x[b]
elif op == 'sub': r = x[a] - x[b]
elif op == 'lui': r = b << 12
elif op == 'slt': r = int(s(x[a]) < s(x[b]))
elif op == 'sltu': r = int(x[a] < x[b])
elif op == 'sltiu': r = int(x[a] < (b & M))
elif op == 'srai': r = s(x[a]) >> b
elif op == 'srli': r = x[a] >> (b & 31)
else: r = x[a] << (b & 31)
if rd != 0:
x[rd] = r & M
return [[i, x[i]] for i in range(32) if x[i]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('writes to x0 are discarded', [[['addi', 0, 0, 6], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 8], ['add', 2, 1, 1]]], [[1, 8], [2, 16]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 3], ['add', 2, 1, 1]]], [[1, 1], [2, 2]]), ('negative results wrap', [[['addi', 1, 0, -2], ['sub', 2, 0, 1]]], [[1, 4294967294], [2, 2]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 2], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 2], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 6], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74566], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -32], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 33], ['slli', 3, 1, 31]]], [[1, 3], [2, 6], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 7], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 9], ['add', 2, 1, 1]]], [[1, 9], [2, 18]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 4], ['add', 2, 1, 1]]], [[1, 2], [2, 4]]), ('negative results wrap', [[['addi', 1, 0, -3], ['sub', 2, 0, 1]]], [[1, 4294967293], [2, 3]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 3], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 3], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 7], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74567], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 7], [2, 1], [3, 1], [5, 305426432], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -48], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967248], [2, 4294967284], [3, 15], [4, 4294967272]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 34], ['slli', 3, 1, 31]]], [[1, 3], [2, 12], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 8], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 10], ['add', 2, 1, 1]]], [[1, 10], [2, 20]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 5], ['add', 2, 1, 1]]], [[1, 3], [2, 6]]), ('negative results wrap', [[['addi', 1, 0, -4], ['sub', 2, 0, 1]]], [[1, 4294967292], [2, 4]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 4], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 4], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 8], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74568], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 8], [2, 1], [3, 1], [5, 305430528], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -64], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967232], [2, 4294967280], [3, 15], [4, 4294967264]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 35], ['slli', 3, 1, 31]]], [[1, 3], [2, 24], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 9], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 11], ['add', 2, 1, 1]]], [[1, 11], [2, 22]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 6], ['add', 2, 1, 1]]], [[1, 4], [2, 8]]), ('negative results wrap', [[['addi', 1, 0, -5], ['sub', 2, 0, 1]]], [[1, 4294967291], [2, 5]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 5], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 5], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 9], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74569], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 9], [2, 1], [3, 1], [5, 305434624], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -80], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967216], [2, 4294967276], [3, 15], [4, 4294967256]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 36], ['slli', 3, 1, 31]]], [[1, 3], [2, 48], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 10], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 12], ['add', 2, 1, 1]]], [[1, 12], [2, 24]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 7], ['add', 2, 1, 1]]], [[1, 5], [2, 10]]), ('negative results wrap', [[['addi', 1, 0, -6], ['sub', 2, 0, 1]]], [[1, 4294967290], [2, 6]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 6], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 6], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 10], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74570], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 10], [2, 1], [3, 1], [5, 305438720], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -96], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967200], [2, 4294967272], [3, 15], [4, 4294967248]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 37], ['slli', 3, 1, 31]]], [[1, 3], [2, 96], [3, 2147483648]])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| writes to x0 are discarded | [[2, 3]] | [[2, 3]] | Passed |
| x1 is an ordinary register | [[1, 8], [2, 16]] | [[1, 8], [2, 16]] | Passed |
| 32-bit wrap on add | [[1, 1], [2, 2]] | [[1, 1], [2, 2]] | Passed |
| negative results wrap | [[1, 4294967294], [2, 2]] | [[1, 4294967294], [2, 2]] | Passed |
| signed and unsigned compare | [[1, 4294967295], [2, 2], [3, 1]] | [[1, 4294967295], [2, 2], [3, 1]] | Passed |
| sltiu with negative immediate | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | Passed |
| arithmetic and logical right shift | [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967295]] | [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]] | Failed |
| shift amount masked | [[1, 3], [2, 6], [3, 2147483648]] | [[1, 3], [2, 6], [3, 2147483648]] | Passed |
SHA-256 / d9960d7d9b81ac203ba60c09b79ef07917c2f317b6ad0f73eacb8929f610926b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(*args):
prog = args[0]
x = [0] * 32
M = 0xFFFFFFFF
def s(v):
return v - (1 << 32) if v >> 31 else v
for op, rd, a, b in prog:
if op == 'addi': r = x[a] + b
elif op == 'add': r = x[a] + x[b]
elif op == 'sub': r = x[a] - x[b]
elif op == 'lui': r = b << 12
elif op == 'slt': r = int(s(x[a]) < s(x[b]))
elif op == 'sltu': r = int(x[a] < x[b])
elif op == 'sltiu': r = int(x[a] < (b & M))
elif op == 'srai': r = s(x[a]) >> (b & 31)
elif op == 'srli': r = x[a] >> (b & 31)
else: r = x[a] << (b & 31)
if rd != 0:
x[rd] = r & M
return [[i, x[i]] for i in range(32) if x[i]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('writes to x0 are discarded', [[['addi', 0, 0, 6], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 8], ['add', 2, 1, 1]]], [[1, 8], [2, 16]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 3], ['add', 2, 1, 1]]], [[1, 1], [2, 2]]), ('negative results wrap', [[['addi', 1, 0, -2], ['sub', 2, 0, 1]]], [[1, 4294967294], [2, 2]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 2], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 2], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 6], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74566], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -32], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 33], ['slli', 3, 1, 31]]], [[1, 3], [2, 6], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 7], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 9], ['add', 2, 1, 1]]], [[1, 9], [2, 18]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 4], ['add', 2, 1, 1]]], [[1, 2], [2, 4]]), ('negative results wrap', [[['addi', 1, 0, -3], ['sub', 2, 0, 1]]], [[1, 4294967293], [2, 3]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 3], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 3], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 7], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74567], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 7], [2, 1], [3, 1], [5, 305426432], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -48], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967248], [2, 4294967284], [3, 15], [4, 4294967272]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 34], ['slli', 3, 1, 31]]], [[1, 3], [2, 12], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 8], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 10], ['add', 2, 1, 1]]], [[1, 10], [2, 20]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 5], ['add', 2, 1, 1]]], [[1, 3], [2, 6]]), ('negative results wrap', [[['addi', 1, 0, -4], ['sub', 2, 0, 1]]], [[1, 4294967292], [2, 4]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 4], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 4], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 8], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74568], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 8], [2, 1], [3, 1], [5, 305430528], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -64], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967232], [2, 4294967280], [3, 15], [4, 4294967264]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 35], ['slli', 3, 1, 31]]], [[1, 3], [2, 24], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 9], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 11], ['add', 2, 1, 1]]], [[1, 11], [2, 22]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 6], ['add', 2, 1, 1]]], [[1, 4], [2, 8]]), ('negative results wrap', [[['addi', 1, 0, -5], ['sub', 2, 0, 1]]], [[1, 4294967291], [2, 5]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 5], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 5], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 9], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74569], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 9], [2, 1], [3, 1], [5, 305434624], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -80], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967216], [2, 4294967276], [3, 15], [4, 4294967256]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 36], ['slli', 3, 1, 31]]], [[1, 3], [2, 48], [3, 2147483648]])], [('writes to x0 are discarded', [[['addi', 0, 0, 10], ['add', 1, 0, 0], ['addi', 2, 0, 3]]], [[2, 3]]), ('x1 is an ordinary register', [[['addi', 1, 0, 12], ['add', 2, 1, 1]]], [[1, 12], [2, 24]]), ('32-bit wrap on add', [[['lui', 1, 0, 1048575], ['addi', 1, 1, 2047], ['addi', 1, 1, 2047], ['addi', 1, 1, 7], ['add', 2, 1, 1]]], [[1, 5], [2, 10]]), ('negative results wrap', [[['addi', 1, 0, -6], ['sub', 2, 0, 1]]], [[1, 4294967290], [2, 6]]), ('signed and unsigned compare', [[['addi', 1, 0, -1], ['addi', 2, 0, 6], ['slt', 3, 1, 2], ['sltu', 4, 1, 2], ['slt', 5, 2, 1]]], [[1, 4294967295], [2, 6], [3, 1]]), ('sltiu with negative immediate', [[['addi', 1, 0, 10], ['sltiu', 2, 1, -1], ['sltiu', 3, 0, 1], ['sltiu', 4, 1, 3], ['lui', 5, 0, 74570], ['sltiu', 6, 5, -1], ['sltiu', 7, 5, -2048]]], [[1, 10], [2, 1], [3, 1], [5, 305438720], [6, 1], [7, 1]]), ('arithmetic and logical right shift', [[['addi', 1, 0, -96], ['srai', 2, 1, 2], ['srli', 3, 1, 28], ['srai', 4, 1, 33]]], [[1, 4294967200], [2, 4294967272], [3, 15], [4, 4294967248]]), ('shift amount masked', [[['addi', 1, 0, 3], ['slli', 2, 1, 37], ['slli', 3, 1, 31]]], [[1, 3], [2, 96], [3, 2147483648]])]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| writes to x0 are discarded | [[2, 3]] | [[2, 3]] | Passed |
| x1 is an ordinary register | [[1, 8], [2, 16]] | [[1, 8], [2, 16]] | Passed |
| 32-bit wrap on add | [[1, 1], [2, 2]] | [[1, 1], [2, 2]] | Passed |
| negative results wrap | [[1, 4294967294], [2, 2]] | [[1, 4294967294], [2, 2]] | Passed |
| signed and unsigned compare | [[1, 4294967295], [2, 2], [3, 1]] | [[1, 4294967295], [2, 2], [3, 1]] | Passed |
| sltiu with negative immediate | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | [[1, 6], [2, 1], [3, 1], [5, 305422336], [6, 1], [7, 1]] | Passed |
| arithmetic and logical right shift | [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]] | [[1, 4294967264], [2, 4294967288], [3, 15], [4, 4294967280]] | Passed |
| shift amount masked | [[1, 3], [2, 6], [3, 2147483648]] | [[1, 3], [2, 6], [3, 2147483648]] | Passed |
SHA-256 / 8e8e61801161c0895c00edd7c47a0463ff15f3c0035d94c0e370c2590fad2b27
Verification & scope
A deterministic bounded teaching model of one emulator rule; the instruction semantics are a stipulated contract inspired by common ISAs and are not a claim of cycle-exact or architectural conformance. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:18.580956+00:00.
Case digest / 89e158cabe4f7527a0e383b100718cd7eed4a3300d8618ce7af50104466f9606