core: Do addpcis using the main adder (#189)
authorPaul Mackerras <paulus@ozlabs.org>
Fri, 5 Jun 2020 01:29:31 +0000 (11:29 +1000)
committerGitHub <noreply@github.com>
Fri, 5 Jun 2020 01:29:31 +0000 (11:29 +1000)
By adding logic to decode2 to be able to send the instruction address
down the A input, and making CONST_DX_HI (renamed to CONST_DXHI4) add
4 to the immediate value (easy since the bottom 16 bits were zero),
we can do addpcis using the main adder.  This reduces the width of the
result mux and frees up one value in insn_type_t, since we can now use
OP_ADD for addpcis.

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

index 5eedbabf2349fe4a9fa50484e0466858c7ad7ab5..4aae7073ab02682d63a4e65bdc2411c2091a8281 100644 (file)
@@ -107,7 +107,7 @@ architecture behaviour of decode1 is
                 -- mcrf; and cr logical ops
                2#000#    =>       (ALU,    OP_CROP,      NONE,       NONE,        NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'),
                -- addpcis
-               2#001#    =>       (ALU,    OP_ADDPCIS,   NONE,       CONST_DX_HI, NONE, RT,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'),
+               2#001#    =>       (ALU,    OP_ADD,       CIA,        CONST_DXHI4, NONE, RT,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'),
                 -- bclr, bcctr, bctar
                2#100#    =>       (ALU,    OP_BCREG,     SPR,        SPR,         NONE, SPR,  '1', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '0'),
                 -- isync
index da0bdff5af5839586702903bfb8888f9b821f849..772c1df514e5e0d35a50fdbd852f8296958008bf 100644 (file)
@@ -56,7 +56,9 @@ architecture behaviour of decode2 is
 
        function decode_input_reg_a (t : input_reg_a_t; insn_in : std_ulogic_vector(31 downto 0);
                                     reg_data : std_ulogic_vector(63 downto 0);
-                                    ispr : gspr_index_t) return decode_input_reg_t is
+                                    ispr : gspr_index_t;
+                                     instr_addr : std_ulogic_vector(63 downto 0))
+            return decode_input_reg_t is
        begin
                if t = RA or (t = RA_OR_ZERO and insn_ra(insn_in) /= "00000") then
                    assert is_fast_spr(ispr) = '0' report "Decode A says GPR but ISPR says SPR:" &
@@ -71,6 +73,8 @@ architecture behaviour of decode2 is
                        report "Decode A says SPR but ISPR is invalid:" &
                        to_hstring(ispr) severity failure;
                    return (is_fast_spr(ispr), ispr, reg_data);
+                elsif t = CIA then
+                    return ('0', (others => '0'), instr_addr);
                else
                        return ('0', (others => '0'), (others => '0'));
                end if;
@@ -100,8 +104,8 @@ architecture behaviour of decode2 is
                        ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_bd(insn_in)) & "00", 64)));
                when CONST_DS =>
                        ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64)));
-               when CONST_DX_HI =>
-                       ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_dx(insn_in)) & x"0000", 64)));
+               when CONST_DXHI4 =>
+                       ret := ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_dx(insn_in)) & x"0004", 64)));
                 when CONST_M1 =>
                        ret := ('0', (others => '0'), x"FFFFFFFFFFFFFFFF");
                when CONST_SH =>
@@ -282,7 +286,8 @@ begin
                --v.e.input_cr := d_in.decode.input_cr;
                --v.e.output_cr := d_in.decode.output_cr;
     
-               decoded_reg_a := decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, r_in.read1_data, d_in.ispr1);
+               decoded_reg_a := decode_input_reg_a (d_in.decode.input_reg_a, d_in.insn, r_in.read1_data, d_in.ispr1,
+                                                     d_in.nia);
                decoded_reg_b := decode_input_reg_b (d_in.decode.input_reg_b, d_in.insn, r_in.read2_data, d_in.ispr2);
                decoded_reg_c := decode_input_reg_c (d_in.decode.input_reg_c, d_in.insn, r_in.read3_data);
                decoded_reg_o := decode_output_reg (d_in.decode.output_reg_a, d_in.insn, d_in.ispr1);
index bd1650780ca6363af2d34d0497953d1e5d4728e4..9cd6d690d2b01516b924b29befb4df76430d307b 100644 (file)
@@ -3,7 +3,7 @@ use ieee.std_logic_1164.all;
 
 package decode_types is
     type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD,
-                        OP_ADDPCIS, OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG,
+                        OP_AND, OP_ATTN, OP_B, OP_BC, OP_BCREG,
                         OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPRB,
                         OP_CNTZ, OP_CROP,
                         OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,
@@ -20,8 +20,9 @@ package decode_types is
                         OP_XOR,
                          OP_FETCH_FAILED
                         );
-    type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR);
-    type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DX_HI, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR);
+    type input_reg_a_t is (NONE, RA, RA_OR_ZERO, SPR, CIA);
+    type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD,
+                           CONST_DXHI4, CONST_DS, CONST_M1, CONST_SH, CONST_SH32, SPR);
     type input_reg_c_t is (NONE, RS);
     type output_reg_a_t is (NONE, RT, RA, SPR);
     type rc_t is (NONE, ONE, RC);
index 3207958637ee4294edaec589636ab812ed456127..cac8e8a93db409f59a1f058e6c86b7d9a04b206b 100644 (file)
@@ -528,9 +528,6 @@ begin
                 end if;
            when OP_NOP =>
                -- Do nothing
-           when OP_ADDPCIS =>
-               result := ppc_adde(next_nia, b_in, '0')(63 downto 0);
-               result_en := '1';
            when OP_ADD | OP_CMP | OP_TRAP =>
                if e_in.invert_a = '0' then
                    a_inv := a_in;