execute1: Use truth table embedded in instruction for CR logical ops
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 16 Jan 2020 02:18:56 +0000 (13:18 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Wed, 5 Feb 2020 11:21:11 +0000 (22:21 +1100)
It turns out that CR logical instructions have the truth table of
the operation embedded in the instruction word.  This means that we
can collect the two input operand bits into a 2-bit value and use
that as the index to select the appropriate bit from the instruction
word.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
execute1.vhdl

index ae13c72d4d77c61a322751e0626c5739f4d709d5..e41a743a5dbbbbb32fc20247ca7861039359e2d6 100644 (file)
@@ -200,6 +200,7 @@ begin
        variable bo, bi : std_ulogic_vector(4 downto 0);
        variable bf, bfa : std_ulogic_vector(2 downto 0);
        variable cr_op : std_ulogic_vector(9 downto 0);
+        variable cr_operands : std_ulogic_vector(1 downto 0);
        variable bt, ba, bb : std_ulogic_vector(4 downto 0);
        variable btnum, banum, bbnum : integer range 0 to 31;
        variable crresult : std_ulogic;
@@ -532,27 +533,10 @@ begin
                    btnum := 31 - to_integer(unsigned(bt));
                    banum := 31 - to_integer(unsigned(ba));
                    bbnum := 31 - to_integer(unsigned(bb));
-                   case cr_op(8 downto 5) is
-                   when "1001" => -- CREQV
-                       crresult := not(e_in.cr(banum) xor e_in.cr(bbnum));
-                   when "0111" => -- CRNAND
-                       crresult := not(e_in.cr(banum) and e_in.cr(bbnum));
-                   when "0100" => -- CRANDC
-                       crresult := (e_in.cr(banum) and not e_in.cr(bbnum));
-                   when "1000" => -- CRAND
-                       crresult := (e_in.cr(banum) and e_in.cr(bbnum));
-                   when "0001" => -- CRNOR
-                       crresult := not(e_in.cr(banum) or e_in.cr(bbnum));
-                   when "1101" => -- CRORC
-                       crresult := (e_in.cr(banum) or not e_in.cr(bbnum));
-                   when "0110" => -- CRXOR
-                       crresult := (e_in.cr(banum) xor e_in.cr(bbnum));
-                   when "1110" => -- CROR
-                       crresult := (e_in.cr(banum) or e_in.cr(bbnum));
-                   when others =>
-                       crresult := '0';
-                       report "BAD CR?";
-                   end case;
+                    -- Bits 5-8 of cr_op give the truth table of the requested
+                    -- logical operation
+                    cr_operands := e_in.cr(banum) & e_in.cr(bbnum);
+                    crresult := cr_op(5 + to_integer(unsigned(cr_operands)));
                    v.e.write_cr_mask := num_to_fxm((31-btnum) / 4);
                    for i in 0 to 31 loop
                        if i = btnum then