From 554ae88540f7b98e80697bde527bfc0680dd6e42 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 24 Sep 2019 15:47:25 +1000 Subject: [PATCH 01/14] Implement absolute branches Signed-off-by: Benjamin Herrenschmidt --- common.vhdl | 3 ++- decode1.vhdl | 16 ++-------------- decode2.vhdl | 1 + decode_types.vhdl | 8 ++++---- execute1.vhdl | 12 ++++++++++-- insn_helpers.vhdl | 6 ++++++ ppc_fx_insns.vhdl | 6 ------ 7 files changed, 25 insertions(+), 27 deletions(-) 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; From 3e6f656a9054417326073d62bbd1abc9e782b428 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 25 Sep 2019 00:09:35 +1000 Subject: [PATCH 02/14] Add MCRF instruction Hopefully it's not too timing catastrophic. The variable newcrf will be handy for the other CR ops when we implement them I suspect. Signed-off-by: Benjamin Herrenschmidt --- decode1.vhdl | 2 +- decode2.vhdl | 2 ++ decode_types.vhdl | 2 +- execute1.vhdl | 19 +++++++++++++++++++ insn_helpers.vhdl | 6 ++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index b07962e..c003739 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -120,7 +120,7 @@ architecture behaviour of decode1 is --PPC_MADDHD --PPC_MADDHDU --PPC_MADDLD - --PPC_MCRF + PPC_MCRF => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_MCRXR --PPC_MCRXRX PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), diff --git a/decode2.vhdl b/decode2.vhdl index 2756c71..c1c6e6b 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -159,6 +159,8 @@ architecture behaviour of decode2 is return "0" & insn_bi(insn_in); when L => return "00000" & insn_l(insn_in); + when BFA => + return "000" & insn_bfa(insn_in); when NONE => return "000000"; end case; diff --git a/decode_types.vhdl b/decode_types.vhdl index 2f449c9..63e78c0 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -64,7 +64,7 @@ package decode_types is type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); type constant_a_t is (NONE, SH, SH32, FXM, BO, BF, TOO, BC); - type constant_b_t is (NONE, MB, ME, MB32, BI, L); + type constant_b_t is (NONE, MB, ME, MB32, BI, L, BFA); type constant_c_t is (NONE, ME32, BH); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index b6af0ac..e75fac7 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -52,9 +52,11 @@ begin execute1_1: process(all) variable v : reg_type; variable result : std_ulogic_vector(63 downto 0); + variable newcrf : std_ulogic_vector(3 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0); variable result_en : integer; variable crnum : integer; + variable scrnum : integer; variable lo, hi : integer; begin result := (others => '0'); @@ -183,6 +185,23 @@ begin result := e_in.read_data2; end if; result_en := 1; + when OP_MCRF => + v.e.write_cr_enable := '1'; + crnum := to_integer(unsigned(e_in.const1(2 downto 0))); + scrnum := to_integer(unsigned(e_in.const2(2 downto 0))); + 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; when OP_MFCTR => result := ctrl.ctr; result_en := 1; diff --git a/insn_helpers.vhdl b/insn_helpers.vhdl index e9e9375..d3ddcca 100644 --- a/insn_helpers.vhdl +++ b/insn_helpers.vhdl @@ -18,6 +18,7 @@ package insn_helpers is 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; + function insn_bfa (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; @@ -112,6 +113,11 @@ package body insn_helpers is return insn_in(25 downto 23); end; + function insn_bfa (insn_in : std_ulogic_vector) return std_ulogic_vector is + begin + return insn_in(20 downto 18); + end; + function insn_fxm (insn_in : std_ulogic_vector) return std_ulogic_vector is begin return insn_in(19 downto 12); From c9e92483b80f2e204b986a032bbf80c4ce87e394 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 28 Sep 2019 14:43:46 +1000 Subject: [PATCH 03/14] decode: Push mtspr/mfspr register decoding down into execute1 Instead of doing mfctr, mflr, mftb, mtctr, mtlr as separate ops, just pass down mfspr and mtspr ops with the spr number and let execute1 decode which SPR we're addressing. This will help reduce the number of instruction bits decode1 needs to look at. In fact we now pass down the whole instruction from decode2 to execute1. We will need more bits of the instruction in future, and the tools should just optimize away any that we don't end up using. Since the 'aa' bit was just a copy of an instruction bit, we can now remove it from the record. Signed-off-by: Paul Mackerras --- Makefile | 2 +- common.vhdl | 4 ++-- decode1.vhdl | 24 ++---------------------- decode2.vhdl | 2 +- decode_types.vhdl | 5 ++--- execute1.vhdl | 35 ++++++++++++++++++++--------------- 6 files changed, 28 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 13d245e..8075439 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ crhelpers.o: common.o decode1.o: common.o decode_types.o decode2.o: decode_types.o common.o helpers.o insn_helpers.o decode_types.o: -execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o +execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o insn_helpers.o execute2.o: common.o crhelpers.o ppc_fx_insns.o fetch1.o: common.o fetch2.o: common.o wishbone_types.o diff --git a/common.vhdl b/common.vhdl index 694e20c..8b1d4cf 100644 --- a/common.vhdl +++ b/common.vhdl @@ -58,13 +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; + insn: std_ulogic_vector(31 downto 0); end record; - 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')); + 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')); type Decode2ToMultiplyType is record valid: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index c003739..98f6d35 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -125,12 +125,8 @@ architecture behaviour of decode1 is --PPC_MCRXRX PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MFOCRF => (ALU, OP_MFOCRF, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFCTR => (ALU, OP_MFCTR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFLR => (ALU, OP_MFLR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFTB => (ALU, OP_MFTB, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTCTR => (ALU, OP_MTCTR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTLR => (ALU, OP_MTLR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_MFSPR + PPC_MFSPR => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + PPC_MTSPR => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MOD => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_MTCRF => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MTOCRF => (ALU, OP_MTOCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), @@ -527,22 +523,6 @@ begin elsif std_match(f_in.insn, "011111-----1---------0000010011-") then report "PPC_mfocrf"; ppc_insn := PPC_MFOCRF; - -- Specific MF/MT SPR encodings first - elsif std_match(f_in.insn, "011111-----01001000000101010011-") then - report "PPC_mfctr"; - ppc_insn := PPC_MFCTR; - elsif std_match(f_in.insn, "011111-----01000000000101010011-") then - report "PPC_mflr"; - ppc_insn := PPC_MFLR; - elsif std_match(f_in.insn, "011111-----01100010000101010011-") then - report "PPC_mftb"; - ppc_insn := PPC_MFTB; - elsif std_match(f_in.insn, "011111-----01001000000111010011-") then - report "PPC_mtctr"; - ppc_insn := PPC_MTCTR; - elsif std_match(f_in.insn, "011111-----01000000000111010011-") then - report "PPC_mtlr"; - ppc_insn := PPC_MTLR; elsif std_match(f_in.insn, "011111---------------0101010011-") then report "PPC_mfspr"; ppc_insn := PPC_MFSPR; diff --git a/decode2.vhdl b/decode2.vhdl index c1c6e6b..2b816a7 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -264,13 +264,13 @@ 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; v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn); v.e.const2 := decode_const_b(d_in.decode.const_b, d_in.insn); v.e.const3 := decode_const_c(d_in.decode.const_c, d_in.insn); + v.e.insn := d_in.insn; -- multiply unit v.m.insn_type := d_in.decode.insn_type; diff --git a/decode_types.vhdl b/decode_types.vhdl index 63e78c0..1437bf0 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -48,9 +48,8 @@ package decode_types is OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH, OP_EXTSW, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF, - OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFCTR, OP_MFLR, - OP_MFTB, OP_MFSPR, OP_MOD, - OP_MTCRF, OP_MTOCRF, OP_MTCTR, OP_MTLR, OP_MTSPR, OP_MUL_L64, + OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFSPR, OP_MOD, + OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD, OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR, diff --git a/execute1.vhdl b/execute1.vhdl index e75fac7..0d85e71 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -7,6 +7,7 @@ use work.decode_types.all; use work.common.all; use work.helpers.all; use work.crhelpers.all; +use work.insn_helpers.all; use work.ppc_fx_insns.all; entity execute1 is @@ -102,7 +103,7 @@ begin result_en := 1; when OP_B => f_out.redirect <= '1'; - if (e_in.aa) then + if (insn_aa(e_in.insn)) 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)); @@ -113,7 +114,7 @@ begin 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'; - if (e_in.aa) then + if (insn_aa(e_in.insn)) 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)); @@ -202,19 +203,17 @@ begin hi := lo + 3; v.e.write_cr_data(hi downto lo) := newcrf; end loop; - when OP_MFCTR => - result := ctrl.ctr; - result_en := 1; - when OP_MFLR => - result := ctrl.lr; - result_en := 1; - when OP_MFTB => - result := ctrl.tb; - result_en := 1; - when OP_MTCTR => - ctrl_tmp.ctr <= e_in.read_data1; - when OP_MTLR => - ctrl_tmp.lr <= e_in.read_data1; + when OP_MFSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + result := ctrl.ctr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + result := ctrl.lr; + result_en := 1; + elsif std_match(e_in.insn(20 downto 11), "0110001000") then + result := ctrl.tb; + result_en := 1; + end if; when OP_MFCR => result := x"00000000" & e_in.cr; result_en := 1; @@ -239,6 +238,12 @@ begin crnum := fxm_to_num(e_in.const1(7 downto 0)); v.e.write_cr_mask := num_to_fxm(crnum); v.e.write_cr_data := e_in.read_data1(31 downto 0); + when OP_MTSPR => + if std_match(e_in.insn(20 downto 11), "0100100000") then + ctrl_tmp.ctr <= e_in.read_data1; + elsif std_match(e_in.insn(20 downto 11), "0100000000") then + ctrl_tmp.lr <= e_in.read_data1; + end if; when OP_NAND => result := ppc_nand(e_in.read_data1, e_in.read_data2); result_en := 1; From e30a87593a2a913d64f6e0dcb91be9ee36928573 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 29 Sep 2019 09:17:39 +1000 Subject: [PATCH 04/14] decode: Start moving towards decoding by major opcode first With this, we have a table for most major opcodes and separate tables for each major opcode that has further decoding required. These tables are still mostly indexed by the ppc_insn_t values, however. A few things are still decoded completely at the top level: nop, attn and sim_config. Signed-off-by: Paul Mackerras --- decode1.vhdl | 693 +++++++++++++++++++++++---------------------------- 1 file changed, 313 insertions(+), 380 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 98f6d35..25bd597 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -22,10 +22,92 @@ end entity decode1; architecture behaviour of decode1 is signal r, rin : Decode1ToDecode2Type; + subtype major_opcode_t is unsigned(5 downto 0); + type major_rom_array_t is array(0 to 63) of decode_rom_t; + type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; + type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; + constant illegal_inst : decode_rom_t := + (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + + constant major_decode_rom_array : major_rom_array_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + 12 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic + 13 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. + 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi + 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis + 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. + 29 => (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'), -- andis. + 18 => (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'), -- b + 16 => (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'), -- bc + 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi + 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli + 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz + 35 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu + 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha + 43 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau + 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz + 41 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu + 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz + 33 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwz + 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli + 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori + 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris + 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi + 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm + 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, NONE, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb + 39 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu + 44 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth + 45 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu + 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw + 37 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu + 8 => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic + 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi + --PPC_TWI 3 + 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori + 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris + others => illegal_inst + ); + + constant decode_op_19_array : decode_rom_array_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + PPC_ILLEGAL => (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_ADDPCIS + 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_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_CRAND + --PPC_CRANDC + --PPC_CREQV + --PPC_CRNAND + --PPC_CRNOR + --PPC_CROR + --PPC_CRORC + --PPC_CRXOR + PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + PPC_MCRF => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + others => decode_rom_init + ); + + constant decode_op_30_array : decode_rom_array_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + PPC_ILLEGAL => (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_RLDCL => (ALU, OP_RLDCL, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + PPC_RLDCR => (ALU, OP_RLDCR, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + PPC_RLDIC => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + PPC_RLDICL => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + PPC_RLDICR => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + PPC_RLDIMI => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + others => decode_rom_init + ); + -- Note: reformat with column -t -o ' ' - constant decode_rom_array : decode_rom_array_t := ( + constant decode_op_31_array : decode_rom_array_t := ( -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl -- op 1 2 3 in out in out len ext 32 sgn pipe PPC_ILLEGAL => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), @@ -33,43 +115,20 @@ architecture behaviour of decode1 is PPC_ADDC => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_ADDE => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), --PPC_ADDEX - PPC_ADDI => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_ADDIC => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_ADDIC_RC => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), - PPC_ADDIS => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_ADDME - --PPC_ADDPCIS PPC_ADDZE => (ALU, OP_ADDE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_AND => (ALU, OP_AND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_ANDC => (ALU, OP_ANDC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ANDI_RC => (ALU, OP_AND, RS, CONST_UI, 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_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_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_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_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 PPC_CMP => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_CMPB => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_CMPEQB - PPC_CMPI => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_CMPL => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_CMPLI => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_CMPRB PPC_CNTLZD => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_CNTLZW => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_CNTTZD => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_CNTTZW => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_CRAND - --PPC_CRANDC - --PPC_CREQV - --PPC_CRNAND - --PPC_CRNOR - --PPC_CROR - --PPC_CRORC - --PPC_CRXOR --PPC_DARN PPC_DCBF => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_DCBST => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), @@ -85,81 +144,50 @@ architecture behaviour of decode1 is --PPC_ICBI PPC_ICBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_ISEL => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_LBARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - --CONST_LI matches CONST_SI, so reuse it - PPC_LBZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LBZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LBZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LBZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LD => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_LDARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), PPC_LDBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LDU => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LDUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LDX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHA => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), PPC_LHARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_LHAU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), PPC_LHAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), PPC_LHAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), PPC_LHBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LHZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LHZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWA => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), PPC_LWARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), PPC_LWAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), PPC_LWAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), PPC_LWBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWZ => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWZU => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LWZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_LWZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_MADDHD - --PPC_MADDHDU - --PPC_MADDLD - PPC_MCRF => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_MCRXR --PPC_MCRXRX PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MFOCRF => (ALU, OP_MFOCRF, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MFSPR => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTSPR => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MOD => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_MTCRF => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MTOCRF => (ALU, OP_MTOCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_MTSPR + PPC_MTSPR => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_MULHD => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), PPC_MULHDU => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_MULHW => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), PPC_MULHWU => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), PPC_MULLD => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), - PPC_MULLI => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), PPC_MULLW => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), PPC_NAND => (ALU, OP_NAND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_NEG => (ALU, OP_NEG, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_NOP => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_NOR => (ALU, OP_NOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_OR => (ALU, OP_OR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_ORC => (ALU, OP_ORC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ORI => (ALU, OP_OR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_ORIS => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_POPCNTB => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_POPCNTD => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_POPCNTW => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_PRTYD => (ALU, OP_PRTYD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_PRTYW => (ALU, OP_PRTYW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_RLDCL => (ALU, OP_RLDCL, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDCR => (ALU, OP_RLDCR, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDIC => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDICL => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDICR => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDIMI => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLWIMI => (ALU, OP_RLWIMI, RA, RS, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLWINM => (ALU, OP_RLWINM, RS, NONE, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLWNM => (ALU, OP_RLWNM, RS, RB, NONE, RA, NONE, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), --PPC_SETB PPC_SLD => (ALU, OP_SLD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SLW => (ALU, OP_SLW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), @@ -169,48 +197,54 @@ architecture behaviour of decode1 is PPC_SRAWI => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SRD => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SRW => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_STB => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_STBCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), - PPC_STBU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), PPC_STBUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), PPC_STBX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_STD => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STDBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STDCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STDU => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STDUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STDX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STH => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STHBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STHCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STHU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STHUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STHX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STW => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STWBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_STWCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STWU => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STWUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), PPC_STWX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_SUBF => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SUBFC => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SUBFE => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SUBFIC => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_SUBFME PPC_SUBFZE => (ALU, OP_SUBFE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), PPC_SYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), --PPC_TD - PPC_TDI => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), PPC_TW => (ALU, OP_TW, RA, RB, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_TWI PPC_XOR => (ALU, OP_XOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_XORI => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_XORIS => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_SIM_CONFIG => (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - others => decode_rom_init ); + constant decode_op_58_array : minor_rom_array_2_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld + 1 => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu + 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa + others => decode_rom_init + ); + + constant decode_op_62_array : minor_rom_array_2_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std + 1 => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu + others => decode_rom_init + ); + + constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + begin decode1_0: process(clk) begin @@ -225,6 +259,7 @@ begin decode1_1: process(all) variable v : Decode1ToDecode2Type; variable ppc_insn: ppc_insn_t; + variable majorop : major_opcode_t; begin v := r; @@ -237,542 +272,440 @@ begin if f_in.valid = '1' then report "Decode insn " & to_hstring(f_in.insn) & " at " & to_hstring(f_in.nia); + end if; - if std_match(f_in.insn, "011111---------------0100001010-") then + majorop := unsigned(f_in.insn(31 downto 26)); + if majorop = "011111" then + -- major opcode 31, lots of things + if std_match(f_in.insn, "---------------------0100001010-") then report "PPC_add"; ppc_insn := PPC_ADD; - elsif std_match(f_in.insn, "011111---------------0000001010-") then + elsif std_match(f_in.insn, "---------------------0000001010-") then report "PPC_addc"; ppc_insn := PPC_ADDC; - elsif std_match(f_in.insn, "011111---------------0010001010-") then + elsif std_match(f_in.insn, "---------------------0010001010-") then report "PPC_adde"; ppc_insn := PPC_ADDE; - elsif std_match(f_in.insn, "011111---------------0010101010-") then + elsif std_match(f_in.insn, "---------------------0010101010-") then report "PPC_addex"; ppc_insn := PPC_ADDEX; - elsif std_match(f_in.insn, "001110--------------------------") then - report "PPC_addi"; - ppc_insn := PPC_ADDI; - elsif std_match(f_in.insn, "001100--------------------------") then - report "PPC_addic"; - ppc_insn := PPC_ADDIC; - elsif std_match(f_in.insn, "001101--------------------------") then - report "PPC_addic."; - ppc_insn := PPC_ADDIC_RC; - elsif std_match(f_in.insn, "001111--------------------------") then - report "PPC_addis"; - ppc_insn := PPC_ADDIS; - elsif std_match(f_in.insn, "011111---------------0011101010-") then + elsif std_match(f_in.insn, "---------------------0011101010-") then report "PPC_addme"; ppc_insn := PPC_ADDME; - elsif std_match(f_in.insn, "010011--------------------00010-") then - report "PPC_addpcis"; - ppc_insn := PPC_ADDPCIS; - elsif std_match(f_in.insn, "011111---------------0011001010-") then + elsif std_match(f_in.insn, "---------------------0011001010-") then report "PPC_addze"; ppc_insn := PPC_ADDZE; - elsif std_match(f_in.insn, "011111---------------0000011100-") then + elsif std_match(f_in.insn, "---------------------0000011100-") then report "PPC_and"; ppc_insn := PPC_AND; - elsif std_match(f_in.insn, "011111---------------0000111100-") then + elsif std_match(f_in.insn, "---------------------0000111100-") then report "PPC_andc"; ppc_insn := PPC_ANDC; - elsif std_match(f_in.insn, "011100--------------------------") then - report "PPC_andi."; - ppc_insn := PPC_ANDI_RC; - elsif std_match(f_in.insn, "011101--------------------------") then - report "PPC_andis."; - ppc_insn := PPC_ANDIS_RC; - elsif std_match(f_in.insn, "000000---------------0100000000-") then - report "PPC_attn"; - ppc_insn := PPC_ATTN; - elsif std_match(f_in.insn, "010010--------------------------") then - report "PPC_b"; - ppc_insn := PPC_B; - elsif std_match(f_in.insn, "010000--------------------------") then - report "PPC_bc"; - ppc_insn := PPC_BC; - elsif std_match(f_in.insn, "010011---------------1000010000-") then - report "PPC_bcctr"; - ppc_insn := PPC_BCCTR; - elsif std_match(f_in.insn, "010011---------------0000010000-") then - report "PPC_bclr"; - ppc_insn := PPC_BCLR; - elsif std_match(f_in.insn, "010011---------------1000110000-") then - report "PPC_bctar"; - ppc_insn := PPC_BCTAR; - elsif std_match(f_in.insn, "011111---------------0011111100-") then + elsif std_match(f_in.insn, "---------------------0011111100-") then report "PPC_bperm"; ppc_insn := PPC_BPERM; - elsif std_match(f_in.insn, "011111---------------0000000000-") then + elsif std_match(f_in.insn, "---------------------0000000000-") then report "PPC_cmp"; ppc_insn := PPC_CMP; - elsif std_match(f_in.insn, "011111---------------0111111100-") then + elsif std_match(f_in.insn, "---------------------0111111100-") then report "PPC_cmpb"; ppc_insn := PPC_CMPB; - elsif std_match(f_in.insn, "011111---------------0011100000-") then + elsif std_match(f_in.insn, "---------------------0011100000-") then report "PPC_cmpeqb"; ppc_insn := PPC_CMPEQB; - elsif std_match(f_in.insn, "001011--------------------------") then - report "PPC_cmpi"; - ppc_insn := PPC_CMPI; - elsif std_match(f_in.insn, "011111---------------0000100000-") then + elsif std_match(f_in.insn, "---------------------0000100000-") then report "PPC_cmpl"; ppc_insn := PPC_CMPL; - elsif std_match(f_in.insn, "001010--------------------------") then - report "PPC_cmpli"; - ppc_insn := PPC_CMPLI; - elsif std_match(f_in.insn, "011111---------------0011000000-") then + elsif std_match(f_in.insn, "---------------------0011000000-") then report "PPC_cmprb"; ppc_insn := PPC_CMPRB; - elsif std_match(f_in.insn, "011111---------------0000111010-") then + elsif std_match(f_in.insn, "---------------------0000111010-") then report "PPC_cntlzd"; ppc_insn := PPC_CNTLZD; - elsif std_match(f_in.insn, "011111---------------0000011010-") then + elsif std_match(f_in.insn, "---------------------0000011010-") then report "PPC_cntlzw"; ppc_insn := PPC_CNTLZW; - elsif std_match(f_in.insn, "011111---------------1000111010-") then + elsif std_match(f_in.insn, "---------------------1000111010-") then report "PPC_cnttzd"; ppc_insn := PPC_CNTTZD; - elsif std_match(f_in.insn, "011111---------------1000011010-") then + elsif std_match(f_in.insn, "---------------------1000011010-") then report "PPC_cnttzw"; ppc_insn := PPC_CNTTZW; - elsif std_match(f_in.insn, "010011---------------0100000001-") then - report "PPC_crand"; - ppc_insn := PPC_CRAND; - elsif std_match(f_in.insn, "010011---------------0010000001-") then - report "PPC_crandc"; - ppc_insn := PPC_CRANDC; - elsif std_match(f_in.insn, "010011---------------0100100001-") then - report "PPC_creqv"; - ppc_insn := PPC_CREQV; - elsif std_match(f_in.insn, "010011---------------0011100001-") then - report "PPC_crnand"; - ppc_insn := PPC_CRNAND; - elsif std_match(f_in.insn, "010011---------------0000100001-") then - report "PPC_crnor"; - ppc_insn := PPC_CRNOR; - elsif std_match(f_in.insn, "010011---------------0111000001-") then - report "PPC_cror"; - ppc_insn := PPC_CROR; - elsif std_match(f_in.insn, "010011---------------0110100001-") then - report "PPC_crorc"; - ppc_insn := PPC_CRORC; - elsif std_match(f_in.insn, "010011---------------0011000001-") then - report "PPC_crxor"; - ppc_insn := PPC_CRXOR; - elsif std_match(f_in.insn, "011111---------------1011110011-") then + elsif std_match(f_in.insn, "---------------------1011110011-") then report "PPC_darn"; ppc_insn := PPC_DARN; - elsif std_match(f_in.insn, "011111---------------0001010110-") then + elsif std_match(f_in.insn, "---------------------0001010110-") then report "PPC_dcbf"; ppc_insn := PPC_DCBF; - elsif std_match(f_in.insn, "011111---------------0000110110-") then + elsif std_match(f_in.insn, "---------------------0000110110-") then report "PPC_dcbst"; ppc_insn := PPC_DCBST; - elsif std_match(f_in.insn, "011111---------------0100010110-") then + elsif std_match(f_in.insn, "---------------------0100010110-") then report "PPC_dcbt"; ppc_insn := PPC_DCBT; - elsif std_match(f_in.insn, "011111---------------0011110110-") then + elsif std_match(f_in.insn, "---------------------0011110110-") then report "PPC_dcbtst"; ppc_insn := PPC_DCBTST; - elsif std_match(f_in.insn, "011111---------------1111110110-") then + elsif std_match(f_in.insn, "---------------------1111110110-") then report "PPC_dcbz"; ppc_insn := PPC_DCBZ; - elsif std_match(f_in.insn, "011111----------------11--010-1-") then + elsif std_match(f_in.insn, "----------------------11--010-1-") then report "PPC_div"; ppc_insn := PPC_DIV; - elsif std_match(f_in.insn, "011111---------------0100011100-") then + elsif std_match(f_in.insn, "---------------------0100011100-") then report "PPC_eqv"; ppc_insn := PPC_EQV; - elsif std_match(f_in.insn, "011111---------------1110111010-") then + elsif std_match(f_in.insn, "---------------------1110111010-") then report "PPC_extsb"; ppc_insn := PPC_EXTSB; - elsif std_match(f_in.insn, "011111---------------1110011010-") then + elsif std_match(f_in.insn, "---------------------1110011010-") then report "PPC_extsh"; ppc_insn := PPC_EXTSH; - elsif std_match(f_in.insn, "011111---------------1111011010-") then + elsif std_match(f_in.insn, "---------------------1111011010-") then report "PPC_extsw"; ppc_insn := PPC_EXTSW; - elsif std_match(f_in.insn, "011111---------------110111101--") then + elsif std_match(f_in.insn, "---------------------110111101--") then report "PPC_extswsli"; ppc_insn := PPC_EXTSWSLI; - elsif std_match(f_in.insn, "011111---------------1111010110-") then + elsif std_match(f_in.insn, "---------------------1111010110-") then report "PPC_icbi"; ppc_insn := PPC_ICBI; - elsif std_match(f_in.insn, "011111---------------0000010110-") then + elsif std_match(f_in.insn, "---------------------0000010110-") then report "PPC_icbt"; ppc_insn := PPC_ICBT; - elsif std_match(f_in.insn, "011111--------------------01111-") then + elsif std_match(f_in.insn, "--------------------------01111-") then report "PPC_isel"; ppc_insn := PPC_ISEL; - elsif std_match(f_in.insn, "010011---------------0010010110-") then - report "PPC_isync"; - ppc_insn := PPC_ISYNC; - elsif std_match(f_in.insn, "011111---------------0000110100-") then + elsif std_match(f_in.insn, "---------------------0000110100-") then report "PPC_lbarx"; ppc_insn := PPC_LBARX; - elsif std_match(f_in.insn, "100010--------------------------") then - report "PPC_lbz"; - ppc_insn := PPC_LBZ; - elsif std_match(f_in.insn, "100011--------------------------") then - report "PPC_lbzu"; - ppc_insn := PPC_LBZU; - elsif std_match(f_in.insn, "011111---------------0001110111-") then + elsif std_match(f_in.insn, "---------------------0001110111-") then report "PPC_lbzux"; ppc_insn := PPC_LBZUX; - elsif std_match(f_in.insn, "011111---------------0001010111-") then + elsif std_match(f_in.insn, "---------------------0001010111-") then report "PPC_lbzx"; ppc_insn := PPC_LBZX; - elsif std_match(f_in.insn, "111010------------------------00") then - report "PPC_ld"; - ppc_insn := PPC_LD; - elsif std_match(f_in.insn, "011111---------------0001010100-") then + elsif std_match(f_in.insn, "---------------------0001010100-") then report "PPC_ldarx"; ppc_insn := PPC_LDARX; - elsif std_match(f_in.insn, "011111---------------1000010100-") then + elsif std_match(f_in.insn, "---------------------1000010100-") then report "PPC_ldbrx"; ppc_insn := PPC_LDBRX; - elsif std_match(f_in.insn, "111010------------------------01") then - report "PPC_ldu"; - ppc_insn := PPC_LDU; - elsif std_match(f_in.insn, "011111---------------0000110101-") then + elsif std_match(f_in.insn, "---------------------0000110101-") then report "PPC_ldux"; ppc_insn := PPC_LDUX; - elsif std_match(f_in.insn, "011111---------------0000010101-") then + elsif std_match(f_in.insn, "---------------------0000010101-") then report "PPC_ldx"; ppc_insn := PPC_LDX; - elsif std_match(f_in.insn, "101010--------------------------") then - report "PPC_lha"; - ppc_insn := PPC_LHA; - elsif std_match(f_in.insn, "011111---------------0001110100-") then + elsif std_match(f_in.insn, "---------------------0001110100-") then report "PPC_lharx"; ppc_insn := PPC_LHARX; - elsif std_match(f_in.insn, "101011--------------------------") then - report "PPC_lhau"; - ppc_insn := PPC_LHAU; - elsif std_match(f_in.insn, "011111---------------0101110111-") then + elsif std_match(f_in.insn, "---------------------0101110111-") then report "PPC_lhaux"; ppc_insn := PPC_LHAUX; - elsif std_match(f_in.insn, "011111---------------0101010111-") then + elsif std_match(f_in.insn, "---------------------0101010111-") then report "PPC_lhax"; ppc_insn := PPC_LHAX; - elsif std_match(f_in.insn, "011111---------------1100010110-") then + elsif std_match(f_in.insn, "---------------------1100010110-") then report "PPC_lhbrx"; ppc_insn := PPC_LHBRX; - elsif std_match(f_in.insn, "101000--------------------------") then - report "PPC_lhz"; - ppc_insn := PPC_LHZ; - elsif std_match(f_in.insn, "101001--------------------------") then - report "PPC_lhzu"; - ppc_insn := PPC_LHZU; - elsif std_match(f_in.insn, "011111---------------0100110111-") then + elsif std_match(f_in.insn, "---------------------0100110111-") then report "PPC_lhzux"; ppc_insn := PPC_LHZUX; - elsif std_match(f_in.insn, "011111---------------0100010111-") then + elsif std_match(f_in.insn, "---------------------0100010111-") then report "PPC_lhzx"; ppc_insn := PPC_LHZX; - elsif std_match(f_in.insn, "111010------------------------10") then - report "PPC_lwa"; - ppc_insn := PPC_LWA; - elsif std_match(f_in.insn, "011111---------------0000010100-") then + elsif std_match(f_in.insn, "---------------------0000010100-") then report "PPC_lwarx"; ppc_insn := PPC_LWARX; - elsif std_match(f_in.insn, "011111---------------0101110101-") then + elsif std_match(f_in.insn, "---------------------0101110101-") then report "PPC_lwaux"; ppc_insn := PPC_LWAUX; - elsif std_match(f_in.insn, "011111---------------0101010101-") then + elsif std_match(f_in.insn, "---------------------0101010101-") then report "PPC_lwax"; ppc_insn := PPC_LWAX; - elsif std_match(f_in.insn, "011111---------------1000010110-") then + elsif std_match(f_in.insn, "---------------------1000010110-") then report "PPC_lwbrx"; ppc_insn := PPC_LWBRX; - elsif std_match(f_in.insn, "100000--------------------------") then - report "PPC_lwz"; - ppc_insn := PPC_LWZ; - elsif std_match(f_in.insn, "100001--------------------------") then - report "PPC_lwzu"; - ppc_insn := PPC_LWZU; - elsif std_match(f_in.insn, "011111---------------0000110111-") then + elsif std_match(f_in.insn, "---------------------0000110111-") then report "PPC_lwzux"; ppc_insn := PPC_LWZUX; - elsif std_match(f_in.insn, "011111---------------0000010111-") then + elsif std_match(f_in.insn, "---------------------0000010111-") then report "PPC_lwzx"; ppc_insn := PPC_LWZX; - elsif std_match(f_in.insn, "000100--------------------110000") then - report "PPC_maddhd"; - ppc_insn := PPC_MADDHD; - elsif std_match(f_in.insn, "000100--------------------110001") then - report "PPC_maddhdu"; - ppc_insn := PPC_MADDHDU; - elsif std_match(f_in.insn, "000100--------------------110011") then - report "PPC_maddld"; - ppc_insn := PPC_MADDLD; - elsif std_match(f_in.insn, "010011---------------0000000000-") then - report "PPC_mcrf"; - ppc_insn := PPC_MCRF; - elsif std_match(f_in.insn, "011111---------------1000000000-") then + elsif std_match(f_in.insn, "---------------------1000000000-") then report "PPC_mcrxr"; ppc_insn := PPC_MCRXR; - elsif std_match(f_in.insn, "011111---------------1001000000-") then + elsif std_match(f_in.insn, "---------------------1001000000-") then report "PPC_mcrxrx"; ppc_insn := PPC_MCRXRX; - elsif std_match(f_in.insn, "011111-----0---------0000010011-") then + elsif std_match(f_in.insn, "-----------0---------0000010011-") then report "PPC_mfcr"; ppc_insn := PPC_MFCR; - elsif std_match(f_in.insn, "011111-----1---------0000010011-") then + elsif std_match(f_in.insn, "-----------1---------0000010011-") then report "PPC_mfocrf"; ppc_insn := PPC_MFOCRF; - elsif std_match(f_in.insn, "011111---------------0101010011-") then + elsif std_match(f_in.insn, "---------------------0101010011-") then report "PPC_mfspr"; ppc_insn := PPC_MFSPR; - elsif std_match(f_in.insn, "011111----------------1000010-1-") then + elsif std_match(f_in.insn, "----------------------1000010-1-") then report "PPC_mod"; ppc_insn := PPC_MOD; - elsif std_match(f_in.insn, "011111-----0---------0010010000-") then + elsif std_match(f_in.insn, "-----------0---------0010010000-") then report "PPC_mtcrf"; ppc_insn := PPC_MTCRF; - elsif std_match(f_in.insn, "011111-----1---------0010010000-") then + elsif std_match(f_in.insn, "-----------1---------0010010000-") then report "PPC_mtocrf"; ppc_insn := PPC_MTOCRF; - elsif std_match(f_in.insn, "011111---------------0111010011-") then + elsif std_match(f_in.insn, "---------------------0111010011-") then report "PPC_mtspr"; ppc_insn := PPC_MTSPR; - elsif std_match(f_in.insn, "011111----------------001001001-") then + elsif std_match(f_in.insn, "----------------------001001001-") then report "PPC_mulhd"; ppc_insn := PPC_MULHD; - elsif std_match(f_in.insn, "011111----------------000001001-") then + elsif std_match(f_in.insn, "----------------------000001001-") then report "PPC_mulhdu"; ppc_insn := PPC_MULHDU; - elsif std_match(f_in.insn, "011111----------------001001011-") then + elsif std_match(f_in.insn, "----------------------001001011-") then report "PPC_mulhw"; ppc_insn := PPC_MULHW; - elsif std_match(f_in.insn, "011111----------------000001011-") then + elsif std_match(f_in.insn, "----------------------000001011-") then report "PPC_mulhwu"; ppc_insn := PPC_MULHWU; - elsif std_match(f_in.insn, "011111---------------0011101001-") then + elsif std_match(f_in.insn, "---------------------0011101001-") then report "PPC_mulld"; ppc_insn := PPC_MULLD; - elsif std_match(f_in.insn, "000111--------------------------") then - report "PPC_mulli"; - ppc_insn := PPC_MULLI; - elsif std_match(f_in.insn, "011111---------------0011101011-") then + elsif std_match(f_in.insn, "---------------------0011101011-") then report "PPC_mullw"; ppc_insn := PPC_MULLW; - elsif std_match(f_in.insn, "011111---------------0111011100-") then + elsif std_match(f_in.insn, "---------------------0111011100-") then report "PPC_nand"; ppc_insn := PPC_NAND; - elsif std_match(f_in.insn, "011111---------------0001101000-") then + elsif std_match(f_in.insn, "---------------------0001101000-") then report "PPC_neg"; ppc_insn := PPC_NEG; - elsif std_match(f_in.insn, "011111---------------0001111100-") then + elsif std_match(f_in.insn, "---------------------0001111100-") then report "PPC_nor"; ppc_insn := PPC_NOR; - elsif std_match(f_in.insn, "011111---------------0110111100-") then + elsif std_match(f_in.insn, "---------------------0110111100-") then report "PPC_or"; ppc_insn := PPC_OR; - elsif std_match(f_in.insn, "011111---------------0110011100-") then + elsif std_match(f_in.insn, "---------------------0110011100-") then report "PPC_orc"; ppc_insn := PPC_ORC; -- Has to be before ori - elsif std_match(f_in.insn, "01100000000000000000000000000000") then - report "PPC_nop"; - ppc_insn := PPC_NOP; - elsif std_match(f_in.insn, "011000--------------------------") then - report "PPC_ori"; - ppc_insn := PPC_ORI; - elsif std_match(f_in.insn, "011001--------------------------") then - report "PPC_oris"; - ppc_insn := PPC_ORIS; - elsif std_match(f_in.insn, "011111---------------0001111010-") then + elsif std_match(f_in.insn, "---------------------0001111010-") then report "PPC_popcntb"; ppc_insn := PPC_POPCNTB; - elsif std_match(f_in.insn, "011111---------------0111111010-") then + elsif std_match(f_in.insn, "---------------------0111111010-") then report "PPC_popcntd"; ppc_insn := PPC_POPCNTD; - elsif std_match(f_in.insn, "011111---------------0101111010-") then + elsif std_match(f_in.insn, "---------------------0101111010-") then report "PPC_popcntw"; ppc_insn := PPC_POPCNTW; - elsif std_match(f_in.insn, "011111---------------0010111010-") then + elsif std_match(f_in.insn, "---------------------0010111010-") then report "PPC_prtyd"; ppc_insn := PPC_PRTYD; - elsif std_match(f_in.insn, "011111---------------0010011010-") then + elsif std_match(f_in.insn, "---------------------0010011010-") then report "PPC_prtyw"; ppc_insn := PPC_PRTYW; - elsif std_match(f_in.insn, "011110---------------------1000-") then - report "PPC_rldcl"; - ppc_insn := PPC_RLDCL; - elsif std_match(f_in.insn, "011110---------------------1001-") then - report "PPC_rldcr"; - ppc_insn := PPC_RLDCR; - elsif std_match(f_in.insn, "011110---------------------010--") then - report "PPC_rldic"; - ppc_insn := PPC_RLDIC; - elsif std_match(f_in.insn, "011110---------------------000--") then - report "PPC_rldicl"; - ppc_insn := PPC_RLDICL; - elsif std_match(f_in.insn, "011110---------------------001--") then - report "PPC_rldicr"; - ppc_insn := PPC_RLDICR; - elsif std_match(f_in.insn, "011110---------------------011--") then - report "PPC_rldimi"; - ppc_insn := PPC_RLDIMI; - elsif std_match(f_in.insn, "010100--------------------------") then - report "PPC_rlwimi"; - ppc_insn := PPC_RLWIMI; - elsif std_match(f_in.insn, "010101--------------------------") then - report "PPC_rlwinm"; - ppc_insn := PPC_RLWINM; - elsif std_match(f_in.insn, "010111--------------------------") then - report "PPC_rlwnm"; - ppc_insn := PPC_RLWNM; - elsif std_match(f_in.insn, "011111---------------0010000000-") then + elsif std_match(f_in.insn, "---------------------0010000000-") then report "PPC_setb"; ppc_insn := PPC_SETB; - elsif std_match(f_in.insn, "011111---------------0000011011-") then + elsif std_match(f_in.insn, "---------------------0000011011-") then report "PPC_sld"; ppc_insn := PPC_SLD; - elsif std_match(f_in.insn, "011111---------------0000011000-") then + elsif std_match(f_in.insn, "---------------------0000011000-") then report "PPC_slw"; ppc_insn := PPC_SLW; - elsif std_match(f_in.insn, "011111---------------1100011010-") then + elsif std_match(f_in.insn, "---------------------1100011010-") then report "PPC_srad"; ppc_insn := PPC_SRAD; - elsif std_match(f_in.insn, "011111---------------110011101--") then + elsif std_match(f_in.insn, "---------------------110011101--") then report "PPC_sradi"; ppc_insn := PPC_SRADI; - elsif std_match(f_in.insn, "011111---------------1100011000-") then + elsif std_match(f_in.insn, "---------------------1100011000-") then report "PPC_sraw"; ppc_insn := PPC_SRAW; - elsif std_match(f_in.insn, "011111---------------1100111000-") then + elsif std_match(f_in.insn, "---------------------1100111000-") then report "PPC_srawi"; ppc_insn := PPC_SRAWI; - elsif std_match(f_in.insn, "011111---------------1000011011-") then + elsif std_match(f_in.insn, "---------------------1000011011-") then report "PPC_srd"; ppc_insn := PPC_SRD; - elsif std_match(f_in.insn, "011111---------------1000011000-") then + elsif std_match(f_in.insn, "---------------------1000011000-") then report "PPC_srw"; ppc_insn := PPC_SRW; - elsif std_match(f_in.insn, "100110--------------------------") then - report "PPC_stb"; - ppc_insn := PPC_STB; - elsif std_match(f_in.insn, "011111---------------1010110110-") then + elsif std_match(f_in.insn, "---------------------1010110110-") then report "PPC_stbcx"; ppc_insn := PPC_STBCX; - elsif std_match(f_in.insn, "100111--------------------------") then - report "PPC_stbu"; - ppc_insn := PPC_STBU; - elsif std_match(f_in.insn, "011111---------------0011110111-") then + elsif std_match(f_in.insn, "---------------------0011110111-") then report "PPC_stbux"; ppc_insn := PPC_STBUX; - elsif std_match(f_in.insn, "011111---------------0011010111-") then + elsif std_match(f_in.insn, "---------------------0011010111-") then report "PPC_stbx"; ppc_insn := PPC_STBX; - elsif std_match(f_in.insn, "111110------------------------00") then - report "PPC_std"; - ppc_insn := PPC_STD; - elsif std_match(f_in.insn, "011111---------------1010010100-") then + elsif std_match(f_in.insn, "---------------------1010010100-") then report "PPC_stdbrx"; ppc_insn := PPC_STDBRX; - elsif std_match(f_in.insn, "011111---------------0011010110-") then + elsif std_match(f_in.insn, "---------------------0011010110-") then report "PPC_stdcx"; ppc_insn := PPC_STDCX; - elsif std_match(f_in.insn, "111110------------------------01") then - report "PPC_stdu"; - ppc_insn := PPC_STDU; - elsif std_match(f_in.insn, "011111---------------0010110101-") then + elsif std_match(f_in.insn, "---------------------0010110101-") then report "PPC_stdux"; ppc_insn := PPC_STDUX; - elsif std_match(f_in.insn, "011111---------------0010010101-") then + elsif std_match(f_in.insn, "---------------------0010010101-") then report "PPC_stdx"; ppc_insn := PPC_STDX; - elsif std_match(f_in.insn, "101100--------------------------") then - report "PPC_sth"; - ppc_insn := PPC_STH; - elsif std_match(f_in.insn, "011111---------------1110010110-") then + elsif std_match(f_in.insn, "---------------------1110010110-") then report "PPC_sthbrx"; ppc_insn := PPC_STHBRX; - elsif std_match(f_in.insn, "011111---------------1011010110-") then + elsif std_match(f_in.insn, "---------------------1011010110-") then report "PPC_sthcx"; ppc_insn := PPC_STHCX; - elsif std_match(f_in.insn, "101101--------------------------") then - report "PPC_sthu"; - ppc_insn := PPC_STHU; - elsif std_match(f_in.insn, "011111---------------0110110111-") then + elsif std_match(f_in.insn, "---------------------0110110111-") then report "PPC_sthux"; ppc_insn := PPC_STHUX; - elsif std_match(f_in.insn, "011111---------------0110010111-") then + elsif std_match(f_in.insn, "---------------------0110010111-") then report "PPC_sthx"; ppc_insn := PPC_STHX; - elsif std_match(f_in.insn, "100100--------------------------") then - report "PPC_stw"; - ppc_insn := PPC_STW; - elsif std_match(f_in.insn, "011111---------------1010010110-") then + elsif std_match(f_in.insn, "---------------------1010010110-") then report "PPC_stwbrx"; ppc_insn := PPC_STWBRX; - elsif std_match(f_in.insn, "011111---------------0010010110-") then + elsif std_match(f_in.insn, "---------------------0010010110-") then report "PPC_stwcx"; ppc_insn := PPC_STWCX; - elsif std_match(f_in.insn, "100101--------------------------") then - report "PPC_stwu"; - ppc_insn := PPC_STWU; - elsif std_match(f_in.insn, "011111---------------0010110111-") then + elsif std_match(f_in.insn, "---------------------0010110111-") then report "PPC_stwux"; ppc_insn := PPC_STWUX; - elsif std_match(f_in.insn, "011111---------------0010010111-") then + elsif std_match(f_in.insn, "---------------------0010010111-") then report "PPC_stwx"; ppc_insn := PPC_STWX; - elsif std_match(f_in.insn, "011111---------------0000101000-") then + elsif std_match(f_in.insn, "---------------------0000101000-") then report "PPC_subf"; ppc_insn := PPC_SUBF; - elsif std_match(f_in.insn, "011111---------------0000001000-") then + elsif std_match(f_in.insn, "---------------------0000001000-") then report "PPC_subfc"; ppc_insn := PPC_SUBFC; - elsif std_match(f_in.insn, "011111---------------0010001000-") then + elsif std_match(f_in.insn, "---------------------0010001000-") then report "PPC_subfe"; ppc_insn := PPC_SUBFE; - elsif std_match(f_in.insn, "001000--------------------------") then - report "PPC_subfic"; - ppc_insn := PPC_SUBFIC; - elsif std_match(f_in.insn, "011111---------------0011101000-") then + elsif std_match(f_in.insn, "---------------------0011101000-") then report "PPC_subfme"; ppc_insn := PPC_SUBFME; - elsif std_match(f_in.insn, "011111---------------0011001000-") then + elsif std_match(f_in.insn, "---------------------0011001000-") then report "PPC_subfze"; ppc_insn := PPC_SUBFZE; - elsif std_match(f_in.insn, "011111---------------1001010110-") then + elsif std_match(f_in.insn, "---------------------1001010110-") then report "PPC_sync"; ppc_insn := PPC_SYNC; - elsif std_match(f_in.insn, "011111---------------0001000100-") then + elsif std_match(f_in.insn, "---------------------0001000100-") then report "PPC_td"; ppc_insn := PPC_TD; - elsif std_match(f_in.insn, "000010--------------------------") then - report "PPC_tdi"; - ppc_insn := PPC_TDI; - elsif std_match(f_in.insn, "011111---------------0000000100-") then + elsif std_match(f_in.insn, "---------------------0000000100-") then report "PPC_tw"; ppc_insn := PPC_TW; - elsif std_match(f_in.insn, "000011--------------------------") then - report "PPC_twi"; - ppc_insn := PPC_TWI; - elsif std_match(f_in.insn, "011111---------------0100111100-") then + elsif std_match(f_in.insn, "---------------------0100111100-") then report "PPC_xor"; ppc_insn := PPC_XOR; - elsif std_match(f_in.insn, "011010--------------------------") then - report "PPC_xori"; - ppc_insn := PPC_XORI; - elsif std_match(f_in.insn, "011011--------------------------") then - report "PPC_xoris"; - ppc_insn := PPC_XORIS; - elsif std_match(f_in.insn, "000001---------------0000000011-") then - report "PPC_SIM_CONFIG"; - ppc_insn := PPC_SIM_CONFIG; else report "PPC_illegal"; ppc_insn := PPC_ILLEGAL; end if; + v.decode := decode_op_31_array(ppc_insn); + + elsif majorop = "010011" then + if std_match(f_in.insn, "--------------------------00010-") then + report "PPC_addpcis"; + ppc_insn := PPC_ADDPCIS; + elsif std_match(f_in.insn, "---------------------1000010000-") then + report "PPC_bcctr"; + ppc_insn := PPC_BCCTR; + elsif std_match(f_in.insn, "---------------------0000010000-") then + report "PPC_bclr"; + ppc_insn := PPC_BCLR; + elsif std_match(f_in.insn, "---------------------1000110000-") then + report "PPC_bctar"; + ppc_insn := PPC_BCTAR; + elsif std_match(f_in.insn, "---------------------0100000001-") then + report "PPC_crand"; + ppc_insn := PPC_CRAND; + elsif std_match(f_in.insn, "---------------------0010000001-") then + report "PPC_crandc"; + ppc_insn := PPC_CRANDC; + elsif std_match(f_in.insn, "---------------------0100100001-") then + report "PPC_creqv"; + ppc_insn := PPC_CREQV; + elsif std_match(f_in.insn, "---------------------0011100001-") then + report "PPC_crnand"; + ppc_insn := PPC_CRNAND; + elsif std_match(f_in.insn, "---------------------0000100001-") then + report "PPC_crnor"; + ppc_insn := PPC_CRNOR; + elsif std_match(f_in.insn, "---------------------0111000001-") then + report "PPC_cror"; + ppc_insn := PPC_CROR; + elsif std_match(f_in.insn, "---------------------0110100001-") then + report "PPC_crorc"; + ppc_insn := PPC_CRORC; + elsif std_match(f_in.insn, "---------------------0011000001-") then + report "PPC_crxor"; + ppc_insn := PPC_CRXOR; + elsif std_match(f_in.insn, "---------------------0010010110-") then + report "PPC_isync"; + ppc_insn := PPC_ISYNC; + elsif std_match(f_in.insn, "---------------------0000000000-") then + report "PPC_mcrf"; + ppc_insn := PPC_MCRF; + else + report "PPC_illegal"; + ppc_insn := PPC_ILLEGAL; + end if; + v.decode := decode_op_19_array(ppc_insn); + + elsif majorop = "011110" then + if std_match(f_in.insn, "---------------------------1000-") then + report "PPC_rldcl"; + ppc_insn := PPC_RLDCL; + elsif std_match(f_in.insn, "---------------------------1001-") then + report "PPC_rldcr"; + ppc_insn := PPC_RLDCR; + elsif std_match(f_in.insn, "---------------------------010--") then + report "PPC_rldic"; + ppc_insn := PPC_RLDIC; + elsif std_match(f_in.insn, "---------------------------000--") then + report "PPC_rldicl"; + ppc_insn := PPC_RLDICL; + elsif std_match(f_in.insn, "---------------------------001--") then + report "PPC_rldicr"; + ppc_insn := PPC_RLDICR; + elsif std_match(f_in.insn, "---------------------------011--") then + report "PPC_rldimi"; + ppc_insn := PPC_RLDIMI; + else + report "PPC_illegal"; + ppc_insn := PPC_ILLEGAL; + end if; + v.decode := decode_op_30_array(ppc_insn); + + elsif majorop = "111010" then + v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0)))); + + elsif majorop = "111110" then + v.decode := decode_op_62_array(to_integer(unsigned(f_in.insn(1 downto 0)))); + + elsif std_match(f_in.insn, "01100000000000000000000000000000") then + report "PPC_nop"; + v.decode := nop_instr; + elsif std_match(f_in.insn, "000001---------------0000000011-") then + report "PPC_SIM_CONFIG"; + v.decode := sim_cfg_instr; + elsif std_match(f_in.insn, "000000---------------0100000000-") then + report "PPC_attn"; + v.decode := attn_instr; - v.decode := decode_rom_array(ppc_insn); + else + v.decode := major_decode_rom_array(to_integer(majorop)); end if; if flush_in = '1' then From 00e9f801f664e1240cd43cd73c9881d1c6fa1922 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 29 Sep 2019 16:26:07 +1000 Subject: [PATCH 05/14] decode: Index minor op table with insn bits for opcode 19 This changes the decoding of major opcode 19 from using the ppc_insn_t index to using bits of the instruction word directly. Opcode 19 has a 10-bit minor opcode field (bits 10..1) but the space is sparsely filled. Therefore we index a table of single-bit entries with the 10-bit minor opcode to filter out the illegal minor opcodes, and index a table using just 3 bits -- 5, 3 and 2 -- of the instruction to get the decode entry. This groups together all the instructions in 4 columns of the opcode map as a single entry. That means that mcrf and all the CR logical ops get grouped together, and bcctr, bclr and bctar get grouped together. At present the CR logical ops are not implemented, so their grouping has no impact. The code for bclr and bcctr in execute1 is now common, using a single op, and it now determines the branch address by looking at bit 10 of the instruction word at execute time. Signed-off-by: Paul Mackerras --- decode1.vhdl | 113 +++++++++++++++++++--------------------------- decode_types.vhdl | 5 +- execute1.vhdl | 16 +++---- 3 files changed, 57 insertions(+), 77 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 25bd597..ee5e6eb 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -24,6 +24,8 @@ architecture behaviour of decode1 is subtype major_opcode_t is unsigned(5 downto 0); type major_rom_array_t is array(0 to 63) of decode_rom_t; + type minor_valid_array_t is array(0 to 1023) of std_ulogic; + type op_19_subop_array_t is array(0 to 7) of decode_rom_t; type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; @@ -72,25 +74,42 @@ architecture behaviour of decode1 is others => illegal_inst ); - constant decode_op_19_array : decode_rom_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - PPC_ILLEGAL => (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_ADDPCIS - 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_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_CRAND - --PPC_CRANDC - --PPC_CREQV - --PPC_CRNAND - --PPC_CRNOR - --PPC_CROR - --PPC_CRORC - --PPC_CRXOR - PPC_ISYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MCRF => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - others => decode_rom_init + -- indexed by bits 10..1 of instruction word + constant decode_op_19_valid : minor_valid_array_t := ( + -- addpcis, 5 upper bits are part of constant + 2#0000000010# => '1', 2#0000100010# => '1', 2#0001000010# => '1', 2#0001100010# => '1', 2#0010000010# => '1', 2#0010100010# => '1', 2#0011000010# => '1', 2#0011100010# => '1', + 2#0100000010# => '1', 2#0100100010# => '1', 2#0101000010# => '1', 2#0101100010# => '1', 2#0110000010# => '1', 2#0110100010# => '1', 2#0111000010# => '1', 2#0111100010# => '1', + 2#1000000010# => '1', 2#1000100010# => '1', 2#1001000010# => '1', 2#1001100010# => '1', 2#1010000010# => '1', 2#1010100010# => '1', 2#1011000010# => '1', 2#1011100010# => '1', + 2#1100000010# => '1', 2#1100100010# => '1', 2#1101000010# => '1', 2#1101100010# => '1', 2#1110000010# => '1', 2#1110100010# => '1', 2#1111000010# => '1', 2#1111100010# => '1', + 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#0010010110# => '1', -- isync + 2#0000000000# => '1', -- mcrf + others => '0' + ); + + -- indexed by bits 5, 3, 2 of instruction word + constant decode_op_19_array : op_19_subop_array_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + -- mcrf; cr logical ops not implemented yet + 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + -- addpcis not implemented yet + 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + -- bclr, bcctr, bctar + 2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), + -- isync + 2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + others => illegal_inst ); constant decode_op_30_array : decode_rom_array_t := ( @@ -260,6 +279,7 @@ begin variable v : Decode1ToDecode2Type; variable ppc_insn: ppc_insn_t; variable majorop : major_opcode_t; + variable op_19_bits: std_ulogic_vector(2 downto 0); begin v := r; @@ -615,53 +635,14 @@ begin v.decode := decode_op_31_array(ppc_insn); elsif majorop = "010011" then - if std_match(f_in.insn, "--------------------------00010-") then - report "PPC_addpcis"; - ppc_insn := PPC_ADDPCIS; - elsif std_match(f_in.insn, "---------------------1000010000-") then - report "PPC_bcctr"; - ppc_insn := PPC_BCCTR; - elsif std_match(f_in.insn, "---------------------0000010000-") then - report "PPC_bclr"; - ppc_insn := PPC_BCLR; - elsif std_match(f_in.insn, "---------------------1000110000-") then - report "PPC_bctar"; - ppc_insn := PPC_BCTAR; - elsif std_match(f_in.insn, "---------------------0100000001-") then - report "PPC_crand"; - ppc_insn := PPC_CRAND; - elsif std_match(f_in.insn, "---------------------0010000001-") then - report "PPC_crandc"; - ppc_insn := PPC_CRANDC; - elsif std_match(f_in.insn, "---------------------0100100001-") then - report "PPC_creqv"; - ppc_insn := PPC_CREQV; - elsif std_match(f_in.insn, "---------------------0011100001-") then - report "PPC_crnand"; - ppc_insn := PPC_CRNAND; - elsif std_match(f_in.insn, "---------------------0000100001-") then - report "PPC_crnor"; - ppc_insn := PPC_CRNOR; - elsif std_match(f_in.insn, "---------------------0111000001-") then - report "PPC_cror"; - ppc_insn := PPC_CROR; - elsif std_match(f_in.insn, "---------------------0110100001-") then - report "PPC_crorc"; - ppc_insn := PPC_CRORC; - elsif std_match(f_in.insn, "---------------------0011000001-") then - report "PPC_crxor"; - ppc_insn := PPC_CRXOR; - elsif std_match(f_in.insn, "---------------------0010010110-") then - report "PPC_isync"; - ppc_insn := PPC_ISYNC; - elsif std_match(f_in.insn, "---------------------0000000000-") then - report "PPC_mcrf"; - ppc_insn := PPC_MCRF; - else - report "PPC_illegal"; - ppc_insn := PPC_ILLEGAL; - end if; - v.decode := decode_op_19_array(ppc_insn); + if decode_op_19_valid(to_integer(unsigned(f_in.insn(10 downto 1)))) = '0' then + report "op 19 illegal subcode"; + v.decode := illegal_inst; + else + op_19_bits := f_in.insn(5) & f_in.insn(3) & f_in.insn(2); + v.decode := decode_op_19_array(to_integer(unsigned(op_19_bits))); + report "op 19 sub " & to_hstring(op_19_bits); + end if; elsif majorop = "011110" then if std_match(f_in.insn, "---------------------------1000-") then diff --git a/decode_types.vhdl b/decode_types.vhdl index 1437bf0..aab59cf 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -39,9 +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_BC, - OP_BCCTR, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP, - OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB, + OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC, OP_BCREG, + 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, OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST, diff --git a/execute1.vhdl b/execute1.vhdl index 0d85e71..efbba14 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -120,18 +120,18 @@ begin 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 + when OP_BCREG => + -- bits 10 and 6 distinguish between bclr, bcctr and bctar + if e_in.const1(4-2) = '0' and e_in.insn(10) = '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 <= ctrl.lr(63 downto 2) & "00"; - end if; - when OP_BCCTR => - if ppc_bcctr_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr) = 1 then - f_out.redirect <= '1'; - f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00"; + if e_in.insn(10) = '0' then + f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; + else + f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00"; + end if; end if; when OP_CMPB => result := ppc_cmpb(e_in.read_data1, e_in.read_data2); From 21d3f8a5eddde004174eba43b80a490c3b09e6f7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 29 Sep 2019 16:41:52 +1000 Subject: [PATCH 06/14] decode: Index minor op table with insn bits for opcode 30 This comprises the 64-bit rotate and mask instructions. In order to reduce the table index to 3 bits, we combine rldcl and rdlcr into a single op (OP_RLDCX), and choose the right mask at execute time based on bit 1 of the instruction word. Signed-off-by: Paul Mackerras --- decode1.vhdl | 47 +++++++++++++---------------------------------- decode_types.vhdl | 2 +- execute1.vhdl | 11 ++++++----- 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index ee5e6eb..9b4f2d9 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -26,6 +26,7 @@ architecture behaviour of decode1 is type major_rom_array_t is array(0 to 63) of decode_rom_t; type minor_valid_array_t is array(0 to 1023) of std_ulogic; type op_19_subop_array_t is array(0 to 7) of decode_rom_t; + type op_30_subop_array_t is array(0 to 7) of decode_rom_t; type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; @@ -112,17 +113,16 @@ architecture behaviour of decode1 is others => illegal_inst ); - constant decode_op_30_array : decode_rom_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - PPC_ILLEGAL => (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_RLDCL => (ALU, OP_RLDCL, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDCR => (ALU, OP_RLDCR, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDIC => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDICL => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDICR => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_RLDIMI => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - others => decode_rom_init + constant decode_op_30_array : op_30_subop_array_t := ( + -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op 1 2 3 in out in out len ext 32 sgn pipe + 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + -- rldcl, rldcr + 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + others => illegal_inst ); -- Note: reformat with column -t -o ' ' @@ -280,6 +280,7 @@ begin variable ppc_insn: ppc_insn_t; variable majorop : major_opcode_t; variable op_19_bits: std_ulogic_vector(2 downto 0); + variable op_30_bits: std_ulogic_vector(2 downto 0); begin v := r; @@ -645,29 +646,7 @@ begin end if; elsif majorop = "011110" then - if std_match(f_in.insn, "---------------------------1000-") then - report "PPC_rldcl"; - ppc_insn := PPC_RLDCL; - elsif std_match(f_in.insn, "---------------------------1001-") then - report "PPC_rldcr"; - ppc_insn := PPC_RLDCR; - elsif std_match(f_in.insn, "---------------------------010--") then - report "PPC_rldic"; - ppc_insn := PPC_RLDIC; - elsif std_match(f_in.insn, "---------------------------000--") then - report "PPC_rldicl"; - ppc_insn := PPC_RLDICL; - elsif std_match(f_in.insn, "---------------------------001--") then - report "PPC_rldicr"; - ppc_insn := PPC_RLDICR; - elsif std_match(f_in.insn, "---------------------------011--") then - report "PPC_rldimi"; - ppc_insn := PPC_RLDIMI; - else - report "PPC_illegal"; - ppc_insn := PPC_ILLEGAL; - end if; - v.decode := decode_op_30_array(ppc_insn); + v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 2)))); elsif majorop = "111010" then v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0)))); diff --git a/decode_types.vhdl b/decode_types.vhdl index aab59cf..5421265 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -51,7 +51,7 @@ package decode_types is OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD, - OP_PRTYW, OP_RLDCL, OP_RLDCR, OP_RLDIC, OP_RLDICL, OP_RLDICR, + OP_PRTYW, OP_RLDCX, OP_RLDIC, OP_RLDICL, OP_RLDICR, OP_RLDIMI, OP_RLWIMI, OP_RLWINM, OP_RLWNM, OP_SETB, OP_SLD, OP_SLW, OP_SRAD, OP_SRADI, OP_SRAW, OP_SRAWI, OP_SRD, OP_SRW, OP_SUBF, OP_SUBFE, OP_SUBFME, OP_SYNC, OP_TD, OP_TDI, OP_TW, diff --git a/execute1.vhdl b/execute1.vhdl index efbba14..7b08010 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -274,11 +274,12 @@ begin when OP_PRTYW => result := ppc_prtyw(e_in.read_data1); result_en := 1; - when OP_RLDCL => - result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); - result_en := 1; - when OP_RLDCR => - result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); + when OP_RLDCX => + if e_in.insn(1) = '0' then + result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); + else + result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); + end if; result_en := 1; when OP_RLDICL => result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); From bbae2d1eda63cd1e5aeb2ecf130011c7d3daa34f Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 30 Sep 2019 15:03:06 +1000 Subject: [PATCH 07/14] decode: Index minor op table with insn bits for opcode 31 This changes decode_op_31_array from being indexed by a ppc_insn_t (which is derived from the instruction word by a whole series of if/elsif statements) to being indexed directly by bits 10...1 of the instruction word. With this we no longer need ppc_insn. This then means that the decode1 stage doesn't distinguish between mfcr and mfocrf, or between mtcrf and mtocrf, since those are distinguished by the value in bit 20 of the instruction. To accommodate that, execute1 changes so that the one op value (OP_MFCR) does either the mfcr or the mfocrf behaviour depending on bit 20 of the instruction word; and similarly for mtcrf/mtocrf. Signed-off-by: Paul Mackerras --- decode1.vhdl | 613 ++++++++++++---------------------------------- decode_types.vhdl | 40 +-- execute1.vhdl | 42 ++-- 3 files changed, 184 insertions(+), 511 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 9b4f2d9..d2814bd 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -27,10 +27,9 @@ architecture behaviour of decode1 is type minor_valid_array_t is array(0 to 1023) of std_ulogic; type op_19_subop_array_t is array(0 to 7) of decode_rom_t; type op_30_subop_array_t is array(0 to 7) of decode_rom_t; + type op_31_subop_array_t is array(0 to 1023) of decode_rom_t; type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; - type decode_rom_array_t is array(ppc_insn_t) of decode_rom_t; - constant illegal_inst : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); @@ -126,121 +125,165 @@ architecture behaviour of decode1 is ); -- Note: reformat with column -t -o ' ' - constant decode_op_31_array : decode_rom_array_t := ( + constant decode_op_31_array : op_31_subop_array_t := ( -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl -- op 1 2 3 in out in out len ext 32 sgn pipe - PPC_ILLEGAL => (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_ADD => (ALU, OP_ADD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ADDC => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ADDE => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_ADDEX - --PPC_ADDME - PPC_ADDZE => (ALU, OP_ADDE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_AND => (ALU, OP_AND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ANDC => (ALU, OP_ANDC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_BPERM - PPC_CMP => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_CMPB => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_CMPEQB - PPC_CMPL => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_CMPRB - PPC_CNTLZD => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_CNTLZW => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_CNTTZD => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_CNTTZW => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_DARN - PPC_DCBF => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_DCBST => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_DCBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_DCBTST => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_DCBZ - PPC_DIV => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_EQV => (ALU, OP_EQV, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_EXTSB => (ALU, OP_EXTSB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_EXTSH => (ALU, OP_EXTSH, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_EXTSW => (ALU, OP_EXTSW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_EXTSWSLI - --PPC_ICBI - PPC_ICBT => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_ISEL => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LBARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_LBZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LBZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LDARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_LDBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LDUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LDX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_LHAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LHAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LHZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LHZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWARX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_LWAUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LWAX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWBRX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_LWZUX => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_LWZX => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_MCRXR - --PPC_MCRXRX - PPC_MFCR => (ALU, OP_MFCR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFOCRF => (ALU, OP_MFOCRF, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MFSPR => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MOD => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_MTCRF => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTOCRF => (ALU, OP_MTOCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MTSPR => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_MULHD => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), - PPC_MULHDU => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_MULHW => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), - PPC_MULHWU => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), - PPC_MULLD => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), - PPC_MULLW => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), - PPC_NAND => (ALU, OP_NAND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_NEG => (ALU, OP_NEG, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_NOR => (ALU, OP_NOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_OR => (ALU, OP_OR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_ORC => (ALU, OP_ORC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_POPCNTB => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_POPCNTD => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_POPCNTW => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_PRTYD => (ALU, OP_PRTYD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_PRTYW => (ALU, OP_PRTYW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_SETB - PPC_SLD => (ALU, OP_SLD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SLW => (ALU, OP_SLW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRAD => (ALU, OP_SRAD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRADI => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRAW => (ALU, OP_SRAW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRAWI => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRD => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SRW => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_STBCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), - PPC_STBUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), - PPC_STBX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_STDBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STDCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STDUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_STDX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STHBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STHCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STHUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_STHX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STWBRX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_STWCX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), - PPC_STWUX => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), - PPC_STWX => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_SUBF => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SUBFC => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SUBFE => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - --PPC_SUBFME - PPC_SUBFZE => (ALU, OP_SUBFE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - PPC_SYNC => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - --PPC_TD - PPC_TW => (ALU, OP_TW, RA, RB, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), - PPC_XOR => (ALU, OP_XOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - others => decode_rom_init + 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add + 2#0000001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc + 2#0010001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde + -- 2#--10101010# addex + -- 2#0011101010# addme + 2#0011001010# => (ALU, OP_ADDE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze + 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and + 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc + -- 2#0011111100# bperm + 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp + 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb + -- 2#0011100000# cmpeqb + 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl + -- 2#0011000000# cmprb + 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd + 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw + 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd + 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw + -- 2#1011110011# darn + 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf + 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst + 2#0100010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbt + 2#0011110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbtst + -- 2#1111110110# dcbz + 2#0110001001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdeu + 2#0110001011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divweu + 2#0110101001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divde + 2#0110101011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwe + 2#0111001001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdu + 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu + 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd + 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw + 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv + 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb + 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh + 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw + -- 2#110111101-# extswsli + -- 2#1111010110# icbi + 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt + 2#0000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000110100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx + 2#0001110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux + 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx + 2#0001010100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx + 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx + 2#0000110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux + 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx + 2#0001110100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx + 2#0101110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux + 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax + 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx + 2#0100110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux + 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx + 2#0000010100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx + 2#0101110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux + 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax + 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx + 2#0000110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux + 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx + -- 2#1000000000# mcrxr + -- 2#1001000000# mcrxrx + 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfcr/mfocrf + 2#0101010011# => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfspr + 2#0100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modud + 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw + 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd + 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw + 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf + 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr + 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#0000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + -- next 4 have reserved bit set + 2#1001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#1000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#1001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld + 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw + 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand + 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg + 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor + 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or + 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc + 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb + 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd + 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw + 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd + 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw + -- 2#0010000000# setb + 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld + 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw + 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad + 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw + 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi + 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd + 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 2#1010110110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx + 2#0011110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux + 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx + 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx + 2#0011010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx + 2#0010110101# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux + 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx + 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx + 2#1011010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx + 2#0110110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux + 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx + 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx + 2#0010010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx + 2#0010110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux + 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx + 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf + 2#0000001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc + 2#0010001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfe + -- 2#0011101000# subfme + 2#0011001000# => (ALU, OP_SUBFE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfze + 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync + -- 2#0001000100# td + 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw + 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor + others => illegal_inst ); constant decode_op_58_array : minor_rom_array_2_t := ( @@ -277,7 +320,6 @@ begin decode1_1: process(all) variable v : Decode1ToDecode2Type; - variable ppc_insn: ppc_insn_t; variable majorop : major_opcode_t; variable op_19_bits: std_ulogic_vector(2 downto 0); variable op_30_bits: std_ulogic_vector(2 downto 0); @@ -289,8 +331,6 @@ begin v.insn := f_in.insn; v.stop_mark := f_in.stop_mark; - ppc_insn := PPC_ILLEGAL; - if f_in.valid = '1' then report "Decode insn " & to_hstring(f_in.insn) & " at " & to_hstring(f_in.nia); end if; @@ -298,342 +338,7 @@ begin majorop := unsigned(f_in.insn(31 downto 26)); if majorop = "011111" then -- major opcode 31, lots of things - if std_match(f_in.insn, "---------------------0100001010-") then - report "PPC_add"; - ppc_insn := PPC_ADD; - elsif std_match(f_in.insn, "---------------------0000001010-") then - report "PPC_addc"; - ppc_insn := PPC_ADDC; - elsif std_match(f_in.insn, "---------------------0010001010-") then - report "PPC_adde"; - ppc_insn := PPC_ADDE; - elsif std_match(f_in.insn, "---------------------0010101010-") then - report "PPC_addex"; - ppc_insn := PPC_ADDEX; - elsif std_match(f_in.insn, "---------------------0011101010-") then - report "PPC_addme"; - ppc_insn := PPC_ADDME; - elsif std_match(f_in.insn, "---------------------0011001010-") then - report "PPC_addze"; - ppc_insn := PPC_ADDZE; - elsif std_match(f_in.insn, "---------------------0000011100-") then - report "PPC_and"; - ppc_insn := PPC_AND; - elsif std_match(f_in.insn, "---------------------0000111100-") then - report "PPC_andc"; - ppc_insn := PPC_ANDC; - elsif std_match(f_in.insn, "---------------------0011111100-") then - report "PPC_bperm"; - ppc_insn := PPC_BPERM; - elsif std_match(f_in.insn, "---------------------0000000000-") then - report "PPC_cmp"; - ppc_insn := PPC_CMP; - elsif std_match(f_in.insn, "---------------------0111111100-") then - report "PPC_cmpb"; - ppc_insn := PPC_CMPB; - elsif std_match(f_in.insn, "---------------------0011100000-") then - report "PPC_cmpeqb"; - ppc_insn := PPC_CMPEQB; - elsif std_match(f_in.insn, "---------------------0000100000-") then - report "PPC_cmpl"; - ppc_insn := PPC_CMPL; - elsif std_match(f_in.insn, "---------------------0011000000-") then - report "PPC_cmprb"; - ppc_insn := PPC_CMPRB; - elsif std_match(f_in.insn, "---------------------0000111010-") then - report "PPC_cntlzd"; - ppc_insn := PPC_CNTLZD; - elsif std_match(f_in.insn, "---------------------0000011010-") then - report "PPC_cntlzw"; - ppc_insn := PPC_CNTLZW; - elsif std_match(f_in.insn, "---------------------1000111010-") then - report "PPC_cnttzd"; - ppc_insn := PPC_CNTTZD; - elsif std_match(f_in.insn, "---------------------1000011010-") then - report "PPC_cnttzw"; - ppc_insn := PPC_CNTTZW; - elsif std_match(f_in.insn, "---------------------1011110011-") then - report "PPC_darn"; - ppc_insn := PPC_DARN; - elsif std_match(f_in.insn, "---------------------0001010110-") then - report "PPC_dcbf"; - ppc_insn := PPC_DCBF; - elsif std_match(f_in.insn, "---------------------0000110110-") then - report "PPC_dcbst"; - ppc_insn := PPC_DCBST; - elsif std_match(f_in.insn, "---------------------0100010110-") then - report "PPC_dcbt"; - ppc_insn := PPC_DCBT; - elsif std_match(f_in.insn, "---------------------0011110110-") then - report "PPC_dcbtst"; - ppc_insn := PPC_DCBTST; - elsif std_match(f_in.insn, "---------------------1111110110-") then - report "PPC_dcbz"; - ppc_insn := PPC_DCBZ; - elsif std_match(f_in.insn, "----------------------11--010-1-") then - report "PPC_div"; - ppc_insn := PPC_DIV; - elsif std_match(f_in.insn, "---------------------0100011100-") then - report "PPC_eqv"; - ppc_insn := PPC_EQV; - elsif std_match(f_in.insn, "---------------------1110111010-") then - report "PPC_extsb"; - ppc_insn := PPC_EXTSB; - elsif std_match(f_in.insn, "---------------------1110011010-") then - report "PPC_extsh"; - ppc_insn := PPC_EXTSH; - elsif std_match(f_in.insn, "---------------------1111011010-") then - report "PPC_extsw"; - ppc_insn := PPC_EXTSW; - elsif std_match(f_in.insn, "---------------------110111101--") then - report "PPC_extswsli"; - ppc_insn := PPC_EXTSWSLI; - elsif std_match(f_in.insn, "---------------------1111010110-") then - report "PPC_icbi"; - ppc_insn := PPC_ICBI; - elsif std_match(f_in.insn, "---------------------0000010110-") then - report "PPC_icbt"; - ppc_insn := PPC_ICBT; - elsif std_match(f_in.insn, "--------------------------01111-") then - report "PPC_isel"; - ppc_insn := PPC_ISEL; - elsif std_match(f_in.insn, "---------------------0000110100-") then - report "PPC_lbarx"; - ppc_insn := PPC_LBARX; - elsif std_match(f_in.insn, "---------------------0001110111-") then - report "PPC_lbzux"; - ppc_insn := PPC_LBZUX; - elsif std_match(f_in.insn, "---------------------0001010111-") then - report "PPC_lbzx"; - ppc_insn := PPC_LBZX; - elsif std_match(f_in.insn, "---------------------0001010100-") then - report "PPC_ldarx"; - ppc_insn := PPC_LDARX; - elsif std_match(f_in.insn, "---------------------1000010100-") then - report "PPC_ldbrx"; - ppc_insn := PPC_LDBRX; - elsif std_match(f_in.insn, "---------------------0000110101-") then - report "PPC_ldux"; - ppc_insn := PPC_LDUX; - elsif std_match(f_in.insn, "---------------------0000010101-") then - report "PPC_ldx"; - ppc_insn := PPC_LDX; - elsif std_match(f_in.insn, "---------------------0001110100-") then - report "PPC_lharx"; - ppc_insn := PPC_LHARX; - elsif std_match(f_in.insn, "---------------------0101110111-") then - report "PPC_lhaux"; - ppc_insn := PPC_LHAUX; - elsif std_match(f_in.insn, "---------------------0101010111-") then - report "PPC_lhax"; - ppc_insn := PPC_LHAX; - elsif std_match(f_in.insn, "---------------------1100010110-") then - report "PPC_lhbrx"; - ppc_insn := PPC_LHBRX; - elsif std_match(f_in.insn, "---------------------0100110111-") then - report "PPC_lhzux"; - ppc_insn := PPC_LHZUX; - elsif std_match(f_in.insn, "---------------------0100010111-") then - report "PPC_lhzx"; - ppc_insn := PPC_LHZX; - elsif std_match(f_in.insn, "---------------------0000010100-") then - report "PPC_lwarx"; - ppc_insn := PPC_LWARX; - elsif std_match(f_in.insn, "---------------------0101110101-") then - report "PPC_lwaux"; - ppc_insn := PPC_LWAUX; - elsif std_match(f_in.insn, "---------------------0101010101-") then - report "PPC_lwax"; - ppc_insn := PPC_LWAX; - elsif std_match(f_in.insn, "---------------------1000010110-") then - report "PPC_lwbrx"; - ppc_insn := PPC_LWBRX; - elsif std_match(f_in.insn, "---------------------0000110111-") then - report "PPC_lwzux"; - ppc_insn := PPC_LWZUX; - elsif std_match(f_in.insn, "---------------------0000010111-") then - report "PPC_lwzx"; - ppc_insn := PPC_LWZX; - elsif std_match(f_in.insn, "---------------------1000000000-") then - report "PPC_mcrxr"; - ppc_insn := PPC_MCRXR; - elsif std_match(f_in.insn, "---------------------1001000000-") then - report "PPC_mcrxrx"; - ppc_insn := PPC_MCRXRX; - elsif std_match(f_in.insn, "-----------0---------0000010011-") then - report "PPC_mfcr"; - ppc_insn := PPC_MFCR; - elsif std_match(f_in.insn, "-----------1---------0000010011-") then - report "PPC_mfocrf"; - ppc_insn := PPC_MFOCRF; - elsif std_match(f_in.insn, "---------------------0101010011-") then - report "PPC_mfspr"; - ppc_insn := PPC_MFSPR; - elsif std_match(f_in.insn, "----------------------1000010-1-") then - report "PPC_mod"; - ppc_insn := PPC_MOD; - elsif std_match(f_in.insn, "-----------0---------0010010000-") then - report "PPC_mtcrf"; - ppc_insn := PPC_MTCRF; - elsif std_match(f_in.insn, "-----------1---------0010010000-") then - report "PPC_mtocrf"; - ppc_insn := PPC_MTOCRF; - elsif std_match(f_in.insn, "---------------------0111010011-") then - report "PPC_mtspr"; - ppc_insn := PPC_MTSPR; - elsif std_match(f_in.insn, "----------------------001001001-") then - report "PPC_mulhd"; - ppc_insn := PPC_MULHD; - elsif std_match(f_in.insn, "----------------------000001001-") then - report "PPC_mulhdu"; - ppc_insn := PPC_MULHDU; - elsif std_match(f_in.insn, "----------------------001001011-") then - report "PPC_mulhw"; - ppc_insn := PPC_MULHW; - elsif std_match(f_in.insn, "----------------------000001011-") then - report "PPC_mulhwu"; - ppc_insn := PPC_MULHWU; - elsif std_match(f_in.insn, "---------------------0011101001-") then - report "PPC_mulld"; - ppc_insn := PPC_MULLD; - elsif std_match(f_in.insn, "---------------------0011101011-") then - report "PPC_mullw"; - ppc_insn := PPC_MULLW; - elsif std_match(f_in.insn, "---------------------0111011100-") then - report "PPC_nand"; - ppc_insn := PPC_NAND; - elsif std_match(f_in.insn, "---------------------0001101000-") then - report "PPC_neg"; - ppc_insn := PPC_NEG; - elsif std_match(f_in.insn, "---------------------0001111100-") then - report "PPC_nor"; - ppc_insn := PPC_NOR; - elsif std_match(f_in.insn, "---------------------0110111100-") then - report "PPC_or"; - ppc_insn := PPC_OR; - elsif std_match(f_in.insn, "---------------------0110011100-") then - report "PPC_orc"; - ppc_insn := PPC_ORC; - -- Has to be before ori - elsif std_match(f_in.insn, "---------------------0001111010-") then - report "PPC_popcntb"; - ppc_insn := PPC_POPCNTB; - elsif std_match(f_in.insn, "---------------------0111111010-") then - report "PPC_popcntd"; - ppc_insn := PPC_POPCNTD; - elsif std_match(f_in.insn, "---------------------0101111010-") then - report "PPC_popcntw"; - ppc_insn := PPC_POPCNTW; - elsif std_match(f_in.insn, "---------------------0010111010-") then - report "PPC_prtyd"; - ppc_insn := PPC_PRTYD; - elsif std_match(f_in.insn, "---------------------0010011010-") then - report "PPC_prtyw"; - ppc_insn := PPC_PRTYW; - elsif std_match(f_in.insn, "---------------------0010000000-") then - report "PPC_setb"; - ppc_insn := PPC_SETB; - elsif std_match(f_in.insn, "---------------------0000011011-") then - report "PPC_sld"; - ppc_insn := PPC_SLD; - elsif std_match(f_in.insn, "---------------------0000011000-") then - report "PPC_slw"; - ppc_insn := PPC_SLW; - elsif std_match(f_in.insn, "---------------------1100011010-") then - report "PPC_srad"; - ppc_insn := PPC_SRAD; - elsif std_match(f_in.insn, "---------------------110011101--") then - report "PPC_sradi"; - ppc_insn := PPC_SRADI; - elsif std_match(f_in.insn, "---------------------1100011000-") then - report "PPC_sraw"; - ppc_insn := PPC_SRAW; - elsif std_match(f_in.insn, "---------------------1100111000-") then - report "PPC_srawi"; - ppc_insn := PPC_SRAWI; - elsif std_match(f_in.insn, "---------------------1000011011-") then - report "PPC_srd"; - ppc_insn := PPC_SRD; - elsif std_match(f_in.insn, "---------------------1000011000-") then - report "PPC_srw"; - ppc_insn := PPC_SRW; - elsif std_match(f_in.insn, "---------------------1010110110-") then - report "PPC_stbcx"; - ppc_insn := PPC_STBCX; - elsif std_match(f_in.insn, "---------------------0011110111-") then - report "PPC_stbux"; - ppc_insn := PPC_STBUX; - elsif std_match(f_in.insn, "---------------------0011010111-") then - report "PPC_stbx"; - ppc_insn := PPC_STBX; - elsif std_match(f_in.insn, "---------------------1010010100-") then - report "PPC_stdbrx"; - ppc_insn := PPC_STDBRX; - elsif std_match(f_in.insn, "---------------------0011010110-") then - report "PPC_stdcx"; - ppc_insn := PPC_STDCX; - elsif std_match(f_in.insn, "---------------------0010110101-") then - report "PPC_stdux"; - ppc_insn := PPC_STDUX; - elsif std_match(f_in.insn, "---------------------0010010101-") then - report "PPC_stdx"; - ppc_insn := PPC_STDX; - elsif std_match(f_in.insn, "---------------------1110010110-") then - report "PPC_sthbrx"; - ppc_insn := PPC_STHBRX; - elsif std_match(f_in.insn, "---------------------1011010110-") then - report "PPC_sthcx"; - ppc_insn := PPC_STHCX; - elsif std_match(f_in.insn, "---------------------0110110111-") then - report "PPC_sthux"; - ppc_insn := PPC_STHUX; - elsif std_match(f_in.insn, "---------------------0110010111-") then - report "PPC_sthx"; - ppc_insn := PPC_STHX; - elsif std_match(f_in.insn, "---------------------1010010110-") then - report "PPC_stwbrx"; - ppc_insn := PPC_STWBRX; - elsif std_match(f_in.insn, "---------------------0010010110-") then - report "PPC_stwcx"; - ppc_insn := PPC_STWCX; - elsif std_match(f_in.insn, "---------------------0010110111-") then - report "PPC_stwux"; - ppc_insn := PPC_STWUX; - elsif std_match(f_in.insn, "---------------------0010010111-") then - report "PPC_stwx"; - ppc_insn := PPC_STWX; - elsif std_match(f_in.insn, "---------------------0000101000-") then - report "PPC_subf"; - ppc_insn := PPC_SUBF; - elsif std_match(f_in.insn, "---------------------0000001000-") then - report "PPC_subfc"; - ppc_insn := PPC_SUBFC; - elsif std_match(f_in.insn, "---------------------0010001000-") then - report "PPC_subfe"; - ppc_insn := PPC_SUBFE; - elsif std_match(f_in.insn, "---------------------0011101000-") then - report "PPC_subfme"; - ppc_insn := PPC_SUBFME; - elsif std_match(f_in.insn, "---------------------0011001000-") then - report "PPC_subfze"; - ppc_insn := PPC_SUBFZE; - elsif std_match(f_in.insn, "---------------------1001010110-") then - report "PPC_sync"; - ppc_insn := PPC_SYNC; - elsif std_match(f_in.insn, "---------------------0001000100-") then - report "PPC_td"; - ppc_insn := PPC_TD; - elsif std_match(f_in.insn, "---------------------0000000100-") then - report "PPC_tw"; - ppc_insn := PPC_TW; - elsif std_match(f_in.insn, "---------------------0100111100-") then - report "PPC_xor"; - ppc_insn := PPC_XOR; - else - report "PPC_illegal"; - ppc_insn := PPC_ILLEGAL; - end if; - v.decode := decode_op_31_array(ppc_insn); + v.decode := decode_op_31_array(to_integer(unsigned(f_in.insn(10 downto 1)))); elsif majorop = "010011" then if decode_op_19_valid(to_integer(unsigned(f_in.insn(10 downto 1)))) = '0' then diff --git a/decode_types.vhdl b/decode_types.vhdl index 5421265..b5989ce 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -2,42 +2,6 @@ library ieee; use ieee.std_logic_1164.all; 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_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, - PPC_CROR, PPC_CRORC, PPC_CRXOR, PPC_DARN, PPC_DCBF, PPC_DCBST, - PPC_DCBT, PPC_DCBTST, PPC_DCBZ, PPC_DIV, - PPC_EQV, PPC_EXTSB, PPC_EXTSH, PPC_EXTSW, - PPC_EXTSWSLI, PPC_ICBI, PPC_ICBT, PPC_ISEL, PPC_ISYNC, - PPC_LBARX, PPC_LBZ, PPC_LBZU, PPC_LBZUX, PPC_LBZX, PPC_LD, - PPC_LDARX, PPC_LDBRX, PPC_LDU, PPC_LDUX, PPC_LDX, PPC_LHA, - PPC_LHARX, PPC_LHAU, PPC_LHAUX, PPC_LHAX, PPC_LHBRX, PPC_LHZ, - PPC_LHZU, PPC_LHZUX, PPC_LHZX, PPC_LWA, PPC_LWARX, PPC_LWAUX, - PPC_LWAX, PPC_LWBRX, PPC_LWZ, PPC_LWZU, PPC_LWZUX, PPC_LWZX, - PPC_MADDHD, PPC_MADDHDU, PPC_MADDLD, PPC_MCRF, PPC_MCRXR, - PPC_MCRXRX, PPC_MFCR, PPC_MFOCRF, PPC_MFSPR, PPC_MFTB, - PPC_MOD, PPC_MTCRF, - PPC_MFCTR, PPC_MTCTR, PPC_MFLR, PPC_MTLR, PPC_MTOCRF, - PPC_MTSPR, PPC_MULHD, PPC_MULHDU, PPC_MULHW, PPC_MULHWU, - PPC_MULLD, PPC_MULLI, PPC_MULLW, PPC_NAND, PPC_NEG, PPC_NOR, PPC_NOP, - PPC_OR, PPC_ORC, PPC_ORI, PPC_ORIS, PPC_POPCNTB, PPC_POPCNTD, - PPC_POPCNTW, PPC_PRTYD, PPC_PRTYW, PPC_RLDCL, PPC_RLDCR, - PPC_RLDIC, PPC_RLDICL, PPC_RLDICR, PPC_RLDIMI, PPC_RLWIMI, - PPC_RLWINM, PPC_RLWNM, PPC_SETB, PPC_SLD, PPC_SLW, PPC_SRAD, - PPC_SRADI, PPC_SRAW, PPC_SRAWI, PPC_SRD, PPC_SRW, PPC_STB, - PPC_STBCX, PPC_STBU, PPC_STBUX, PPC_STBX, PPC_STD, PPC_STDBRX, - PPC_STDCX, PPC_STDU, PPC_STDUX, PPC_STDX, PPC_STH, PPC_STHBRX, - PPC_STHCX, PPC_STHU, PPC_STHUX, PPC_STHX, PPC_STW, PPC_STWBRX, - PPC_STWCX, PPC_STWU, PPC_STWUX, PPC_STWX, PPC_SUBF, PPC_SUBFC, - PPC_SUBFE, PPC_SUBFIC, PPC_SUBFME, PPC_SUBFZE, PPC_SYNC, PPC_TD, - PPC_TDI, PPC_TW, PPC_TWI, PPC_XOR, PPC_XORI, PPC_XORIS, - 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_BC, OP_BCREG, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB, @@ -47,8 +11,8 @@ package decode_types is OP_DCBZ, OP_DIV, OP_EQV, OP_EXTSB, OP_EXTSH, OP_EXTSW, OP_EXTSWSLI, OP_ICBI, OP_ICBT, OP_ISEL, OP_ISYNC, OP_LOAD, OP_STORE, OP_MADDHD, OP_MADDHDU, OP_MADDLD, OP_MCRF, - OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFOCRF, OP_MFSPR, OP_MOD, - OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64, + OP_MCRXR, OP_MCRXRX, OP_MFCR, OP_MFSPR, OP_MOD, + OP_MTCRF, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD, OP_PRTYW, OP_RLDCX, OP_RLDIC, OP_RLDICL, OP_RLDICR, diff --git a/execute1.vhdl b/execute1.vhdl index 7b08010..72fcebe 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -215,28 +215,32 @@ begin result_en := 1; end if; when OP_MFCR => - result := x"00000000" & e_in.cr; - result_en := 1; - when OP_MFOCRF => - crnum := fxm_to_num(e_in.const1(7 downto 0)); - result := (others => '0'); - for i in 0 to 7 loop - lo := (7-i)*4; - hi := lo + 3; - if crnum = i then - result(hi downto lo) := e_in.cr(hi downto lo); - end if; - end loop; + if e_in.insn(20) = '0' then + -- mfcr + result := x"00000000" & e_in.cr; + else + -- mfocrf + crnum := fxm_to_num(e_in.const1(7 downto 0)); + result := (others => '0'); + for i in 0 to 7 loop + lo := (7-i)*4; + hi := lo + 3; + if crnum = i then + result(hi downto lo) := e_in.cr(hi downto lo); + end if; + end loop; + end if; result_en := 1; when OP_MTCRF => v.e.write_cr_enable := '1'; - v.e.write_cr_mask := e_in.const1(7 downto 0); - v.e.write_cr_data := e_in.read_data1(31 downto 0); - when OP_MTOCRF => - v.e.write_cr_enable := '1'; - -- We require one hot priority encoding here - crnum := fxm_to_num(e_in.const1(7 downto 0)); - v.e.write_cr_mask := num_to_fxm(crnum); + if e_in.insn(20) = '0' then + -- mtcrf + v.e.write_cr_mask := e_in.const1(7 downto 0); + else + -- mtocrf: We require one hot priority encoding here + crnum := fxm_to_num(e_in.const1(7 downto 0)); + v.e.write_cr_mask := num_to_fxm(crnum); + end if; v.e.write_cr_data := e_in.read_data1(31 downto 0); when OP_MTSPR => if std_match(e_in.insn(20 downto 11), "0100100000") then From 143d0ae9e402f209e1f1a5dc345cfa7e93137bba Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 1 Oct 2019 15:49:07 +1000 Subject: [PATCH 08/14] decode: Fix larx/stcx instructions to use RA_OR_ZERO not RA The l?arx and st?cx. instructions are defined to use the normal indexed mode address calculations, i.e. (RA|0) + RB. Fix their entries in the decode table to say RA_OR_ZERO rather than RA. Signed-off-by: Paul Mackerras --- decode1.vhdl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index d2814bd..8ac989a 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -199,20 +199,20 @@ architecture behaviour of decode1 is 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0000110100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx + 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx 2#0001110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx - 2#0001010100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx + 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx 2#0000110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx - 2#0001110100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx + 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx 2#0101110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx 2#0100110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx - 2#0000010100# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx + 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx 2#0101110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx @@ -259,19 +259,19 @@ architecture behaviour of decode1 is 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw - 2#1010110110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx + 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx 2#0011110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx - 2#0011010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx + 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx 2#0010110101# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx - 2#1011010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx + 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx 2#0110110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx - 2#0010010110# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx + 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx 2#0010110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf From 58b06eb5f35dbb274510e93874110361dbd74715 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 2 Oct 2019 22:21:09 +1000 Subject: [PATCH 09/14] decode: Remove const fields from decode_rom_t The const* fields of decode_rom_t drove multiplexers in decode2 that picked out various instruction fields and put them into the const* fields of the Decode2ToExecute1Type record, from where they were used in execute1. However, the code in execute1 can just as easily use the appropriate fields of the original instruction word, since that is now available in execute1. This therefore changes the code to do that, resulting in smaller decode tables. Suggested-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- common.vhdl | 3 - decode1.vhdl | 408 +++++++++++++++++++++++----------------------- decode2.vhdl | 57 ------- decode_types.vhdl | 10 +- execute1.vhdl | 85 +++++++--- 5 files changed, 265 insertions(+), 298 deletions(-) diff --git a/common.vhdl b/common.vhdl index 8b1d4cf..4966f2d 100644 --- a/common.vhdl +++ b/common.vhdl @@ -52,9 +52,6 @@ package common is read_reg2: std_ulogic_vector(4 downto 0); read_data1: std_ulogic_vector(63 downto 0); read_data2: std_ulogic_vector(63 downto 0); - const1: std_ulogic_vector(7 downto 0); - const2: std_ulogic_vector(5 downto 0); - const3: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 8ac989a..3ac7e71 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -31,46 +31,46 @@ architecture behaviour of decode1 is type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; constant illegal_inst : decode_rom_t := - (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); constant major_decode_rom_array : major_rom_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - 12 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic - 13 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. - 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi - 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis - 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. - 29 => (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'), -- andis. - 18 => (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'), -- b - 16 => (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'), -- bc - 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi - 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli - 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz - 35 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu - 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha - 43 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau - 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz - 41 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu - 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz - 33 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwz - 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli - 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori - 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris - 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi - 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, SH32, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm - 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, NONE, MB32, ME32, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm - 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb - 39 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu - 44 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth - 45 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu - 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw - 37 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu - 8 => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic - 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe + 12 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic + 13 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. + 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi + 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis + 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. + 29 => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. + 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- b + 16 => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- bc + 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi + 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli + 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz + 35 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu + 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha + 43 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau + 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz + 41 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu + 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz + 33 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwz + 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli + 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori + 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris + 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi + 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm + 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb + 39 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu + 44 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth + 45 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu + 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw + 37 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu + 8 => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic + 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi --PPC_TWI 3 - 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori - 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris + 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori + 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris others => illegal_inst ); @@ -99,213 +99,213 @@ architecture behaviour of decode1 is -- indexed by bits 5, 3, 2 of instruction word constant decode_op_19_array : op_19_subop_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe -- mcrf; cr logical ops not implemented yet - 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, BF, BFA, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addpcis not implemented yet - 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- bclr, bcctr, bctar - 2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, BO, BI, BH, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), + 2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- isync - 2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + 2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), others => illegal_inst ); constant decode_op_30_array : op_30_subop_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, SH, ME, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, SH, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe + 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcl, rldcr - 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, NONE, MB, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), others => illegal_inst ); -- Note: reformat with column -t -o ' ' constant decode_op_31_array : op_31_subop_array_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add - 2#0000001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc - 2#0010001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe + 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add + 2#0000001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc + 2#0010001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde -- 2#--10101010# addex -- 2#0011101010# addme - 2#0011001010# => (ALU, OP_ADDE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze - 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and - 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc + 2#0011001010# => (ALU, OP_ADDE, RA, NONE, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze + 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and + 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc -- 2#0011111100# bperm - 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp - 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb + 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp + 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb -- 2#0011100000# cmpeqb - 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, BF, L, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl + 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl -- 2#0011000000# cmprb - 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd - 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw - 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd - 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw + 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd + 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw + 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd + 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw -- 2#1011110011# darn - 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf - 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst - 2#0100010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbt - 2#0011110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbtst + 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf + 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst + 2#0100010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbt + 2#0011110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbtst -- 2#1111110110# dcbz - 2#0110001001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdeu - 2#0110001011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divweu - 2#0110101001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divde - 2#0110101011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwe - 2#0111001001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdu - 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu - 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd - 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw - 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv - 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb - 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh - 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw + 2#0110001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdeu + 2#0110001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divweu + 2#0110101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divde + 2#0110101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwe + 2#0111001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdu + 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu + 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd + 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw + 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv + 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb + 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh + 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw -- 2#110111101-# extswsli -- 2#1111010110# icbi - 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt - 2#0000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, BC, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx - 2#0001110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux - 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx - 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx - 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx - 2#0000110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux - 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx - 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx - 2#0101110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux - 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax - 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx - 2#0100110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux - 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx - 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx - 2#0101110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux - 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax - 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx - 2#0000110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux - 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx + 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt + 2#0000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx + 2#0001110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux + 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx + 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx + 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx + 2#0000110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux + 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx + 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx + 2#0101110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux + 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax + 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx + 2#0100110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux + 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx + 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx + 2#0101110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux + 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax + 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx + 2#0000110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux + 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx -- 2#1000000000# mcrxr -- 2#1001000000# mcrxrx - 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, FXM, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfcr/mfocrf - 2#0101010011# => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfspr - 2#0100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modud - 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw - 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd - 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw - 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, FXM, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf - 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr - 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd - 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu - 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw - 2#0000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfcr/mfocrf + 2#0101010011# => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfspr + 2#0100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modud + 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw + 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd + 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw + 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf + 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr + 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#0000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu -- next 4 have reserved bit set - 2#1001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd - 2#1000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu - 2#1001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw - 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu - 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld - 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw - 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand - 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg - 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor - 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or - 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc - 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb - 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd - 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw - 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd - 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw + 2#1001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#1000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#1001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld + 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw + 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand + 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg + 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor + 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or + 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc + 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb + 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd + 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw + 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd + 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw -- 2#0010000000# setb - 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld - 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw - 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad - 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw - 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, SH, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi - 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd - 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw - 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx - 2#0011110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux - 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx - 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx - 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx - 2#0010110101# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux - 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx - 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx - 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx - 2#0110110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux - 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx - 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx - 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx - 2#0010110111# => (LDST, OP_STORE, RA, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux - 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx - 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf - 2#0000001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc - 2#0010001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfe + 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld + 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw + 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad + 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw + 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi + 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd + 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx + 2#0011110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux + 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx + 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx + 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx + 2#0010110101# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux + 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx + 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx + 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx + 2#0110110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux + 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx + 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx + 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx + 2#0010110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux + 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx + 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf + 2#0000001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc + 2#0010001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfe -- 2#0011101000# subfme - 2#0011001000# => (ALU, OP_SUBFE, RA, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfze - 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync + 2#0011001000# => (ALU, OP_SUBFE, RA, NONE, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfze + 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync -- 2#0001000100# td - 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, TOO, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw - 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor + 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw + 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor others => illegal_inst ); constant decode_op_58_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld - 1 => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu - 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe + 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld + 1 => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu + 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa others => decode_rom_init ); constant decode_op_62_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out const const const CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op 1 2 3 in out in out len ext 32 sgn pipe - 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std - 1 => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, NONE, NONE, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu + -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out in out len ext 32 sgn pipe + 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std + 1 => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu others => decode_rom_init ); - constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); - constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); - constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); begin decode1_0: process(clk) diff --git a/decode2.vhdl b/decode2.vhdl index 2b816a7..593a025 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -124,60 +124,6 @@ architecture behaviour of decode2 is end case; end; - function decode_const_a (t : constant_a_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is - begin - case t is - when SH => - return "00" & insn_sh(insn_in); - when SH32 => - return "000" & insn_sh32(insn_in); - when FXM => - return insn_fxm(insn_in); - when BO => - return "000" & insn_bo(insn_in); - when BF => - return "00000" & insn_bf(insn_in); - when TOO => - return "000" & insn_to(insn_in); - when BC => - return "000" & insn_bc(insn_in); - when NONE => - return "00000000"; - end case; - end; - - function decode_const_b (t : constant_b_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is - begin - case t is - when MB => - return insn_mb(insn_in); - when ME => - return insn_me(insn_in); - when MB32 => - return "0" & insn_mb32(insn_in); - when BI => - return "0" & insn_bi(insn_in); - when L => - return "00000" & insn_l(insn_in); - when BFA => - return "000" & insn_bfa(insn_in); - when NONE => - return "000000"; - end case; - end; - - function decode_const_c (t : constant_c_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is - begin - case t is - when ME32 => - return insn_me32(insn_in); - when BH => - return "000" & insn_bh(insn_in); - when NONE => - return "00000"; - end case; - end; - function decode_rc (t : rc_t; insn_in : std_ulogic_vector(31 downto 0)) return std_ulogic is begin case t is @@ -267,9 +213,6 @@ begin if d_in.decode.lr = '1' then v.e.lr := insn_lk(d_in.insn); end if; - v.e.const1 := decode_const_a(d_in.decode.const_a, d_in.insn); - v.e.const2 := decode_const_b(d_in.decode.const_b, d_in.insn); - v.e.const3 := decode_const_c(d_in.decode.const_c, d_in.insn); v.e.insn := d_in.insn; -- multiply unit diff --git a/decode_types.vhdl b/decode_types.vhdl index b5989ce..03eb0c3 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -25,9 +25,6 @@ package decode_types is type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); - type constant_a_t is (NONE, SH, SH32, FXM, BO, BF, TOO, BC); - type constant_b_t is (NONE, MB, ME, MB32, BI, L, BFA); - type constant_c_t is (NONE, ME32, BH); type rc_t is (NONE, ONE, RC); constant SH_OFFSET : integer := 0; @@ -59,10 +56,6 @@ package decode_types is input_reg_c : input_reg_c_t; output_reg_a : output_reg_a_t; - const_a : constant_a_t; - const_b : constant_b_t; - const_c : constant_c_t; - input_cr : std_ulogic; output_cr : std_ulogic; @@ -88,8 +81,7 @@ package decode_types is constant decode_rom_init : decode_rom_t := (unit => NONE, insn_type => OP_ILLEGAL, input_reg_a => NONE, input_reg_b => NONE, input_reg_c => NONE, - output_reg_a => NONE, const_a => NONE, const_b => NONE, - const_c => NONE, input_cr => '0', output_cr => '0', + output_reg_a => NONE, input_cr => '0', output_cr => '0', input_carry => '0', output_carry => '0', length => NONE, byte_reverse => '0', sign_extend => '0', update => '0', reserve => '0', mul_32bit => '0', diff --git a/execute1.vhdl b/execute1.vhdl index 72fcebe..cb86e3e 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -59,6 +59,11 @@ begin variable crnum : integer; variable scrnum : integer; variable lo, hi : integer; + variable sh, mb, me : std_ulogic_vector(5 downto 0); + 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 l : std_ulogic; begin result := (others => '0'); result_with_carry := (others => '0'); @@ -109,10 +114,12 @@ begin 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 + bo := insn_bo(e_in.insn); + bi := insn_bi(e_in.insn); + if bo(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 + if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then f_out.redirect <= '1'; if (insn_aa(e_in.insn)) then f_out.redirect_nia <= std_ulogic_vector(signed(e_in.read_data2)); @@ -122,10 +129,12 @@ begin end if; when OP_BCREG => -- bits 10 and 6 distinguish between bclr, bcctr and bctar - if e_in.const1(4-2) = '0' and e_in.insn(10) = '0' then + bo := insn_bo(e_in.insn); + bi := insn_bi(e_in.insn); + if bo(4-2) = '0' and e_in.insn(10) = '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 + if ppc_bc_taken(bo, bi, e_in.cr, ctrl.ctr) = 1 then f_out.redirect <= '1'; if e_in.insn(10) = '0' then f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; @@ -137,22 +146,26 @@ begin result := ppc_cmpb(e_in.read_data1, e_in.read_data2); result_en := 1; when OP_CMP => + bf := insn_bf(e_in.insn); + l := insn_l(e_in.insn); v.e.write_cr_enable := '1'; - crnum := to_integer(unsigned(e_in.const1(2 downto 0))); + crnum := to_integer(unsigned(bf)); v.e.write_cr_mask := num_to_fxm(crnum); for i in 0 to 7 loop lo := i*4; hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmp(e_in.const2(0), 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); end loop; when OP_CMPL => + bf := insn_bf(e_in.insn); + l := insn_l(e_in.insn); v.e.write_cr_enable := '1'; - crnum := to_integer(unsigned(e_in.const1(2 downto 0))); + crnum := to_integer(unsigned(bf)); v.e.write_cr_mask := num_to_fxm(crnum); for i in 0 to 7 loop lo := i*4; hi := lo + 3; - v.e.write_cr_data(hi downto lo) := ppc_cmpl(e_in.const2(0), 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); end loop; when OP_CNTLZW => result := ppc_cntlzw(e_in.read_data1); @@ -179,7 +192,7 @@ begin result := ppc_eqv(e_in.read_data1, e_in.read_data2); result_en := 1; when OP_ISEL => - crnum := to_integer(unsigned(e_in.const1)); + crnum := to_integer(unsigned(insn_bc(e_in.insn))); if e_in.cr(31-crnum) = '1' then result := e_in.read_data1; else @@ -187,9 +200,11 @@ 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(e_in.const1(2 downto 0))); - scrnum := to_integer(unsigned(e_in.const2(2 downto 0))); + 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; @@ -220,7 +235,7 @@ begin result := x"00000000" & e_in.cr; else -- mfocrf - crnum := fxm_to_num(e_in.const1(7 downto 0)); + crnum := fxm_to_num(insn_fxm(e_in.insn)); result := (others => '0'); for i in 0 to 7 loop lo := (7-i)*4; @@ -235,10 +250,10 @@ begin v.e.write_cr_enable := '1'; if e_in.insn(20) = '0' then -- mtcrf - v.e.write_cr_mask := e_in.const1(7 downto 0); + v.e.write_cr_mask := insn_fxm(e_in.insn); else -- mtocrf: We require one hot priority encoding here - crnum := fxm_to_num(e_in.const1(7 downto 0)); + crnum := fxm_to_num(insn_fxm(e_in.insn)); v.e.write_cr_mask := num_to_fxm(crnum); end if; v.e.write_cr_data := e_in.read_data1(31 downto 0); @@ -279,32 +294,50 @@ begin result := ppc_prtyw(e_in.read_data1); result_en := 1; when OP_RLDCX => + -- note rldcl mb field and rldcr me field are in the same place + mb := insn_mb(e_in.insn); if e_in.insn(1) = '0' then - result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); + result := ppc_rldcl(e_in.read_data1, e_in.read_data2, mb); else - result := ppc_rldcr(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); + result := ppc_rldcr(e_in.read_data1, e_in.read_data2, mb); end if; result_en := 1; when OP_RLDICL => - result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); + sh := insn_sh(e_in.insn); + mb := insn_mb(e_in.insn); + result := ppc_rldicl(e_in.read_data1, sh, mb); result_en := 1; when OP_RLDICR => - result := ppc_rldicr(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); + sh := insn_sh(e_in.insn); + me := insn_me(e_in.insn); + result := ppc_rldicr(e_in.read_data1, sh, me); result_en := 1; when OP_RLWNM => - result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, e_in.const2(4 downto 0), e_in.const3(4 downto 0)); + mb32 := insn_mb32(e_in.insn); + me32 := insn_me32(e_in.insn); + result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, mb32, me32); result_en := 1; when OP_RLWINM => - result := ppc_rlwinm(e_in.read_data1, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0)); + sh32 := insn_sh32(e_in.insn); + mb32 := insn_mb32(e_in.insn); + me32 := insn_me32(e_in.insn); + result := ppc_rlwinm(e_in.read_data1, sh32, mb32, me32); result_en := 1; when OP_RLDIC => - result := ppc_rldic(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); + sh := insn_sh(e_in.insn); + mb := insn_mb(e_in.insn); + result := ppc_rldic(e_in.read_data1, sh, mb); result_en := 1; when OP_RLDIMI => - result := ppc_rldimi(e_in.read_data1, e_in.read_data2, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); + sh := insn_sh(e_in.insn); + mb := insn_mb(e_in.insn); + result := ppc_rldimi(e_in.read_data1, e_in.read_data2, sh, mb); result_en := 1; when OP_RLWIMI => - result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.const3(4 downto 0)); + sh32 := insn_sh32(e_in.insn); + mb32 := insn_mb32(e_in.insn); + me32 := insn_me32(e_in.insn); + result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, sh32, mb32, me32); result_en := 1; when OP_SLD => result := ppc_sld(e_in.read_data1, e_in.read_data2); @@ -318,7 +351,8 @@ begin ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRAWI => - result_with_carry := ppc_srawi(e_in.read_data1, e_in.const1(5 downto 0)); + sh := '0' & insn_sh32(e_in.insn); + result_with_carry := ppc_srawi(e_in.read_data1, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; @@ -328,7 +362,8 @@ begin ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRADI => - result_with_carry := ppc_sradi(e_in.read_data1, e_in.const1(5 downto 0)); + sh := insn_sh(e_in.insn); + result_with_carry := ppc_sradi(e_in.read_data1, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; From b0f302ecf4a6073bb96dfea47dd139b009f54d6c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 4 Oct 2019 08:25:53 +1000 Subject: [PATCH 10/14] decode: Make all update-form indexed loads and stores use RA_OR_ZERO Experimentation on POWER9 indicates that the invalid form of lbzux with RA=0 uses just RB as the address, not R0 + RB. Extrapolating this to all update-form loads and stores with RA=0, change all the update-form loads and stores to use RA_OR_ZERO rather than RA. This then means that all decode ROM entries with insn_type = LDST have input_reg_a = RA_OR_ZERO. Signed-off-by: Paul Mackerras --- decode1.vhdl | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/decode1.vhdl b/decode1.vhdl index 3ac7e71..2b66b95 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -47,13 +47,13 @@ architecture behaviour of decode1 is 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz - 35 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu + 35 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha - 43 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau + 43 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz - 41 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu + 41 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz - 33 => (LDST, OP_LOAD, RA, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwz + 33 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzu 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris @@ -61,11 +61,11 @@ architecture behaviour of decode1 is 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb - 39 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu - 44 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth - 45 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu + 39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu + 44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth + 45 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw - 37 => (LDST, OP_STORE, RA, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu + 37 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu 8 => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi --PPC_TWI 3 @@ -200,23 +200,23 @@ architecture behaviour of decode1 is 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx - 2#0001110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux + 2#0001110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx - 2#0000110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux + 2#0000110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx - 2#0101110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux + 2#0101110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx - 2#0100110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux + 2#0100110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx - 2#0101110101# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux + 2#0101110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx - 2#0000110111# => (LDST, OP_LOAD, RA, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux + 2#0000110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx -- 2#1000000000# mcrxr -- 2#1001000000# mcrxrx @@ -260,19 +260,19 @@ architecture behaviour of decode1 is 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx - 2#0011110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux + 2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx - 2#0010110101# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux + 2#0010110101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx - 2#0110110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux + 2#0110110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx - 2#0010110111# => (LDST, OP_STORE, RA, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux + 2#0010110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf 2#0000001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc @@ -290,7 +290,7 @@ architecture behaviour of decode1 is -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl -- op in out in out len ext 32 sgn pipe 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld - 1 => (LDST, OP_LOAD, RA, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu + 1 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa others => decode_rom_init ); @@ -299,7 +299,7 @@ architecture behaviour of decode1 is -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl -- op in out in out len ext 32 sgn pipe 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std - 1 => (LDST, OP_STORE, RA, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu + 1 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu others => decode_rom_init ); From 96b402a4bfb4ec8d74c64aa2dd4b8de7ee90e3c0 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 4 Oct 2019 16:11:21 +1000 Subject: [PATCH 11/14] Consolidate add/subtract instructions into a single op All of the PPC add and subtract instructions, including carrying and extended versions, do much the same arithmetic operation: result = (I xor A) + B + C where A is the value from RA, I provides a logical inversion of A (i.e. I is 0 or -1), B is either from RB or is a constant 0 or -1, and C is 0, 1 or the carry bit from XER (CA). To consolidate all the add/subtract instructions into a single OP_ADD, we add a column to decode_rom_t to indicate when A should be inverted, and change the input_carry field to a 3-state selector to select C in the equation above. This also adds a new "CONST_M1" value for input_reg_b_t to indicate that B is a constant -1. This allows us to implement addme and subfme. The addex instruction appears not to exist, so the comments referring to it are removed. Signed-off-by: Paul Mackerras --- common.vhdl | 5 +- decode1.vhdl | 415 +++++++++++++++++++++++----------------------- decode2.vhdl | 3 + decode_types.vhdl | 12 +- execute1.vhdl | 35 ++-- 5 files changed, 243 insertions(+), 227 deletions(-) diff --git a/common.vhdl b/common.vhdl index 4966f2d..bd24329 100644 --- a/common.vhdl +++ b/common.vhdl @@ -55,13 +55,14 @@ package common is cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; - input_carry: std_ulogic; + invert_a: std_ulogic; + input_carry: carry_in_t; output_carry: std_ulogic; input_cr: std_ulogic; output_cr: std_ulogic; insn: std_ulogic_vector(31 downto 0); 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', invert_a => '0', input_carry => ZERO, 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 2b66b95..9125758 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -31,46 +31,46 @@ architecture behaviour of decode1 is type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; constant illegal_inst : decode_rom_t := - (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); constant major_decode_rom_array : major_rom_array_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe - 12 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic - 13 => (ALU, OP_ADDE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. - 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi - 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis - 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. - 29 => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. - 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- b - 16 => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- bc - 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi - 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli - 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz - 35 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu - 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha - 43 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau - 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz - 41 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu - 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz - 33 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzu - 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli - 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori - 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris - 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi - 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm - 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm - 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb - 39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu - 44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth - 45 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu - 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw - 37 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu - 8 => (ALU, OP_SUBFE, RA, CONST_SI, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic - 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + 12 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic + 13 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. + 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi + 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis + 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. + 29 => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. + 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- b + 16 => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- bc + 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi + 10 => (ALU, OP_CMPL, RA, CONST_UI, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpli + 34 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbz + 35 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzu + 42 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lha + 43 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhau + 40 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhz + 41 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzu + 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz + 33 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzu + 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli + 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori + 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris + 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi + 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm + 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb + 39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu + 44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth + 45 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthu + 36 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stw + 37 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwu + 8 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '1', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic + 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi --PPC_TWI 3 - 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori - 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris + 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori + 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris others => illegal_inst ); @@ -99,213 +99,214 @@ architecture behaviour of decode1 is -- indexed by bits 5, 3, 2 of instruction word constant decode_op_19_array : op_19_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe -- mcrf; cr logical ops not implemented yet - 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addpcis not implemented yet - 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- bclr, bcctr, bctar - 2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), + 2#100# => (ALU, OP_BCREG, NONE, NONE, NONE, NONE, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- isync - 2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), + 2#111# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), others => illegal_inst ); constant decode_op_30_array : op_30_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe - 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcl, rldcr - 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), others => illegal_inst ); -- Note: reformat with column -t -o ' ' constant decode_op_31_array : op_31_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe - 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add - 2#0000001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc - 2#0010001010# => (ALU, OP_ADDE, RA, RB, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde - -- 2#--10101010# addex - -- 2#0011101010# addme - 2#0011001010# => (ALU, OP_ADDE, RA, NONE, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze - 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and - 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add + 2#0000001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc + 2#0010001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde + 2#0011101010# => (ALU, OP_ADD, RA, CONST_M1, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addme + 2#0011001010# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze + 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and + 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc -- 2#0011111100# bperm - 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp - 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb + 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp + 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb -- 2#0011100000# cmpeqb - 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl + 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl -- 2#0011000000# cmprb - 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd - 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw - 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd - 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw + 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd + 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw + 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd + 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw -- 2#1011110011# darn - 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf - 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst - 2#0100010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbt - 2#0011110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbtst + 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf + 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst + 2#0100010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbt + 2#0011110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbtst -- 2#1111110110# dcbz - 2#0110001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdeu - 2#0110001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divweu - 2#0110101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divde - 2#0110101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwe - 2#0111001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdu - 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu - 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd - 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw - 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv - 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb - 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh - 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw + 2#0110001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdeu + 2#0110001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divweu + 2#0110101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divde + 2#0110101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwe + 2#0111001001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divdu + 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu + 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd + 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw + 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv + 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb + 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh + 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw -- 2#110111101-# extswsli -- 2#1111010110# icbi - 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt - 2#0000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel - 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx - 2#0001110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux - 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx - 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx - 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx - 2#0000110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux - 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx - 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx - 2#0101110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux - 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax - 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx - 2#0100110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux - 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx - 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx - 2#0101110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux - 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax - 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx - 2#0000110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux - 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx + 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt + 2#0000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1000101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1001101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1010101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1011101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1100101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1101101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1110101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111001111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#1111101111# => (ALU, OP_ISEL, RA_OR_ZERO, RB, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- isel + 2#0000110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lbarx + 2#0001110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lbzux + 2#0001010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lbzx + 2#0001010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- ldarx + 2#1000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldbrx + 2#0000110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldux + 2#0000010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ldx + 2#0001110100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lharx + 2#0101110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lhaux + 2#0101010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lhax + 2#1100010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhbrx + 2#0100110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lhzux + 2#0100010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lhzx + 2#0000010100# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- lwarx + 2#0101110101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '1', '1', '0', '0', '0', NONE, '0', '1'), -- lwaux + 2#0101010101# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwax + 2#1000010110# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwbrx + 2#0000110111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzux + 2#0000010111# => (LDST, OP_LOAD, RA_OR_ZERO, RB, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwzx -- 2#1000000000# mcrxr -- 2#1001000000# mcrxrx - 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfcr/mfocrf - 2#0101010011# => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfspr - 2#0100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modud - 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw - 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd - 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw - 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf - 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr - 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd - 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu - 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw - 2#0000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + 2#0000010011# => (ALU, OP_MFCR, NONE, NONE, NONE, RT, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfcr/mfocrf + 2#0101010011# => (ALU, OP_MFSPR, NONE, NONE, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mfspr + 2#0100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modud + 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw + 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd + 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw + 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf + 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr + 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#0000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu -- next 4 have reserved bit set - 2#1001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd - 2#1000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu - 2#1001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw - 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu - 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld - 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw - 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand - 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg - 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor - 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or - 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc - 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb - 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd - 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw - 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd - 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw + 2#1001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd + 2#1000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu + 2#1001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw + 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu + 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld + 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw + 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand + 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg + 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor + 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or + 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc + 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb + 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd + 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw + 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd + 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw -- 2#0010000000# setb - 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld - 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw - 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad - 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw - 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi - 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd - 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw - 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx - 2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux - 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx - 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx - 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx - 2#0010110101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux - 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx - 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx - 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx - 2#0110110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux - 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx - 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx - 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx - 2#0010110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux - 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx - 2#0000101000# => (ALU, OP_SUBF, RA, RB, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf - 2#0000001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, '0', '0', '0', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc - 2#0010001000# => (ALU, OP_SUBFE, RA, RB, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfe - -- 2#0011101000# subfme - 2#0011001000# => (ALU, OP_SUBFE, RA, NONE, NONE, RT, '0', '0', '1', '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfze - 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync + 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld + 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw + 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad + 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw + 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi + 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd + 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx + 2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux + 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx + 2#1010010100# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdbrx + 2#0011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stdcx + 2#0010110101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdux + 2#0010010101# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stdx + 2#1110010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthbrx + 2#1011010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- sthcx + 2#0110110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- sthux + 2#0110010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sthx + 2#1010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '1', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwbrx + 2#0010010110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '1', '0', '0', NONE, '0', '1'), -- stwcx + 2#0010110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stwux + 2#0010010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- stwx + 2#0000101000# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '1', ONE, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subf + 2#0000001000# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '1', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfc + 2#0010001000# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '1', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfe + 2#0011101000# => (ALU, OP_ADD, RA, CONST_M1, NONE, RT, '0', '0', '1', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfme + 2#0011001000# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '1', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- subfze + 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync -- 2#0001000100# td - 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw - 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor + 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw + 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor others => illegal_inst ); constant decode_op_58_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe - 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld - 1 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu - 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld + 1 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu + 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa others => decode_rom_init ); constant decode_op_62_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out CR CR cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out in out len ext 32 sgn pipe - 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std - 1 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std + 1 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu others => decode_rom_init ); - constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); - constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); - constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, '0', '0', '0', '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl + -- op in out A in out len ext 32 sgn pipe + constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); + constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); + constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); begin decode1_0: process(clk) diff --git a/decode2.vhdl b/decode2.vhdl index 593a025..1594b0f 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -96,6 +96,8 @@ architecture behaviour of decode2 is return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_bd(insn_in)) & "00", 64))); when CONST_DS => return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64))); + when CONST_M1 => + return ('0', (others => '0'), x"FFFFFFFFFFFFFFFF"); when NONE => return ('0', (others => '0'), (others => '0')); end case; @@ -208,6 +210,7 @@ begin v.e.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn); v.e.rc := decode_rc(d_in.decode.rc, d_in.insn); v.e.cr := c_in.read_cr_data; + v.e.invert_a := d_in.decode.invert_a; v.e.input_carry := d_in.decode.input_carry; v.e.output_carry := d_in.decode.output_carry; if d_in.decode.lr = '1' then diff --git a/decode_types.vhdl b/decode_types.vhdl index 03eb0c3..ccc6a8d 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -2,7 +2,7 @@ library ieee; use ieee.std_logic_1164.all; package decode_types is - 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_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC, OP_BCREG, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB, OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND, @@ -18,14 +18,15 @@ package decode_types is OP_PRTYW, OP_RLDCX, OP_RLDIC, OP_RLDICL, OP_RLDICR, OP_RLDIMI, OP_RLWIMI, OP_RLWINM, OP_RLWNM, OP_SETB, OP_SLD, OP_SLW, OP_SRAD, OP_SRADI, OP_SRAW, OP_SRAWI, OP_SRD, OP_SRW, - OP_SUBF, OP_SUBFE, OP_SUBFME, OP_SYNC, OP_TD, OP_TDI, OP_TW, + OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_TWI, OP_XOR, OP_SIM_CONFIG); type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RS); - type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS); + type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); type rc_t is (NONE, ONE, RC); + type carry_in_t is (ZERO, CA, ONE); constant SH_OFFSET : integer := 0; constant MB_OFFSET : integer := 1; @@ -59,7 +60,8 @@ package decode_types is input_cr : std_ulogic; output_cr : std_ulogic; - input_carry : std_ulogic; + invert_a : std_ulogic; + input_carry : carry_in_t; output_carry : std_ulogic; -- load/store signals @@ -82,7 +84,7 @@ package decode_types is insn_type => OP_ILLEGAL, input_reg_a => NONE, input_reg_b => NONE, input_reg_c => NONE, output_reg_a => NONE, input_cr => '0', output_cr => '0', - input_carry => '0', output_carry => '0', + invert_a => '0', input_carry => ZERO, output_carry => '0', length => NONE, byte_reverse => '0', sign_extend => '0', update => '0', reserve => '0', mul_32bit => '0', mul_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0'); diff --git a/execute1.vhdl b/execute1.vhdl index cb86e3e..6d77361 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -41,6 +41,18 @@ architecture behaviour of execute1 is signal ctrl: ctrl_t := (carry => '0', others => (others => '0')); signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0')); + + function decode_input_carry (carry_sel : carry_in_t; ca_in : std_ulogic) return std_ulogic is + begin + case carry_sel is + when ZERO => + return '0'; + when CA => + return ca_in; + when ONE => + return '1'; + end case; + end; begin execute1_0: process(clk) begin @@ -52,6 +64,7 @@ begin execute1_1: process(all) variable v : reg_type; + variable a_inv : std_ulogic_vector(63 downto 0); variable result : std_ulogic_vector(63 downto 0); variable newcrf : std_ulogic_vector(3 downto 0); variable result_with_carry : std_ulogic_vector(64 downto 0); @@ -93,12 +106,16 @@ begin when OP_NOP => -- Do nothing when OP_ADD => - result := ppc_add(e_in.read_data1, e_in.read_data2); - result_en := 1; - when OP_ADDE => - result_with_carry := ppc_adde(e_in.read_data1, e_in.read_data2, ctrl.carry and e_in.input_carry); + if e_in.invert_a = '0' then + a_inv := e_in.read_data1; + else + a_inv := not e_in.read_data1; + end if; + result_with_carry := ppc_adde(a_inv, e_in.read_data2, decode_input_carry(e_in.input_carry, ctrl.carry)); result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry; + if e_in.output_carry then + ctrl_tmp.carry <= result_with_carry(64); + end if; result_en := 1; when OP_AND => result := ppc_and(e_in.read_data1, e_in.read_data2); @@ -373,14 +390,6 @@ begin when OP_SRW => result := ppc_srw(e_in.read_data1, e_in.read_data2); result_en := 1; - when OP_SUBF => - result := ppc_subf(e_in.read_data1, e_in.read_data2); - result_en := 1; - when OP_SUBFE => - result_with_carry := ppc_subfe(e_in.read_data1, e_in.read_data2, ctrl.carry or not(e_in.input_carry)); - result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64) and e_in.output_carry; - result_en := 1; when OP_XOR => result := ppc_xor(e_in.read_data1, e_in.read_data2); result_en := 1; From 7fe84220a51f08d79af71966c46ae52bc8369b00 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 4 Oct 2019 19:26:37 +1000 Subject: [PATCH 12/14] decode: Avoid multiplexing from instruction reg fields to regfile address ports This aims to simplify the logic between the instruction image and the register file read address ports and reduce the size of the decode tables. With this patch, the input_reg_a column of the decode tables can only select RA or zeroes, the input_reg_b column can only select RB or a constant (0, -1, or an immediate value from the instruction), and the input_reg_c columns can only select RS or zeroes. That means that the rotate/shift/logical ops now have their first input coming in via the input_reg_c column. That means we need to add a read_data3 field to the Decode2ToExecuteType record, but that will go away again when we split out the rotate/mask/logical ops to their own unit. As a related but not tightly connected change, this patch also sets the read1_enable signal to the register file be 0 when RA=0 and the input_reg_a for the instruction is RA_OR_ZERO (previously it was 1). Signed-off-by: Paul Mackerras --- common.vhdl | 1 + decode1.vhdl | 92 +++++++++++++++++++++++------------------------ decode2.vhdl | 28 ++++----------- decode_types.vhdl | 4 +-- execute1.vhdl | 82 +++++++++++++++++++++--------------------- 5 files changed, 97 insertions(+), 110 deletions(-) diff --git a/common.vhdl b/common.vhdl index bd24329..67872c8 100644 --- a/common.vhdl +++ b/common.vhdl @@ -52,6 +52,7 @@ package common is read_reg2: std_ulogic_vector(4 downto 0); read_data1: std_ulogic_vector(63 downto 0); read_data2: std_ulogic_vector(63 downto 0); + read_data3: std_ulogic_vector(63 downto 0); cr: std_ulogic_vector(31 downto 0); lr: std_ulogic; rc: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 9125758..0173084 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -40,8 +40,8 @@ architecture behaviour of decode1 is 13 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi 15 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI_HI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addis - 28 => (ALU, OP_AND, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. - 29 => (ALU, OP_AND, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. + 28 => (ALU, OP_AND, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andi. + 29 => (ALU, OP_AND, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- andis. 18 => (ALU, OP_B, NONE, CONST_LI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- b 16 => (ALU, OP_BC, NONE, CONST_BD, NONE, NONE, '1', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '1', '1'), -- bc 11 => (ALU, OP_CMP, RA, CONST_SI, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpi @@ -55,11 +55,11 @@ architecture behaviour of decode1 is 32 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- lwz 33 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- lwzu 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli - 24 => (ALU, OP_OR, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori - 25 => (ALU, OP_OR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris - 20 => (ALU, OP_RLWIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi - 21 => (ALU, OP_RLWINM, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm - 23 => (ALU, OP_RLWNM, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 24 => (ALU, OP_OR, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori + 25 => (ALU, OP_OR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris + 20 => (ALU, OP_RLWIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi + 21 => (ALU, OP_RLWINM, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm + 23 => (ALU, OP_RLWNM, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb 39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu 44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth @@ -69,8 +69,8 @@ architecture behaviour of decode1 is 8 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '1', ONE, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- subfic 2 => (ALU, OP_TDI, RA, CONST_SI, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tdi --PPC_TWI 3 - 26 => (ALU, OP_XOR, RS, CONST_UI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori - 27 => (ALU, OP_XOR, RS, CONST_UI_HI, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris + 26 => (ALU, OP_XOR, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xori + 27 => (ALU, OP_XOR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- xoris others => illegal_inst ); @@ -115,12 +115,12 @@ architecture behaviour of decode1 is constant decode_op_30_array : op_30_subop_array_t := ( -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl -- op in out A in out len ext 32 sgn pipe - 2#010# => (ALU, OP_RLDIC, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#000# => (ALU, OP_RLDICL, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#001# => (ALU, OP_RLDICR, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#011# => (ALU, OP_RLDIMI, RA, RS, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#010# => (ALU, OP_RLDIC, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#000# => (ALU, OP_RLDICL, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#001# => (ALU, OP_RLDICR, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#011# => (ALU, OP_RLDIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcl, rldcr - 2#100# => (ALU, OP_RLDCX, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#100# => (ALU, OP_RLDCX, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), others => illegal_inst ); @@ -133,18 +133,18 @@ architecture behaviour of decode1 is 2#0010001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde 2#0011101010# => (ALU, OP_ADD, RA, CONST_M1, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addme 2#0011001010# => (ALU, OP_ADD, RA, NONE, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addze - 2#0000011100# => (ALU, OP_AND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and - 2#0000111100# => (ALU, OP_ANDC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc + 2#0000011100# => (ALU, OP_AND, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- and + 2#0000111100# => (ALU, OP_ANDC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- andc -- 2#0011111100# bperm 2#0000000000# => (ALU, OP_CMP, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmp - 2#0111111100# => (ALU, OP_CMPB, RS, RB, NONE, RA, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb + 2#0111111100# => (ALU, OP_CMPB, NONE, RB, RS, RA, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpb -- 2#0011100000# cmpeqb 2#0000100000# => (ALU, OP_CMPL, RA, RB, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- cmpl -- 2#0011000000# cmprb - 2#0000111010# => (ALU, OP_CNTLZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd - 2#0000011010# => (ALU, OP_CNTLZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw - 2#1000111010# => (ALU, OP_CNTTZD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd - 2#1000011010# => (ALU, OP_CNTTZW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw + 2#0000111010# => (ALU, OP_CNTLZD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzd + 2#0000011010# => (ALU, OP_CNTLZW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cntlzw + 2#1000111010# => (ALU, OP_CNTTZD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzd + 2#1000011010# => (ALU, OP_CNTTZW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- cnttzw -- 2#1011110011# darn 2#0001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbf 2#0000110110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- dcbst @@ -159,10 +159,10 @@ architecture behaviour of decode1 is 2#0111001011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divwu 2#0111101001# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divd 2#0111101011# => (DIV, OP_DIV, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- divw - 2#0100011100# => (ALU, OP_EQV, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv - 2#1110111010# => (ALU, OP_EXTSB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb - 2#1110011010# => (ALU, OP_EXTSH, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh - 2#1111011010# => (ALU, OP_EXTSW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw + 2#0100011100# => (ALU, OP_EQV, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- eqv + 2#1110111010# => (ALU, OP_EXTSB, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsb + 2#1110011010# => (ALU, OP_EXTSH, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsh + 2#1111011010# => (ALU, OP_EXTSW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- extsw -- 2#110111101-# extswsli -- 2#1111010110# icbi 2#0000010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- icbt @@ -225,8 +225,8 @@ architecture behaviour of decode1 is 2#0100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- moduw 2#1100001001# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsd 2#1100001011# => (DIV, OP_MOD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- modsw - 2#0010010000# => (ALU, OP_MTCRF, RS, NONE, NONE, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf - 2#0111010011# => (ALU, OP_MTSPR, RS, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr + 2#0010010000# => (ALU, OP_MTCRF, NONE, NONE, RS, NONE, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtcrf/mtocrf + 2#0111010011# => (ALU, OP_MTSPR, NONE, NONE, RS, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- mtspr 2#0001001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulhd 2#0000001001# => (MUL, OP_MUL_H64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- mulhdu 2#0001001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mulhw @@ -238,26 +238,26 @@ architecture behaviour of decode1 is 2#1000001011# => (MUL, OP_MUL_H32, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- mulhwu 2#0011101001# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- mulld 2#0011101011# => (MUL, OP_MUL_L64, RA, RB, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- mullw - 2#0111011100# => (ALU, OP_NAND, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand + 2#0111011100# => (ALU, OP_NAND, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nand 2#0001101000# => (ALU, OP_NEG, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- neg - 2#0001111100# => (ALU, OP_NOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor - 2#0110111100# => (ALU, OP_OR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or - 2#0110011100# => (ALU, OP_ORC, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc - 2#0001111010# => (ALU, OP_POPCNTB, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb - 2#0111111010# => (ALU, OP_POPCNTD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd - 2#0101111010# => (ALU, OP_POPCNTW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw - 2#0010111010# => (ALU, OP_PRTYD, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd - 2#0010011010# => (ALU, OP_PRTYW, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw + 2#0001111100# => (ALU, OP_NOR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- nor + 2#0110111100# => (ALU, OP_OR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- or + 2#0110011100# => (ALU, OP_ORC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- orc + 2#0001111010# => (ALU, OP_POPCNTB, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntb + 2#0111111010# => (ALU, OP_POPCNTD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntd + 2#0101111010# => (ALU, OP_POPCNTW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- popcntw + 2#0010111010# => (ALU, OP_PRTYD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd + 2#0010011010# => (ALU, OP_PRTYW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw -- 2#0010000000# setb - 2#0000011011# => (ALU, OP_SLD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld - 2#0000011000# => (ALU, OP_SLW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw - 2#1100011010# => (ALU, OP_SRAD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad - 2#1100111010# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100111011# => (ALU, OP_SRADI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100011000# => (ALU, OP_SRAW, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw - 2#1100111000# => (ALU, OP_SRAWI, RS, NONE, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi - 2#1000011011# => (ALU, OP_SRD, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd - 2#1000011000# => (ALU, OP_SRW, RS, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 2#0000011011# => (ALU, OP_SLD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld + 2#0000011000# => (ALU, OP_SLW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw + 2#1100011010# => (ALU, OP_SRAD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad + 2#1100111010# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100111011# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi + 2#1100011000# => (ALU, OP_SRAW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw + 2#1100111000# => (ALU, OP_SRAWI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi + 2#1000011011# => (ALU, OP_SRD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd + 2#1000011000# => (ALU, OP_SRW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx 2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx @@ -281,7 +281,7 @@ architecture behaviour of decode1 is 2#1001010110# => (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sync -- 2#0001000100# td 2#0000000100# => (ALU, OP_TW, RA, RB, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- tw - 2#0100111100# => (ALU, OP_XOR, RS, RB, NONE, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor + 2#0100111100# => (ALU, OP_XOR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- xor others => illegal_inst ); diff --git a/decode2.vhdl b/decode2.vhdl index 1594b0f..e22b065 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -62,16 +62,11 @@ architecture behaviour of decode2 is function decode_input_reg_a (t : input_reg_a_t; insn_in : std_ulogic_vector(31 downto 0); reg_data : std_ulogic_vector(63 downto 0)) return decode_input_reg_t is begin - case t is - when RA => + if t = RA or (t = RA_OR_ZERO and insn_ra(insn_in) /= "00000") then return ('1', insn_ra(insn_in), reg_data); - when RA_OR_ZERO => - return ('1', insn_ra(insn_in), ra_or_zero(reg_data, insn_ra(insn_in))); - when RS => - return ('1', insn_rs(insn_in), reg_data); - when NONE => + else return ('0', (others => '0'), (others => '0')); - end case; + end if; end; function decode_input_reg_b (t : input_reg_b_t; insn_in : std_ulogic_vector(31 downto 0); @@ -80,8 +75,6 @@ architecture behaviour of decode2 is case t is when RB => return ('1', insn_rb(insn_in), reg_data); - when RS => - return ('1', insn_rs(insn_in), reg_data); when CONST_UI => return ('0', (others => '0'), std_ulogic_vector(resize(unsigned(insn_ui(insn_in)), 64))); when CONST_SI => @@ -152,17 +145,9 @@ begin end if; end process; - r_out.read1_reg <= insn_ra(d_in.insn) when (d_in.decode.input_reg_a = RA) else - insn_ra(d_in.insn) when d_in.decode.input_reg_a = RA_OR_ZERO else - insn_rs(d_in.insn) when d_in.decode.input_reg_a = RS else - (others => '0'); - - r_out.read2_reg <= insn_rb(d_in.insn) when d_in.decode.input_reg_b = RB else - insn_rs(d_in.insn) when d_in.decode.input_reg_b = RS else - (others => '0'); - - r_out.read3_reg <= insn_rs(d_in.insn) when d_in.decode.input_reg_c = RS else - (others => '0'); + r_out.read1_reg <= insn_ra(d_in.insn); + r_out.read2_reg <= insn_rb(d_in.insn); + r_out.read3_reg <= insn_rs(d_in.insn); c_out.read <= d_in.decode.input_cr; @@ -207,6 +192,7 @@ begin v.e.read_data1 := decoded_reg_a.data; v.e.read_reg2 := decoded_reg_b.reg; v.e.read_data2 := decoded_reg_b.data; + v.e.read_data3 := decoded_reg_c.data; v.e.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn); v.e.rc := decode_rc(d_in.decode.rc, d_in.insn); v.e.cr := c_in.read_cr_data; diff --git a/decode_types.vhdl b/decode_types.vhdl index ccc6a8d..cbdf449 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -21,8 +21,8 @@ package decode_types is OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_TWI, OP_XOR, OP_SIM_CONFIG); - type input_reg_a_t is (NONE, RA, RA_OR_ZERO, RS); - type input_reg_b_t is (NONE, RB, RS, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); + type input_reg_a_t is (NONE, RA, RA_OR_ZERO); + type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index 6d77361..cdd79f1 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -118,10 +118,10 @@ begin end if; result_en := 1; when OP_AND => - result := ppc_and(e_in.read_data1, e_in.read_data2); + result := ppc_and(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ANDC => - result := ppc_andc(e_in.read_data1, e_in.read_data2); + result := ppc_andc(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_B => f_out.redirect <= '1'; @@ -160,7 +160,7 @@ begin end if; end if; when OP_CMPB => - result := ppc_cmpb(e_in.read_data1, e_in.read_data2); + result := ppc_cmpb(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_CMP => bf := insn_bf(e_in.insn); @@ -185,28 +185,28 @@ begin v.e.write_cr_data(hi downto lo) := ppc_cmpl(l, e_in.read_data1, e_in.read_data2); end loop; when OP_CNTLZW => - result := ppc_cntlzw(e_in.read_data1); + result := ppc_cntlzw(e_in.read_data3); result_en := 1; when OP_CNTTZW => - result := ppc_cnttzw(e_in.read_data1); + result := ppc_cnttzw(e_in.read_data3); result_en := 1; when OP_CNTLZD => - result := ppc_cntlzd(e_in.read_data1); + result := ppc_cntlzd(e_in.read_data3); result_en := 1; when OP_CNTTZD => - result := ppc_cnttzd(e_in.read_data1); + result := ppc_cnttzd(e_in.read_data3); result_en := 1; when OP_EXTSB => - result := ppc_extsb(e_in.read_data1); + result := ppc_extsb(e_in.read_data3); result_en := 1; when OP_EXTSH => - result := ppc_extsh(e_in.read_data1); + result := ppc_extsh(e_in.read_data3); result_en := 1; when OP_EXTSW => - result := ppc_extsw(e_in.read_data1); + result := ppc_extsw(e_in.read_data3); result_en := 1; when OP_EQV => - result := ppc_eqv(e_in.read_data1, e_in.read_data2); + result := ppc_eqv(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ISEL => crnum := to_integer(unsigned(insn_bc(e_in.insn))); @@ -273,125 +273,125 @@ begin crnum := fxm_to_num(insn_fxm(e_in.insn)); v.e.write_cr_mask := num_to_fxm(crnum); end if; - v.e.write_cr_data := e_in.read_data1(31 downto 0); + v.e.write_cr_data := e_in.read_data3(31 downto 0); when OP_MTSPR => if std_match(e_in.insn(20 downto 11), "0100100000") then - ctrl_tmp.ctr <= e_in.read_data1; + ctrl_tmp.ctr <= e_in.read_data3; elsif std_match(e_in.insn(20 downto 11), "0100000000") then - ctrl_tmp.lr <= e_in.read_data1; + ctrl_tmp.lr <= e_in.read_data3; end if; when OP_NAND => - result := ppc_nand(e_in.read_data1, e_in.read_data2); + result := ppc_nand(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_NEG => result := ppc_neg(e_in.read_data1); result_en := 1; when OP_NOR => - result := ppc_nor(e_in.read_data1, e_in.read_data2); + result := ppc_nor(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_OR => - result := ppc_or(e_in.read_data1, e_in.read_data2); + result := ppc_or(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_ORC => - result := ppc_orc(e_in.read_data1, e_in.read_data2); + result := ppc_orc(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_POPCNTB => - result := ppc_popcntb(e_in.read_data1); + result := ppc_popcntb(e_in.read_data3); result_en := 1; when OP_POPCNTW => - result := ppc_popcntw(e_in.read_data1); + result := ppc_popcntw(e_in.read_data3); result_en := 1; when OP_POPCNTD => - result := ppc_popcntd(e_in.read_data1); + result := ppc_popcntd(e_in.read_data3); result_en := 1; when OP_PRTYD => - result := ppc_prtyd(e_in.read_data1); + result := ppc_prtyd(e_in.read_data3); result_en := 1; when OP_PRTYW => - result := ppc_prtyw(e_in.read_data1); + result := ppc_prtyw(e_in.read_data3); result_en := 1; when OP_RLDCX => -- note rldcl mb field and rldcr me field are in the same place mb := insn_mb(e_in.insn); if e_in.insn(1) = '0' then - result := ppc_rldcl(e_in.read_data1, e_in.read_data2, mb); + result := ppc_rldcl(e_in.read_data3, e_in.read_data2, mb); else - result := ppc_rldcr(e_in.read_data1, e_in.read_data2, mb); + result := ppc_rldcr(e_in.read_data3, e_in.read_data2, mb); end if; result_en := 1; when OP_RLDICL => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldicl(e_in.read_data1, sh, mb); + result := ppc_rldicl(e_in.read_data3, sh, mb); result_en := 1; when OP_RLDICR => sh := insn_sh(e_in.insn); me := insn_me(e_in.insn); - result := ppc_rldicr(e_in.read_data1, sh, me); + result := ppc_rldicr(e_in.read_data3, sh, me); result_en := 1; when OP_RLWNM => mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwnm(e_in.read_data1, e_in.read_data2, mb32, me32); + result := ppc_rlwnm(e_in.read_data3, e_in.read_data2, mb32, me32); result_en := 1; when OP_RLWINM => sh32 := insn_sh32(e_in.insn); mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwinm(e_in.read_data1, sh32, mb32, me32); + result := ppc_rlwinm(e_in.read_data3, sh32, mb32, me32); result_en := 1; when OP_RLDIC => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldic(e_in.read_data1, sh, mb); + result := ppc_rldic(e_in.read_data3, sh, mb); result_en := 1; when OP_RLDIMI => sh := insn_sh(e_in.insn); mb := insn_mb(e_in.insn); - result := ppc_rldimi(e_in.read_data1, e_in.read_data2, sh, mb); + result := ppc_rldimi(e_in.read_data1, e_in.read_data3, sh, mb); result_en := 1; when OP_RLWIMI => sh32 := insn_sh32(e_in.insn); mb32 := insn_mb32(e_in.insn); me32 := insn_me32(e_in.insn); - result := ppc_rlwimi(e_in.read_data1, e_in.read_data2, sh32, mb32, me32); + result := ppc_rlwimi(e_in.read_data1, e_in.read_data3, sh32, mb32, me32); result_en := 1; when OP_SLD => - result := ppc_sld(e_in.read_data1, e_in.read_data2); + result := ppc_sld(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SLW => - result := ppc_slw(e_in.read_data1, e_in.read_data2); + result := ppc_slw(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SRAW => - result_with_carry := ppc_sraw(e_in.read_data1, e_in.read_data2); + result_with_carry := ppc_sraw(e_in.read_data3, e_in.read_data2); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRAWI => sh := '0' & insn_sh32(e_in.insn); - result_with_carry := ppc_srawi(e_in.read_data1, sh); + result_with_carry := ppc_srawi(e_in.read_data3, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRAD => - result_with_carry := ppc_srad(e_in.read_data1, e_in.read_data2); + result_with_carry := ppc_srad(e_in.read_data3, e_in.read_data2); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRADI => sh := insn_sh(e_in.insn); - result_with_carry := ppc_sradi(e_in.read_data1, sh); + result_with_carry := ppc_sradi(e_in.read_data3, sh); result := result_with_carry(63 downto 0); ctrl_tmp.carry <= result_with_carry(64); result_en := 1; when OP_SRD => - result := ppc_srd(e_in.read_data1, e_in.read_data2); + result := ppc_srd(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SRW => - result := ppc_srw(e_in.read_data1, e_in.read_data2); + result := ppc_srw(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_XOR => - result := ppc_xor(e_in.read_data1, e_in.read_data2); + result := ppc_xor(e_in.read_data3, e_in.read_data2); result_en := 1; when OP_SIM_CONFIG => From 90b6e273809e81c1c32a537b94cef0f530e63337 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 6 Oct 2019 15:21:27 +1100 Subject: [PATCH 13/14] Generalize the mul_32bit and mul_signed fields of decode_rom_t This changes the names of the mul_32bit and mul_signed fields of decode_rom_t to is_32bit and is_signed, so they can be used with other types of operations besides multiplies. This plumbs the is_32bit and is_signed flags down into execute1, though they are not used at this point. Signed-off-by: Paul Mackerras --- common.vhdl | 7 ++++++- decode1.vhdl | 28 ++++++++++++++-------------- decode2.vhdl | 8 +++++--- decode_types.vhdl | 10 +++++----- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/common.vhdl b/common.vhdl index 67872c8..284d52f 100644 --- a/common.vhdl +++ b/common.vhdl @@ -61,9 +61,14 @@ package common is output_carry: std_ulogic; input_cr: std_ulogic; output_cr: std_ulogic; + is_32bit: std_ulogic; + is_signed: std_ulogic; insn: std_ulogic_vector(31 downto 0); end record; - constant Decode2ToExecute1Init : Decode2ToExecute1Type := (valid => '0', insn_type => OP_ILLEGAL, lr => '0', rc => '0', invert_a => '0', input_carry => ZERO, 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', invert_a => '0', + input_carry => ZERO, output_carry => '0', input_cr => '0', output_cr => '0', + is_32bit => '0', is_signed => '0', others => (others => '0')); type Decode2ToMultiplyType is record valid: std_ulogic; diff --git a/decode1.vhdl b/decode1.vhdl index 0173084..275c45e 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -34,8 +34,8 @@ architecture behaviour of decode1 is (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); constant major_decode_rom_array : major_rom_array_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe 12 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addic 13 => (ALU, OP_ADD, RA, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', ONE, '0', '1'), -- addic. 14 => (ALU, OP_ADD, RA_OR_ZERO, CONST_SI, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addi @@ -99,8 +99,8 @@ architecture behaviour of decode1 is -- indexed by bits 5, 3, 2 of instruction word constant decode_op_19_array : op_19_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe -- mcrf; cr logical ops not implemented yet 2#000# => (ALU, OP_MCRF, NONE, NONE, NONE, NONE, '1', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- addpcis not implemented yet @@ -113,8 +113,8 @@ architecture behaviour of decode1 is ); constant decode_op_30_array : op_30_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe 2#010# => (ALU, OP_RLDIC, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), 2#000# => (ALU, OP_RLDICL, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), 2#001# => (ALU, OP_RLDICR, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), @@ -126,8 +126,8 @@ architecture behaviour of decode1 is -- Note: reformat with column -t -o ' ' constant decode_op_31_array : op_31_subop_array_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe 2#0100001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- add 2#0000001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- addc 2#0010001010# => (ALU, OP_ADD, RA, RB, NONE, RT, '0', '0', '0', CA, '1', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- adde @@ -286,8 +286,8 @@ architecture behaviour of decode1 is ); constant decode_op_58_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe 0 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ld 1 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- ldu 2 => (LDST, OP_LOAD, RA_OR_ZERO, CONST_DS, NONE, RT, '0', '0', '0', ZERO, '0', is4B, '0', '1', '0', '0', '0', '0', NONE, '0', '1'), -- lwa @@ -295,15 +295,15 @@ architecture behaviour of decode1 is ); constant decode_op_62_array : minor_rom_array_2_t := ( - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe 0 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- std 1 => (LDST, OP_STORE, RA_OR_ZERO, CONST_DS, RS, NONE, '0', '0', '0', ZERO, '0', is8B, '0', '0', '1', '0', '0', '0', NONE, '0', '1'), -- stdu others => decode_rom_init ); - -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv mul mul rc lk sgl - -- op in out A in out len ext 32 sgn pipe + -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl + -- op in out A in out len ext pipe constant attn_instr : decode_rom_t := (ALU, OP_ILLEGAL, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'); constant nop_instr : decode_rom_t := (ALU, OP_NOP, NONE, NONE, NONE, NONE, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); constant sim_cfg_instr : decode_rom_t := (ALU, OP_SIM_CONFIG,NONE, NONE, NONE, RT, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'); diff --git a/decode2.vhdl b/decode2.vhdl index e22b065..7c6c0ca 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -199,6 +199,8 @@ begin v.e.invert_a := d_in.decode.invert_a; v.e.input_carry := d_in.decode.input_carry; v.e.output_carry := d_in.decode.output_carry; + v.e.is_32bit := d_in.decode.is_32bit; + v.e.is_signed := d_in.decode.is_signed; if d_in.decode.lr = '1' then v.e.lr := insn_lk(d_in.insn); end if; @@ -211,8 +213,8 @@ begin v.m.write_reg := decode_output_reg(d_in.decode.output_reg_a, d_in.insn); v.m.rc := decode_rc(d_in.decode.rc, d_in.insn); - if d_in.decode.mul_32bit = '1' then - if d_in.decode.mul_signed = '1' then + if d_in.decode.is_32bit = '1' then + if d_in.decode.is_signed = '1' then v.m.data1 := (others => mul_a(31)); v.m.data1(31 downto 0) := mul_a(31 downto 0); v.m.data2 := (others => mul_b(31)); @@ -222,7 +224,7 @@ begin v.m.data2 := '0' & x"00000000" & mul_b(31 downto 0); end if; else - if d_in.decode.mul_signed = '1' then + if d_in.decode.is_signed = '1' then v.m.data1 := mul_a(63) & mul_a; v.m.data2 := mul_b(63) & mul_b; else diff --git a/decode_types.vhdl b/decode_types.vhdl index cbdf449..6ac91a5 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -71,9 +71,9 @@ package decode_types is update : std_ulogic; reserve : std_ulogic; - -- multiplier signals - mul_32bit : std_ulogic; - mul_signed : std_ulogic; + -- multiplier and ALU signals + is_32bit : std_ulogic; + is_signed : std_ulogic; rc : rc_t; lr : std_ulogic; @@ -86,8 +86,8 @@ package decode_types is output_reg_a => NONE, input_cr => '0', output_cr => '0', invert_a => '0', input_carry => ZERO, output_carry => '0', length => NONE, byte_reverse => '0', sign_extend => '0', - update => '0', reserve => '0', mul_32bit => '0', - mul_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0'); + update => '0', reserve => '0', is_32bit => '0', + is_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0'); end decode_types; From f7c393ba7e73787a77c444bba6c9eed329ff3b32 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 7 Oct 2019 18:26:11 +1100 Subject: [PATCH 14/14] Add a rotate/mask/shift unit and use it in execute1 This adds a new entity 'rotator' which contains combinatorial logic for rotating and masking 64-bit values. It implements the operations of the rlwinm, rlwnm, rlwimi, rldicl, rldicr, rldic, rldimi, rldcl, rldcr, sld, slw, srd, srw, srad, sradi, sraw and srawi instructions. It consists of a 3-stage 64-bit rotator using 4:1 multiplexors at each stage, two mask generators, output logic and control logic. The insn_type_t values used for these instructions have been reduced to just 5: OP_RLC, OP_RLCL and OP_RLCR for the rotate and mask instructions (clear both left and right, clear left, clear right variants), OP_SHL for left shifts, and OP_SHR for right shifts. The control signals for the rotator are derived from the opcode and from the is_32bit and is_signed fields of the decode_rom_t. The rotator is instantiated as an entity in execute1 so that we can be sure we only have one of it. Signed-off-by: Paul Mackerras --- Makefile | 10 +- decode1.vhdl | 45 ++++---- decode2.vhdl | 6 +- decode_types.vhdl | 7 +- execute1.vhdl | 109 ++++++------------- microwatt.core | 1 + rotator.vhdl | 183 +++++++++++++++++++++++++++++++ rotator_tb.vhdl | 269 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 523 insertions(+), 107 deletions(-) create mode 100644 rotator.vhdl create mode 100644 rotator_tb.vhdl diff --git a/Makefile b/Makefile index 8075439..7b28b31 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ GHDL=ghdl GHDLFLAGS=--std=08 -Psim-unisim CFLAGS=-O2 -Wall -all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb dmi_dtm_tb divider_tb +all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb dmi_dtm_tb divider_tb \ + rotator_tb # XXX # loadstore_tb fetch_tb @@ -22,7 +23,7 @@ crhelpers.o: common.o decode1.o: common.o decode_types.o decode2.o: decode_types.o common.o helpers.o insn_helpers.o decode_types.o: -execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o insn_helpers.o +execute1.o: decode_types.o common.o helpers.o crhelpers.o ppc_fx_insns.o insn_helpers.o rotator.o execute2.o: common.o crhelpers.o ppc_fx_insns.o fetch1.o: common.o fetch2.o: common.o wishbone_types.o @@ -40,6 +41,8 @@ divider_tb.o: decode_types.o common.o glibc_random.o ppc_fx_insns.o divider.o divider.o: common.o decode_types.o crhelpers.o ppc_fx_insns.o: helpers.o register_file.o: common.o +rotator.o: common.o +rotator_tb.o: common.o glibc_random.o ppc_fx_insns.o insn_helpers.o rotator.o sim_console.o: simple_ram_behavioural_helpers.o: simple_ram_behavioural_tb.o: wishbone_types.o simple_ram_behavioural.o @@ -81,6 +84,9 @@ multiply_tb: multiply_tb.o divider_tb: divider_tb.o $(GHDL) -e $(GHDLFLAGS) $@ +rotator_tb: rotator_tb.o + $(GHDL) -e $(GHDLFLAGS) $@ + simple_ram_tb: simple_ram_tb.o $(GHDL) -e $(GHDLFLAGS) $@ diff --git a/decode1.vhdl b/decode1.vhdl index 275c45e..8ad123f 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -26,7 +26,7 @@ architecture behaviour of decode1 is type major_rom_array_t is array(0 to 63) of decode_rom_t; type minor_valid_array_t is array(0 to 1023) of std_ulogic; type op_19_subop_array_t is array(0 to 7) of decode_rom_t; - type op_30_subop_array_t is array(0 to 7) of decode_rom_t; + type op_30_subop_array_t is array(0 to 15) of decode_rom_t; type op_31_subop_array_t is array(0 to 1023) of decode_rom_t; type minor_rom_array_2_t is array(0 to 3) of decode_rom_t; @@ -57,9 +57,9 @@ architecture behaviour of decode1 is 7 => (MUL, OP_MUL_L64, RA, CONST_SI, NONE, RT, '0', '1', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '1', NONE, '0', '1'), -- mulli 24 => (ALU, OP_OR, NONE, CONST_UI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- ori 25 => (ALU, OP_OR, NONE, CONST_UI_HI, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- oris - 20 => (ALU, OP_RLWIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwimi - 21 => (ALU, OP_RLWINM, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwinm - 23 => (ALU, OP_RLWNM, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rlwnm + 20 => (ALU, OP_RLC, RA, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwimi + 21 => (ALU, OP_RLC, NONE, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwinm + 23 => (ALU, OP_RLC, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- rlwnm 38 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stb 39 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbu 44 => (LDST, OP_STORE, RA_OR_ZERO, CONST_SI, RS, NONE, '0', '0', '0', ZERO, '0', is2B, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- sth @@ -115,12 +115,16 @@ architecture behaviour of decode1 is constant decode_op_30_array : op_30_subop_array_t := ( -- unit internal in1 in2 in3 out CR CR inv cry cry ldst BR sgn upd rsrv 32b sgn rc lk sgl -- op in out A in out len ext pipe - 2#010# => (ALU, OP_RLDIC, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#000# => (ALU, OP_RLDICL, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#001# => (ALU, OP_RLDICR, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - 2#011# => (ALU, OP_RLDIMI, RA, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), - -- rldcl, rldcr - 2#100# => (ALU, OP_RLDCX, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), + 2#0100# => (ALU, OP_RLC, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldic + 2#0101# => (ALU, OP_RLC, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldic + 2#0000# => (ALU, OP_RLCL, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicl + 2#0001# => (ALU, OP_RLCL, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicl + 2#0010# => (ALU, OP_RLCR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicr + 2#0011# => (ALU, OP_RLCR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldicr + 2#0110# => (ALU, OP_RLC, RA, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldimi + 2#0111# => (ALU, OP_RLC, RA, CONST_SH, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldimi + 2#1000# => (ALU, OP_RLCL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcl + 2#1001# => (ALU, OP_RLCR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- rldcr others => illegal_inst ); @@ -249,15 +253,15 @@ architecture behaviour of decode1 is 2#0010111010# => (ALU, OP_PRTYD, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyd 2#0010011010# => (ALU, OP_PRTYW, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', NONE, '0', '1'), -- prtyw -- 2#0010000000# setb - 2#0000011011# => (ALU, OP_SLD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld - 2#0000011000# => (ALU, OP_SLW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- slw - 2#1100011010# => (ALU, OP_SRAD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srad - 2#1100111010# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100111011# => (ALU, OP_SRADI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sradi - 2#1100011000# => (ALU, OP_SRAW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sraw - 2#1100111000# => (ALU, OP_SRAWI, NONE, NONE, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srawi - 2#1000011011# => (ALU, OP_SRD, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd - 2#1000011000# => (ALU, OP_SRW, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srw + 2#0000011011# => (ALU, OP_SHL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- sld + 2#0000011000# => (ALU, OP_SHL, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- slw + 2#1100011010# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- srad + 2#1100111010# => (ALU, OP_SHR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- sradi + 2#1100111011# => (ALU, OP_SHR, NONE, CONST_SH, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '0', '1', RC, '0', '1'), -- sradi + 2#1100011000# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- sraw + 2#1100111000# => (ALU, OP_SHR, NONE, CONST_SH32, RS, RA, '0', '0', '0', ZERO, '1', NONE, '0', '0', '0', '0', '1', '1', RC, '0', '1'), -- srawi + 2#1000011011# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- srd + 2#1000011000# => (ALU, OP_SHR, NONE, RB, RS, RA, '0', '0', '0', ZERO, '0', NONE, '0', '0', '0', '0', '1', '0', RC, '0', '1'), -- srw 2#1010110110# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '1', '0', '0', RC, '0', '1'), -- stbcx 2#0011110111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '1', '0', '0', '0', RC, '0', '1'), -- stbux 2#0011010111# => (LDST, OP_STORE, RA_OR_ZERO, RB, RS, NONE, '0', '0', '0', ZERO, '0', is1B, '0', '0', '0', '0', '0', '0', RC, '0', '1'), -- stbx @@ -323,7 +327,6 @@ begin variable v : Decode1ToDecode2Type; variable majorop : major_opcode_t; variable op_19_bits: std_ulogic_vector(2 downto 0); - variable op_30_bits: std_ulogic_vector(2 downto 0); begin v := r; @@ -352,7 +355,7 @@ begin end if; elsif majorop = "011110" then - v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 2)))); + v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 1)))); elsif majorop = "111010" then v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0)))); diff --git a/decode2.vhdl b/decode2.vhdl index 7c6c0ca..c0afcc2 100644 --- a/decode2.vhdl +++ b/decode2.vhdl @@ -90,7 +90,11 @@ architecture behaviour of decode2 is when CONST_DS => return ('0', (others => '0'), std_ulogic_vector(resize(signed(insn_ds(insn_in)) & "00", 64))); when CONST_M1 => - return ('0', (others => '0'), x"FFFFFFFFFFFFFFFF"); + return ('0', (others => '0'), x"FFFFFFFFFFFFFFFF"); + when CONST_SH => + return ('0', (others => '0'), x"00000000000000" & "00" & insn_in(1) & insn_in(15 downto 11)); + when CONST_SH32 => + return ('0', (others => '0'), x"00000000000000" & "000" & insn_in(15 downto 11)); when NONE => return ('0', (others => '0'), (others => '0')); end case; diff --git a/decode_types.vhdl b/decode_types.vhdl index 6ac91a5..54b17e7 100644 --- a/decode_types.vhdl +++ b/decode_types.vhdl @@ -15,14 +15,13 @@ package decode_types is OP_MTCRF, OP_MTSPR, OP_MUL_L64, OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, OP_ORC, OP_POPCNTB, OP_POPCNTD, OP_POPCNTW, OP_PRTYD, - OP_PRTYW, OP_RLDCX, OP_RLDIC, OP_RLDICL, OP_RLDICR, - OP_RLDIMI, OP_RLWIMI, OP_RLWINM, OP_RLWNM, OP_SETB, OP_SLD, - OP_SLW, OP_SRAD, OP_SRADI, OP_SRAW, OP_SRAWI, OP_SRD, OP_SRW, + OP_PRTYW, OP_RLC, OP_RLCL, OP_RLCR, OP_SETB, + OP_SHL, OP_SHR, OP_SYNC, OP_TD, OP_TDI, OP_TW, OP_TWI, OP_XOR, OP_SIM_CONFIG); type input_reg_a_t is (NONE, RA, RA_OR_ZERO); - type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1); + type input_reg_b_t is (NONE, RB, CONST_UI, CONST_SI, CONST_SI_HI, CONST_UI_HI, CONST_LI, CONST_BD, CONST_DS, CONST_M1, CONST_SH, CONST_SH32); type input_reg_c_t is (NONE, RS); type output_reg_a_t is (NONE, RT, RA); type rc_t is (NONE, ONE, RC); diff --git a/execute1.vhdl b/execute1.vhdl index cdd79f1..9f54bad 100644 --- a/execute1.vhdl +++ b/execute1.vhdl @@ -42,6 +42,10 @@ architecture behaviour of execute1 is signal ctrl: ctrl_t := (carry => '0', others => (others => '0')); signal ctrl_tmp: ctrl_t := (carry => '0', others => (others => '0')); + signal right_shift, rot_clear_left, rot_clear_right: std_ulogic; + signal rotator_result: std_ulogic_vector(63 downto 0); + signal rotator_carry: std_ulogic; + function decode_input_carry (carry_sel : carry_in_t; ca_in : std_ulogic) return std_ulogic is begin case carry_sel is @@ -54,6 +58,22 @@ architecture behaviour of execute1 is end case; end; begin + + rotator_0: entity work.rotator + port map ( + rs => e_in.read_data3, + ra => e_in.read_data1, + shift => e_in.read_data2(6 downto 0), + insn => e_in.insn, + is_32bit => e_in.is_32bit, + right_shift => right_shift, + arith => e_in.is_signed, + clear_left => rot_clear_left, + clear_right => rot_clear_right, + result => rotator_result, + carry_out => rotator_carry + ); + execute1_0: process(clk) begin if rising_edge(clk) then @@ -93,6 +113,11 @@ begin terminate_out <= '0'; f_out <= Execute1ToFetch1TypeInit; + -- rotator control signals + right_shift <= '1' when e_in.insn_type = OP_SHR else '0'; + rot_clear_left <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCL else '0'; + rot_clear_right <= '1' when e_in.insn_type = OP_RLC or e_in.insn_type = OP_RLCR else '0'; + if e_in.valid = '1' then v.e.valid := '1'; @@ -310,85 +335,11 @@ begin when OP_PRTYW => result := ppc_prtyw(e_in.read_data3); result_en := 1; - when OP_RLDCX => - -- note rldcl mb field and rldcr me field are in the same place - mb := insn_mb(e_in.insn); - if e_in.insn(1) = '0' then - result := ppc_rldcl(e_in.read_data3, e_in.read_data2, mb); - else - result := ppc_rldcr(e_in.read_data3, e_in.read_data2, mb); - end if; - result_en := 1; - when OP_RLDICL => - sh := insn_sh(e_in.insn); - mb := insn_mb(e_in.insn); - result := ppc_rldicl(e_in.read_data3, sh, mb); - result_en := 1; - when OP_RLDICR => - sh := insn_sh(e_in.insn); - me := insn_me(e_in.insn); - result := ppc_rldicr(e_in.read_data3, sh, me); - result_en := 1; - when OP_RLWNM => - mb32 := insn_mb32(e_in.insn); - me32 := insn_me32(e_in.insn); - result := ppc_rlwnm(e_in.read_data3, e_in.read_data2, mb32, me32); - result_en := 1; - when OP_RLWINM => - sh32 := insn_sh32(e_in.insn); - mb32 := insn_mb32(e_in.insn); - me32 := insn_me32(e_in.insn); - result := ppc_rlwinm(e_in.read_data3, sh32, mb32, me32); - result_en := 1; - when OP_RLDIC => - sh := insn_sh(e_in.insn); - mb := insn_mb(e_in.insn); - result := ppc_rldic(e_in.read_data3, sh, mb); - result_en := 1; - when OP_RLDIMI => - sh := insn_sh(e_in.insn); - mb := insn_mb(e_in.insn); - result := ppc_rldimi(e_in.read_data1, e_in.read_data3, sh, mb); - result_en := 1; - when OP_RLWIMI => - sh32 := insn_sh32(e_in.insn); - mb32 := insn_mb32(e_in.insn); - me32 := insn_me32(e_in.insn); - result := ppc_rlwimi(e_in.read_data1, e_in.read_data3, sh32, mb32, me32); - result_en := 1; - when OP_SLD => - result := ppc_sld(e_in.read_data3, e_in.read_data2); - result_en := 1; - when OP_SLW => - result := ppc_slw(e_in.read_data3, e_in.read_data2); - result_en := 1; - when OP_SRAW => - result_with_carry := ppc_sraw(e_in.read_data3, e_in.read_data2); - result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64); - result_en := 1; - when OP_SRAWI => - sh := '0' & insn_sh32(e_in.insn); - result_with_carry := ppc_srawi(e_in.read_data3, sh); - result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64); - result_en := 1; - when OP_SRAD => - result_with_carry := ppc_srad(e_in.read_data3, e_in.read_data2); - result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64); - result_en := 1; - when OP_SRADI => - sh := insn_sh(e_in.insn); - result_with_carry := ppc_sradi(e_in.read_data3, sh); - result := result_with_carry(63 downto 0); - ctrl_tmp.carry <= result_with_carry(64); - result_en := 1; - when OP_SRD => - result := ppc_srd(e_in.read_data3, e_in.read_data2); - result_en := 1; - when OP_SRW => - result := ppc_srw(e_in.read_data3, e_in.read_data2); + when OP_RLC | OP_RLCL | OP_RLCR | OP_SHL | OP_SHR => + result := rotator_result; + if e_in.output_carry = '1' then + ctrl_tmp.carry <= rotator_carry; + end if; result_en := 1; when OP_XOR => result := ppc_xor(e_in.read_data3, e_in.read_data2); diff --git a/microwatt.core b/microwatt.core index 94ff0c1..6143f50 100644 --- a/microwatt.core +++ b/microwatt.core @@ -24,6 +24,7 @@ filesets: - loadstore2.vhdl - multiply.vhdl - divider.vhdl + - rotator.vhdl - writeback.vhdl - insn_helpers.vhdl - core.vhdl diff --git a/rotator.vhdl b/rotator.vhdl new file mode 100644 index 0000000..d8a8ee9 --- /dev/null +++ b/rotator.vhdl @@ -0,0 +1,183 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.common.all; + +entity rotator is + port (rs: in std_ulogic_vector(63 downto 0); + ra: in std_ulogic_vector(63 downto 0); + shift: in std_ulogic_vector(6 downto 0); + insn: in std_ulogic_vector(31 downto 0); + is_32bit: in std_ulogic; + right_shift: in std_ulogic; + arith: in std_ulogic; + clear_left: in std_ulogic; + clear_right: in std_ulogic; + result: out std_ulogic_vector(63 downto 0); + carry_out: out std_ulogic + ); +end entity rotator; + +architecture behaviour of rotator is + signal repl32: std_ulogic_vector(63 downto 0); + signal rot_count: std_ulogic_vector(5 downto 0); + signal rot1, rot2, rot: std_ulogic_vector(63 downto 0); + signal sh, mb, me: std_ulogic_vector(6 downto 0); + signal mr, ml: std_ulogic_vector(63 downto 0); + signal output_mode: std_ulogic_vector(1 downto 0); + + -- note BE bit numbering + function right_mask(mask_begin: std_ulogic_vector(6 downto 0)) return std_ulogic_vector is + variable ret: std_ulogic_vector(63 downto 0); + begin + ret := (others => '0'); + for i in 0 to 63 loop + if i >= to_integer(unsigned(mask_begin)) then + ret(63 - i) := '1'; + end if; + end loop; + return ret; + end; + + function left_mask(mask_end: std_ulogic_vector(6 downto 0)) return std_ulogic_vector is + variable ret: std_ulogic_vector(63 downto 0); + begin + ret := (others => '0'); + if mask_end(6) = '0' then + for i in 0 to 63 loop + if i <= to_integer(unsigned(mask_end)) then + ret(63 - i) := '1'; + end if; + end loop; + end if; + return ret; + end; + +begin + rotator_0: process(all) + begin + -- First replicate bottom 32 bits to both halves if 32-bit + if is_32bit = '1' then + repl32 <= rs(31 downto 0) & rs(31 downto 0); + else + repl32 <= rs; + end if; + + -- Negate shift count for right shifts + if right_shift = '1' then + rot_count <= std_ulogic_vector(- signed(shift(5 downto 0))); + else + rot_count <= shift(5 downto 0); + end if; + + -- Rotator works in 3 stages using 2 bits of the rotate count each + -- time. This gives 4:1 multiplexors which is ideal for the 6-input + -- LUTs in the Xilinx Artix 7. + -- We look at the low bits of the rotate count first because they will + -- have less delay through the negation above. + -- First rotate by 0, 1, 2, or 3 + case rot_count(1 downto 0) is + when "00" => + rot1 <= repl32; + when "01" => + rot1 <= repl32(62 downto 0) & repl32(63); + when "10" => + rot1 <= repl32(61 downto 0) & repl32(63 downto 62); + when others => + rot1 <= repl32(60 downto 0) & repl32(63 downto 61); + end case; + -- Next rotate by 0, 4, 8 or 12 + case rot_count(3 downto 2) is + when "00" => + rot2 <= rot1; + when "01" => + rot2 <= rot1(59 downto 0) & rot1(63 downto 60); + when "10" => + rot2 <= rot1(55 downto 0) & rot1(63 downto 56); + when others => + rot2 <= rot1(51 downto 0) & rot1(63 downto 52); + end case; + -- Lastly rotate by 0, 16, 32 or 48 + case rot_count(5 downto 4) is + when "00" => + rot <= rot2; + when "01" => + rot <= rot2(47 downto 0) & rot2(63 downto 48); + when "10" => + rot <= rot2(31 downto 0) & rot2(63 downto 32); + when others => + rot <= rot2(15 downto 0) & rot2(63 downto 16); + end case; + + -- Trim shift count to 6 bits for 32-bit shifts + sh <= (shift(6) and not is_32bit) & shift(5 downto 0); + + -- Work out mask begin/end indexes (caution, big-endian bit numbering) + if clear_left = '1' then + if is_32bit = '1' then + mb <= "01" & insn(10 downto 6); + else + mb <= "0" & insn(5) & insn(10 downto 6); + end if; + elsif right_shift = '1' then + -- this is basically mb <= sh + (is_32bit? 32: 0); + if is_32bit = '1' then + mb <= sh(5) & not sh(5) & sh(4 downto 0); + else + mb <= sh; + end if; + else + mb <= ('0' & is_32bit & "00000"); + end if; + if clear_right = '1' and is_32bit = '1' then + me <= "01" & insn(5 downto 1); + elsif clear_right = '1' and clear_left = '0' then + me <= "0" & insn(5) & insn(10 downto 6); + else + -- effectively, 63 - sh + me <= sh(6) & not sh(5 downto 0); + end if; + + -- Calculate left and right masks + mr <= right_mask(mb); + ml <= left_mask(me); + + -- Work out output mode + -- 00 for sl[wd] + -- 0w for rlw*, rldic, rldicr, rldimi, where w = 1 iff mb > me + -- 10 for rldicl, sr[wd] + -- 1z for sra[wd][i], z = 1 if rs is negative + if (clear_left = '1' and clear_right = '0') or right_shift = '1' then + output_mode(1) <= '1'; + output_mode(0) <= arith and repl32(63); + else + output_mode(1) <= '0'; + if clear_right = '1' and unsigned(mb(5 downto 0)) > unsigned(me(5 downto 0)) then + output_mode(0) <= '1'; + else + output_mode(0) <= '0'; + end if; + end if; + + -- Generate output from rotated input and masks + case output_mode is + when "00" => + result <= (rot and (mr and ml)) or (ra and not (mr and ml)); + when "01" => + result <= (rot and (mr or ml)) or (ra and not (mr or ml)); + when "10" => + result <= rot and mr; + when others => + result <= rot or not mr; + end case; + + -- Generate carry output for arithmetic shift right of negative value + if output_mode = "11" then + carry_out <= or (rs and not ml); + else + carry_out <= '0'; + end if; + end process; +end behaviour; diff --git a/rotator_tb.vhdl b/rotator_tb.vhdl new file mode 100644 index 0000000..3cb46b0 --- /dev/null +++ b/rotator_tb.vhdl @@ -0,0 +1,269 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.common.all; +use work.glibc_random.all; +use work.ppc_fx_insns.all; +use work.insn_helpers.all; + +entity rotator_tb is +end rotator_tb; + +architecture behave of rotator_tb is + constant clk_period: time := 10 ns; + signal ra, rs: std_ulogic_vector(63 downto 0); + signal shift: std_ulogic_vector(6 downto 0) := (others => '0'); + signal insn: std_ulogic_vector(31 downto 0) := (others => '0'); + signal is_32bit, right_shift, arith, clear_left, clear_right: std_ulogic := '0'; + signal result: std_ulogic_vector(63 downto 0); + signal carry_out: std_ulogic; + +begin + rotator_0: entity work.rotator + port map ( + rs => rs, + ra => ra, + shift => shift, + insn => insn, + is_32bit => is_32bit, + right_shift => right_shift, + arith => arith, + clear_left => clear_left, + clear_right => clear_right, + result => result, + carry_out => carry_out + ); + + stim_process: process + variable behave_ra: std_ulogic_vector(63 downto 0); + variable behave_ca_ra: std_ulogic_vector(64 downto 0); + begin + -- rlwinm, rlwnm + report "test rlw[i]nm"; + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rlwnm_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rlwinm(rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); + assert behave_ra = result + report "bad rlwnm expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- rlwimi + report "test rlwimi"; + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rlwimi_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + ra <= pseudorand(64); + shift <= "00" & pseudorand(5); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rlwimi(ra, rs, shift(4 downto 0), insn_mb32(insn), insn_me32(insn)); + assert behave_ra = result + report "bad rlwimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- rldicl, rldcl + report "test rld[i]cl"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '0'; + rldicl_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldicl(rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldicl expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- rldicr, rldcr + report "test rld[i]cr"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '1'; + rldicr_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldicr(rs, shift(5 downto 0), insn_me(insn)); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "insn me = " & to_hstring(insn_me(insn)); + --report "result = " & to_hstring(result); + assert behave_ra = result + report "bad rldicr expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- rldic + report "test rldic"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rldic_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= '0' & pseudorand(6); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldic(rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldic expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- rldimi + report "test rldimi"; + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '1'; + clear_right <= '1'; + rldimi_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + ra <= pseudorand(64); + shift <= '0' & pseudorand(6); + insn <= x"00000" & '0' & pseudorand(10) & '0'; + wait for clk_period; + behave_ra := ppc_rldimi(ra, rs, shift(5 downto 0), insn_mb(insn)); + assert behave_ra = result + report "bad rldimi expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- slw + report "test slw"; + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + slw_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + wait for clk_period; + behave_ra := ppc_slw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad slw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- sld + report "test sld"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '0'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + sld_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + wait for clk_period; + behave_ra := ppc_sld(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad sld expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- srw + report "test srw"; + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '1'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + srw_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + wait for clk_period; + behave_ra := ppc_srw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad srw expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- srd + report "test srd"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '1'; + arith <= '0'; + clear_left <= '0'; + clear_right <= '0'; + srd_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + wait for clk_period; + behave_ra := ppc_srd(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + assert behave_ra = result + report "bad srd expected " & to_hstring(behave_ra) & " got " & to_hstring(result); + end loop; + + -- sraw[i] + report "test sraw[i]"; + ra <= (others => '0'); + is_32bit <= '1'; + right_shift <= '1'; + arith <= '1'; + clear_left <= '0'; + clear_right <= '0'; + sraw_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= '0' & pseudorand(6); + wait for clk_period; + behave_ca_ra := ppc_sraw(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "result = " & to_hstring(carry_out & result); + assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out + report "bad sraw expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); + end loop; + + -- srad[i] + report "test srad[i]"; + ra <= (others => '0'); + is_32bit <= '0'; + right_shift <= '1'; + arith <= '1'; + clear_left <= '0'; + clear_right <= '0'; + srad_loop : for i in 0 to 1000 loop + rs <= pseudorand(64); + shift <= pseudorand(7); + wait for clk_period; + behave_ca_ra := ppc_srad(rs, std_ulogic_vector(resize(unsigned(shift), 64))); + --report "rs = " & to_hstring(rs); + --report "ra = " & to_hstring(ra); + --report "shift = " & to_hstring(shift); + --report "result = " & to_hstring(carry_out & result); + assert behave_ca_ra(63 downto 0) = result and behave_ca_ra(64) = carry_out + report "bad srad expected " & to_hstring(behave_ca_ra) & " got " & to_hstring(carry_out & result); + end loop; + + assert false report "end of test" severity failure; + wait; + end process; +end behave;