Skip to content

Commit 2a0d189

Browse files
committed
fix(tests): drag remaining stale tests into line with the corrected ISA
After commit 6761f0c unblocked the workspace test step in CI by fixing the SRAI/L32R decoder unit tests, five more pre-existing stale tests surfaced (the fmt + clippy gates above were masking them on the same runs). Fix: * tests/xtensa_exec.rs::enc_srai: helper aliased `at = shamt` (a shortcut that worked only when the broken decoder colocated source and shamt in the `t` field). Take both arguments independently — source goes in `t`, shamt in `s` — matching ISA RM §4.3 RRR encoding. Updated the two SRAI exec callers. * tests/xtensa_exec.rs::test_exec_entry_window_overflow_of{4,8,12}: mark `#[ignore]`. They verify the F5 per-instruction window-overflow vector path that is intentionally disabled in execute() with `#[cfg(any())]` (the canonical OF{4,8,12} firmware handlers double-fault on freshly-created task frames). Sim uses transparent shadow-spill on CALL{n} instead — see spill_shadow_on_call. * hw-oracle/tests/oracles.rs::entry_window_overflow_of4: split into an inner spec helper plus manual `#[test] #[ignore]` for the sim variant and `#[test] #[cfg(feature="hw-oracle")] #[ignore]` for the hw variant. Same reason as the xtensa_exec ignore. Keeps the oracle case as the canonical hardware spec without dragging the sim suite into red. * hw-oracle/src/arm_thumb.rs::movw_r0_0xbeef_encoding: the expected bit-pattern (0xF64B_00EF) decoded back to `movw r0, #0xB8EF`, not `#0xBEEF`. Recomputed using ARMv7-M ARM §A6.7.74 — imm4=0xB, i=1, imm3=6, imm8=0xEF gives lo=0x60EF, so the full word is 0xF64B_60EF. After this: 347 lib tests + every workspace integration test pass, 3 sim-side overflow tests ignored with reasons. fmt + clippy clean.
1 parent 6761f0c commit 2a0d189

3 files changed

Lines changed: 59 additions & 22 deletions

File tree

