Implement absolute branches

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
jtag-port
Benjamin Herrenschmidt 5 years ago committed by Paul Mackerras
parent 4174cd8e93
commit 554ae88540

@ -58,12 +58,13 @@ package common is
cr: std_ulogic_vector(31 downto 0); cr: std_ulogic_vector(31 downto 0);
lr: std_ulogic; lr: std_ulogic;
rc: std_ulogic; rc: std_ulogic;
aa: std_ulogic;
input_carry: std_ulogic; input_carry: std_ulogic;
output_carry: std_ulogic; output_carry: std_ulogic;
input_cr: std_ulogic; input_cr: std_ulogic;
output_cr: std_ulogic; output_cr: std_ulogic;
end record; end record;
constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0')); constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', aa => '0', input_carry => '0', output_carry => '0', input_cr => '0', output_cr => '0', others => (others => '0'));


type Decode2ToMultiplyType is record type Decode2ToMultiplyType is record
valid: std_ulogic; valid: std_ulogic;

@ -46,11 +46,8 @@ architecture behaviour of decode1 is
PPC_ANDIS_RC => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), PPC_ANDIS_RC => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'),
PPC_ATTN => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_ATTN => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'),
PPC_B => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), PPC_B => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'),
--PPC_BA
PPC_BC => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, BO, BI, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), PPC_BC => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, BO, BI, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'),
--PPC_BCA
PPC_BCCTR => (ALU, OP_BCCTR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), PPC_BCCTR => (ALU, OP_BCCTR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'),
--PPC_BCLA
PPC_BCLR => (ALU, OP_BCLR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), PPC_BCLR => (ALU, OP_BCLR, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'),
--PPC_BCTAR --PPC_BCTAR
--PPC_BPERM --PPC_BPERM
@ -293,24 +290,15 @@ begin
elsif std_match(f_in.insn, "000000---------------0100000000-") then elsif std_match(f_in.insn, "000000---------------0100000000-") then
report "PPC_attn"; report "PPC_attn";
ppc_insn := PPC_ATTN; ppc_insn := PPC_ATTN;
elsif std_match(f_in.insn, "010010------------------------0-") then elsif std_match(f_in.insn, "010010--------------------------") then
report "PPC_b"; report "PPC_b";
ppc_insn := PPC_B; ppc_insn := PPC_B;
elsif std_match(f_in.insn, "010010------------------------1-") then elsif std_match(f_in.insn, "010000--------------------------") then
report "PPC_ba";
ppc_insn := PPC_BA;
elsif std_match(f_in.insn, "010000------------------------0-") then
report "PPC_bc"; report "PPC_bc";
ppc_insn := PPC_BC; ppc_insn := PPC_BC;
elsif std_match(f_in.insn, "010000------------------------10") then
report "PPC_bca";
ppc_insn := PPC_BCA;
elsif std_match(f_in.insn, "010011---------------1000010000-") then elsif std_match(f_in.insn, "010011---------------1000010000-") then
report "PPC_bcctr"; report "PPC_bcctr";
ppc_insn := PPC_BCCTR; ppc_insn := PPC_BCCTR;
elsif std_match(f_in.insn, "010000------------------------11") then
report "PPC_bcla";
ppc_insn := PPC_BCLA;
elsif std_match(f_in.insn, "010011---------------0000010000-") then elsif std_match(f_in.insn, "010011---------------0000010000-") then
report "PPC_bclr"; report "PPC_bclr";
ppc_insn := PPC_BCLR; ppc_insn := PPC_BCLR;

@ -262,6 +262,7 @@ begin
v.e.cr := c_in.read_cr_data; v.e.cr := c_in.read_cr_data;
v.e.input_carry := d_in.decode.input_carry; v.e.input_carry := d_in.decode.input_carry;
v.e.output_carry := d_in.decode.output_carry; v.e.output_carry := d_in.decode.output_carry;
v.e.aa := insn_aa(d_in.insn);
if d_in.decode.lr = '1' then if d_in.decode.lr = '1' then
v.e.lr := insn_lk(d_in.insn); v.e.lr := insn_lk(d_in.insn);
end if; end if;

@ -5,8 +5,8 @@ package decode_types is
type ppc_insn_t is (PPC_ILLEGAL, PPC_ADD, PPC_ADDC, PPC_ADDE, type ppc_insn_t is (PPC_ILLEGAL, PPC_ADD, PPC_ADDC, PPC_ADDE,
PPC_ADDEX, PPC_ADDI, PPC_ADDIC, PPC_ADDIC_RC, PPC_ADDIS, PPC_ADDEX, PPC_ADDI, PPC_ADDIC, PPC_ADDIC_RC, PPC_ADDIS,
PPC_ADDME, PPC_ADDPCIS, PPC_ADDZE, PPC_AND, PPC_ANDC, PPC_ADDME, PPC_ADDPCIS, PPC_ADDZE, PPC_AND, PPC_ANDC,
PPC_ANDI_RC, PPC_ANDIS_RC, PPC_ATTN, PPC_B, PPC_BA, PPC_BC, PPC_ANDI_RC, PPC_ANDIS_RC, PPC_ATTN, PPC_B, PPC_BC,
PPC_BCA, PPC_BCCTR, PPC_BCLA, PPC_BCLR, PPC_BCTAR, PPC_BPERM, PPC_BCCTR, PPC_BCLR, PPC_BCTAR, PPC_BPERM,
PPC_CMP, PPC_CMPB, PPC_CMPEQB, PPC_CMPI, PPC_CMPL, PPC_CMPLI, PPC_CMP, PPC_CMPB, PPC_CMPEQB, PPC_CMPI, PPC_CMPL, PPC_CMPLI,
PPC_CMPRB, PPC_CNTLZD, PPC_CNTLZW, PPC_CNTTZD, PPC_CNTTZW, PPC_CMPRB, PPC_CNTLZD, PPC_CNTLZW, PPC_CNTTZD, PPC_CNTTZW,
PPC_CRAND, PPC_CRANDC, PPC_CREQV, PPC_CRNAND, PPC_CRNOR, PPC_CRAND, PPC_CRANDC, PPC_CREQV, PPC_CRNAND, PPC_CRNOR,
@ -39,8 +39,8 @@ package decode_types is
PPC_SIM_CONFIG); PPC_SIM_CONFIG);


type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ADDE, OP_ADDEX, OP_ADDME, type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ADDE, OP_ADDEX, OP_ADDME,
OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BA, OP_BC, OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC,
OP_BCA, OP_BCCTR, OP_BCLA, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP, OP_BCCTR, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP,
OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB, OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB,
OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND, OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND,
OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC,

@ -100,15 +100,23 @@ begin
result_en := 1; result_en := 1;
when OP_B => when OP_B =>
f_out.redirect <= '1'; f_out.redirect <= '1';
if (e_in.aa) then
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
else
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
end if;
when OP_BC => when OP_BC =>
if e_in.const1(4-2) = '0' then if e_in.const1(4-2) = '0' then
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
end if; end if;
if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
f_out.redirect <= '1'; f_out.redirect <= '1';
if (e_in.aa) then
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2));
else
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
end if; end if;
end if;
when OP_BCLR => when OP_BCLR =>
if e_in.const1(4-2) = '0' then if e_in.const1(4-2) = '0' then
ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);

