URL
https://opencores.org/ocsvn/core_arm/core_arm/trunk
Subversion Repositories core_arm
[/] [core_arm/] [trunk/] [vhdl/] [arm/] [libs/] [armdecode.vhd] - Rev 4
Compare with Previous | Blame | View Log
library ieee; use ieee.std_logic_1164.all; use work.config.all; use work.memdef.all; use work.armpmodel.all; use work.armshiefter.all; -- PREFIX: ade_xxx package armdecode is ------------------------------------------------------------------------------- -- Addressing modes: -- DAta PRocessing Addressing Modes : DAPRAM -- LoaD/STore Addressing Modes : LDSTAM -- Load/Store misc (V4) Addressing Modes : LSV4AM -- DAta PRocessing Addressing Modes (DAPRAM): -- -- o ade_DAPRAM_simm: -- - DP op2: Register : <rm> -- - DP op2: Register <SDIR> by Immediate : <rm>, <SDIR> #<imm> -- - DP op2: Register RRX : <rm>, RRX -- - <SDIR>: {LSL}|{LSR}|{ASR}|{ROR} -- o ade_DAPRAM_sreg: -- - DP op2: Register <SDIR> by Register : <rm>, <SDIR> <rs> -- - <SDIR>: {LSL}|{LSR}|{ASR}|{ROR} -- o ade_DAPRAM_immrot: -- - DP op2: Immediate #<imm> type ade_DAPRAM is ( ade_DAPRAM_simm, -- OP2 shieft with imm ade_DAPRAM_sreg, -- OP2 shieft with reg ade_DAPRAM_immrot -- OP2 immidiate rotated ); -- Load/Store Addressing Modes (LDSTAM) and Load/Store misc (V4) Addressing Modes (LSV4AM) : -- -- o adm_LDSTAMxLSV4AM_reg: -- * <LSV4AM> -- - L/S W/UB: Register Offset : [<rn>, +/-<rm>] -- - L/S W/UB: Register Offset pre-indexed : [<rn>, +/-<rm>]! -- - L/S W/UB: Register Offset post-indexed : [<rn>], +/-<rm> -- - L/S W/UB: Scaled Register Offset : [<rn>, +/-<rm>, <LSAMscale>] -- - L/S W/UB: Scaled Register Offset pre-indexed : [<rn>, +/-<rm>, <LSAMscale>]! -- - L/S W/UB: Scaled Register Offset post-indexed : [<rn>], +/-<rm>, <LSAMscale> -- - <LSAMscale>: {LSL #<imm>}|{LSR #<imm>}|{ASR #<imm>}|{ROR #<imm>}|{RRX} -- * <LDSTAM> -- - L/S MISC: Register offset : [<rn>, #+/-<rm>] -- - L/S MISC: Register offset pre-index : [<rn>, #+/-<rm>] ! -- - L/S MISC: Register offset post-index : [<rn>], #+/-<rm> -- o adm_LDSTAMxLSV4AM_imm: -- * <LSV4AM> -- - L/S W/UB: Immediate Offset : [<rn>, #+/-<offset12>] -- - L/S W/UB: Immediate Offset pre-indexed : [<rn>, #+/-<offset12>]! -- - L/S W/UB: Immediate Offset post-indexed : [<rn>], #+/-<offset12> -- * <LDSTAM> -- - L/S MISC: Immediate offset : [<rn>, #+/-<off>] -- - L/S MISC: Immediate offset pre-index : [<rn>, #+/-<off>] ! -- - L/S MISC: Immediate offset post-index : [<rn>], #+/-<off> type ade_LDSTAMxLSV4AM is ( ade_LDSTAMxLSV4AM_imm, -- addr v1 imm -- addr v4 imm ade_LDSTAMxLSV4AM_reg -- addr v1 reg (shieft with imm) -- addr v4 reg ); -- Prefix/Postfix type ade_pos is ( ade_pre, -- pre indexed ade_post -- post indexed ); -- Decoded addressing mode type ade_amode is record DAPRAM_typ : ade_DAPRAM; LDSTAM_typ : ade_LDSTAMxLSV4AM; LSV4AM_typ : ade_LDSTAMxLSV4AM; LDSTAMxLSV4AM_pos : ade_pos; DAPRAMxLDSTAM_sdir : ash_sdir; LDSTAMxLSV4AM_uacc : std_logic; LDSTAMxLSV4AM_wb : std_logic; end record; -- Decode addressing mode procedure ade_decode_amode ( insn : in std_logic_vector(31 downto 0); am : out ade_amode ); ------------------------------------------------------------------------------- -- Implemented instructions: type ade_decinsn is ( type_arm_invalid,type_arm_nop, type_arm_mrs, type_arm_bx, type_arm_mul, type_arm_mla, type_arm_swp, type_arm_sumull, type_arm_sumlal, type_arm_strhb, type_arm_ldrhb, type_arm_and, type_arm_sub, type_arm_eor, type_arm_rsb, type_arm_add, type_arm_sbc, type_arm_adc, type_arm_msr, type_arm_teq, type_arm_cmn, type_arm_tst, type_arm_cmp, type_arm_orr, type_arm_mov, type_arm_mvn, type_arm_str1, type_arm_str2, type_arm_str3, type_arm_ldr1, type_arm_stm, type_arm_ldm, type_arm_b, type_arm_swi, type_arm_cdp, type_arm_mrc, type_arm_mcr, type_arm_stc, type_arm_ldc, type_arm_rsc, type_arm_bic, type_arm_undefined ); -- Instruction groups type ade_insntyp is ( ade_typmem, ade_typalu, ade_typmisc, ade_typcp ); -- this decoder is automatically generated by "decgen" function ade_decode_v4( insn_in : in std_logic_vector(31 downto 0) ) return ade_decinsn; ------------------------------------------------------------------------------- -- Condition code constant ADE_COND_U : integer := 31; constant ADE_COND_D : integer := 28; constant ADE_COND_EQ : std_logic_vector(3 downto 0) := "0000"; constant ADE_COND_NE : std_logic_vector(3 downto 0) := "0001"; constant ADE_COND_CS : std_logic_vector(3 downto 0) := "0010"; constant ADE_COND_CC : std_logic_vector(3 downto 0) := "0011"; constant ADE_COND_MI : std_logic_vector(3 downto 0) := "0100"; constant ADE_COND_PL : std_logic_vector(3 downto 0) := "0101"; constant ADE_COND_VS : std_logic_vector(3 downto 0) := "0110"; constant ADE_COND_VC : std_logic_vector(3 downto 0) := "0111"; constant ADE_COND_HI : std_logic_vector(3 downto 0) := "1000"; constant ADE_COND_LS : std_logic_vector(3 downto 0) := "1001"; constant ADE_COND_GE : std_logic_vector(3 downto 0) := "1010"; constant ADE_COND_LT : std_logic_vector(3 downto 0) := "1011"; constant ADE_COND_GT : std_logic_vector(3 downto 0) := "1100"; constant ADE_COND_LE : std_logic_vector(3 downto 0) := "1101"; constant ADE_COND_AL : std_logic_vector(3 downto 0) := "1110"; constant ADE_COND_NV : std_logic_vector(3 downto 0) := "1111"; ------------------------------------------------------------------------------- -- Alu codes constant ADE_OP_U : integer := 24; constant ADE_OP_D : integer := 21; constant ADE_OP_AND : std_logic_vector(3 downto 0) := "0000"; constant ADE_OP_EOR : std_logic_vector(3 downto 0) := "0001"; constant ADE_OP_SUB : std_logic_vector(3 downto 0) := "0010"; constant ADE_OP_RSB : std_logic_vector(3 downto 0) := "0011"; constant ADE_OP_ADD : std_logic_vector(3 downto 0) := "0100"; constant ADE_OP_ADC : std_logic_vector(3 downto 0) := "0101"; constant ADE_OP_SBC : std_logic_vector(3 downto 0) := "0110"; constant ADE_OP_RSC : std_logic_vector(3 downto 0) := "0111"; constant ADE_OP_TST : std_logic_vector(3 downto 0) := "1000"; constant ADE_OP_TEQ : std_logic_vector(3 downto 0) := "1001"; constant ADE_OP_CMP : std_logic_vector(3 downto 0) := "1010"; constant ADE_OP_CMN : std_logic_vector(3 downto 0) := "1011"; constant ADE_OP_ORR : std_logic_vector(3 downto 0) := "1100"; constant ADE_OP_MOV : std_logic_vector(3 downto 0) := "1101"; constant ADE_OP_BIC : std_logic_vector(3 downto 0) := "1110"; constant ADE_OP_MVN : std_logic_vector(3 downto 0) := "1111"; constant ADE_SETCPSR_C : integer := 20; -- set cpsr ------------------------------------------------------------------------------- -- swp, msr, mrs codes constant ADE_MSR_R : integer := 22; -- '1' = spsr: '0' = cpsr constant ADE_MRS_R : integer := 22; -- '1' = spsr: '0' = cpsr constant ADE_MSR_IMM : integer := 16; -- '1' = imm; '0' = reg constant ADE_WB_C : integer := 21; -- same as ADE_LDSTAMxLSV4AM_WB constant ADE_SWPB_C : integer := 22; -- 1=SWPB,0=SWP constant ADE_BROFF_U : integer := 23; -- branch offset constant ADE_BROFF_D : integer := 0; constant ADE_BRLINK_C : integer := 22; ------------------------------------------------------------------------------- -- ld, st codes constant ADE_LDSTAM_OFF_U : integer := 11; -- <offset12> of armcmd_l1.vhd LDSSTAM constant ADE_LDSTAM_OFF_D : integer := 0; constant ADE_LSV4AM_OFF8_HU : integer := 11; -- <offset8> of armcmd_l4.vhd LSV4AM constant ADE_LSV4AM_OFF8_HD : integer := 8; constant ADE_LSV4AM_OFF8_LU : integer := 3; constant ADE_LSV4AM_OFF8_LD : integer := 0; constant ADE_LDSTAM_UBYTE : integer := 22; -- '1': unsigned byte, '0': word constant ADE_LSV4AM_SIGNED : integer := 6; -- '1': unsigned byte, '0': word constant ADE_LSV4AM_HALF : integer := 5; -- '1': unsigned byte, '0': word constant ADE_LDSTAMxLSV4AM_ADD : integer := 23; -- '1': add, '0': sub constant ADE_PAB_U : integer := 24; -- '0': after / '1': before constant ADE_UID_U : integer := 23; -- '1':increment / '0':decrement constant ADE_REGLIST_U : integer := 15; constant ADE_REGLIST_D : integer := 0; ------------------------------------------------------------------------------- -- coprocessor constant ADE_MRC_MCR_C : integer := 20; -- '1':MRC '0':MCR constant ADE_LDC_STC_WB_C : integer := 21; -- '1': writeback '0': nowriteback (ADE_LDSTAMxLSV4AM_WB) constant ADE_LDC_STC_P_C : integer := 24; -- '1': Post; '0': Pre (negate ADE_LDSTAMxLSV4AM_POS) ------------------------------------------------------------------------------- -- registers constant ADE_RN_U : integer := 19; constant ADE_RN_D : integer := 16; constant ADE_RD_U : integer := 15; constant ADE_RD_D : integer := 12; constant ADE_RM_U : integer := 3; constant ADE_RM_D : integer := 0; constant ADE_SREG_U : integer := 11; -- shieft register constant ADE_SREG_D : integer := 8; ------------------------------------------------------------------------------- -- festg out insn type ade_feinsn is record insn : std_logic_vector(31 downto 0); pc : std_logic_vector(31 downto 0); pc_vir : std_logic_vector(31 downto 0); valid : std_logic; trap : std_logic; end record; -- Decoded insn type ade_insn is record pc_8 : std_logic_vector(31 downto 0); insn : std_logic_vector(31 downto 0); insntyp : ade_insntyp; decinsn : ade_decinsn; am : ade_amode; valid : std_logic; id : std_logic_vector(2 downto 0); end record; -- destg out insn type ade_deinsn is record insn : ade_insn; trap : std_logic; end record; ------------------------------------------------------------------------------- end armdecode; package body armdecode is -- Addressing mode decode constants -- DAPRAM: am.DAPRAM_typ constant ADE_DAPRAM_TYP : integer := 25; -- '1': imm rot, '0': sreg/simm (shiefted) constant ADE_DAPRAM_TYP_P : integer := 4; -- shiefted: ('0': imm , '1': reg) -- LDSTAM: am.LDSTAM_typ constant ADE_LDSTAM_TYP : integer := 25; -- '0': adm_LDSTAM_imm, '1': adm_LDSTAM_reg (shiefted) -- LSV4AM: am.LSV4AM_typ constant ADE_LSV4AM_TYP : integer := 22; -- '1': adm_LSV4AM_imm , '0': adm_LSV4AM_reg -- DAPRAM, LDSTAM: am.DAPRAMxLDSTAM_sdir constant ADE_DAPRAMxLDSTAM_SDIR_U : integer := 6; -- shieft type constant ADE_DAPRAMxLDSTAM_SDIR_D : integer := 5; constant ADE_DAPRAMxLDSTAM_SDIRNONE_U : integer := 11; -- no shieft constant ADE_DAPRAMxLDSTAM_SDIRNONE_D : integer := 4; constant ADE_DAPRAMxLDSTAM_SDIRROR_U : integer := 11; -- ror constant ADE_DAPRAMxLDSTAM_SDIRROR_D : integer := 7; -- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_pos -- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_wb -- LDSTAM, LSV4AM: am.LDSTAMxLSV4AM_uacc constant ADE_LDSTAMxLSV4AM_POS : integer := 24; -- '0': postindexed, '1': preindexed constant ADE_LDSTAMxLSV4AM_WB : integer := 21; -- postindexed: 0 = normal, 1 = usermode procedure ade_decode_amode ( insn : in std_logic_vector(31 downto 0); am : out ade_amode ) is variable tmp : std_logic_vector(4 downto 0); begin -- DAPRAM: typ am.DAPRAM_typ := ade_DAPRAM_simm; if insn(ADE_DAPRAM_TYP_P) = '1' then am.DAPRAM_typ := ade_DAPRAM_sreg; end if; -- DPAM and LSAM: shieft direction am.DAPRAMxLDSTAM_sdir := ash_sdir_srrx; case insn(ADE_DAPRAMxLDSTAM_SDIR_U downto ADE_DAPRAMxLDSTAM_SDIR_D) is when "00" => am.DAPRAMxLDSTAM_sdir := ash_sdir_slsl; if insn(ADE_DAPRAMxLDSTAM_SDIRNONE_U downto ADE_DAPRAMxLDSTAM_SDIRNONE_D) = "00000000" then am.DAPRAMxLDSTAM_sdir := ash_sdir_snone; end if; when "01" => am.DAPRAMxLDSTAM_sdir := ash_sdir_slsr; when "10" => am.DAPRAMxLDSTAM_sdir := ash_sdir_sasr; when "11" => if not (insn(ADE_DAPRAMxLDSTAM_SDIRROR_U downto ADE_DAPRAMxLDSTAM_SDIRROR_D) = "00000") then am.DAPRAMxLDSTAM_sdir := ash_sdir_sror; end if; when others => null; end case; -- DAPRAM: typ if insn(ADE_DAPRAM_TYP) = '1' then am.DAPRAM_typ := ade_DAPRAM_immrot; end if; -- LDSTAM: typ am.LDSTAM_typ := ade_LDSTAMxLSV4AM_imm; if insn(ADE_LDSTAM_TYP) = '1' then am.LDSTAM_typ := ade_LDSTAMxLSV4AM_reg; -- am.DAPRAMxLDSTAM_sdir := ade_snone; end if; -- LDSTAM and LSV4AM: preindexed / postindexed am.LDSTAMxLSV4AM_uacc := '0'; am.LDSTAMxLSV4AM_wb := '1'; if insn(ADE_LDSTAMxLSV4AM_POS) = '1' then am.LDSTAMxLSV4AM_pos := ade_pre; if insn(ADE_LDSTAMxLSV4AM_WB) = '0' then am.LDSTAMxLSV4AM_wb := '0'; end if; else am.LDSTAMxLSV4AM_pos := ade_post; if insn(ADE_LDSTAMxLSV4AM_WB) = '1' then am.LDSTAMxLSV4AM_uacc := '1'; end if; end if; -- LSV4AM: offset, register (not shiefted) am.LSV4AM_typ := ade_LDSTAMxLSV4AM_imm; if insn(ADE_LSV4AM_TYP) = '0' then am.LSV4AM_typ := ade_LDSTAMxLSV4AM_reg; end if; end; -- todo: remember fixing recursion bug in decgen function ade_decode_v4( insn_in : in std_logic_vector(31 downto 0) ) return ade_decinsn is variable arm_nop : std_logic; variable arm_mrs : std_logic; variable arm_bx : std_logic; variable arm_mul : std_logic; variable arm_mla : std_logic; variable arm_swp : std_logic; variable arm_sumull : std_logic; variable arm_sumlal : std_logic; variable arm_strhb : std_logic; variable arm_ldrhb : std_logic; variable arm_and : std_logic; variable arm_sub : std_logic; variable arm_eor : std_logic; variable arm_rsb : std_logic; variable arm_add : std_logic; variable arm_sbc : std_logic; variable arm_adc : std_logic; variable arm_rsc : std_logic; variable arm_msr : std_logic; variable arm_teq : std_logic; variable arm_cmn : std_logic; variable arm_tst : std_logic; variable arm_cmp : std_logic; variable arm_orr : std_logic; variable arm_bic : std_logic; variable arm_mov : std_logic; variable arm_mvn : std_logic; variable arm_str1 : std_logic; variable arm_str2 : std_logic; variable arm_str3 : std_logic; variable arm_ldr1 : std_logic; variable arm_undefined : std_logic; variable arm_stm : std_logic; variable arm_ldm : std_logic; variable arm_b : std_logic; variable arm_swi : std_logic; variable arm_cdp : std_logic; variable arm_mrc : std_logic; variable arm_mcr : std_logic; variable arm_stc : std_logic; variable arm_ldc : std_logic; variable vec_1 : std_logic_vector(1 downto 0); variable vec_2 : std_logic_vector(2 downto 0); variable vec_3 : std_logic_vector(4 downto 0); variable vec_4 : std_logic_vector(21 downto 0); variable vec_5 : std_logic_vector(12 downto 0); variable vec_6 : std_logic_vector(18 downto 0); variable vec_7 : std_logic_vector(4 downto 0); variable vec_8 : std_logic_vector(0 downto 0); variable vec_9 : std_logic_vector(0 downto 0); variable vec_10 : std_logic_vector(4 downto 0); variable vec_11 : std_logic_vector(0 downto 0); variable vec_12 : std_logic_vector(2 downto 0); variable vec_13 : std_logic_vector(0 downto 0); variable vec_14 : std_logic_vector(0 downto 0); variable vec_15 : std_logic_vector(0 downto 0); variable vec_16 : std_logic_vector(0 downto 0); variable vec_17 : std_logic_vector(6 downto 0); variable vec_18 : std_logic_vector(0 downto 0); variable vec_19 : std_logic_vector(0 downto 0); variable vec_20 : std_logic_vector(0 downto 0); variable vec_21 : std_logic_vector(0 downto 0); variable vec_22 : std_logic_vector(0 downto 0); variable vec_23 : std_logic_vector(0 downto 0); variable vec_24 : std_logic_vector(7 downto 0); variable vec_25 : std_logic_vector(0 downto 0); variable vec_26 : std_logic_vector(1 downto 0); variable vec_27 : std_logic_vector(0 downto 0); variable vec_28 : std_logic_vector(0 downto 0); variable vec_29 : std_logic_vector(0 downto 0); variable vec_30 : std_logic_vector(0 downto 0); variable vec_31 : std_logic_vector(0 downto 0); variable vec_32 : std_logic_vector(0 downto 0); variable vec_33 : std_logic_vector(0 downto 0); variable insn_return : ade_decinsn; variable insn : std_logic_vector(31 downto 0); begin insn := insn_in; -- decoder assumes littleendian: word[3 2 1 0] insn := insn_in; if CFG_BO_PROC = lmd_big then insn := insn(7 downto 0) & insn(15 downto 8) & insn(23 downto 16) & insn(31 downto 24); end if; insn_return := type_arm_invalid; vec_1 := insn(3 downto 2); vec_2 := insn(31 downto 31)&insn(28 downto 28)&insn(1 downto 1); vec_3 := insn(30 downto 29)&insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0); vec_4 := insn(27 downto 16)&insn(14 downto 14)&insn(12 downto 4); arm_nop := '0'; vec_5 := insn(27 downto 24)&insn(19 downto 16)&insn(12 downto 8); arm_mrs := '0'; vec_6 := insn(30 downto 29)&insn(23 downto 8)&insn(0 downto 0); arm_bx := '0'; vec_7 := insn(30 downto 29)&insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0); vec_8 := insn(14 downto 14); arm_mul := '0'; vec_9 := insn(14 downto 14); arm_mla := '0'; vec_10 := insn(19 downto 16)&insn(12 downto 12); arm_swp := '0'; arm_sumull := '0'; arm_sumlal := '0'; vec_11 := insn(12 downto 12); arm_strhb := '0'; arm_ldrhb := '0'; vec_12 := insn(15 downto 15)&insn(13 downto 13)&insn(0 downto 0); vec_13 := insn(14 downto 14); arm_and := '0'; arm_sub := '0'; vec_14 := insn(14 downto 14); arm_eor := '0'; arm_rsb := '0'; vec_15 := insn(14 downto 14); arm_add := '0'; arm_sbc := '0'; vec_16 := insn(14 downto 14); arm_adc := '0'; arm_rsc := '0'; vec_17 := insn(23 downto 20)&insn(12 downto 12)&insn(10 downto 9); arm_msr := '0'; vec_18 := insn(14 downto 14); arm_teq := '0'; arm_cmn := '0'; vec_19 := insn(14 downto 14); arm_tst := '0'; arm_cmp := '0'; vec_20 := insn(14 downto 14); arm_orr := '0'; arm_bic := '0'; vec_21 := insn(14 downto 14); arm_mov := '0'; arm_mvn := '0'; vec_22 := insn(12 downto 12); vec_23 := insn(1 downto 1); arm_str1 := '0'; vec_24 := insn(31 downto 28)&insn(19 downto 16); arm_str2 := '0'; vec_25 := insn(28 downto 28); arm_str3 := '0'; arm_ldr1 := '0'; vec_26 := insn(28 downto 28)&insn(1 downto 1); arm_undefined := '0'; vec_27 := insn(1 downto 1); vec_28 := insn(12 downto 12); arm_stm := '0'; arm_ldm := '0'; arm_b := '0'; vec_29 := insn(1 downto 1); vec_30 := insn(0 downto 0); arm_swi := '0'; vec_31 := insn(28 downto 28); arm_cdp := '0'; vec_32 := insn(12 downto 12); arm_mrc := '0'; arm_mcr := '0'; vec_33 := insn(12 downto 12); arm_stc := '0'; arm_ldc := '0'; case vec_1 is when "00" => case vec_2 is when "000" => case vec_3 is when "00111" => case vec_4 is when "0000000000000000001110" => arm_nop := '1'; if arm_nop = '1' then insn_return := type_arm_nop; end if; when others => null; end case; when "00001" => case vec_5 is when "0000000001111" => arm_mrs := '1'; if arm_mrs = '1' then insn_return := type_arm_mrs; end if; when others => null; end case; when others => null; end case; when "010" => case vec_6 is when "0011111111001011111" => arm_bx := '1'; if arm_bx = '1' then insn_return := type_arm_bx; end if; when others => null; end case; when "110" => case vec_7 is when "00000" => case vec_8 is when "0" => arm_mul := '1'; if arm_mul = '1' then insn_return := type_arm_mul; end if; when others => null; end case; when "00010" => case vec_9 is when "0" => arm_mla := '1'; if arm_mla = '1' then insn_return := type_arm_mla; end if; when others => null; end case; when "00001" => case vec_10 is when "00000" => arm_swp := '1'; if arm_swp = '1' then insn_return := type_arm_swp; end if; when others => null; end case; when "00100" => arm_sumull := '1'; if arm_sumull = '1' then insn_return := type_arm_sumull; end if; when "00110" => arm_sumlal := '1'; if arm_sumlal = '1' then insn_return := type_arm_sumlal; end if; when others => null; end case; case vec_11 is when "0" => arm_strhb := '1' and not (arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal); if arm_strhb = '1' then insn_return := type_arm_strhb; end if; when "1" => arm_ldrhb := '1' and not (arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal); if arm_ldrhb = '1' then insn_return := type_arm_ldrhb; end if; when others => null; end case; when others => null; end case; case vec_12 is when "000" => case vec_13 is when "0" => arm_and := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_and = '1' then insn_return := type_arm_and; end if; when "1" => arm_sub := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_sub = '1' then insn_return := type_arm_sub; end if; when others => null; end case; when "010" => case vec_14 is when "0" => arm_eor := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_eor = '1' then insn_return := type_arm_eor; end if; when "1" => arm_rsb := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_rsb = '1' then insn_return := type_arm_rsb; end if; when others => null; end case; when "100" => case vec_15 is when "0" => arm_add := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_add = '1' then insn_return := type_arm_add; end if; when "1" => arm_sbc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_sbc = '1' then insn_return := type_arm_sbc; end if; when others => null; end case; when "110" => case vec_16 is when "0" => arm_adc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_adc = '1' then insn_return := type_arm_adc; end if; when "1" => arm_rsc := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_rsc = '1' then insn_return := type_arm_rsc; end if; when others => null; end case; when "011" => case vec_17 is when "1111000" => arm_msr := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_msr = '1' then insn_return := type_arm_msr; end if; when others => null; end case; case vec_18 is when "0" => arm_teq := '1' and not (arm_msr or arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_teq = '1' then insn_return := type_arm_teq; end if; when "1" => arm_cmn := '1' and not (arm_msr or arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_cmn = '1' then insn_return := type_arm_cmn; end if; when others => null; end case; when "001" => case vec_19 is when "0" => arm_tst := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_tst = '1' then insn_return := type_arm_tst; end if; when "1" => arm_cmp := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_cmp = '1' then insn_return := type_arm_cmp; end if; when others => null; end case; when "101" => case vec_20 is when "0" => arm_orr := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_orr = '1' then insn_return := type_arm_orr; end if; when "1" => arm_bic := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_bic = '1' then insn_return := type_arm_bic; end if; when others => null; end case; when "111" => case vec_21 is when "0" => arm_mov := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_mov = '1' then insn_return := type_arm_mov; end if; when "1" => arm_mvn := '1' and not (arm_nop or arm_mrs or arm_bx or arm_mul or arm_mla or arm_swp or arm_sumull or arm_sumlal or arm_strhb or arm_ldrhb); if arm_mvn = '1' then insn_return := type_arm_mvn; end if; when others => null; end case; when others => null; end case; when "01" => case vec_22 is when "0" => case vec_23 is when "0" => arm_str1 := '1'; if arm_str1 = '1' then insn_return := type_arm_str1; end if; when "1" => case vec_24 is when "00000000" => arm_str2 := '1'; if arm_str2 = '1' then insn_return := type_arm_str2; end if; when others => null; end case; when others => null; end case; case vec_25 is when "0" => arm_str3 := '1' and not (arm_str1 or arm_str2); if arm_str3 = '1' then insn_return := type_arm_str3; end if; when others => null; end case; when "1" => arm_ldr1 := '1'; if arm_ldr1 = '1' then insn_return := type_arm_ldr1; end if; when others => null; end case; case vec_26 is when "11" => arm_undefined := '1' and not (arm_str1 or arm_str2 or arm_str3 or arm_ldr1); if arm_undefined = '1' then insn_return := type_arm_undefined; end if; when others => null; end case; when "10" => case vec_27 is when "0" => case vec_28 is when "0" => arm_stm := '1'; if arm_stm = '1' then insn_return := type_arm_stm; end if; when "1" => arm_ldm := '1'; if arm_ldm = '1' then insn_return := type_arm_ldm; end if; when others => null; end case; when "1" => arm_b := '1'; if arm_b = '1' then insn_return := type_arm_b; end if; when others => null; end case; when "11" => case vec_29 is when "1" => case vec_30 is when "1" => arm_swi := '1'; if arm_swi = '1' then insn_return := type_arm_swi; end if; when "0" => case vec_31 is when "0" => arm_cdp := '1'; if arm_cdp = '1' then insn_return := type_arm_cdp; end if; when "1" => case vec_32 is when "1" => arm_mrc := '1'; if arm_mrc = '1' then insn_return := type_arm_mrc; end if; when "0" => arm_mcr := '1'; if arm_mcr = '1' then insn_return := type_arm_mcr; end if; when others => null; end case; when others => null; end case; when others => null; end case; when "0" => case vec_33 is when "0" => arm_stc := '1'; if arm_stc = '1' then insn_return := type_arm_stc; end if; when "1" => arm_ldc := '1'; if arm_ldc = '1' then insn_return := type_arm_ldc; end if; when others => null; end case; when others => null; end case; when others => null; end case; return insn_return; end; end armdecode;