crates/core/tests/xtensa_exec.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,15 @@ fn enc_srli(ar: u32, at: u32, shamt: u32) -> u32 {
9191

9292
/// Encode SRAI ar, at, shamt (0..=31).
9393
///
94-
/// ISA encoding: shamt = (op2 & 1) << 4 | t; at = t (low nibble of shamt).
95-
/// For shamt 0..=15: op2=0x2, t=shamt, at=shamt.
96-
/// For shamt 16..=31: op2=0x3, t=shamt&0xF, at=shamt&0xF.
97-
/// Caller must place the value to shift in register `shamt & 0xF`.
98-
fn enc_srai(ar: u32, shamt: u32) -> u32 {
99-
let op2 = 0x2 | (shamt >> 4); // 0x2 or 0x3
100-
let t = shamt & 0xF; // t == at (source register)
101-
rrr(op2, 0x1, ar, 0, t)
94+
/// ISA encoding per Xtensa RM §4.3 (RRR variant):
95+
/// r (15:12) = ar — destination
96+
/// s (11:8) = shamt[3:0]
97+
/// t (7:4) = at — source register (independent of shamt)
98+
/// op2[0] = shamt[4]
99+
fn enc_srai(ar: u32, at: u32, shamt: u32) -> u32 {
100+
let op2 = 0x2 | (shamt >> 4); // 0x2 or 0x3 for shamt[4]
101+
let s = shamt & 0xF; // shamt[3:0]
102+
rrr(op2, 0x1, ar, s, at)
102103
}
103104

104105
/// Encode SSL as_ (op0=0, op1=0, op2=0x4, r=0x1, s=as_, t=0).
@@ -855,7 +856,7 @@ fn test_exec_srai_positive() {
855856
&mut bus,
856857
TEST_PC as u64,
857858
&[
858-
enc_srai(5, 4), // SRAI a5, a4, 4 → 0x7FFFFFFF >> 4 = 0x07FFFFFF
859+
enc_srai(5, 4, 4), // SRAI a5, a4, 4 → 0x7FFFFFFF >> 4 = 0x07FFFFFF
859860
st0(4, 0, 0),
860861
],
861862
);
@@ -883,7 +884,7 @@ fn test_exec_srai_negative() {
883884
&mut bus,
884885
TEST_PC as u64,
885886
&[
886-
enc_srai(5, 8), // SRAI a5, a8, 8 → sign-extended
887+
enc_srai(5, 8, 8), // SRAI a5, a8, 8 → sign-extended
887888
st0(4, 0, 0),
888889
],
889890
);
@@ -4046,7 +4047,18 @@ fn setup_entry_overflow(cpu: &mut XtensaLx7, callinc: u8) {
40464047
/// F3: ENTRY with CALLINC=1 triggers WindowOverflow4.
40474048
/// Expect: PC = VECBASE + OF4 offset (0x000), EPC1 = original PC, PS.EXCM=1,
40484049
/// WindowBase NOT rotated (still 0), WindowStart check bit still set.
4049-
#[test]
4050+
///
4051+
/// IGNORED: real silicon vectors to OF4/OF8/OF12 handlers on overflow; the
4052+
/// sim instead transparently shadows the displaced frame on CALL{n} (see
4053+
/// `spill_shadow_on_call` in cpu/xtensa_lx7.rs). Vectoring to the
4054+
/// firmware's canonical OF handler would double-fault — its
4055+
/// `l32e a0, a1, -12` reads uninitialised stack on freshly-created task
4056+
/// frames. The F5 per-instruction overflow check at the top of execute()
4057+
/// is gated off with `#[cfg(any())]` for the same reason. Re-enable both
4058+
/// the check and this test if/when the firmware OF-handler path is fully
4059+
/// modelled.
4060+
#[test]
4061+
#[ignore = "F5 overflow vector intentionally disabled; sim uses shadow-spill instead"]
40504062
fn test_exec_entry_window_overflow_of4() {
40514063
let mut cpu = XtensaLx7::new();
40524064
let mut bus = SystemBus::new();
@@ -4087,9 +4099,9 @@ fn test_exec_entry_window_overflow_of4() {
40874099
}
40884100

40894101
/// F3: ENTRY with CALLINC=2 triggers WindowOverflow8.
4090-
/// Expect: PC = VECBASE + OF8 offset (0x080), EPC1 = original PC, PS.EXCM=1,
4091-
/// WindowBase NOT rotated (still 0).
4102+
/// IGNORED — same reason as `test_exec_entry_window_overflow_of4`.
40924103
#[test]
4104+
#[ignore = "F5 overflow vector intentionally disabled; sim uses shadow-spill instead"]
40934105
fn test_exec_entry_window_overflow_of8() {
40944106
let mut cpu = XtensaLx7::new();
40954107
let mut bus = SystemBus::new();
@@ -4124,9 +4136,9 @@ fn test_exec_entry_window_overflow_of8() {
41244136
}
41254137

41264138
/// F3: ENTRY with CALLINC=3 triggers WindowOverflow12.
4127-
/// Expect: PC = VECBASE + OF12 offset (0x100), EPC1 = original PC, PS.EXCM=1,
4128-
/// WindowBase NOT rotated (still 0).
4139+
/// IGNORED — same reason as `test_exec_entry_window_overflow_of4`.
41294140
#[test]
4141+
#[ignore = "F5 overflow vector intentionally disabled; sim uses shadow-spill instead"]
41304142
fn test_exec_entry_window_overflow_of12() {
41314143
let mut cpu = XtensaLx7::new();
41324144
let mut bus = SystemBus::new();

crates/hw-oracle/src/arm_thumb.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -937,10 +937,13 @@ mod encoder_tests {
937937

938938
#[test]
939939
fn movw_r0_0xbeef_encoding() {
940-
// MOV.W r0, #0xBEEF (T3 encoding). Cross-checked with:
941-
// echo 'movw r0, #0xBEEF' | arm-none-eabi-as -mthumb -mcpu=cortex-m4 -o /tmp/t.o
942-
// arm-none-eabi-objdump -d /tmp/t.o → 0xf64b 0x00ef
943-
// Our encoder returns u32 in hi-then-lo order: hi=0xF64B, lo=0x00EF.
944-
assert_eq!(movw_imm16(0, 0xBEEF), 0xF64B_00EF);
940+
// MOV.W r0, #0xBEEF (T3 encoding) per ARMv7-M ARM §A6.7.74:
941+
// imm32 = ZeroExtend(imm4:i:imm3:imm8, 32)
942+
// For 0xBEEF: imm4=0xB, i=1, imm3=6, imm8=0xEF.
943+
// hi = 0xF240 | (i<<10) | imm4 = 0xF240 | 0x0400 | 0x000B = 0xF64B
944+
// lo = (imm3<<12) | (Rd<<8) | imm8 = 0x6000 | 0x0000 | 0x00EF = 0x60EF
945+
// Cross-checked: arm-none-eabi-as `movw r0, #0xBEEF` → 4b f6 ef 60
946+
// (LE byte stream: hi=0xF64B, lo=0x60EF).
947+
assert_eq!(movw_imm16(0, 0xBEEF), 0xF64B_60EF);
945948
}
946949
}

crates/hw-oracle/tests/oracles.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,8 +920,15 @@ fn call4_entry_retw_no_overflow() -> OracleCase {
920920
/// IRAM_BASE+3..7: zeros (unreachable)
921921
/// IRAM_BASE+8: ENTRY a1, 32 [0x36,0x41,0x00]
922922
/// IRAM_BASE+0x800: BREAK ← OF4 vector (VECBASE+0x000) [0xF0,0x41,0x00]
923-
#[hw_oracle_test]
924-
fn entry_window_overflow_of4() -> OracleCase {
923+
///
924+
/// NOTE — F5 window-overflow vectoring is intentionally disabled in our
925+
/// sim (the canonical `l32e a0, a1, -12` handler double-faults on
926+
/// freshly-created task frames). We use transparent shadow-spilling on
927+
/// CALL{n} instead — see `spill_shadow_on_call` in cpu/xtensa_lx7.rs and
928+
/// the `#[cfg(any())]`-gated F5 check at the top of execute(). The case
929+
/// body below is still kept as the canonical hardware spec; the sim
930+
/// variant is wrapped manually as `#[ignore]` below.
931+
fn entry_window_overflow_of4_inner_spec() -> OracleCase {
925932
// Oracle program lays out BREAKs at all three OF vectors (0x000, 0x080,
926933
// 0x100) so the CPU halts cleanly regardless of which OFx the rotation
927934
// algorithm dispatches to. The expectation pins the dispatch — change it
@@ -952,6 +959,21 @@ fn entry_window_overflow_of4() -> OracleCase {
952959
})
953960
}
954961

962+
/// Sim variant: ignored. See note on `entry_window_overflow_of4_inner_spec`.
963+
#[test]
964+
#[ignore = "F5 overflow vector disabled in sim — shadow-spill used instead"]
965+
fn entry_window_overflow_of4_sim() {
966+
labwired_hw_oracle::run_sim(entry_window_overflow_of4_inner_spec());
967+
}
968+
969+
/// HW variant: feature-gated, exercises real-silicon vectoring.
970+
#[test]
971+
#[cfg(feature = "hw-oracle")]
972+
#[ignore = "hw-oracle: requires connected ESP32-S3 board"]
973+
fn entry_window_overflow_of4_hw() {
974+
labwired_hw_oracle::run_hw(entry_window_overflow_of4_inner_spec());
975+
}
976+
955977
// ── H7.3: Nested 2-level CALL4 → ENTRY → CALL4 → ENTRY (no overflow) ────────
956978

957979
/// Two successive CALL4→ENTRY pairs; WindowBase ends at 2, WindowStart = 0x0007.

0 commit comments

Comments
 (0)