diff --git a/decode1.vhdl b/decode1.vhdl index 159df1d..a95cfad 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -161,9 +161,9 @@ architecture behaviour of decode1 is 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 + 2#0011100000# => (ALU, OP_CMPEQB, RA, RB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- cmpeqb 2#0000100000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '1', '0', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- cmpl - -- 2#0011000000# cmprb + 2#0011000000# => (ALU, OP_CMPRB, RA, RB, NONE, NONE, '0', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'), -- cmprb 2#0000111010# => (ALU, OP_CNTZ, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- cntlzd 2#0000011010# => (ALU, OP_CNTZ, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '0'), -- cntlzw 2#1000111010# => (ALU, OP_CNTZ, NONE, NONE, RS, RA, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '0'), -- cnttzd diff --git a/execute1.vhdl b/execute1.vhdl index cb9b13d..b836e33 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -633,6 +633,22 @@ begin end if; end if; end if; + when OP_CMPRB => + newcrf := ppc_cmprb(a_in, b_in, insn_l(e_in.insn)); + bf := insn_bf(e_in.insn); + crnum := to_integer(unsigned(bf)); + v.e.write_cr_enable := '1'; + v.e.write_cr_mask := num_to_fxm(crnum); + v.e.write_cr_data := newcrf & newcrf & newcrf & newcrf & + newcrf & newcrf & newcrf & newcrf; + when OP_CMPEQB => + newcrf := ppc_cmpeqb(a_in, b_in); + bf := insn_bf(e_in.insn); + crnum := to_integer(unsigned(bf)); + v.e.write_cr_enable := '1'; + v.e.write_cr_mask := num_to_fxm(crnum); + v.e.write_cr_data := newcrf & newcrf & newcrf & newcrf & + newcrf & newcrf & newcrf & newcrf; when OP_AND | OP_OR | OP_XOR | OP_POPCNT | OP_PRTY | OP_CMPB | OP_EXTS | OP_BPERM => result := logical_result; result_en := '1'; diff --git a/ppc_fx_insns.vhdl b/ppc_fx_insns.vhdl index 5fdf1c7..c34a884 100644 --- a/ppc_fx_insns.vhdl +++ b/ppc_fx_insns.vhdl @@ -87,6 +87,8 @@ package ppc_fx_insns is so: std_ulogic) return std_ulogic_vector; function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cmpeqb (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cmprb (ra, rb: std_ulogic_vector(63 downto 0); l: std_ulogic) return std_ulogic_vector; function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; @@ -746,6 +748,34 @@ package body ppc_fx_insns is return ret; end; + function ppc_cmpeqb (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable match: std_ulogic; + variable j: integer; + begin + match := '0'; + for i in 0 to 7 loop + j := i * 8; + if ra(7 downto 0) = rb(j + 7 downto j) then + match := '1'; + end if; + end loop; + return '0' & match & "00"; + end; + + function ppc_cmprb (ra, rb: std_ulogic_vector(63 downto 0); l: std_ulogic) return std_ulogic_vector is + variable match: std_ulogic; + variable v: unsigned(7 downto 0); + begin + match := '0'; + v := unsigned(ra(7 downto 0)); + if v >= unsigned(rb(7 downto 0)) and v <= unsigned(rb(15 downto 8)) then + match := '1'; + elsif l = '1' and v >= unsigned(rb(23 downto 16)) and v <= unsigned(rb(31 downto 24)) then + match := '1'; + end if; + return '0' & match & "00"; + end; + -- Not synthesizable function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is variable tmp: signed(31 downto 0);