1
0
mirror of https://github.com/antonblanchard/microwatt.git synced 2026-04-07 21:40:53 +00:00

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>
This commit is contained in:
Paul Mackerras
2019-09-28 14:43:46 +10:00
parent 3e6f656a90
commit c9e92483b8
6 changed files with 28 additions and 44 deletions

View File

@@ -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

View 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;

View 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;

View 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;

View 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,

View 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;