aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/arm/disassembler/arm_disasm.h
blob: 9600e2ade4cf3688feaae0d21b3449318b659bf3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2006 The Android Open Source Project

#ifndef ARMDIS_H
#define ARMDIS_H

#include <stdint.h>

// Note: this list of opcodes must match the list used to initialize
// the opflags[] array in opcode.cpp.
enum Opcode {
    OP_INVALID,
    OP_UNDEFINED,
    OP_ADC,
    OP_ADD,
    OP_AND,
    OP_B,
    OP_BL,
    OP_BIC,
    OP_BKPT,
    OP_BLX,
    OP_BX,
    OP_CDP,
    OP_CLZ,
    OP_CMN,
    OP_CMP,
    OP_EOR,
    OP_LDC,
    OP_LDM,
    OP_LDR,
    OP_LDRB,
    OP_LDRBT,
    OP_LDRH,
    OP_LDRSB,
    OP_LDRSH,
    OP_LDRT,
    OP_MCR,
    OP_MLA,
    OP_MOV,
    OP_MRC,
    OP_MRS,
    OP_MSR,
    OP_MUL,
    OP_MVN,
    OP_ORR,
    OP_PLD,
    OP_RSB,
    OP_RSC,
    OP_SBC,
    OP_SMLAL,
    OP_SMULL,
    OP_STC,
    OP_STM,
    OP_STR,
    OP_STRB,
    OP_STRBT,
    OP_STRH,
    OP_STRT,
    OP_SUB,
    OP_SWI,
    OP_SWP,
    OP_SWPB,
    OP_TEQ,
    OP_TST,
    OP_UMLAL,
    OP_UMULL,

    // Define thumb opcodes
    OP_THUMB_UNDEFINED,
    OP_THUMB_ADC,
    OP_THUMB_ADD,
    OP_THUMB_AND,
    OP_THUMB_ASR,
    OP_THUMB_B,
    OP_THUMB_BIC,
    OP_THUMB_BKPT,
    OP_THUMB_BL,
    OP_THUMB_BLX,
    OP_THUMB_BX,
    OP_THUMB_CMN,
    OP_THUMB_CMP,
    OP_THUMB_EOR,
    OP_THUMB_LDMIA,
    OP_THUMB_LDR,
    OP_THUMB_LDRB,
    OP_THUMB_LDRH,
    OP_THUMB_LDRSB,
    OP_THUMB_LDRSH,
    OP_THUMB_LSL,
    OP_THUMB_LSR,
    OP_THUMB_MOV,
    OP_THUMB_MUL,
    OP_THUMB_MVN,
    OP_THUMB_NEG,
    OP_THUMB_ORR,
    OP_THUMB_POP,
    OP_THUMB_PUSH,
    OP_THUMB_ROR,
    OP_THUMB_SBC,
    OP_THUMB_STMIA,
    OP_THUMB_STR,
    OP_THUMB_STRB,
    OP_THUMB_STRH,
    OP_THUMB_SUB,
    OP_THUMB_SWI,
    OP_THUMB_TST,

    OP_END                // must be last
};

class ARM_Disasm {
 public:
  static char *disasm(uint32_t addr, uint32_t insn, char *buffer);
  static Opcode decode(uint32_t insn);

 private:
  static Opcode decode00(uint32_t insn);
  static Opcode decode01(uint32_t insn);
  static Opcode decode10(uint32_t insn);
  static Opcode decode11(uint32_t insn);
  static Opcode decode_mul(uint32_t insn);
  static Opcode decode_ldrh(uint32_t insn);
  static Opcode decode_alu(uint32_t insn);

  static char *disasm_alu(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_bx(uint32_t insn, char *ptr);
  static char *disasm_bkpt(uint32_t insn, char *ptr);
  static char *disasm_clz(uint32_t insn, char *ptr);
  static char *disasm_memblock(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_mem(uint32_t insn, char *ptr);
  static char *disasm_memhalf(uint32_t insn, char *ptr);
  static char *disasm_mcr(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_mla(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_umlal(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_mul(Opcode opcode, uint32_t insn, char *ptr);
  static char *disasm_mrs(uint32_t insn, char *ptr);
  static char *disasm_msr(uint32_t insn, char *ptr);
  static char *disasm_pld(uint32_t insn, char *ptr);
  static char *disasm_swi(uint32_t insn, char *ptr);
  static char *disasm_swp(Opcode opcode, uint32_t insn, char *ptr);
};

extern char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *result);
extern Opcode decode_insn_thumb(uint32_t given);

#endif /* ARMDIS_H */