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>
jtag-port
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);
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

@ -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,

@ -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);

Loading…
Cancel
Save