From 3e6f656a9054417326073d62bbd1abc9e782b428 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 25 Sep 2019 00:09:35 +1000 Subject: [PATCH] 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 --- decode1.vhdl | 2 +- decode2.vhdl | 2 ++ decode_types.vhdl | 2 +- execute1.vhdl | 19 +++++++++++++++++++ insn_helpers.vhdl | 6 ++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index b07962e..c003739 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -120,7 +120,7 @@ architecture behaviour of decode1 is --PPC_MADDHD --PPC_MADDHDU --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_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'), diff --git a/decode2.vhdl b/decode2.vhdl index 2756c71..c1c6e6b 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -159,6 +159,8 @@ architecture behaviour of decode2 is return "0" & insn_bi(insn_in); when L => return "00000" & insn_l(insn_in); + when BFA => + return "000" & insn_bfa(insn_in); when NONE => return "000000"; end case; diff --git a/decode_types.vhdl b/decode_types.vhdl index 2f449c9..63e78c0 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -64,7 +64,7 @@ package decode_types is type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); 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 rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index b6af0ac..e75fac7 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -52,9 +52,11 @@ begin execute1_1: process(all) variable v : reg_type; 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_en : integer; variable crnum : integer; + variable scrnum : integer; variable lo, hi : integer; begin result := (others => '0'); @@ -183,6 +185,23 @@ begin result := e_in.read_data2; end if; 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 => result := ctrl.ctr; result_en := 1; diff --git a/insn_helpers.vhdl b/insn_helpers.vhdl index e9e9375..d3ddcca 100644 --- a/insn_helpers.vhdl +++ b/insn_helpers.vhdl @@ -18,6 +18,7 @@ package insn_helpers is 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_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_bo (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); 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 begin return insn_in(19 downto 12);