diff --git a/decode1.vhdl b/decode1.vhdl index 0e88ef3..a819b79 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -249,7 +249,7 @@ architecture behaviour of decode1 is -- 2#1001000000# mcrxrx 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfcr/mfocrf 2#0001010011# => (ALU, OP_MFMSR, NONE, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfmsr - 2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr + 2#0101010011# => (ALU, OP_MFSPR, SPR, NONE, RS, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- mfspr 2#0100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- modud 2#0100001011# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', NONE, '0', '0'), -- moduw 2#1100001001# => (ALU, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- modsd diff --git a/execute1.vhdl b/execute1.vhdl index 6940049..c479a45 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -735,6 +735,7 @@ begin when OP_MFSPR => report "MFSPR to SPR " & integer'image(decode_spr_num(e_in.insn)) & "=" & to_hstring(a_in); + result_en := '1'; if is_fast_spr(e_in.read_reg1) then result := a_in; if decode_spr_num(e_in.insn) = SPR_XER then @@ -753,11 +754,15 @@ begin result := ctrl.tb; when SPR_DEC => result := ctrl.dec; - when others => - result := (others => '0'); + when others => + -- mfspr from unimplemented SPRs should be a nop in + -- supervisor mode and a program interrupt for user mode + result := c_in; + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + end if; end case; end if; - result_en := '1'; when OP_MFCR => if e_in.insn(20) = '0' then -- mfcr @@ -823,6 +828,11 @@ begin when SPR_DEC => ctrl_tmp.dec <= c_in; when others => + -- mtspr to unimplemented SPRs should be a nop in + -- supervisor mode and a program interrupt for user mode + if ctrl.msr(MSR_PR) = '1' then + illegal := '1'; + end if; end case; end if; when OP_POPCNT =>