From: Paul Mackerras Date: Fri, 29 Jul 2022 23:42:19 +0000 (+1000) Subject: decode2: Decode unit and single-pipe attributes for mfspr/mtspr in decode2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=47895f8aff5f8ff0d1a3f86509e22c4e5290b181;p=microwatt.git decode2: Decode unit and single-pipe attributes for mfspr/mtspr in decode2 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 --- diff --git a/decode1.vhdl b/decode1.vhdl index 8bea225..f50b82e 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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"; diff --git a/decode2.vhdl b/decode2.vhdl index 0592fe4..6cac985 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -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;