core: Implement the bpermd instruction
authorPaul Mackerras <paulus@ozlabs.org>
Mon, 3 Aug 2020 04:45:19 +0000 (14:45 +1000)
committerPaul Mackerras <paulus@ozlabs.org>
Thu, 6 Aug 2020 01:30:28 +0000 (11:30 +1000)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
decode1.vhdl
execute1.vhdl
logical.vhdl

index 1199bae2e9ee33f5f1469327d8d2ae24c7a79162..159df1d173bc0234f773a0e9a24ddb2f3e1116e2 100644 (file)
@@ -158,7 +158,7 @@ architecture behaviour of decode1 is
         2#1011001010#  =>       (ALU,    OP_ADD,       RA,         NONE,        NONE, RT,   '0', '0', '0', '0', CA,   '1', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- addzeo
         2#0000011100#  =>       (ALU,    OP_AND,       NONE,       RB,          RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- and
         2#0000111100#  =>       (ALU,    OP_AND,       NONE,       RB,          RS,   RA,   '0', '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC,   '0', '0'), -- andc
-        -- 2#0011111100# bperm
+        2#0011111100#  =>       (ALU,    OP_BPERM,     NONE,       NONE,        RS,   RA,   '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- bperm
         2#0000000000#  =>       (ALU,    OP_CMP,       RA,         RB,          NONE, NONE, '0', '1', '1', '0', ONE,  '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '0'), -- cmp
         2#0111111100#  =>       (ALU,    OP_CMPB,      NONE,       RB,          RS,   RA,   '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- cmpb
         -- 2#0011100000# cmpeqb
index c5e1e3ea40b3a941c43ade4d6312f5d1b498bcf4..cb9b13d3638d61b82a3fbbb4342804466ed695c1 100644 (file)
@@ -633,7 +633,7 @@ begin
                         end if;
                     end if;
                 end if;
-           when OP_AND | OP_OR | OP_XOR | OP_POPCNT | OP_PRTY | OP_CMPB | OP_EXTS =>
+           when OP_AND | OP_OR | OP_XOR | OP_POPCNT | OP_PRTY | OP_CMPB | OP_EXTS | OP_BPERM =>
                result := logical_result;
                result_en := '1';
            when OP_B =>
index 0f53544f509dd4e35e186efde8549e3ddc3d4307..2df66dcea7034b510a7ef11ccbe5a4fd5abc4e8d 100644 (file)
@@ -35,11 +35,13 @@ architecture behaviour of logical is
     signal par0, par1 : std_ulogic;
     signal popcnt   : std_ulogic_vector(63 downto 0);
     signal parity   : std_ulogic_vector(63 downto 0);
+    signal permute  : std_ulogic_vector(7 downto 0);
 
 begin
     logical_0: process(all)
         variable rb_adj, tmp : std_ulogic_vector(63 downto 0);
         variable negative : std_ulogic;
+        variable j : integer;
     begin
         -- population counts
         for i in 0 to 31 loop
@@ -81,6 +83,16 @@ begin
             parity(32) <= par1;
         end if;
 
+        -- bit permutation
+        for i in 0 to 7 loop
+            j := i * 8;
+            if rs(j+7 downto j+6) = "00" then
+                permute(i) <= rb(to_integer(unsigned(rs(j+5 downto j))));
+            else
+                permute(i) <= '0';
+            end if;
+        end loop;
+
         rb_adj := rb;
         if invert_in = '1' then
             rb_adj := not rb;
@@ -106,6 +118,8 @@ begin
                 tmp := parity;
             when OP_CMPB =>
                 tmp := ppc_cmpb(rs, rb);
+            when OP_BPERM =>
+                tmp := std_ulogic_vector(resize(unsigned(permute), 64));
             when others =>
                 -- EXTS
                 -- note datalen is a 1-hot encoding