mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-04-12 14:53:10 +00:00
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>
This commit is contained in:
113
decode1.vhdl
113
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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user