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 <paulus@ozlabs.org>
pull/78/head
Paul Mackerras 5 years ago
parent 3e6f656a90
commit c9e92483b8

@ -22,7 +22,7 @@ crhelpers.o: common.o
decode1.o: common.o decode_types.o decode1.o: common.o decode_types.o
decode2.o: decode_types.o common.o helpers.o insn_helpers.o decode2.o: decode_types.o common.o helpers.o insn_helpers.o
decode_types.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 execute2.o: common.o crhelpers.o ppc_fx_insns.o
fetch1.o: common.o fetch1.o: common.o
fetch2.o: common.o wishbone_types.o fetch2.o: common.o wishbone_types.o

@ -58,13 +58,13 @@ package common is
cr: std_ulogic_vector(31 downto 0); cr: std_ulogic_vector(31 downto 0);
lr: std_ulogic; lr: std_ulogic;
rc: std_ulogic; rc: std_ulogic;
aa: std_ulogic;
input_carry: std_ulogic; input_carry: std_ulogic;
output_carry: std_ulogic; output_carry: std_ulogic;
input_cr: std_ulogic; input_cr: std_ulogic;
output_cr: std_ulogic; output_cr: std_ulogic;
insn: std_ulogic_vector(31 downto 0);
end record; 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 type Decode2ToMultiplyType is record
valid: std_ulogic; valid: std_ulogic;

@ -125,12 +125,8 @@ architecture behaviour of decode1 is
--PPC_MCRXRX --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_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_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_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_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_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_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_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_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_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'), 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 elsif std_match(f_in.insn, "011111-----1---------0000010011-") then
report "PPC_mfocrf"; report "PPC_mfocrf";
ppc_insn := 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 elsif std_match(f_in.insn, "011111---------------0101010011-") then
report "PPC_mfspr"; report "PPC_mfspr";
ppc_insn := PPC_MFSPR; ppc_insn := PPC_MFSPR;

@ -264,13 +264,13 @@ begin
v.e.cr := c_in.read_cr_data; v.e.cr := c_in.read_cr_data;
v.e.input_carry := d_in.decode.input_carry; v.e.input_carry := d_in.decode.input_carry;
v.e.output_carry := d_in.decode.output_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 if d_in.decode.lr = '1' then
v.e.lr := insn_lk(d_in.insn); v.e.lr := insn_lk(d_in.insn);
end if; end if;
v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn); 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.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.const3 := decode_const_c(d_in.decode.const_c, d_in.insn);
v.e.insn := d_in.insn;


-- multiply unit -- multiply unit
v.m.insn_type := d_in.decode.insn_type; v.m.insn_type := d_in.decode.insn_type;

@ -48,9 +48,8 @@ package decode_types is
OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH, OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH,
OP_EXTSW, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, 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_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF,
OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFCTR, OP_MFLR, OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFSPR, OP_MOD,
OP_MFTB, OP_MFSPR, OP_MOD, OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64,
OP_MTCRF, OP_MTOCRF, OP_MTCTR, OP_MTLR, OP_MTSPR, OP_MUL_L64,
OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, 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_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD,
OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR, OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR,

@ -7,6 +7,7 @@ use work.decode_types.all;
use work.common.all; use work.common.all;
use work.helpers.all; use work.helpers.all;
use work.crhelpers.all; use work.crhelpers.all;
use work.insn_helpers.all;
use work.ppc_fx_insns.all; use work.ppc_fx_insns.all;


entity execute1 is entity execute1 is
@ -102,7 +103,7 @@ begin
result_en := 1; result_en := 1;
when OP_B => when OP_B =>
f_out.redirect <= '1'; 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)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
else else
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
@ -113,7 +114,7 @@ begin
end if; 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 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'; 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)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
else else
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
@ -202,19 +203,17 @@ begin
hi := lo + 3; hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf; v.e.write_cr_data(hi downto lo) := newcrf;
end loop; end loop;
when OP_MFCTR => when OP_MFSPR =>
result := ctrl.ctr; if std_match(e_in.insn(20 downto 11), "0100100000") then
result_en := 1; result := ctrl.ctr;
when OP_MFLR => result_en := 1;
result := ctrl.lr; elsif std_match(e_in.insn(20 downto 11), "0100000000") then
result_en := 1; result := ctrl.lr;
when OP_MFTB => result_en := 1;
result := ctrl.tb; elsif std_match(e_in.insn(20 downto 11), "0110001000") then
result_en := 1; result := ctrl.tb;
when OP_MTCTR => result_en := 1;
ctrl_tmp.ctr <= e_in.read_data1; end if;
when OP_MTLR =>
ctrl_tmp.lr <= e_in.read_data1;
when OP_MFCR => when OP_MFCR =>
result := x"00000000" & e_in.cr; result := x"00000000" & e_in.cr;
result_en := 1; result_en := 1;
@ -239,6 +238,12 @@ begin
crnum := fxm_to_num(e_in.const1(7 downto 0)); crnum := fxm_to_num(e_in.const1(7 downto 0));
v.e.write_cr_mask := num_to_fxm(crnum); v.e.write_cr_mask := num_to_fxm(crnum);
v.e.write_cr_data := e_in.read_data1(31 downto 0); 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 => when OP_NAND =>
result := ppc_nand(e_in.read_data1, e_in.read_data2); result := ppc_nand(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;

Loading…
Cancel
Save