Summary
ParsingMain.fs rejects the entire COP0 major opcode, so none of the twenty-odd instructions encoded there can reach the lifter.
The second issue is that even with a correct decoder, there is currently nowhere to store the decoded CP0 state. For example, MFC0 $8, $12 moves the Status register into $8, but src/FrontEnd/Registers/MIPS.fs defines no CP0 registers at all.
This is therefore a decode gap first and a model gap second. The decoder can be added from the architecture tables, while the CP0 register file requires deciding how much architectural state should be modeled.
Reproduce
Parse any word whose top six bits are 010000. For example, 0x40086000 is MFC0 $8, $12, but parsing it raises ParsingFailureException.
As a result, it is reported as an undecodable word rather than as an instruction with no lifter.
The consequences are visible in several places in the front end:
src/FrontEnd/MIPS/Opcode.fs already defines MFC0, MTC0, MFHC0, MTHC0, DI, EI, RDPGPR, WRPGPR, ERET, ERETNC, DERET, WAIT, TLBP, TLBR, TLBWI, TLBWR, TLBINV, TLBINVF, CACHE, and CACHEE. However, these opcodes are never produced or lifted, and Disasm.fs has no corresponding opCodeToString arms.
src/FrontEnd/MIPS/Instruction.fs:128-136 handles WAIT in IsInterrupt and DERET, ERET, and ERETNC in IsExit, but these paths are currently unreachable because no decoded instruction can carry those opcodes.
DMFC0 and DMTC0 are not present in the opcode enum at all, so enum entries are required before the decoder can produce them.
Root cause
There are two independent causes.
Decoder. src/FrontEnd/MIPS/ParsingMain.fs:831:
| 0b010000u ->
raise ParsingFailureException (* COP0 *)
The entire COP0 major opcode is rejected.
CACHE is also rejected separately under major opcode 101111.
Register file. src/FrontEnd/Registers/MIPS.fs:167-187 defines only the following registers in addition to the GPRs and FPRs:
| HI = 0x100
| LO = 0x101
| PC = 0x102
| NPC = 0x103
| FCSR = 0x105
| FIR = 0x106
| ExMonAddr = 0x107
| ExMonVal = 0x108
| ULR = 0x109
ExMonAddr and ExMonVal are pseudo registers used to hold the LL/SC exclusive monitor reservation.
There are no CP0 registers such as Status, Cause, EPC, BadVAddr, Count, Compare, EntryHi, EntryLo0, EntryLo1, Index, Wired, or Config.
ULR is the only CP0-derived value in the list. Its documentation describes it as "HWR 29, backed by CP0 UserLocal", but it is a pseudo register accessed through RDHWR, not a CP0 register accessible through MFC0.
Summary
ParsingMain.fsrejects the entire COP0 major opcode, so none of the twenty-odd instructions encoded there can reach the lifter.The second issue is that even with a correct decoder, there is currently nowhere to store the decoded CP0 state. For example,
MFC0 $8, $12moves the Status register into$8, butsrc/FrontEnd/Registers/MIPS.fsdefines no CP0 registers at all.This is therefore a decode gap first and a model gap second. The decoder can be added from the architecture tables, while the CP0 register file requires deciding how much architectural state should be modeled.
Reproduce
Parse any word whose top six bits are
010000. For example,0x40086000isMFC0 $8, $12, but parsing it raisesParsingFailureException.As a result, it is reported as an undecodable word rather than as an instruction with no lifter.
The consequences are visible in several places in the front end:
src/FrontEnd/MIPS/Opcode.fsalready definesMFC0,MTC0,MFHC0,MTHC0,DI,EI,RDPGPR,WRPGPR,ERET,ERETNC,DERET,WAIT,TLBP,TLBR,TLBWI,TLBWR,TLBINV,TLBINVF,CACHE, andCACHEE. However, these opcodes are never produced or lifted, andDisasm.fshas no correspondingopCodeToStringarms.src/FrontEnd/MIPS/Instruction.fs:128-136handlesWAITinIsInterruptandDERET,ERET, andERETNCinIsExit, but these paths are currently unreachable because no decoded instruction can carry those opcodes.DMFC0andDMTC0are not present in the opcode enum at all, so enum entries are required before the decoder can produce them.Root cause
There are two independent causes.
Decoder.
src/FrontEnd/MIPS/ParsingMain.fs:831:The entire COP0 major opcode is rejected.
CACHEis also rejected separately under major opcode101111.Register file.
src/FrontEnd/Registers/MIPS.fs:167-187defines only the following registers in addition to the GPRs and FPRs:ExMonAddrandExMonValare pseudo registers used to hold the LL/SC exclusive monitor reservation.There are no CP0 registers such as
Status,Cause,EPC,BadVAddr,Count,Compare,EntryHi,EntryLo0,EntryLo1,Index,Wired, orConfig.ULRis the only CP0-derived value in the list. Its documentation describes it as"HWR 29, backed by CP0 UserLocal", but it is a pseudo register accessed throughRDHWR, not a CP0 register accessible throughMFC0.