Implement CRNOR and friends

Signed-off-by: Tom Vijlbrief <tvijlbrief@gmail.com>
pull/127/head
Tom Vijlbrief 4 years ago
parent 1a826f077b
commit c05441bf47

@ -84,14 +84,14 @@ architecture behaviour of decode1 is
2#1000010000# => '1', -- bcctr
2#0000010000# => '1', -- bclr
2#1000110000# => '0', -- bctar
2#0100000001# => '0', -- crand
2#0010000001# => '0', -- crandc
2#0100100001# => '0', -- creqv
2#0011100001# => '0', -- crnand
2#0000100001# => '0', -- crnor
2#0111000001# => '0', -- cror
2#0011000001# => '0', -- crorc
2#0110100001# => '0', -- crxor
2#0100000001# => '1', -- crand
2#0010000001# => '1', -- crandc
2#0100100001# => '1', -- creqv
2#0011100001# => '1', -- crnand
2#0000100001# => '1', -- crnor
2#0111000001# => '1', -- cror
2#0110100001# => '1', -- crorc
2#0011000001# => '1', -- crxor
2#0010010110# => '1', -- isync
2#0000000000# => '1', -- mcrf
others => '0'
@ -101,7 +101,7 @@ architecture behaviour of decode1 is
constant decode_op_19_array : op_19_subop_array_t := (
-- unit internal in1 in2 in3 out CR CR inv inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl
-- op in out A out in out len ext pipe
-- mcrf; cr logical ops not implemented yet
-- mcrf; and cr logical ops
2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '0'),
-- addpcis not implemented yet
2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),

@ -152,6 +152,10 @@ begin
variable sh32, mb32, me32 : std_ulogic_vector(4 downto 0);
variable bo, bi : std_ulogic_vector(4 downto 0);
variable bf, bfa : std_ulogic_vector(2 downto 0);
variable cr_op : std_ulogic_vector(9 downto 0);
variable bt, ba, bb : std_ulogic_vector(4 downto 0);
variable btnum, banum, bbnum : integer range 0 to 31;
variable crresult : std_ulogic;
variable l : std_ulogic;
variable next_nia : std_ulogic_vector(63 downto 0);
variable carry_32, carry_64 : std_ulogic;
@ -335,24 +339,64 @@ begin
end if;
result_en := '1';
when OP_MCRF =>
bf := insn_bf(e_in.insn);
bfa := insn_bfa(e_in.insn);
v.e.write_cr_enable := '1';
crnum := to_integer(unsigned(bf));
scrnum := to_integer(unsigned(bfa));
v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop
lo := (7-i)*4;
hi := lo + 3;
if i = scrnum then
newcrf := e_in.cr(hi downto lo);
end if;
end loop;
for i in 0 to 7 loop
lo := i*4;
hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
cr_op := insn_cr(e_in.insn);
report "CR OP " & to_hstring(cr_op);
if cr_op(0) = '0' then -- MCRF
bf := insn_bf(e_in.insn);
bfa := insn_bfa(e_in.insn);
v.e.write_cr_enable := '1';
crnum := to_integer(unsigned(bf));
scrnum := to_integer(unsigned(bfa));
v.e.write_cr_mask := num_to_fxm(crnum);
for i in 0 to 7 loop
lo := (7-i)*4;
hi := lo + 3;
if i = scrnum then
newcrf := e_in.cr(hi downto lo);
end if;
end loop;
for i in 0 to 7 loop
lo := i*4;
hi := lo + 3;
v.e.write_cr_data(hi downto lo) := newcrf;
end loop;
else
v.e.write_cr_enable := '1';
bt := insn_bt(e_in.insn);
ba := insn_ba(e_in.insn);
bb := insn_bb(e_in.insn);
btnum := 31 - to_integer(unsigned(bt));
banum := 31 - to_integer(unsigned(ba));
bbnum := 31 - to_integer(unsigned(bb));
case cr_op(8 downto 5) is
when "1001" => -- CREQV
crresult := not(e_in.cr(banum) xor e_in.cr(bbnum));
when "0111" => -- CRNAND
crresult := not(e_in.cr(banum) and e_in.cr(bbnum));
when "0100" => -- CRANDC
crresult := (e_in.cr(banum) and not e_in.cr(bbnum));
when "1000" => -- CRAND
crresult := (e_in.cr(banum) and e_in.cr(bbnum));
when "0001" => -- CRNOR
crresult := not(e_in.cr(banum) or e_in.cr(bbnum));
when "1101" => -- CRORC
crresult := (e_in.cr(banum) or not e_in.cr(bbnum));
when "0110" => -- CRXOR
crresult := (e_in.cr(banum) xor e_in.cr(bbnum));
when "1110" => -- CROR
crresult := (e_in.cr(banum) or e_in.cr(bbnum));
when others =>
report "BAD CR?";
end case;
v.e.write_cr_mask := num_to_fxm((31-btnum) / 4);
for i in 0 to 31 loop
if i = btnum then
v.e.write_cr_data(i) := crresult;
else
v.e.write_cr_data(i) := e_in.cr(i);
end if;
end loop;
end if;
when OP_MFSPR =>
if is_fast_spr(e_in.read_reg1) then
result := e_in.read_data1;

@ -20,6 +20,10 @@ package insn_helpers is
function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bf (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bfa (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_cr (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bt (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_ba (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bb (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bo (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_bi (insn_in : std_ulogic_vector) return std_ulogic_vector;
@ -124,6 +128,26 @@ package body insn_helpers is
return insn_in(20 downto 18);
end;

function insn_cr (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(10 downto 1);
end;
function insn_bb (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(15 downto 11);
end;

function insn_ba (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(20 downto 16);
end;

function insn_bt (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(25 downto 21);
end;

function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is
begin
return insn_in(19 downto 12);

Loading…
Cancel
Save