From a0d95e791e52b1ca7ee7b14e041453fb54e34a6f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 22 Oct 2019 14:49:35 +1100 Subject: [PATCH] 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 --- decode1.vhdl | 2 +- execute1.vhdl | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 747411b..afb1315 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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 ); diff --git a/execute1.vhdl b/execute1.vhdl index de18a37..ec11678 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -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; -- 2.30.2