diff --git a/decode1.vhdl b/decode1.vhdl index 1199bae..159df1d 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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 diff --git a/execute1.vhdl b/execute1.vhdl index c5e1e3e..cb9b13d 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -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 => diff --git a/logical.vhdl b/logical.vhdl index 0f53544..2df66dc 100644 --- a/logical.vhdl +++ b/logical.vhdl @@ -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