Improve architectural compliance of mfspr and mtspr
authorPaul Mackerras <paulus@ozlabs.org>
Sat, 2 May 2020 10:08:10 +0000 (20:08 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Fri, 8 May 2020 02:12:01 +0000 (12:12 +1000)
Mfspr from an unimplemented SPR should be a no-op in privileged state,
so in this case we need to write back whatever was previously in the
destination register.  For problem state, both mtspr and mfspr to
unimplemented SPRs should cause a program interrupt.

There are special cases in the architecture for SPRs 0, 4 5 and 6
which we still don't implement.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
decode1.vhdl
execute1.vhdl

index 0e88ef38173e4a18ebceb52e3b258d84ffc58c09..a819b79f955f9f6229971c3e650cd2ba7dcab12e 100644 (file)
@@ -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
index 694004988b8fca94bbdb31883d5bdac33704eedf..c479a451f469e359d2eb23a0d53acd188be00b29 100644 (file)
@@ -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 =>