@ -110,11 +110,12 @@ package decode_types is
INSN_rldimi,
INSN_rldimi,
INSN_rlwimi,
INSN_rlwimi,
INSN_rlwinm,
INSN_rlwinm,
INSN_rnop,
INSN_sc,
INSN_sc,
INSN_setb,
INSN_setb,
INSN_slbia,
INSN_slbia,
INSN_sradi,
INSN_sradi, -- 80
INSN_srawi, -- 80
INSN_srawi,
INSN_stbu,
INSN_stbu,
INSN_std,
INSN_std,
INSN_stdu,
INSN_stdu,
@ -123,25 +124,27 @@ package decode_types is
INSN_subfic,
INSN_subfic,
INSN_subfme,
INSN_subfme,
INSN_subfze,
INSN_subfze,
INSN_sync,
INSN_sync, -- 90
INSN_tdi, -- 90
INSN_tdi,
INSN_tlbsync,
INSN_tlbsync,
INSN_twi,
INSN_twi,
INSN_wait,
INSN_wait,
INSN_xori,
INSN_xori,
INSN_xoris,
INSN_xoris,
-- pad to 104
INSN_061, INSN_062, INSN_063, INSN_064, INSN_065, INSN_066, INSN_067,
-- Non-prefixed instructions that have a MLS:D prefixed form and
-- Non-prefixed instructions that have a MLS:D prefixed form and
-- their corresponding prefixed instructions.
-- their corresponding prefixed instructions.
-- The non-prefixed versions have even indexes so that we can
-- The non-prefixed versions have even indexes so that we can
-- convert them to the prefixed version by setting bit 0
-- convert them to the prefixed version by setting bit 0
INSN_addi, -- 96
INSN_addi, -- 104
INSN_paddi,
INSN_paddi,
INSN_lbz,
INSN_lbz,
INSN_plbz,
INSN_plbz,
INSN_lha, -- 100
INSN_lha,
INSN_plha,
INSN_plha,
INSN_lhz,
INSN_lhz, -- 110
INSN_plhz,
INSN_plhz,
INSN_lwz,
INSN_lwz,
INSN_plwz,
INSN_plwz,
@ -149,11 +152,11 @@ package decode_types is
INSN_pstb,
INSN_pstb,
INSN_sth,
INSN_sth,
INSN_psth,
INSN_psth,
INSN_stw, -- 110
INSN_stw,
INSN_pstw,
INSN_pstw,
-- Slots for non-prefixed opcodes that are 8LS:D when prefixed
-- Slots for non-prefixed opcodes that are 8LS:D when prefixed
INSN_lhzu, -- 112
INSN_lhzu, -- 120
INSN_plwa,
INSN_plwa,
INSN_op57,
INSN_op57,
INSN_pld,
INSN_pld,
@ -161,8 +164,7 @@ package decode_types is
INSN_pstd,
INSN_pstd,
-- pad to 128 to simplify comparison logic
-- pad to 128 to simplify comparison logic
INSN_076, INSN_077,
INSN_07e, INSN_07f,
INSN_078, INSN_079, INSN_07a, INSN_07b, INSN_07c, INSN_07d, INSN_07e, INSN_07f,
-- The following instructions have an RB operand but don't access FPRs
-- The following instructions have an RB operand but don't access FPRs
INSN_add,
INSN_add,
@ -475,7 +477,306 @@ package decode_types is
update => '0', reserve => '0', is_32bit => '0',
update => '0', reserve => '0', is_32bit => '0',
is_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0', repeat => NONE);
is_signed => '0', rc => NONE, lr => '0', sgl_pipe => '0', repeat => NONE);
-- This function maps from insn_code values to primary opcode.
-- With this, we don't have to store the primary opcode of each instruction
-- in the icache if we are storing its insn_code.
function recode_primary_opcode(icode: insn_code) return std_ulogic_vector;
end decode_types;
end decode_types;
package body decode_types is
package body decode_types is
function recode_primary_opcode(icode: insn_code) return std_ulogic_vector is
begin
case icode is
when INSN_addic => return "001100";
when INSN_addic_dot => return "001101";
when INSN_addi => return "001110";
when INSN_addis => return "001111";
when INSN_addpcis => return "010011";
when INSN_andi_dot => return "011100";
when INSN_andis_dot => return "011101";
when INSN_attn => return "000000";
when INSN_b => return "010010";
when INSN_bc => return "010000";
when INSN_brh => return "011111";
when INSN_brw => return "011111";
when INSN_brd => return "011111";
when INSN_cmpi => return "001011";
when INSN_cmpli => return "001010";
when INSN_lbz => return "100010";
when INSN_lbzu => return "100011";
when INSN_lfd => return "110010";
when INSN_lfdu => return "110011";
when INSN_lfs => return "110000";
when INSN_lfsu => return "110001";
when INSN_lha => return "101010";
when INSN_lhau => return "101011";
when INSN_lhz => return "101000";
when INSN_lhzu => return "101001";
when INSN_lwz => return "100000";
when INSN_lwzu => return "100001";
when INSN_mulli => return "000111";
when INSN_nop => return "011000";
when INSN_ori => return "011000";
when INSN_oris => return "011001";
when INSN_rlwimi => return "010100";
when INSN_rlwinm => return "010101";
when INSN_rlwnm => return "010111";
when INSN_sc => return "010001";
when INSN_stb => return "100110";
when INSN_stbu => return "100111";
when INSN_stfd => return "110110";
when INSN_stfdu => return "110111";
when INSN_stfs => return "110100";
when INSN_stfsu => return "110101";
when INSN_sth => return "101100";
when INSN_sthu => return "101101";
when INSN_stw => return "100100";
when INSN_stwu => return "100101";
when INSN_subfic => return "001000";
when INSN_tdi => return "000010";
when INSN_twi => return "000011";
when INSN_xori => return "011010";
when INSN_xoris => return "011011";
when INSN_maddhd => return "000100";
when INSN_maddhdu => return "000100";
when INSN_maddld => return "000100";
when INSN_rldic => return "011110";
when INSN_rldicl => return "011110";
when INSN_rldicr => return "011110";
when INSN_rldimi => return "011110";
when INSN_rldcl => return "011110";
when INSN_rldcr => return "011110";
when INSN_ld => return "111010";
when INSN_ldu => return "111010";
when INSN_lwa => return "111010";
when INSN_fdivs => return "111011";
when INSN_fsubs => return "111011";
when INSN_fadds => return "111011";
when INSN_fsqrts => return "111011";
when INSN_fres => return "111011";
when INSN_fmuls => return "111011";
when INSN_frsqrtes => return "111011";
when INSN_fmsubs => return "111011";
when INSN_fmadds => return "111011";
when INSN_fnmsubs => return "111011";
when INSN_fnmadds => return "111011";
when INSN_std => return "111110";
when INSN_stdu => return "111110";
when INSN_fdiv => return "111111";
when INSN_fsub => return "111111";
when INSN_fadd => return "111111";
when INSN_fsqrt => return "111111";
when INSN_fsel => return "111111";
when INSN_fre => return "111111";
when INSN_fmul => return "111111";
when INSN_frsqrte => return "111111";
when INSN_fmsub => return "111111";
when INSN_fmadd => return "111111";
when INSN_fnmsub => return "111111";
when INSN_fnmadd => return "111111";
when INSN_prefix => return "000001";
when INSN_op57 => return "111001";
when INSN_op61 => return "111101";
when INSN_add => return "011111";
when INSN_addc => return "011111";
when INSN_adde => return "011111";
when INSN_addex => return "011111";
when INSN_addg6s => return "011111";
when INSN_addme => return "011111";
when INSN_addze => return "011111";
when INSN_and => return "011111";
when INSN_andc => return "011111";
when INSN_bperm => return "011111";
when INSN_cbcdtd => return "011111";
when INSN_cdtbcd => return "011111";
when INSN_cmp => return "011111";
when INSN_cmpb => return "011111";
when INSN_cmpeqb => return "011111";
when INSN_cmpl => return "011111";
when INSN_cmprb => return "011111";
when INSN_cntlzd => return "011111";
when INSN_cntlzw => return "011111";
when INSN_cnttzd => return "011111";
when INSN_cnttzw => return "011111";
when INSN_darn => return "011111";
when INSN_dcbf => return "011111";
when INSN_dcbst => return "011111";
when INSN_dcbt => return "011111";
when INSN_dcbtst => return "011111";
when INSN_dcbz => return "011111";
when INSN_divdeu => return "011111";
when INSN_divweu => return "011111";
when INSN_divde => return "011111";
when INSN_divwe => return "011111";
when INSN_divdu => return "011111";
when INSN_divwu => return "011111";
when INSN_divd => return "011111";
when INSN_divw => return "011111";
when INSN_eieio => return "011111";
when INSN_eqv => return "011111";
when INSN_extsb => return "011111";
when INSN_extsh => return "011111";
when INSN_extsw => return "011111";
when INSN_extswsli => return "011111";
when INSN_icbi => return "011111";
when INSN_icbt => return "011111";
when INSN_isel => return "011111";
when INSN_lbarx => return "011111";
when INSN_lbzcix => return "011111";
when INSN_lbzux => return "011111";
when INSN_lbzx => return "011111";
when INSN_ldarx => return "011111";
when INSN_ldbrx => return "011111";
when INSN_ldcix => return "011111";
when INSN_ldux => return "011111";
when INSN_ldx => return "011111";
when INSN_lfdx => return "011111";
when INSN_lfdux => return "011111";
when INSN_lfiwax => return "011111";
when INSN_lfiwzx => return "011111";
when INSN_lfsx => return "011111";
when INSN_lfsux => return "011111";
when INSN_lharx => return "011111";
when INSN_lhaux => return "011111";
when INSN_lhax => return "011111";
when INSN_lhbrx => return "011111";
when INSN_lhzcix => return "011111";
when INSN_lhzux => return "011111";
when INSN_lhzx => return "011111";
when INSN_lwarx => return "011111";
when INSN_lwaux => return "011111";
when INSN_lwax => return "011111";
when INSN_lwbrx => return "011111";
when INSN_lwzcix => return "011111";
when INSN_lwzux => return "011111";
when INSN_lwzx => return "011111";
when INSN_mcrxrx => return "011111";
when INSN_mfcr => return "011111";
when INSN_mfmsr => return "011111";
when INSN_mfspr => return "011111";
when INSN_modud => return "011111";
when INSN_moduw => return "011111";
when INSN_modsd => return "011111";
when INSN_modsw => return "011111";
when INSN_mtcrf => return "011111";
when INSN_mtmsr => return "011111";
when INSN_mtmsrd => return "011111";
when INSN_mtspr => return "011111";
when INSN_mulhd => return "011111";
when INSN_mulhdu => return "011111";
when INSN_mulhw => return "011111";
when INSN_mulhwu => return "011111";
when INSN_mulld => return "011111";
when INSN_mullw => return "011111";
when INSN_nand => return "011111";
when INSN_neg => return "011111";
when INSN_rnop => return "011111";
when INSN_nor => return "011111";
when INSN_or => return "011111";
when INSN_orc => return "011111";
when INSN_popcntb => return "011111";
when INSN_popcntd => return "011111";
when INSN_popcntw => return "011111";
when INSN_prtyd => return "011111";
when INSN_prtyw => return "011111";
when INSN_setb => return "011111";
when INSN_slbia => return "011111";
when INSN_sld => return "011111";
when INSN_slw => return "011111";
when INSN_srad => return "011111";
when INSN_sradi => return "011111";
when INSN_sraw => return "011111";
when INSN_srawi => return "011111";
when INSN_srd => return "011111";
when INSN_srw => return "011111";
when INSN_stbcix => return "011111";
when INSN_stbcx => return "011111";
when INSN_stbux => return "011111";
when INSN_stbx => return "011111";
when INSN_stdbrx => return "011111";
when INSN_stdcix => return "011111";
when INSN_stdcx => return "011111";
when INSN_stdux => return "011111";
when INSN_stdx => return "011111";
when INSN_stfdx => return "011111";
when INSN_stfdux => return "011111";
when INSN_stfiwx => return "011111";
when INSN_stfsx => return "011111";
when INSN_stfsux => return "011111";
when INSN_sthbrx => return "011111";
when INSN_sthcix => return "011111";
when INSN_sthcx => return "011111";
when INSN_sthux => return "011111";
when INSN_sthx => return "011111";
when INSN_stwbrx => return "011111";
when INSN_stwcix => return "011111";
when INSN_stwcx => return "011111";
when INSN_stwux => return "011111";
when INSN_stwx => return "011111";
when INSN_subf => return "011111";
when INSN_subfc => return "011111";
when INSN_subfe => return "011111";
when INSN_subfme => return "011111";
when INSN_subfze => return "011111";
when INSN_sync => return "011111";
when INSN_td => return "011111";
when INSN_tw => return "011111";
when INSN_tlbie => return "011111";
when INSN_tlbiel => return "011111";
when INSN_tlbsync => return "011111";
when INSN_wait => return "011111";
when INSN_xor => return "011111";
when INSN_bcctr => return "010011";
when INSN_bclr => return "010011";
when INSN_bctar => return "010011";
when INSN_crand => return "010011";
when INSN_crandc => return "010011";
when INSN_creqv => return "010011";
when INSN_crnand => return "010011";
when INSN_crnor => return "010011";
when INSN_cror => return "010011";
when INSN_crorc => return "010011";
when INSN_crxor => return "010011";
when INSN_isync => return "010011";
when INSN_mcrf => return "010011";
when INSN_rfid => return "010011";
when INSN_fcfids => return "111011";
when INSN_fcfidus => return "111011";
when INSN_fcmpu => return "111111";
when INSN_fcmpo => return "111111";
when INSN_mcrfs => return "111111";
when INSN_ftdiv => return "111111";
when INSN_ftsqrt => return "111111";
when INSN_mtfsb => return "111111";
when INSN_mtfsfi => return "111111";
when INSN_fmrgow => return "111111";
when INSN_fmrgew => return "111111";
when INSN_mffs => return "111111";
when INSN_mtfsf => return "111111";
when INSN_fcpsgn => return "111111";
when INSN_fneg => return "111111";
when INSN_fmr => return "111111";
when INSN_fnabs => return "111111";
when INSN_fabs => return "111111";
when INSN_frin => return "111111";
when INSN_friz => return "111111";
when INSN_frip => return "111111";
when INSN_frim => return "111111";
when INSN_frsp => return "111111";
when INSN_fctiw => return "111111";
when INSN_fctiwu => return "111111";
when INSN_fctid => return "111111";
when INSN_fcfid => return "111111";
when INSN_fctidu => return "111111";
when INSN_fcfidu => return "111111";
when INSN_fctiwz => return "111111";
when INSN_fctiwuz => return "111111";
when INSN_fctidz => return "111111";
when INSN_fctiduz => return "111111";
when others => return "XXXXXX";
end case;
end;
end decode_types;
end decode_types;