insn: Implement isync instruction

The instruction works by redirecting fetch to nia+4 (hopefully using
the same adder used to generate LR) and doing a backflush. Along with
being single issue, this should guarantee that the next instruction
only gets fetched after the pipe's been emptied.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/114/head
Benjamin Herrenschmidt 5 years ago
parent 6e0ee0b0db
commit a0d95e791e

@ -108,7 +108,7 @@ architecture behaviour of decode1 is
-- bclr, bcctr, bctar
2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'),
-- isync
2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
2#111# => (ALU, OP_ISYNC, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
others => illegal_inst
);


@ -118,6 +118,7 @@ begin
variable bo, bi : std_ulogic_vector(4 downto 0);
variable bf, bfa : std_ulogic_vector(2 downto 0);
variable l : std_ulogic;
variable next_nia : std_ulogic_vector(63 downto 0);
begin
result := (others => '0');
result_with_carry := (others => '0');
@ -135,6 +136,9 @@ begin
terminate_out <= '0';
f_out <= Execute1ToFetch1TypeInit;

-- Next insn adder used in a couple of places
next_nia := std_ulogic_vector(unsigned(e_in.nia) + 4);

-- rotator control signals
right_shift <= '1' when e_in.insn_type = OP_SHR else '0';
rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0';
@ -345,13 +349,17 @@ begin
-- Keep our test cases happy for now, ignore trap instructions
report "OP_TDI FIXME";

when OP_ISYNC =>
f_out.redirect <= '1';
f_out.redirect_nia <= next_nia;

when others =>
terminate_out <= '1';
report "illegal";
end case;

if e_in.lr = '1' then
ctrl_tmp.lr <= std_ulogic_vector(unsigned(e_in.nia) + 4);
ctrl_tmp.lr <= next_nia;
end if;

end if;

Loading…
Cancel
Save