From: Benjamin Herrenschmidt Date: Tue, 24 Sep 2019 05:47:25 +0000 (+1000) Subject: Implement absolute branches X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=554ae88540f7b98e80697bde527bfc0680dd6e42;p=microwatt.git Implement absolute branches Signed-off-by: Benjamin Herrenschmidt --- diff --git a/common.vhdl b/common.vhdl index bb898a0..694e20c 100644 --- a/common.vhdl +++ b/common.vhdl @@ -58,12 +58,13 @@ package common is cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; + aa: std_ulogic; input_carry: std_ulogic; output_carry: std_ulogic; input_cr: std_ulogic; output_cr: std_ulogic; 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 valid: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 7c29781..b07962e 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -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_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_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_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_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_BCTAR --PPC_BPERM @@ -293,24 +290,15 @@ begin elsif std_match(f_in.insn, "000000---------------0100000000-") then report "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"; ppc_insn := PPC_B; - elsif std_match(f_in.insn, "010010------------------------1-") then - report "PPC_ba"; - ppc_insn := PPC_BA; - elsif std_match(f_in.insn, "010000------------------------0-") then + elsif std_match(f_in.insn, "010000--------------------------") then report "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 report "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 report "PPC_bclr"; ppc_insn := PPC_BCLR; diff --git a/decode2.vhdl b/decode2.vhdl index 2ace765..2756c71 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -262,6 +262,7 @@ begin v.e.cr := c_in.read_cr_data; v.e.input_carry := d_in.decode.input_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 v.e.lr := insn_lk(d_in.insn); end if; diff --git a/decode_types.vhdl b/decode_types.vhdl index 64e6dfa..2f449c9 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -5,8 +5,8 @@ package decode_types is 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_ADDME, PPC_ADDPCIS, PPC_ADDZE, PPC_AND, PPC_ANDC, - PPC_ANDI_RC, PPC_ANDIS_RC, PPC_ATTN, PPC_B, PPC_BA, PPC_BC, - PPC_BCA, PPC_BCCTR, PPC_BCLA, PPC_BCLR, PPC_BCTAR, PPC_BPERM, + PPC_ANDI_RC, PPC_ANDIS_RC, PPC_ATTN, PPC_B, PPC_BC, + PPC_BCCTR, PPC_BCLR, PPC_BCTAR, PPC_BPERM, PPC_CMP, PPC_CMPB, PPC_CMPEQB, PPC_CMPI, PPC_CMPL, PPC_CMPLI, PPC_CMPRB, PPC_CNTLZD, PPC_CNTLZW, PPC_CNTTZD, PPC_CNTTZW, PPC_CRAND, PPC_CRANDC, PPC_CREQV, PPC_CRNAND, PPC_CRNOR, @@ -39,8 +39,8 @@ package decode_types is PPC_SIM_CONFIG); 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_BCA, OP_BCCTR, OP_BCLA, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP, + OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC, + OP_BCCTR, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB, OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND, OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, diff --git a/execute1.vhdl b/execute1.vhdl index cec431f..b6af0ac 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -100,14 +100,22 @@ begin result_en := 1; when OP_B => f_out.redirect <= '1'; - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); + 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)); + end if; when OP_BC => if e_in.const1(4-2) = '0' then ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1); 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 f_out.redirect <= '1'; - f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); + 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)); + end if; end if; when OP_BCLR => if e_in.const1(4-2) = '0' then diff --git a/insn_helpers.vhdl b/insn_helpers.vhdl index e91e9e6..e9e9375 100644 --- a/insn_helpers.vhdl +++ b/insn_helpers.vhdl @@ -14,6 +14,7 @@ package insn_helpers is 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_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_bd (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); 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 begin return insn_in(0); diff --git a/ppc_fx_insns.vhdl b/ppc_fx_insns.vhdl index ea42b6d..407881f 100644 --- a/ppc_fx_insns.vhdl +++ b/ppc_fx_insns.vhdl @@ -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_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; end package ppc_fx_insns; @@ -779,11 +778,6 @@ package body ppc_fx_insns is 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 variable crfield: integer; variable crbit_match: std_ulogic;