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 <paulus@ozlabs.org>
pull/78/head
Paul Mackerras 5 years ago
parent e30a87593a
commit 00e9f801f6

@ -24,6 +24,8 @@ architecture behaviour of decode1 is


subtype major_opcode_t is unsigned(5 downto 0); subtype major_opcode_t is unsigned(5 downto 0);
type major_rom_array_t is array(0 to 63) of decode_rom_t; 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 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; 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 others => illegal_inst
); );


constant decode_op_19_array : decode_rom_array_t := ( -- 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 -- 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 -- 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'), -- mcrf; cr logical ops not implemented yet
--PPC_ADDPCIS 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'),
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'), -- addpcis not implemented yet
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'), 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'),
--PPC_BCTAR -- bclr, bcctr, bctar
--PPC_CRAND 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'),
--PPC_CRANDC -- isync
--PPC_CREQV 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'),
--PPC_CRNAND others => illegal_inst
--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 := ( constant decode_op_30_array : decode_rom_array_t := (
@ -260,6 +279,7 @@ begin
variable v : Decode1ToDecode2Type; variable v : Decode1ToDecode2Type;
variable ppc_insn: ppc_insn_t; variable ppc_insn: ppc_insn_t;
variable majorop : major_opcode_t; variable majorop : major_opcode_t;
variable op_19_bits: std_ulogic_vector(2 downto 0);
begin begin
v := r; v := r;


@ -615,53 +635,14 @@ begin
v.decode := decode_op_31_array(ppc_insn); v.decode := decode_op_31_array(ppc_insn);


elsif majorop = "010011" then elsif majorop = "010011" then
if std_match(f_in.insn, "--------------------------00010-") then if decode_op_19_valid(to_integer(unsigned(f_in.insn(10 downto 1)))) = '0' then
report "PPC_addpcis"; report "op 19 illegal subcode";
ppc_insn := PPC_ADDPCIS; v.decode := illegal_inst;
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 else
report "PPC_illegal"; op_19_bits := f_in.insn(5) & f_in.insn(3) & f_in.insn(2);
ppc_insn := PPC_ILLEGAL; v.decode := decode_op_19_array(to_integer(unsigned(op_19_bits)));
report "op 19 sub " & to_hstring(op_19_bits);
end if; end if;
v.decode := decode_op_19_array(ppc_insn);


elsif majorop = "011110" then elsif majorop = "011110" then
if std_match(f_in.insn, "---------------------------1000-") then if std_match(f_in.insn, "---------------------------1000-") then

@ -39,9 +39,8 @@ package decode_types is
PPC_SIM_CONFIG); PPC_SIM_CONFIG);


type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ADDE, OP_ADDEX, OP_ADDME, type insn_type_t is (OP_ILLEGAL, OP_NOP, OP_ADD, OP_ADDE, OP_ADDEX, OP_ADDME,
OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC, OP_ADDPCIS, OP_AND, OP_ANDC, OP_ATTN, OP_B, OP_BC, OP_BCREG,
OP_BCCTR, OP_BCLR, OP_BCTAR, OP_BPERM, OP_CMP, OP_BPERM, OP_CMP, OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB,
OP_CMPB, OP_CMPEQB, OP_CMPL, OP_CMPRB,
OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND, OP_CNTLZD, OP_CNTLZW, OP_CNTTZD, OP_CNTTZW, OP_CRAND,
OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC, OP_CRANDC, OP_CREQV, OP_CRNAND, OP_CRNOR, OP_CROR, OP_CRORC,
OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST, OP_CRXOR, OP_DARN, OP_DCBF, OP_DCBST, OP_DCBT, OP_DCBTST,

@ -120,19 +120,19 @@ begin
f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2)); f_out.redirect_nia <= std_ulogic_vector(signed(e_in.nia) + signed(e_in.read_data2));
end if; end if;
end if; end if;
when OP_BCLR => when OP_BCREG =>
if e_in.const1(4-2) = '0' then -- 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); ctrl_tmp.ctr <= std_ulogic_vector(unsigned(ctrl.ctr) - 1);
end if; end if;
if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then if ppc_bc_taken(e_in.const1(4 downto 0), e_in.const2(4 downto 0), e_in.cr, ctrl.ctr) = 1 then
f_out.redirect <= '1'; f_out.redirect <= '1';
if e_in.insn(10) = '0' then
f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00"; f_out.redirect_nia <= ctrl.lr(63 downto 2) & "00";
end if; else
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"; f_out.redirect_nia <= ctrl.ctr(63 downto 2) & "00";
end if; end if;
end if;
when OP_CMPB => when OP_CMPB =>
result := ppc_cmpb(e_in.read_data1, e_in.read_data2); result := ppc_cmpb(e_in.read_data1, e_in.read_data2);
result_en := 1; result_en := 1;

Loading…
Cancel
Save