From ec9b27660fde71f4098037759d970019db59db2e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 7 Dec 2019 14:31:33 +1100 Subject: [PATCH] execute: Copy XER[SO] to CR for cmp[i] and cmpl[i] instructions We were copying in XER[SO] for the dot-form instructions but not the explicit compare instructions. Fix this. Signed-off-by: Paul Mackerras --- execute1.vhdl | 4 ++-- helpers.vhdl | 28 ++++++++++++++-------------- ppc_fx_insns.vhdl | 32 ++++++++++++++++++++------------ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/execute1.vhdl b/execute1.vhdl index 2391ba2..e1ca950 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -291,7 +291,7 @@ begin for i in 0 to 7 loop lo := i*4; hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2); + v.e.write_cr_data(hi downto lo) := ppc_cmp(l, e_in.read_data1, e_in.read_data2, v.e.xerc.so); end loop; when OP_CMPL => bf := insn_bf(e_in.insn); @@ -302,7 +302,7 @@ begin for i in 0 to 7 loop lo := i*4; hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2); + v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2, v.e.xerc.so); end loop; when OP_CNTZ => result := countzero_result; diff --git a/helpers.vhdl b/helpers.vhdl index 3961332..fe91938 100644 --- a/helpers.vhdl +++ b/helpers.vhdl @@ -17,8 +17,8 @@ package helpers is function cmp_one_byte(a, b: std_ulogic_vector(7 downto 0)) return std_ulogic_vector; - function ppc_signed_compare(a, b: signed(63 downto 0)) return std_ulogic_vector; - function ppc_unsigned_compare(a, b: unsigned(63 downto 0)) return std_ulogic_vector; + function ppc_signed_compare(a, b: signed(63 downto 0); so: std_ulogic) return std_ulogic_vector; + function ppc_unsigned_compare(a, b: unsigned(63 downto 0); so: std_ulogic) return std_ulogic_vector; function ra_or_zero(ra: std_ulogic_vector(63 downto 0); reg: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; @@ -126,32 +126,32 @@ package body helpers is return ret; end; - function ppc_signed_compare(a, b: signed(63 downto 0)) return std_ulogic_vector is - variable ret: std_ulogic_vector(3 downto 0); + function ppc_signed_compare(a, b: signed(63 downto 0); so: std_ulogic) return std_ulogic_vector is + variable ret: std_ulogic_vector(2 downto 0); begin if a < b then - ret := "1000"; + ret := "100"; elsif a > b then - ret := "0100"; + ret := "010"; else - ret := "0010"; + ret := "001"; end if; - return ret; + return ret & so; end; - function ppc_unsigned_compare(a, b: unsigned(63 downto 0)) return std_ulogic_vector is - variable ret: std_ulogic_vector(3 downto 0); + function ppc_unsigned_compare(a, b: unsigned(63 downto 0); so: std_ulogic) return std_ulogic_vector is + variable ret: std_ulogic_vector(2 downto 0); begin if a < b then - ret := "1000"; + ret := "100"; elsif a > b then - ret := "0100"; + ret := "010"; else - ret := "0010"; + ret := "001"; end if; - return ret; + return ret & so; end; function ra_or_zero(ra: std_ulogic_vector(63 downto 0); reg: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is diff --git a/ppc_fx_insns.vhdl b/ppc_fx_insns.vhdl index 407881f..3b03dc2 100644 --- a/ppc_fx_insns.vhdl +++ b/ppc_fx_insns.vhdl @@ -77,10 +77,14 @@ package ppc_fx_insns is function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + so: std_ulogic) return std_ulogic_vector; + function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + so: std_ulogic) return std_ulogic_vector; + function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + so: std_ulogic) return std_ulogic_vector; + function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + so: std_ulogic) return std_ulogic_vector; function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; @@ -677,7 +681,8 @@ package body ppc_fx_insns is return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32)); end; - function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + so: std_ulogic) return std_ulogic_vector is variable tmp: signed(ra'range); begin tmp := signed(ra); @@ -685,10 +690,11 @@ package body ppc_fx_insns is tmp := resize(signed(ra(31 downto 0)), tmp'length); end if; - return ppc_signed_compare(tmp, resize(signed(si), tmp'length)); + return ppc_signed_compare(tmp, resize(signed(si), tmp'length), so); end; - function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + so: std_ulogic) return std_ulogic_vector is variable tmpa, tmpb: signed(ra'range); begin tmpa := signed(ra); @@ -698,10 +704,11 @@ package body ppc_fx_insns is tmpb := resize(signed(rb(31 downto 0)), ra'length); end if; - return ppc_signed_compare(tmpa, tmpb); + return ppc_signed_compare(tmpa, tmpb, so); end; - function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + so: std_ulogic) return std_ulogic_vector is variable tmp: unsigned(ra'range); begin tmp := unsigned(ra); @@ -709,10 +716,11 @@ package body ppc_fx_insns is tmp := resize(unsigned(ra(31 downto 0)), tmp'length); end if; - return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length)); + return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length), so); end; - function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + so: std_ulogic) return std_ulogic_vector is variable tmpa, tmpb: unsigned(ra'range); begin tmpa := unsigned(ra); @@ -722,7 +730,7 @@ package body ppc_fx_insns is tmpb := resize(unsigned(rb(31 downto 0)), ra'length); end if; - return ppc_unsigned_compare(tmpa, tmpb); + return ppc_unsigned_compare(tmpa, tmpb, so); end; function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is