Do sign-extension instructions in writeback instead of execute1
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 14 Oct 2019 03:39:23 +0000 (14:39 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 15 Oct 2019 04:27:00 +0000 (15:27 +1100)
This makes the exts[bhw] instructions do the sign extension in the
writeback stage using the sign-extension logic there instead of
having unique sign extension logic in execute1.  This requires
passing the data length and sign extend flag from decode2 down
through execute1 and execute2 and into writeback.  As a side bonus
we reduce the number of values in insn_type_t by two.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
common.vhdl
decode1.vhdl
decode2.vhdl
decode_types.vhdl
execute1.vhdl
execute2.vhdl
writeback.vhdl

index 321cff1257a69e2244c6108ee5fdef835978b775..41623af292c588fc3cfadc8b569395ef556d3d97 100644 (file)
@@ -64,6 +64,7 @@ package common is
                is_32bit: std_ulogic;
                is_signed: std_ulogic;
                 insn: std_ulogic_vector(31 downto 0);
+                data_len: std_ulogic_vector(3 downto 0);
        end record;
        constant Decode2ToExecute1Init : Decode2ToExecute1Type :=
                (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', invert_a => '0',
@@ -168,12 +169,14 @@ package common is
                write_enable : std_ulogic;
                write_reg: std_ulogic_vector(4 downto 0);
                write_data: std_ulogic_vector(63 downto 0);
+               write_len : std_ulogic_vector(3 downto 0);
                write_cr_enable : std_ulogic;
                write_cr_mask : std_ulogic_vector(7 downto 0);
                write_cr_data : std_ulogic_vector(31 downto 0);
                rc : std_ulogic;
+                sign_extend: std_ulogic;
        end record;
-       constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', others => (others => '0'));
+       constant Execute1ToExecute2Init : Execute1ToExecute2Type := (valid => '0', write_enable => '0', write_cr_enable => '0', rc => '0', sign_extend => '0',  others => (others => '0'));
 
        type Execute2ToWritebackType is record
                valid: std_ulogic;
@@ -181,11 +184,13 @@ package common is
                write_enable : std_ulogic;
                write_reg: std_ulogic_vector(4 downto 0);
                write_data: std_ulogic_vector(63 downto 0);
+               write_len : std_ulogic_vector(3 downto 0);
                write_cr_enable : std_ulogic;
                write_cr_mask : std_ulogic_vector(7 downto 0);
                write_cr_data : std_ulogic_vector(31 downto 0);
+                sign_extend: std_ulogic;
        end record;
-       constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', others => (others => '0'));
+       constant Execute2ToWritebackInit : Execute2ToWritebackType := (valid => '0', rc => '0', write_enable => '0', write_cr_enable => '0', sign_extend => '0', others => (others => '0'));
 
        type MultiplyToWritebackType is record
                valid: std_ulogic;
index 2bdb4230507c34c258b92f4c0be287db605beade..49e37da1c7de9680f24dc54e174bdeece41153e4 100644 (file)
@@ -164,9 +164,9 @@ architecture behaviour of decode1 is
                2#0111101001#  =>       (DIV,    OP_DIV,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'), -- divd
                2#0111101011#  =>       (DIV,    OP_DIV,       RA,         RB,          NONE, RT,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'), -- divw
                2#0100011100#  =>       (ALU,    OP_XOR,       NONE,       RB,          RS,   RA,   '0', '0', '0', '1', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- eqv
-               2#1110111010#  =>       (ALU,    OP_EXTSB,     NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsb
-               2#1110011010#  =>       (ALU,    OP_EXTSH,     NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsh
-               2#1111011010#  =>       (ALU,    OP_EXTSW,     NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsw
+               2#1110111010#  =>       (ALU,    OP_EXTS,      NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsb
+               2#1110011010#  =>       (ALU,    OP_EXTS,      NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsh
+               2#1111011010#  =>       (ALU,    OP_EXTS,      NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- extsw
                -- 2#110111101-# extswsli
                2#1111010110#  =>       (ALU,    OP_NOP,       NONE,       NONE,        NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbi
                2#0000010110#  =>       (ALU,    OP_NOP,       NONE,       NONE,        NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt
index 524943c789df95e1baccc2b6ba272806e1dcf9bc..c8dee489c62b96327e772132276f0fca5a754630 100644 (file)
@@ -208,6 +208,7 @@ begin
                variable decoded_reg_b : decode_input_reg_t;
                variable decoded_reg_c : decode_input_reg_t;
                 variable signed_division: std_ulogic;
+                variable length : std_ulogic_vector(3 downto 0);
        begin
                v := r;
 
@@ -231,6 +232,19 @@ begin
                r_out.read2_enable <= decoded_reg_b.reg_valid;
                r_out.read3_enable <= decoded_reg_c.reg_valid;
 
+               case d_in.decode.length is
+               when is1B =>
+                       length := "0001";
+               when is2B =>
+                       length := "0010";
+               when is4B =>
+                       length := "0100";
+               when is8B =>
+                       length := "1000";
+               when NONE =>
+                       length := "0000";
+               end case;
+
                -- execute unit
                v.e.nia := d_in.nia;
                v.e.insn_type := d_in.decode.insn_type;
@@ -252,6 +266,7 @@ begin
                        v.e.lr := insn_lk(d_in.insn);
                end if;
                 v.e.insn := d_in.insn;
+                v.e.data_len := length;
 
                -- multiply unit
                v.m.insn_type := d_in.decode.insn_type;
@@ -336,19 +351,7 @@ begin
                        v.l.load := '0';
                end if;
 
-               case d_in.decode.length is
-               when is1B =>
-                       v.l.length := "0001";
-               when is2B =>
-                       v.l.length := "0010";
-               when is4B =>
-                       v.l.length := "0100";
-               when is8B =>
-                       v.l.length := "1000";
-               when NONE =>
-                       v.l.length := "0000";
-               end case;
-
+                v.l.length := length;
                v.l.byte_reverse := d_in.decode.byte_reverse;
                v.l.sign_extend := d_in.decode.sign_extend;
                v.l.update := d_in.decode.update;
index 982b172aa8b2443c129cc6d89c69cf199e5edf83..f6b6ca9c5475804e163cb3a98b3741a75b8391a7 100644 (file)
@@ -8,7 +8,7 @@ package decode_types is
                OP_CNTZ, OP_CRAND,
                OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC,
                OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
-               OP_DCBZ, OP_DIV, OP_EXTSB, OP_EXTSH, OP_EXTSW,
+               OP_DCBZ, OP_DIV, OP_EXTS,
                OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC,
                OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF,
                OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFSPR, OP_MOD,
index d0ff461ee376785965fcc89a1ccb7be1adab2f27..85bb5e1380d1ae23047690148c6279fda023a7f3 100644 (file)
@@ -143,6 +143,8 @@ begin
 
                        v.e.valid := '1';
                        v.e.write_reg := e_in.write_reg;
+                        v.e.write_len := x"8";
+                        v.e.sign_extend := '0';
 
                        case_0: case e_in.insn_type is
 
@@ -230,14 +232,10 @@ begin
                                when OP_CNTZ =>
                                        result := countzero_result;
                                        result_en := 1;
-                               when OP_EXTSB =>
-                                       result := ppc_extsb(e_in.read_data3);
-                                       result_en := 1;
-                               when OP_EXTSH =>
-                                       result := ppc_extsh(e_in.read_data3);
-                                       result_en := 1;
-                               when OP_EXTSW =>
-                                       result := ppc_extsw(e_in.read_data3);
+                               when OP_EXTS =>
+                                        v.e.write_len := e_in.data_len;
+                                        v.e.sign_extend := '1';
+                                       result := e_in.read_data3;
                                        result_en := 1;
                                when OP_ISEL =>
                                        crnum := to_integer(unsigned(insn_bc(e_in.insn)));
index de55310a41e3203549910db19811a11736b6a034..97b4103a7a3c41f431f67a54fc37f85308b5c013 100644 (file)
@@ -40,6 +40,8 @@ begin
         v.write_cr_mask := e_in.write_cr_mask;
         v.write_cr_data := e_in.write_cr_data;
         v.rc := e_in.rc;
+        v.write_len := e_in.write_len;
+        v.sign_extend := e_in.sign_extend;
 
         -- Update registers
         rin <= v;
index ba8897031d7fbce0aa5a8205d287111ef66b7ee0..4bae8f7b19b5cb78a807f93bf8b87b24313945cc 100644 (file)
@@ -100,6 +100,8 @@ begin
             w_out.write_reg <= e_in.write_reg;
             data_in <= e_in.write_data;
             w_out.write_enable <= '1';
+            data_len <= unsigned(e_in.write_len);
+            sign_extend <= e_in.sign_extend;
             rc <= e_in.rc;
         end if;