@ -14,6 +14,7 @@ package insn_helpers is
function insn_me32 (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_me32 (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_li (insn_in : std_ulogic_vector) return std_ulogic_vector; function insn_li (insn_in : std_ulogic_vector) return std_ulogic_vector;
function insn_lk (insn_in : std_ulogic_vector) return std_ulogic; function insn_lk (insn_in : std_ulogic_vector) return std_ulogic;
function insn_aa (insn_in : std_ulogic_vector) return std_ulogic;
function insn_rc (insn_in : std_ulogic_vector) return std_ulogic; function insn_rc (insn_in : std_ulogic_vector) return std_ulogic;
function insn_bd (insn_in : std_ulogic_vector) return std_ulogic_vector; 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_bf (insn_in : std_ulogic_vector) return std_ulogic_vector;
@ -91,6 +92,11 @@ package body insn_helpers is
return insn_in(0); return insn_in(0);
end; end;


function insn_aa (insn_in : std_ulogic_vector) return std_ulogic is
begin
return insn_in(1);
end;

function insn_rc (insn_in : std_ulogic_vector) return std_ulogic is function insn_rc (insn_in : std_ulogic_vector) return std_ulogic is
begin begin
return insn_in(0); return insn_in(0);

@ -89,7 +89,6 @@ package ppc_fx_insns is
function ppc_divd (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_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_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_bcctr_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0)) return integer;
end package ppc_fx_insns; end package ppc_fx_insns;
@ -779,11 +778,6 @@ package body ppc_fx_insns is
return std_ulogic_vector(resize(tmp, ra'length)); return std_ulogic_vector(resize(tmp, ra'length));
end; 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 integer is
variable crfield: integer; variable crfield: integer;
variable crbit_match: std_ulogic; variable crbit_match: std_ulogic;

Loading…
Cancel
Save