decode: Push mtspr/mfspr register decoding down into execute1
authorPaul Mackerras <paulus@ozlabs.org>
Sat, 28 Sep 2019 04:43:46 +0000 (14:43 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 1 Oct 2019 05:22:22 +0000 (15:22 +1000)
Instead of doing mfctr, mflr, mftb, mtctr, mtlr as separate ops,
just pass down mfspr and mtspr ops with the spr number and let
execute1 decode which SPR we're addressing.  This will help reduce
the number of instruction bits decode1 needs to look at.

In fact we now pass down the whole instruction from decode2 to
execute1.  We will need more bits of the instruction in future,
and the tools should just optimize away any that we don't end
up using.  Since the 'aa' bit was just a copy of an instruction
bit, we can now remove it from the record.

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

index 13d245ebe706a7bead70ed4ad477a3d0193db6de..8075439a6b48837e703ad93fbbfac051dcbd2474 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ crhelpers.o: common.o
 decode1.o: common.o decode_types.o
 decode2.o: decode_types.o common.o helpers.o insn_helpers.o
 decode_types.o:
-execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o
+execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o insn_helpers.o
 execute2.o: common.o crhelpers.o ppc_fx_insns.o
 fetch1.o: common.o
 fetch2.o: common.o wishbone_types.o
index 694e20cb4d1317ab3babf4daacb89255f00053dc..8b1d4cfea64e390f424da5af06264839fb2c0182 100644 (file)
@@ -58,13 +58,13 @@ package common is
                cr: std_ulogic_vector(31 downto 0);
                lr: std_ulogic;
                rc: std_ulogic;
-               aa: std_ulogic;
                input_carry: std_ulogic;
                output_carry: std_ulogic;
                input_cr: std_ulogic;
                output_cr: std_ulogic;
+                insn: std_ulogic_vector(31 downto 0);
        end record;
-       constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', aa => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0'));
+       constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0'));
 
        type Decode2ToMultiplyType is record
                valid: std_ulogic;
