From 2773036a745a68e793124d2a8f186ebb9cc3bb23 Mon Sep 17 00:00:00 2001 From: Grazfather Date: Thu, 6 Nov 2025 09:05:01 -0500 Subject: [PATCH 1/2] Aviron: Cleanup testrunner IO to look more like main's --- sim/aviron/src/testrunner.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sim/aviron/src/testrunner.zig b/sim/aviron/src/testrunner.zig index a39bc2899..d38adcb77 100644 --- a/sim/aviron/src/testrunner.zig +++ b/sim/aviron/src/testrunner.zig @@ -172,8 +172,8 @@ fn run_test( }; // Check if it was a system exit (via IO) - const exit_mode: ExitMode = if (io.exit_requested) - .{ .system_exit = io.exit_code.? } + const exit_mode: ExitMode = if (io.exit_code) |code| + .{ .system_exit = code } else switch (result) { .breakpoint => .breakpoint, .enter_sleep_mode => .enter_sleep_mode, @@ -310,7 +310,6 @@ const IO = struct { // Exit status tracking exit_code: ?u8 = null, - exit_requested: bool = false, const DataBusType = aviron.Bus(.{ .address_type = u24 }); const IOBusType = aviron.IOBus; @@ -433,7 +432,6 @@ const IO = struct { switch (reg) { .exit => { io.exit_code = value & mask; - io.exit_requested = true; }, .stdio => io.stdout.append(value & mask) catch @panic("out of memory"), @@ -497,7 +495,9 @@ const IO = struct { fn dev_check_exit(ctx: *anyopaque) ?u8 { const io: *IO = @ptrCast(@alignCast(ctx)); - if (io.exit_requested) return io.exit_code; + if (io.exit_code) |code| { + return code; + } return null; } }; From 05253a60056bf64ae46be02cb25797a8b440a46f Mon Sep 17 00:00:00 2001 From: Grazfather Date: Thu, 13 Nov 2025 09:26:22 -0500 Subject: [PATCH 2/2] Aviron: Fix sbiw instruction setting SREG, add tests --- sim/aviron/src/lib/Cpu.zig | 2 +- .../testsuite.avr-gcc/instructions/sbiw.S | 56 +++++++++ .../instructions/sbiw-atmega2560.elf | Bin 0 -> 320 bytes .../instructions/sbiw-atmega2560.elf.json | 106 ++++++++++++++++++ .../instructions/sbiw-atmega328p.elf | Bin 0 -> 320 bytes .../instructions/sbiw-atmega328p.elf.json | 106 ++++++++++++++++++ 6 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 sim/aviron/testsuite.avr-gcc/instructions/sbiw.S create mode 100755 sim/aviron/testsuite/instructions/sbiw-atmega2560.elf create mode 100644 sim/aviron/testsuite/instructions/sbiw-atmega2560.elf.json create mode 100755 sim/aviron/testsuite/instructions/sbiw-atmega328p.elf create mode 100644 sim/aviron/testsuite/instructions/sbiw-atmega328p.elf.json diff --git a/sim/aviron/src/lib/Cpu.zig b/sim/aviron/src/lib/Cpu.zig index 9525f46eb..36ff7175a 100644 --- a/sim/aviron/src/lib/Cpu.zig +++ b/sim/aviron/src/lib/Cpu.zig @@ -755,7 +755,7 @@ const instructions = struct { cpu.sreg.z = (res == 0); cpu.sreg.n = ((res & 0x8000) != 0); cpu.sreg.c = ((src & 0x8000) == 0) and ((res & 0x8000) != 0); - cpu.sreg.v = cpu.sreg.c; + cpu.sreg.v = ((src & 0x8000) != 0) and ((res & 0x8000) == 0); cpu.sreg.s = (cpu.sreg.n != cpu.sreg.v); } diff --git a/sim/aviron/testsuite.avr-gcc/instructions/sbiw.S b/sim/aviron/testsuite.avr-gcc/instructions/sbiw.S new file mode 100644 index 000000000..fd8ea790a --- /dev/null +++ b/sim/aviron/testsuite.avr-gcc/instructions/sbiw.S @@ -0,0 +1,56 @@ +//! { +//! "exit": "breakpoint", +//! "cpus": ["atmega2560", "atmega328p"], +//! "precondition": { +//! "r24": 0, +//! "r25": 0, +//! "r26": 0, +//! "r27": 128, +//! "r28": 8, +//! "r29": 0, +//! "r30": 255, +//! "r31": 255 }, +//! "postcondition": { +//! "r16": 21, +//! "r17": 24, +//! "r18": 2, +//! "r19": 20, +//! "r24": 248, +//! "r25": 255, +//! "r26": 255, +//! "r27": 127, +//! "r28": 0, +//! "r29": 0, +//! "r30": 192, +//! "r31": 255 } +//! } + + ; Test case 1: 0x0000 - 0x08 = 0xFFF8 + ; Precondition: r25:r24 = 0x0000 + ; Expected: r25:r24 = 0xFFF8, C=1, N=1, V=0, S=1, Z=0 + ; SREG should be 0x15 (C=1, Z=0, N=1, V=0, S=1) + sbiw r24, 0x8 + in r16, 0x3F ; Save SREG to r16 + + ; Test case 2: 0x8000 - 0x01 = 0x7FFF (overflow) + ; Precondition: r27:r26 = 0x8000 + ; Expected: r27:r26 = 0x7FFF, C=0, N=0, V=1, S=1, Z=0 + ; SREG should be 0x18 (C=0, Z=0, N=0, V=1, S=1) + sbiw r26, 0x1 + in r17, 0x3F ; Save SREG to r17 + + ; Test case 3: 0x0008 - 0x08 = 0x0000 (zero result) + ; Precondition: r29:r28 = 0x0008 + ; Expected: r29:r28 = 0x0000, C=0, N=0, V=0, S=0, Z=1 + ; SREG should be 0x02 (C=0, Z=1, N=0, V=0, S=0) + sbiw r28, 0x8 + in r18, 0x3F ; Save SREG to r18 + + ; Test case 4: 0xFFFF - 0x3F = 0xFFC0 + ; Precondition: r31:r30 = 0xFFFF + ; Expected: r31:r30 = 0xFFC0, C=0, N=1, V=0, S=1, Z=0 + ; SREG should be 0x14 (C=0, Z=0, N=1, V=0, S=1) + sbiw r30, 0x3F + in r19, 0x3F ; Save SREG to r19 + + break diff --git a/sim/aviron/testsuite/instructions/sbiw-atmega2560.elf b/sim/aviron/testsuite/instructions/sbiw-atmega2560.elf new file mode 100755 index 0000000000000000000000000000000000000000..3b8fd2a0fa4864080aaad63e6dd7f9bd6a74e531 GIT binary patch literal 320 zcmaKmAr1mD6hx<8AS4K~7$nG5i&>8Xh2sPzkf7NL94Kx;isTkO9?X<2LGhAFr+?c2 z|7EpV8)J~M*dpH=7N69BYA}aIg&vBOd)6`&8mUiNO8;*Z>^0S8h59HPhH)&zELLF= zUtt*^chv2%^(XIksQ1o0)c$b(9ii`k88KDwLa#VC&6n>`CQ3?Py9f=@?iuYbzP&!z L)Nk7Poa=l8F>4mU literal 0 HcmV?d00001 diff --git a/sim/aviron/testsuite/instructions/sbiw-atmega2560.elf.json b/sim/aviron/testsuite/instructions/sbiw-atmega2560.elf.json new file mode 100644 index 000000000..6086d1019 --- /dev/null +++ b/sim/aviron/testsuite/instructions/sbiw-atmega2560.elf.json @@ -0,0 +1,106 @@ +{ + "exit": "breakpoint", + "exit_code": 0, + "stdout": "", + "stderr": "", + "stdin": "", + "precondition": { + "sreg": { + "c": null, + "z": null, + "n": null, + "v": null, + "s": null, + "h": null, + "t": null, + "i": null + }, + "r0": null, + "r1": null, + "r2": null, + "r3": null, + "r4": null, + "r5": null, + "r6": null, + "r7": null, + "r8": null, + "r9": null, + "r10": null, + "r11": null, + "r12": null, + "r13": null, + "r14": null, + "r15": null, + "r16": null, + "r17": null, + "r18": null, + "r19": null, + "r20": null, + "r21": null, + "r22": null, + "r23": null, + "r24": 0, + "r25": 0, + "r26": 0, + "r27": 128, + "r28": 8, + "r29": 0, + "r30": 255, + "r31": 255 + }, + "postcondition": { + "sreg": { + "c": null, + "z": null, + "n": null, + "v": null, + "s": null, + "h": null, + "t": null, + "i": null + }, + "r0": null, + "r1": null, + "r2": null, + "r3": null, + "r4": null, + "r5": null, + "r6": null, + "r7": null, + "r8": null, + "r9": null, + "r10": null, + "r11": null, + "r12": null, + "r13": null, + "r14": null, + "r15": null, + "r16": 21, + "r17": 24, + "r18": 2, + "r19": 20, + "r20": null, + "r21": null, + "r22": null, + "r23": null, + "r24": 248, + "r25": 255, + "r26": 255, + "r27": 127, + "r28": 0, + "r29": 0, + "r30": 192, + "r31": 255 + }, + "mileage": 0, + "cpu": "atmega2560", + "cpus": null, + "optimize": "ReleaseSmall", + "gcc_flags": [ + "-g", + "-O2", + "-nostdlib", + "-nostdinc", + "-ffreestanding" + ] +} \ No newline at end of file diff --git a/sim/aviron/testsuite/instructions/sbiw-atmega328p.elf b/sim/aviron/testsuite/instructions/sbiw-atmega328p.elf new file mode 100755 index 0000000000000000000000000000000000000000..1b87a09f26814d28a2c50f5de51332dc2aae5578 GIT binary patch literal 320 zcmaKmAr1mD6hx<8AS4K~7$nG5i&>8Xh2sPzkf7NL94Kx;isTkO9?X<2LGhAFr+?c2 z|7EpV8)J~M*dpH=7N1m~YA}aIg&vBOd)6`&8cFXgrT;ey=9=oVVn8VyhH)&zELLF= zUtt*^chv2%^(XIksQ1o0)c$b(9ii`k88KDwLa#VC&6n>`CQ3?Py9f=@?iuYbzP&!z L)Nk7Poa=l8F98<4 literal 0 HcmV?d00001 diff --git a/sim/aviron/testsuite/instructions/sbiw-atmega328p.elf.json b/sim/aviron/testsuite/instructions/sbiw-atmega328p.elf.json new file mode 100644 index 000000000..2a3da12aa --- /dev/null +++ b/sim/aviron/testsuite/instructions/sbiw-atmega328p.elf.json @@ -0,0 +1,106 @@ +{ + "exit": "breakpoint", + "exit_code": 0, + "stdout": "", + "stderr": "", + "stdin": "", + "precondition": { + "sreg": { + "c": null, + "z": null, + "n": null, + "v": null, + "s": null, + "h": null, + "t": null, + "i": null + }, + "r0": null, + "r1": null, + "r2": null, + "r3": null, + "r4": null, + "r5": null, + "r6": null, + "r7": null, + "r8": null, + "r9": null, + "r10": null, + "r11": null, + "r12": null, + "r13": null, + "r14": null, + "r15": null, + "r16": null, + "r17": null, + "r18": null, + "r19": null, + "r20": null, + "r21": null, + "r22": null, + "r23": null, + "r24": 0, + "r25": 0, + "r26": 0, + "r27": 128, + "r28": 8, + "r29": 0, + "r30": 255, + "r31": 255 + }, + "postcondition": { + "sreg": { + "c": null, + "z": null, + "n": null, + "v": null, + "s": null, + "h": null, + "t": null, + "i": null + }, + "r0": null, + "r1": null, + "r2": null, + "r3": null, + "r4": null, + "r5": null, + "r6": null, + "r7": null, + "r8": null, + "r9": null, + "r10": null, + "r11": null, + "r12": null, + "r13": null, + "r14": null, + "r15": null, + "r16": 21, + "r17": 24, + "r18": 2, + "r19": 20, + "r20": null, + "r21": null, + "r22": null, + "r23": null, + "r24": 248, + "r25": 255, + "r26": 255, + "r27": 127, + "r28": 0, + "r29": 0, + "r30": 192, + "r31": 255 + }, + "mileage": 0, + "cpu": "atmega328p", + "cpus": null, + "optimize": "ReleaseSmall", + "gcc_flags": [ + "-g", + "-O2", + "-nostdlib", + "-nostdinc", + "-ffreestanding" + ] +} \ No newline at end of file