From c9e92483b80f2e204b986a032bbf80c4ce87e394 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 28 Sep 2019 14:43:46 +1000 Subject: [PATCH] decode: Push mtspr/mfspr register decoding down into execute1 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 --- Makefile | 2 +- common.vhdl | 4 ++-- decode1.vhdl | 24 ++---------------------- decode2.vhdl | 2 +- decode_types.vhdl | 5 ++--- execute1.vhdl | 35 ++++++++++++++++++++--------------- 6 files changed, 28 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 13d245e..8075439 100644 --- 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 diff --git a/common.vhdl b/common.vhdl index 694e20c..8b1d4cf 100644 --- a/common.vhdl +++ b/common.vhdl @@ -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; diff --git a/decode1.vhdl b/decode1.vhdl index c003739..98f6d35 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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; diff --git a/decode2.vhdl b/decode2.vhdl index c1c6e6b..2b816a7 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -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; diff --git a/decode_types.vhdl b/decode_types.vhdl index 63e78c0..1437bf0 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -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, diff --git a/execute1.vhdl b/execute1.vhdl index e75fac7..0d85e71 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -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;