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;
+ 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;
function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector;
- function ppc_b (nia: std_ulogic_vector(63 downto 0); bd: std_ulogic_vector(23 downto 0)) return std_ulogic_vector;
- function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return integer;
- function ppc_bcctr_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0)) return integer;
+ function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic;
end package ppc_fx_insns;
package body ppc_fx_insns is
tmp2 := (others => '0');
if hi < lo then
-- Mask wraps around
- tmp2(63 downto lo) := tmp1(63 downto lo);
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi or i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
else
- tmp2(hi downto lo) := tmp1(hi downto lo);
+ for i in 0 to 63 loop
+ if i >= lo and i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
end if;
return tmp2;
end;
tmp2 := (others => '0');
if hi < lo then
-- Mask wraps around
- tmp2(63 downto lo) := tmp1(63 downto lo);
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi or i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
else
- tmp2(hi downto lo) := tmp1(hi downto lo);
+ for i in 0 to 63 loop
+ if i >= lo and i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
end if;
return tmp2;
end;
tmp2 := ra;
if hi < lo then
-- Mask wraps around
- tmp2(63 downto lo) := tmp1(63 downto lo);
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi or i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
else
- tmp2(hi downto lo) := tmp1(hi downto lo);
+ for i in 0 to 63 loop
+ if i >= lo and i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
end if;
return tmp2;
end;
hi := 63-to_integer(unsigned(mb));
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
tmp2 := (others => '0');
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
return tmp2;
end;
lo := 63-to_integer(unsigned(me));
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh))));
tmp2 := (others => '0');
- tmp2(63 downto lo) := tmp1(63 downto lo);
+ for i in 0 to 63 loop
+ if i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
return tmp2;
end;
tmp2 := (others => '0');
if hi < lo then
-- Mask wraps around
- tmp2(63 downto lo) := tmp1(63 downto lo);
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi or i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
else
- tmp2(hi downto lo) := tmp1(hi downto lo);
+ for i in 0 to 63 loop
+ if i >= lo and i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
end if;
return tmp2;
end;
hi := 63-to_integer(unsigned(mb));
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
tmp2 := (others => '0');
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
return tmp2;
end;
lo := 63-to_integer(unsigned(me));
tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0)))));
tmp2 := (others => '0');
- tmp2(63 downto lo) := tmp1(63 downto lo);
+ for i in 0 to 63 loop
+ if i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
return tmp2;
end;
tmp2 := ra;
if hi < lo then
-- Mask wraps around
- tmp2(63 downto lo) := tmp1(63 downto lo);
- tmp2(hi downto 0) := tmp1(hi downto 0);
+ for i in 0 to 63 loop
+ if i <= hi or i >= lo then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
else
- tmp2(hi downto lo) := tmp1(hi downto lo);
+ for i in 0 to 63 loop
+ if i >= lo and i <= hi then
+ tmp2(i) := tmp1(i);
+ end if;
+ end loop;
end if;
return tmp2;
end;
function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
variable n : integer;
variable tmp : signed(31 downto 0);
+ variable mask : std_ulogic_vector(63 downto 0);
variable carry: std_ulogic;
begin
n := to_integer(unsigned(sh));
tmp := shift_right(signed(rs(31 downto 0)), n);
-- what about n = 0?
- carry := or rs(n-1 downto 0) and rs(31);
+ mask := (others => '0');
+ for i in 0 to 63 loop
+ if i < n then
+ mask(i) := '1';
+ end if;
+ end loop;
+ carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(31);
return carry & std_ulogic_vector(resize(tmp, rs'length));
end;
function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
variable n : natural;
variable tmp : signed(31 downto 0);
+ variable mask : std_ulogic_vector(63 downto 0);
variable carry: std_ulogic;
begin
n := to_integer(unsigned(rb(5 downto 0)));
tmp := shift_right(signed(rs(31 downto 0)), n);
-- what about n = 0?
- carry := or rs(n-1 downto 0) and rs(31);
-
+ mask := (others => '0');
+ for i in 0 to 63 loop
+ if i < n then
+ mask(i) := '1';
+ end if;
+ end loop;
+ carry := or (rs and mask) and rs(31);
return carry & std_ulogic_vector(resize(tmp, rs'length));
end;
function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is
variable n : integer;
variable carry: std_ulogic;
+ variable mask : std_ulogic_vector(63 downto 0);
begin
n := to_integer(unsigned(sh));
-- what about n = 0?
- carry := or rs(n-1 downto 0) and rs(63);
+ mask := (others => '0');
+ for i in 0 to 63 loop
+ if i < n then
+ mask(i) := '1';
+ end if;
+ end loop;
+ carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
return carry & std_ulogic_vector(shift_right(signed(rs), n));
end;
function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is
variable n : integer;
variable carry: std_ulogic;
+ variable mask : std_ulogic_vector(63 downto 0);
begin
n := to_integer(unsigned(rb(6 downto 0)));
-- what about n = 0?
- carry := or rs(n-1 downto 0) and rs(63);
+ mask := (others => '0');
+ for i in 0 to 63 loop
+ if i < n then
+ mask(i) := '1';
+ end if;
+ end loop;
+ carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63);
return carry & std_ulogic_vector(shift_right(signed(rs), n));
end;
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);
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);
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);
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);
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
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);
return std_ulogic_vector(resize(tmp, ra'length));
end;
- function ppc_b (nia: std_ulogic_vector(63 downto 0); bd: std_ulogic_vector(23 downto 0)) return std_ulogic_vector is
- begin
- return std_ulogic_vector(signed(nia) + signed(bd & "00"));
- end;
-
- function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return integer is
+ function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic is
variable crfield: integer;
variable crbit_match: std_ulogic;
variable ctr_not_zero: std_ulogic;
variable ctr_ok: std_ulogic;
variable cond_ok: std_ulogic;
- variable ret: integer;
begin
crfield := to_integer(unsigned(bi));
-- BE bit numbering
ctr_not_zero := '1' when ctr /= x"0000000000000001" else '0';
ctr_ok := bo(4-2) or (ctr_not_zero xor bo(4-3));
cond_ok := bo(4-0) or crbit_match;
- if ctr_ok = '1' and cond_ok = '1' then
- ret := 1;
- else
- ret := 0;
- end if;
- return ret;
+ return ctr_ok and cond_ok;
end;
- function ppc_bcctr_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0)) return integer is
- variable crfield: integer;
- variable crbit_match: std_ulogic;
- variable cond_ok: std_ulogic;
- variable ret: integer;
- begin
- crfield := to_integer(unsigned(bi));
- -- BE bit numbering
- crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0';
- cond_ok := bo(4-0) or crbit_match;
- if cond_ok = '1' then
- ret := 1;
- else
- ret := 0;
- end if;
- return ret;
- end;
end package body ppc_fx_insns;