aboutsummaryrefslogtreecommitdiff
path: root/src/ARM_InstrInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ARM_InstrInfo.h')
-rw-r--r--src/ARM_InstrInfo.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/ARM_InstrInfo.h b/src/ARM_InstrInfo.h
new file mode 100644
index 0000000..a702435
--- /dev/null
+++ b/src/ARM_InstrInfo.h
@@ -0,0 +1,263 @@
+#ifndef ARMINSTRINFO_H
+#define ARMINSTRINFO_H
+
+#include "types.h"
+
+namespace ARMInstrInfo
+{
+
+// Instruction kinds, for faster dispatch
+
+#define ak_ALU(n) \
+ ak_##n##_REG_LSL_IMM, \
+ ak_##n##_REG_LSR_IMM, \
+ ak_##n##_REG_ASR_IMM, \
+ ak_##n##_REG_ROR_IMM, \
+ \
+ ak_##n##_REG_LSL_REG, \
+ ak_##n##_REG_LSR_REG, \
+ ak_##n##_REG_ASR_REG, \
+ ak_##n##_REG_ROR_REG, \
+ \
+ ak_##n##_IMM, \
+ \
+ ak_##n##_REG_LSL_IMM_S, \
+ ak_##n##_REG_LSR_IMM_S, \
+ ak_##n##_REG_ASR_IMM_S, \
+ ak_##n##_REG_ROR_IMM_S, \
+ \
+ ak_##n##_REG_LSL_REG_S, \
+ ak_##n##_REG_LSR_REG_S, \
+ ak_##n##_REG_ASR_REG_S, \
+ ak_##n##_REG_ROR_REG_S, \
+ \
+ ak_##n##_IMM_S \
+
+#define ak_Test(n) \
+ ak_##n##_REG_LSL_IMM, \
+ ak_##n##_REG_LSR_IMM, \
+ ak_##n##_REG_ASR_IMM, \
+ ak_##n##_REG_ROR_IMM, \
+ \
+ ak_##n##_REG_LSL_REG, \
+ ak_##n##_REG_LSR_REG, \
+ ak_##n##_REG_ASR_REG, \
+ ak_##n##_REG_ROR_REG, \
+ \
+ ak_##n##_IMM
+
+#define ak_WB_LDRSTR(n) \
+ ak_##n##_REG_LSL, \
+ ak_##n##_REG_LSR, \
+ ak_##n##_REG_ASR, \
+ ak_##n##_REG_ROR, \
+ \
+ ak_##n##_IMM, \
+ \
+ ak_##n##_POST_REG_LSL, \
+ ak_##n##_POST_REG_LSR, \
+ ak_##n##_POST_REG_ASR, \
+ ak_##n##_POST_REG_ROR, \
+ \
+ ak_##n##_POST_IMM
+
+#define ak_HD_LDRSTR(n) \
+ ak_##n##_REG, \
+ ak_##n##_IMM, \
+ \
+ ak_##n##_POST_REG, \
+ ak_##n##_POST_IMM
+
+enum
+{
+ ak_ALU(AND),
+ ak_ALU(EOR),
+ ak_ALU(SUB),
+ ak_ALU(RSB),
+ ak_ALU(ADD),
+ ak_ALU(ADC),
+ ak_ALU(SBC),
+ ak_ALU(RSC),
+ ak_ALU(ORR),
+ ak_ALU(MOV),
+ ak_ALU(BIC),
+ ak_ALU(MVN),
+
+ ak_Test(TST),
+ ak_Test(TEQ),
+ ak_Test(CMP),
+ ak_Test(CMN),
+
+ ak_MUL,
+ ak_MLA,
+ ak_UMULL,
+ ak_UMLAL,
+ ak_SMULL,
+ ak_SMLAL,
+ ak_SMLAxy,
+ ak_SMLAWy,
+ ak_SMULWy,
+ ak_SMLALxy,
+ ak_SMULxy,
+
+ ak_CLZ,
+
+ ak_QADD,
+ ak_QSUB,
+ ak_QDADD,
+ ak_QDSUB,
+
+ ak_WB_LDRSTR(STR),
+ ak_WB_LDRSTR(STRB),
+ ak_WB_LDRSTR(LDR),
+ ak_WB_LDRSTR(LDRB),
+
+ ak_HD_LDRSTR(STRH),
+ ak_HD_LDRSTR(LDRD),
+ ak_HD_LDRSTR(STRD),
+ ak_HD_LDRSTR(LDRH),
+ ak_HD_LDRSTR(LDRSB),
+ ak_HD_LDRSTR(LDRSH),
+
+ ak_SWP,
+ ak_SWPB,
+
+ ak_LDM,
+ ak_STM,
+
+ ak_B,
+ ak_BL,
+ ak_BLX_IMM,
+ ak_BX,
+ ak_BLX_REG,
+
+ ak_UNK,
+ ak_MSR_IMM,
+ ak_MSR_REG,
+ ak_MRS,
+ ak_MCR,
+ ak_MRC,
+ ak_SVC,
+
+ ak_Nop,
+
+ ak_Count,
+
+ tk_LSL_IMM = 0,
+ tk_LSR_IMM,
+ tk_ASR_IMM,
+
+ tk_ADD_REG_,
+ tk_SUB_REG_,
+ tk_ADD_IMM_,
+ tk_SUB_IMM_,
+
+ tk_MOV_IMM,
+ tk_CMP_IMM,
+ tk_ADD_IMM,
+ tk_SUB_IMM,
+
+ tk_AND_REG,
+ tk_EOR_REG,
+ tk_LSL_REG,
+ tk_LSR_REG,
+ tk_ASR_REG,
+ tk_ADC_REG,
+ tk_SBC_REG,
+ tk_ROR_REG,
+ tk_TST_REG,
+ tk_NEG_REG,
+ tk_CMP_REG,
+ tk_CMN_REG,
+ tk_ORR_REG,
+ tk_MUL_REG,
+ tk_BIC_REG,
+ tk_MVN_REG,
+
+ tk_ADD_HIREG,
+ tk_CMP_HIREG,
+ tk_MOV_HIREG,
+
+ tk_ADD_PCREL,
+ tk_ADD_SPREL,
+ tk_ADD_SP,
+
+ tk_LDR_PCREL,
+ tk_STR_REG,
+ tk_STRB_REG,
+ tk_LDR_REG,
+ tk_LDRB_REG,
+ tk_STRH_REG,
+ tk_LDRSB_REG,
+ tk_LDRH_REG,
+ tk_LDRSH_REG,
+ tk_STR_IMM,
+ tk_LDR_IMM,
+ tk_STRB_IMM,
+ tk_LDRB_IMM,
+ tk_STRH_IMM,
+ tk_LDRH_IMM,
+ tk_STR_SPREL,
+ tk_LDR_SPREL,
+
+ tk_PUSH,
+ tk_POP,
+ tk_LDMIA,
+ tk_STMIA,
+
+ tk_BCOND,
+ tk_BX,
+ tk_BLX_REG,
+ tk_B,
+ tk_BL_LONG_1,
+ tk_BL_LONG_2,
+ tk_UNK,
+ tk_SVC,
+
+ // not a real instruction
+ tk_BL_LONG,
+
+ tk_Count
+};
+
+enum
+{
+ flag_N = 1 << 3,
+ flag_Z = 1 << 2,
+ flag_C = 1 << 1,
+ flag_V = 1 << 0,
+};
+
+enum
+{
+ special_NotSpecialAtAll = 0,
+ special_WriteMem,
+ special_LoadMem,
+ special_WaitForInterrupt,
+ special_LoadLiteral
+};
+
+struct Info
+{
+ u16 DstRegs, SrcRegs, NotStrictlyNeeded;
+ u16 Kind;
+
+ u8 SpecialKind;
+
+ u8 ReadFlags;
+ // lower 4 bits - set always
+ // upper 4 bits - might set flag
+ u8 WriteFlags;
+
+ bool EndBlock;
+ bool Branches() const
+ {
+ return DstRegs & (1 << 15);
+ }
+};
+
+Info Decode(bool thumb, u32 num, u32 instr);
+
+}
+
+#endif \ No newline at end of file