Add R4600 CPU support to cputest bench - #109
Merged
Merged
Conversation
The sgiindy_MiSTer core presents as an R4600 (PRId/FIR 0x2020, 16 KB caches with 32-byte lines). This is the patch its gates ran with: accept imp 0x20 as R4000-class in identify(), and expect the R4600's identity and cache geometry. Rebased onto the hardware-validated suite; the PRId/FIR checks keep main's revision masking. Superseded by a proper CPU_R4600 kind in the following commits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The suite refused imp 0x20 with rc=127. The sgiindy_MiSTer FPGA core presents as an R4600 (IRIX 5.3 hard-codes a 32-byte D-cache line for it), so it could not be measured against the hardware-validated expectations. - harness: CPU_R4600 is its own kind (not folded into CPU_R4400), with is_r4600() and has_mips4(); skip messages name any CPU combination. - identity/cache: PRId and FIR imp 0x20, 16 KB caches with 32-byte lines, two ways - from the IDT79R4600 data sheet. - mips4/*: gated on has_mips4() rather than is_r4400(), so the R4600 must refuse MIPS IV like the R4400 (RI outside COP1, FPE inside it). - fpu_denorm: asserted for the R4600 with the R4400 - the R5000's reported observations are byte-identical to the R4400's assertions in every case. - mem/lwr_all_offsets: the two measured parts differ on a partial LWR, so an R4600 passes with either answer and the log names which. No change for the R4400 or the R5000: every branch they take is the same. docs/r4600.md tabulates where each R4600 answer comes from and what the first real R4600 run would confirm. On the sgiindy_MiSTer core (build 30b): cpu=R4600, 2096 passed / 54 failed, 12 failing tests - all in the classes the Indy runs corrected (NaN polarity, COP1 unimplemented -> FPE, COP2 with CU2 set, cvt from long). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rocessor Unusable Every test so far ran in Kernel mode, so nothing could see whether a CPU enforces the CP0 privilege rule: CP0 instructions (and CACHE) are usable in Kernel mode or with Status.CU0 set, otherwise Coprocessor Unusable with Cause.CE = 0 (R4000 manual, chapter 5). excep/cp0_unusable_user maps a scratch page at kuseg 0x00400000, ERETs into it with KSU = User (then Supervisor), runs mfc0 / tlbp there, and comes home through a syscall. A test-local exception hook (um_handler) steps over faults in the mode they came from and keeps the first Cause; a runaway guard returns after eight faults so a broken CPU cannot hang the suite. A control run (syscall only) proves User mode was really entered. excep/cp0_usable_cu0 checks that CU0 grants access. Derived from the manual, not yet run on silicon. On the sgiindy_MiSTer core before its fix: the control passed and all three accesses executed silently (6 failed checks) - which is the finding. IRIS added the same gate in src (rules/testing/cop0-requires-kernel-or-cu0.md). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…sters Disabled on 2026-09-12 because it changed KSEG0's cacheability while its own spilled local was a dirty D-cache line: an uncached reload then read pre-spill RAM, the restore wrote a wrong K0 and the CPU ran into unmapped KUSEG. That hazard is real on hardware too (the Indy passed by luck). Between the first MTC0 and the restore there is now no load, store or call: orig, the counter and two failure bitmasks (one bit per K0 value: the field did not stick / another Config bit moved) live in registers, and results reach memory only after Config is back. Instruction fetch is the one thing the attribute still affects, and the text was written back to memory when the suite relocated itself. On the sgiindy_MiSTer core (R4600 presentation, K0 = 2 uncached): PASS, 2167/0 over 242 tests. Not yet run on silicon. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A pipelined CPU finds a load's value a stage later than any other result, so the instruction immediately behind a load is where forwarding breaks: used at once, used one instruction later, as the next load's base (a pointer chase), in a branch, stored and reloaded at once, overwritten by a second load, narrow loads extended, and the load in a branch delay slot. Each sequence runs with its lines out of the D-cache and in it, since those are different paths through a core. Written as the guard for making the sgiindy_MiSTer core stall only on a real load-use hazard instead of on every load. Plain ISA semantics, true on every part. Passes on that core as it is today (2187/0, 243 tests). One trap recorded in the test: an asm block's "=r" output may be given the same hard register as an input, so a sequence that writes its output before reading an input compares against garbage - the first version of the branch case did exactly that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… on silicon Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mem/load_then_trap: syscall, break, teq, add overflow and a reserved instruction immediately after a load, once with the load's D-cache line invalidated (the load is still filling when the trap executes) and once cached. Exactly one exception, EPC on the trapping instruction, and the loaded value in place when the handler resumes. mem/load_then_more: an mfc0, a ddivu, a jr with its delay slot, a second load and a store two instructions behind, and a store then load then non-memory instruction (the D-cache READWAIT) - each after a load. fpu/trap_behind_a_load: div.s by zero with Z enabled right behind an integer load from a line the operand loads do not fill. Operands are built inside the asm blocks: a loop-invariant input can share a hard register with an "=r" output and arrive clobbered on pass 1 (the first version of load_then_more's divide failed that way on every core). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Not tested on real hardware, but I think we might be pretty close. This is to support the SGI Indy MiSTer core.