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

@ -26,6 +26,7 @@ architecture behaviour of decode1 is
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 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_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 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;
@ -112,17 +113,16 @@ architecture behaviour of decode1 is
others => illegal_inst others => illegal_inst
); );


constant decode_op_30_array : decode_rom_array_t := ( 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 -- 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'), 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'),
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'), 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'),
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'), 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'),
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'), 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'),
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'), -- rldcl, rldcr
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'), 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'),
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 => illegal_inst
others => decode_rom_init
); );


-- Note: reformat with column -t -o ' ' -- Note: reformat with column -t -o ' '
@ -280,6 +280,7 @@ begin
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); variable op_19_bits: std_ulogic_vector(2 downto 0);
variable op_30_bits: std_ulogic_vector(2 downto 0);
begin begin
v := r; v := r;


@ -645,29 +646,7 @@ begin
end if; end if;


elsif majorop = "011110" then elsif majorop = "011110" then
if std_match(f_in.insn, "---------------------------1000-") then v.decode := decode_op_30_array(to_integer(unsigned(f_in.insn(4 downto 2))));
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 elsif majorop = "111010" then
v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0)))); v.decode := decode_op_58_array(to_integer(unsigned(f_in.insn(1 downto 0))));

@ -51,7 +51,7 @@ package decode_types is
OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64, OP_MTCRF, OP_MTOCRF, OP_MTSPR, OP_MUL_L64,
OP_MUL_H64, OP_MUL_H32, OP_NAND, OP_NEG, OP_NOR, OP_OR, 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_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_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_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_SUBF, OP_SUBFE, OP_SUBFME, OP_SYNC, OP_TD, OP_TDI, OP_TW,

@ -274,11 +274,12 @@ begin
when OP_PRTYW => when OP_PRTYW =>
result := ppc_prtyw(e_in.read_data1); result := ppc_prtyw(e_in.read_data1);
result_en := 1; result_en := 1;
when OP_RLDCL => when OP_RLDCX =>
result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0)); if e_in.insn(1) = '0' then
result_en := 1; result := ppc_rldcl(e_in.read_data1, e_in.read_data2, e_in.const2(5 downto 0));
when OP_RLDCR => 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, e_in.const2(5 downto 0));
end if;
result_en := 1; result_en := 1;
when OP_RLDICL => when OP_RLDICL =>
result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0)); result := ppc_rldicl(e_in.read_data1, e_in.const1(5 downto 0), e_in.const2(5 downto 0));

Loading…
Cancel
Save