Add MCRF instruction
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Tue, 24 Sep 2019 14:09:35 +0000 (00:09 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Tue, 1 Oct 2019 05:22:22 +0000 (15:22 +1000)
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>
decode1.vhdl
decode2.vhdl
decode_types.vhdl
execute1.vhdl
insn_helpers.vhdl

index b07962e9d177697513cf91ce83ff2ba34d9df426..c0037393dfc4705419afb728fb166c97b09eb11c 100644 (file)
@@ -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'),
index 2756c7104edc3f8b456c363c21b7b8ead6f0e1b8..c1c6e6b2380e817290f3d61e4081796179c369c8 100644 (file)
@@ -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;
index 2f449c97c169ad3a88981cc8b3806eae4a9cb829..63e78c0ed4889fa57ea3c08cddb0d580190a96ba 100644 (file)
@@ -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);
 
index b6af0ac9c675aa9cae54adcf2882ad6041418dce..e75fac70f09767b29efaf67d1dd2c62c04c751c2 100644 (file)
@@ -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;
index e9e937549ec2af2813311f2716659456ddd7cdc6..d3ddccad34d40a3129dba84bbcc567371606ea5c 100644 (file)
@@ -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);