decode2: Decode unit and single-pipe attributes for mfspr/mtspr in decode2
authorPaul Mackerras <paulus@ozlabs.org>
Fri, 29 Jul 2022 23:42:19 +0000 (09:42 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 9 Aug 2022 09:51:57 +0000 (19:51 +1000)
Instead of doing that in decode1.  That lets us get rid of the
force_single and override_unit fields of reg_internal_t in decode1,
which will simplify following changes to decode1.

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

index 8bea2250badeaa16891dfc14b7c2dad0c4adc108..f50b82e1256d9484eaff2b1f21fd585ecebc1e48 100644 (file)
@@ -54,11 +54,9 @@ architecture behaviour of decode1 is
     type reg_internal_t is record
         override : std_ulogic;
         override_decode: decode_rom_t;
-        override_unit: std_ulogic;
-        force_single: std_ulogic;
     end record;
     constant reg_internal_t_init : reg_internal_t :=
-        (override => '0', override_decode => illegal_inst, override_unit => '0', force_single => '0');
+        (override => '0', override_decode => illegal_inst);
 
     signal ri, ri_in : reg_internal_t;
 
@@ -703,31 +701,6 @@ begin
             end if;
             may_read_rb := '1';
 
-            if std_match(f_in.insn(10 downto 1), "01-1010011") then
-                -- mfspr or mtspr
-                -- Make mtspr to slow SPRs single issue
-                if v.spr_info.valid = '1' then
-                    vi.force_single := f_in.insn(8);
-                end if;
-                -- send MMU-related SPRs to loadstore1
-                case sprn is
-                    when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR =>
-                        vi.override_decode.unit := LDST;
-                        vi.override_unit := '1';
-                        -- make mtspr to loadstore SPRs single-issue
-                        if f_in.insn(8) = '1' then
-                            vi.force_single := '1';
-                        end if;
-                    when others =>
-                end case;
-               -- FIXME: This is a bit fragile doing this here but sprn depends
-               -- on f_in.insn
-               if is_X(f_in.insn) then
-                   vi.override_decode.unit := NONE;
-                   vi.override_unit := 'X';
-                   vi.force_single := 'X';
-               end if;
-            end if;
             if HAS_FPU and std_match(f_in.insn(10 downto 1), "1----10111") then
                 -- lower half of column 23 has FP loads and stores
                 fprs := '1';
@@ -880,11 +853,6 @@ begin
         d_out <= r;
         if ri.override = '1' then
             d_out.decode <= ri.override_decode;
-        elsif ri.override_unit = '1' then
-            d_out.decode.unit <= ri.override_decode.unit;
-        end if;
-        if ri.force_single = '1' then
-            d_out.decode.sgl_pipe <= '1';
         end if;
         f_out.redirect <= br.predict;
         f_out.redirect_nia <= br_target & "00";
index 0592fe40ad402833b816dfafc681db316a74c1bf..6cac9853938b2a4ca60d49daabe980d2c85a8744 100644 (file)
@@ -389,6 +389,7 @@ begin
         variable v : reg_type;
         variable length : std_ulogic_vector(3 downto 0);
         variable op : insn_type_t;
+        variable unit : unit_t;
         variable valid_in : std_ulogic;
         variable decctr : std_ulogic;
         variable sprs_busy : std_ulogic;
@@ -401,6 +402,7 @@ begin
             v.e := Decode2ToExecute1Init;
 
             sprs_busy := '0';
+            unit := d_in.decode.unit;
 
             if d_in.valid = '1' then
                 v.prev_sgl := dc2.sgl_pipe;
@@ -433,13 +435,27 @@ begin
                         v.input_ov := '1';      -- need SO state if setting OV to 0
                     end if;
                 when OP_MFSPR =>
-                    if decode_spr_num(d_in.insn) = SPR_XER then
-                        v.input_ov := '1';
-                    end if;
+                    case decode_spr_num(d_in.insn) is
+                        when SPR_XER =>
+                            v.input_ov := '1';
+                        when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR =>
+                            unit := LDST;
+                        when others =>
+                    end case;
                 when OP_MTSPR =>
-                    if decode_spr_num(d_in.insn) = SPR_XER then
-                        v.e.output_xer := '1';
-                        v.output_ov := '1';
+                    case decode_spr_num(d_in.insn) is
+                        when SPR_XER =>
+                            v.e.output_xer := '1';
+                            v.output_ov := '1';
+                        when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR =>
+                            unit := LDST;
+                            if d_in.valid = '1' then
+                                v.sgl_pipe := '1';
+                            end if;
+                        when others =>
+                    end case;
+                    if d_in.spr_info.valid = '1' and d_in.valid = '1' then
+                        v.sgl_pipe := '1';
                     end if;
                 when OP_CMP | OP_MCRXRX =>
                     v.input_ov := '1';
@@ -528,7 +544,7 @@ begin
 
             -- execute unit
             v.e.nia := d_in.nia;
-            v.e.unit := d_in.decode.unit;
+            v.e.unit := unit;
             v.e.fac := d_in.decode.facility;
             v.e.read_reg1 := d_in.reg_a;
             v.e.read_reg2 := d_in.reg_b;