Add MCRF instruction

Hopefully it's not too timing catastrophic. The variable newcrf will
be handy for the other CR ops when we implement them I suspect.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/78/head
Benjamin Herrenschmidt 5 years ago committed by Paul Mackerras
parent 554ae88540
commit 3e6f656a90

@ -120,7 +120,7 @@ architecture behaviour of decode1 is
--PPC_MADDHD --PPC_MADDHD
--PPC_MADDHDU --PPC_MADDHDU
--PPC_MADDLD --PPC_MADDLD
--PPC_MCRF PPC_MCRF => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'),
--PPC_MCRXR --PPC_MCRXR
--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'),

@ -159,6 +159,8 @@ architecture behaviour of decode2 is
return "0" & insn_bi(insn_in); return "0" & insn_bi(insn_in);
when L => when L =>
return "00000" & insn_l(insn_in); return "00000" & insn_l(insn_in);
when BFA =>
return "000" & insn_bfa(insn_in);
when NONE => when NONE =>
return "000000"; return "000000";
end case; end case;

@ -64,7 +64,7 @@ package decode_types is
type input_reg_c_t is (NONE, RS); type input_reg_c_t is (NONE, RS);
type output_reg_a_t is (NONE, RT, RA); type output_reg_a_t is (NONE, RT, RA);
type constant_a_t is (NONE, SH, SH32, FXM, BO, BF, TOO, BC); type constant_a_t is (NONE, SH, SH32, FXM, BO, BF, TOO, BC);
type constant_b_t is (NONE, MB, ME, MB32, BI, L); type constant_b_t is (NONE, MB, ME, MB32, BI, L, BFA);
type constant_c_t is (NONE, ME32, BH); type constant_c_t is (NONE, ME32, BH);
type rc_t is (NONE, ONE, RC); type rc_t is (NONE, ONE, RC);



@ -52,9 +52,11 @@ begin
execute1_1: process(all) execute1_1: process(all)
variable v : reg_type; variable v : reg_type;
variable result : std_ulogic_vector(63 downto 0); variable result : std_ulogic_vector(63 downto 0);
variable newcrf : std_ulogic_vector(3 downto 0);
variable result_with_carry : std_ulogic_vector(64 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0);
variable result_en : integer; variable result_en : integer;
variable crnum : integer; variable crnum : integer;
variable scrnum : integer;
variable lo, hi : integer; variable lo, hi : integer;
begin begin
result := (others => '0'); result := (others => '0');
@ -183,6 +185,23 @@ begin
result := e_in.read_data2; result := e_in.read_data2;
end if; end if;
result_en := 1; result_en := 1;
when OP_MCRF =>
v.e.write_cr_enable := '1';
crnum := to_integer(unsigned(e_in.const1(2 downto 0)));
scrnum := to_integer(unsigned(e_in.const2(2 downto 0)));
v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop
lo := (7-i)*4;
hi := lo + 3;
if i = scrnum then
newcrf := e_in.cr(hi downto lo);
end if;
end loop;
for i in 0 to 7 loop
lo := i*4;
hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
when OP_MFCTR => when OP_MFCTR =>
result := ctrl.ctr; result := ctrl.ctr;
result_en := 1; result_en := 1;

@ -18,6 +18,7 @@ package insn_helpers is
function insn_rc (insn_in : std_ulogic_vector) return std_ulogic; function insn_rc (insn_in : std_ulogic_vector) return std_ulogic;
function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bf (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_bf (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bfa (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bo (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_bo (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bi (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_bi (insn_in : std_ulogic_vector) return std_ulogic_vector;
@ -112,6 +113,11 @@ package body insn_helpers is
return insn_in(25 downto 23); return insn_in(25 downto 23);
end; end;


function insn_bfa (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(20 downto 18);
end;

function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin begin
return insn_in(19 downto 12); return insn_in(19 downto 12);

Loading…
Cancel
Save