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 <paulus@ozlabs.org>
pull/382/head
Paul Mackerras 2 years ago
parent 09965b9102
commit 47895f8aff

@ -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";

@ -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;

Loading…
Cancel
Save