/* OpenIDA - Outil d'analyse de fichiers binaires * encoding.h - prototypes pour le décodage des instructions ARM v4/v5/v6 * * Copyright (C) 2013 Cyrille Bagard * * This file is part of OpenIDA. * * OpenIDA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * OpenIDA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #ifndef _ARCH_ARM_V456_ENCODING_H #define _ARCH_ARM_V456_ENCODING_H #include /** * Coprocessor data processing. * § A3.1 Instruction set encoding. */ #define ARM_V456_DATA_PROC_IMM_SHIFT_1_BITS 0x0e000010 #define ARM_V456_DATA_PROC_IMM_SHIFT_1_MASK 0x00000000 #define ARM_V456_MISC_INSTRUCTIONS_BITS 0x0f900010 #define ARM_V456_MISC_INSTRUCTIONS_MASK 0x01000000 #define ARM_V456_DATA_PROC_IMM_SHIFT_2_BITS 0x0e000090 #define ARM_V456_DATA_PROC_IMM_SHIFT_2_MASK 0x00000010 #define ARM_V456_MISC_INSTRS_BITS 0x0f900090 #define ARM_V456_MISC_INSTRS_MASK 0x01000010 #define ARM_V456_MUL_EXTRA_LD_ST_BITS 0x0e000090 #define ARM_V456_MUL_EXTRA_LD_ST_MASK 0x00000090 #define ARM_V456_DATA_PROC_IMM_2_BITS 0x0e000000 #define ARM_V456_DATA_PROC_IMM_2_MASK 0x02000000 #define ARM_V456_UNDEF_INSTR_BITS 0x0fb00000 #define ARM_V456_UNDEF_INSTR_MASK 0x03000000 #define ARM_V456_MOVE_IMM_STATUS_REG_BITS 0x0fb00000 #define ARM_V456_MOVE_IMM_STATUS_REG_MASK 0x03200000 #define ARM_V456_LD_ST_IMM_OFFSET_BITS 0x0e000000 #define ARM_V456_LD_ST_IMM_OFFSET_MASK 0x04000000 #define ARM_V456_ISET_LD_ST_REG_OFFSET_BITS 0x0e000010 #define ARM_V456_ISET_LD_ST_REG_OFFSET_MASK 0x06000000 #define ARM_V456_ISET_MEDIA_INSTRS_4_BITS 0x0e000010 #define ARM_V456_ISET_MEDIA_INSTRS_4_MASK 0x06000010 #define ARM_V456_ISET_ARCH_UNDEFINED_BITS 0x0ff000f0 #define ARM_V456_ISET_ARCH_UNDEFINED_MASK 0x07f000f0 #define ARM_V456_ISET_LD_ST_MULTIPLE_BITS 0x0e000000 #define ARM_V456_ISET_LD_ST_MULTIPLE_MASK 0x08000000 #define ARM_V456_ISET_BRANCH_LINK_BITS 0x0e000000 #define ARM_V456_ISET_BRANCH_LINK_MASK 0x0a000000 #define ARM_V456_ISET_LD_ST_REG_TRANS_BITS 0x0e000000 #define ARM_V456_ISET_LD_ST_REG_TRANS_MASK 0x0c000000 #define ARM_V456_ISET_COPROC_DATA_PROC_BITS 0x0f000010 #define ARM_V456_ISET_COPROC_DATA_PROC_MASK 0x0e000000 #define ARM_V456_ISET_COPROC_REG_TRANS_BITS 0x0f000010 #define ARM_V456_ISET_COPROC_REG_TRANS_MASK 0x0e000010 #define ARM_V456_ISET_SOFT_INTERRUPT_BITS 0x0f000000 #define ARM_V456_ISET_SOFT_INTERRUPT_MASK 0x0f000000 #define ARM_V456_ISET_UNCOND_INSTRS_BITS 0xf0000000 #define ARM_V456_ISET_UNCOND_INSTRS_MASK 0xf0000000 /* Enumération des jeux possibles */ typedef enum _ArmV456InstrSets { ARM_V456_ISET_DATA_PROC_IMM_SHIFT_1, /* Data processing immediate shift */ ARM_V456_ISET_MISC_INSTRUCTIONS, /* Miscellaneous instructions */ ARM_V456_ISET_DATA_PROC_IMM_SHIFT_2, /* Data processing register shift [2] */ ARM_V456_MISC_INSTRS, /* Miscellaneous instructions */ ARM_V456_MUL_EXTRA_LD_ST, /* Multiplies - Extra load/stores */ ARM_V456_DATA_PROC_IMM_2, /* Data processing immediate [2] */ ARM_V456_UNDEF_INSTR, /* Undefined instruction */ ARM_V456_MOVE_IMM_STATUS_REG, /* Move immediate to status register */ ARM_V456_LD_ST_IMM_OFFSET, /* Load/store immediate offset */ ARM_V456_ISET_LD_ST_REG_OFFSET, /* Load/store register offset */ ARM_V456_ISET_MEDIA_INSTRS_4, /* Media instructions [4] */ ARM_V456_ISET_ARCH_UNDEFINED, /* Architecturally undefined */ ARM_V456_ISET_LD_ST_MULTIPLE, /* Load/store multiple */ ARM_V456_ISET_BRANCH_LINK, /* Branch and branch with link */ ARM_V456_ISET_LD_ST_REG_TRANS, /* Coproc. load/store and double register transfers */ ARM_V456_ISET_COPROC_DATA_PROC, /* Coprocessor data processing */ ARM_V456_ISET_COPROC_REG_TRANS, /* Coprocessor register transfers */ ARM_V456_ISET_SOFT_INTERRUPT, /* Software interrupt */ ARM_V456_ISET_UNCOND_INSTRS, /* Unconditional instructions */ ARM_V456_ISET_COUNT } ArmV456InstrSets; /* Jeux réordonnés pour la reconnaissance */ static const uint32_t _arm_v456_encoding_sets[ARM_V456_ISET_COUNT][2] = { /* 0 0 0 */ { ARM_V456_MISC_INSTRS_BITS, ARM_V456_MISC_INSTRS_MASK }, { ARM_V456_MISC_INSTRUCTIONS_BITS, ARM_V456_MISC_INSTRUCTIONS_MASK }, { ARM_V456_DATA_PROC_IMM_SHIFT_2_BITS, ARM_V456_DATA_PROC_IMM_SHIFT_2_MASK }, { ARM_V456_MUL_EXTRA_LD_ST_BITS, ARM_V456_MUL_EXTRA_LD_ST_MASK }, { ARM_V456_DATA_PROC_IMM_SHIFT_1_BITS, ARM_V456_DATA_PROC_IMM_SHIFT_1_MASK }, /* 0 0 1 */ { ARM_V456_UNDEF_INSTR_BITS, ARM_V456_UNDEF_INSTR_MASK }, { ARM_V456_MOVE_IMM_STATUS_REG_BITS, ARM_V456_MOVE_IMM_STATUS_REG_MASK }, { ARM_V456_DATA_PROC_IMM_2_BITS, ARM_V456_DATA_PROC_IMM_2_MASK }, /* 0 1 0 */ { ARM_V456_LD_ST_IMM_OFFSET_BITS, ARM_V456_LD_ST_IMM_OFFSET_MASK }, /* 0 1 1 */ { ARM_V456_ISET_ARCH_UNDEFINED_BITS, ARM_V456_ISET_ARCH_UNDEFINED_MASK }, { ARM_V456_ISET_LD_ST_REG_OFFSET_BITS, ARM_V456_ISET_LD_ST_REG_OFFSET_MASK }, { ARM_V456_ISET_MEDIA_INSTRS_4_BITS, ARM_V456_ISET_MEDIA_INSTRS_4_MASK }, /* 1 0 0 */ { ARM_V456_ISET_LD_ST_MULTIPLE_BITS, ARM_V456_ISET_LD_ST_MULTIPLE_MASK }, /* 1 0 1 */ { ARM_V456_ISET_BRANCH_LINK_BITS, ARM_V456_ISET_BRANCH_LINK_MASK }, /* 1 1 0 */ { ARM_V456_ISET_LD_ST_REG_TRANS_BITS, ARM_V456_ISET_LD_ST_REG_TRANS_MASK }, /* 1 1 1 */ { ARM_V456_ISET_COPROC_DATA_PROC_BITS, ARM_V456_ISET_COPROC_DATA_PROC_MASK }, { ARM_V456_ISET_COPROC_REG_TRANS_BITS, ARM_V456_ISET_COPROC_REG_TRANS_MASK }, { ARM_V456_ISET_SOFT_INTERRUPT_BITS, ARM_V456_ISET_SOFT_INTERRUPT_MASK }, /* x x x */ { ARM_V456_ISET_UNCOND_INSTRS_BITS, ARM_V456_ISET_UNCOND_INSTRS_MASK } }; #define IS_ENCODING_SET(val, set) (((val) & (set[0])) == (set[1])) #define ARM_V456_BIT_L (1 << 20) #define ARM_V456_BIT_W (1 << 21) #define ARM_V456_BIT_U (1 << 22) #define ARM_V456_BIT_P (1 << 23) #define ARM_V456_BIT_I (1 << 24) #define ARM_V456_REG_RN(instr) (((instr) >> 16) & 0x0f) #define ARM_V456_REG_RD(instr) (((instr) >> 12) & 0x0f) #define ARM_V456_ADDR_MODE(instr) ((instr) & 0xfff) #endif /* _ARCH_ARM_V456_ENCODING_H */