insn: Implement isync instruction
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 22 Oct 2019 03:49:35 +0000 (14:49 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 23 Oct 2019 01:31:16 +0000 (12:31 +1100)
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>
decode1.vhdl
execute1.vhdl

index 747411b4c9cf155d8db71e1593f1c80fbbb5d1a2..afb1315ac158abb3ff610006dff2a4b3370be9d2 100644 (file)
@@ -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
         );
 
index de18a3754cf075ca542935a73ab12b7751f5d8ee..ec11678e6c2dc7cce5199a856169272d9c167ca8 100644 (file)
@@ -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;