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;
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';
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";
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;
v.e := Decode2ToExecute1Init;
sprs_busy := '0';
+ unit := d_in.decode.unit;
if d_in.valid = '1' then
v.prev_sgl := dc2.sgl_pipe;
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';
-- 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;