index c0037393dfc4705419afb728fb166c97b09eb11c..98f6d35e94f486276b76f98d9664b9eaa56e3506 100644 (file)
@@ -125,12 +125,8 @@ architecture behaviour of decode1 is
                --PPC_MCRXRX
                PPC_MFCR       =>       (ALU,    OP_MFCR,      NONE,       NONE,        NONE, RT,   NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
                PPC_MFOCRF     =>       (ALU,    OP_MFOCRF,    NONE,       NONE,        NONE, RT,   FXM,  NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               PPC_MFCTR      =>       (ALU,    OP_MFCTR,     NONE,       NONE,        NONE, RT,   NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               PPC_MFLR       =>       (ALU,    OP_MFLR,      NONE,       NONE,        NONE, RT,   NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               PPC_MFTB       =>       (ALU,    OP_MFTB,      NONE,       NONE,        NONE, RT,   NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               PPC_MTCTR      =>       (ALU,    OP_MTCTR,     RS,         NONE,        NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               PPC_MTLR       =>       (ALU,    OP_MTLR,      RS,         NONE,        NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
-               --PPC_MFSPR
+               PPC_MFSPR      =>       (ALU,    OP_MFSPR,     NONE,       NONE,        NONE, RT,   NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
+               PPC_MTSPR      =>       (ALU,    OP_MTSPR,     RS,         NONE,        NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
                PPC_MOD        =>       (DIV,    OP_MOD,       RA,         RB,          NONE, RT,   NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '1'),
                PPC_MTCRF      =>       (ALU,    OP_MTCRF,     RS,         NONE,        NONE, NONE, FXM,  NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
                PPC_MTOCRF     =>       (ALU,    OP_MTOCRF,    RS,         NONE,        NONE, NONE, FXM,  NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
@@ -527,22 +523,6 @@ begin
                        elsif std_match(f_in.insn, "011111-----1---------0000010011-") then
                                report "PPC_mfocrf";
                                ppc_insn := PPC_MFOCRF;
-                       -- Specific MF/MT SPR encodings first
-                       elsif std_match(f_in.insn, "011111-----01001000000101010011-") then
-                               report "PPC_mfctr";
-                               ppc_insn := PPC_MFCTR;
-                       elsif std_match(f_in.insn, "011111-----01000000000101010011-") then
-                               report "PPC_mflr";
-                               ppc_insn := PPC_MFLR;
-                       elsif std_match(f_in.insn, "011111-----01100010000101010011-") then
-                               report "PPC_mftb";
-                               ppc_insn := PPC_MFTB;
-                       elsif std_match(f_in.insn, "011111-----01001000000111010011-") then
-                               report "PPC_mtctr";
-                               ppc_insn := PPC_MTCTR;
-                       elsif std_match(f_in.insn, "011111-----01000000000111010011-") then
-                               report "PPC_mtlr";
-                               ppc_insn := PPC_MTLR;
                        elsif std_match(f_in.insn, "011111---------------0101010011-") then
                                report "PPC_mfspr";
                                ppc_insn := PPC_MFSPR;
index c1c6e6b2380e817290f3d61e4081796179c369c8..2b816a745ce7e75a2650c7ac86e9f14e20fa2908 100644 (file)
@@ -264,13 +264,13 @@ begin
                v.e.cr := c_in.read_cr_data;
                v.e.input_carry := d_in.decode.input_carry;
                v.e.output_carry := d_in.decode.output_carry;
-               v.e.aa := insn_aa(d_in.insn);
                if d_in.decode.lr = '1' then
                        v.e.lr := insn_lk(d_in.insn);
                end if;
                v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn);
                v.e.const2 := decode_const_b(d_in.decode.const_b, d_in.insn);
                v.e.const3 := decode_const_c(d_in.decode.const_c, d_in.insn);
+                v.e.insn := d_in.insn;
 
                -- multiply unit
                v.m.insn_type := d_in.decode.insn_type;
index 63e78c0ed4889fa57ea3c08cddb0d580190a96ba..1437bf0bcd1cbf0d397729f5d72f0e7931fbfd03 100644 (file)
@@ -48,9 +48,8 @@ package decode_types is
                OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH,
                OP_EXTSW, 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_MFOCRF, OP_MFCTR, OP_MFLR,
-               OP_MFTB, OP_MFSPR, OP_MOD,
-               OP_MTCRF, OP_MTOCRF, OP_MTCTR, OP_MTLR, OP_MTSPR, OP_MUL_L64,
+               OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFSPR, OP_MOD,
+               OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64,
                OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR,
                OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD,
                OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR,
index e75fac70f09767b29efaf67d1dd2c62c04c751c2..0d85e711961eea9a19cc9e4b59ed219c501f5a3f 100644 (file)
@@ -7,6 +7,7 @@ use work.decode_types.all;
 use work.common.all;
 use work.helpers.all;
 use work.crhelpers.all;
+use work.insn_helpers.all;
 use work.ppc_fx_insns.all;
 
 entity execute1 is
@@ -102,7 +103,7 @@ begin
                                        result_en := 1;
                                when OP_B =>
                                        f_out.redirect <= '1';
-                                       if (e_in.aa) then
+                                       if (insn_aa(e_in.insn)) then
                                            f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
                                        else
                                            f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
@@ -113,7 +114,7 @@ begin
                                        end if;
                                        if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
                                                f_out.redirect <= '1';
-                                               if (e_in.aa) then
+                                               if (insn_aa(e_in.insn)) then
                                                    f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
                                                else
                                                    f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
@@ -202,19 +203,17 @@ begin
                                                hi := lo + 3;
                                                v.e.write_cr_data(hi downto lo) := newcrf;
                                        end loop;
-                               when OP_MFCTR =>
-                                       result := ctrl.ctr;
-                                       result_en := 1;
-                               when OP_MFLR =>
-                                       result := ctrl.lr;
-                                       result_en := 1;
-                               when OP_MFTB =>
-                                       result := ctrl.tb;
-                                       result_en := 1;
-                               when OP_MTCTR =>
-                                       ctrl_tmp.ctr <= e_in.read_data1;
-                               when OP_MTLR =>
-                                       ctrl_tmp.lr <= e_in.read_data1;
+                                when OP_MFSPR =>
+                                        if std_match(e_in.insn(20 downto 11), "0100100000") then
+                                                result := ctrl.ctr;
+                                                result_en := 1;
+                                        elsif std_match(e_in.insn(20 downto 11), "0100000000") then
+                                                result := ctrl.lr;
+                                                result_en := 1;
+                                        elsif std_match(e_in.insn(20 downto 11), "0110001000") then
+                                                result := ctrl.tb;
+                                                result_en := 1;
+                                        end if;
                                when OP_MFCR =>
                                        result := x"00000000" & e_in.cr;
                                        result_en := 1;
@@ -239,6 +238,12 @@ begin
                                        crnum := fxm_to_num(e_in.const1(7 downto 0));
                                        v.e.write_cr_mask := num_to_fxm(crnum);
                                        v.e.write_cr_data := e_in.read_data1(31 downto 0);
+                               when OP_MTSPR =>
+                                        if std_match(e_in.insn(20 downto 11), "0100100000") then
+                                                ctrl_tmp.ctr <= e_in.read_data1;
+                                        elsif std_match(e_in.insn(20 downto 11), "0100000000") then
+                                                ctrl_tmp.lr <= e_in.read_data1;
+                                        end if;
                                when OP_NAND =>
                                        result := ppc_nand(e_in.read_data1, e_in.read_data2);
                                        result_en := 1;