1 /***************************************************************************
2  *   Copyright (C) 2006 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
17  ***************************************************************************/
18 
19 #ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H
20 #define OPENOCD_TARGET_ARM_DISASSEMBLER_H
21 
22 enum arm_instruction_type {
23 	ARM_UNKNOWN_INSTRUCTION,
24 
25 	/* Branch instructions */
26 	ARM_B,
27 	ARM_BL,
28 	ARM_BX,
29 	ARM_BLX,
30 
31 	/* Data processing instructions */
32 	ARM_AND,
33 	ARM_EOR,
34 	ARM_SUB,
35 	ARM_RSB,
36 	ARM_ADD,
37 	ARM_ADC,
38 	ARM_SBC,
39 	ARM_RSC,
40 	ARM_TST,
41 	ARM_TEQ,
42 	ARM_CMP,
43 	ARM_CMN,
44 	ARM_ORR,
45 	ARM_MOV,
46 	ARM_BIC,
47 	ARM_MVN,
48 
49 	/* Load/store instructions */
50 	ARM_LDR,
51 	ARM_LDRB,
52 	ARM_LDRT,
53 	ARM_LDRBT,
54 
55 	ARM_LDRH,
56 	ARM_LDRSB,
57 	ARM_LDRSH,
58 
59 	ARM_LDM,
60 
61 	ARM_STR,
62 	ARM_STRB,
63 	ARM_STRT,
64 	ARM_STRBT,
65 
66 	ARM_STRH,
67 
68 	ARM_STM,
69 
70 	/* Status register access instructions */
71 	ARM_MRS,
72 	ARM_MSR,
73 
74 	/* Multiply instructions */
75 	ARM_MUL,
76 	ARM_MLA,
77 	ARM_SMULL,
78 	ARM_SMLAL,
79 	ARM_UMULL,
80 	ARM_UMLAL,
81 
82 	/* Miscellaneous instructions */
83 	ARM_CLZ,
84 
85 	/* Exception return instructions */
86 	ARM_ERET,
87 
88 	/* Exception generating instructions */
89 	ARM_BKPT,
90 	ARM_SWI,
91 	ARM_HVC,
92 	ARM_SMC,
93 
94 	/* Coprocessor instructions */
95 	ARM_CDP,
96 	ARM_LDC,
97 	ARM_STC,
98 	ARM_MCR,
99 	ARM_MRC,
100 
101 	/* Semaphore instructions */
102 	ARM_SWP,
103 	ARM_SWPB,
104 
105 	/* Enhanced DSP extensions */
106 	ARM_MCRR,
107 	ARM_MRRC,
108 	ARM_PLD,
109 	ARM_DSB,
110 	ARM_ISB,
111 	ARM_QADD,
112 	ARM_QDADD,
113 	ARM_QSUB,
114 	ARM_QDSUB,
115 	ARM_SMLAxy,
116 	ARM_SMLALxy,
117 	ARM_SMLAWy,
118 	ARM_SMULxy,
119 	ARM_SMULWy,
120 	ARM_LDRD,
121 	ARM_STRD,
122 
123 	ARM_UNDEFINED_INSTRUCTION = 0xffffffff,
124 };
125 
126 struct arm_b_bl_bx_blx_instr {
127 	int reg_operand;
128 	uint32_t target_address;
129 };
130 
131 union arm_shifter_operand {
132 	struct {
133 		uint32_t immediate;
134 	} immediate;
135 	struct {
136 		uint8_t Rm;
137 		uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
138 		uint8_t shift_imm;
139 	} immediate_shift;
140 	struct {
141 		uint8_t Rm;
142 		uint8_t shift;
143 		uint8_t Rs;
144 	} register_shift;
145 };
146 
147 struct arm_data_proc_instr {
148 	int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */
149 	uint8_t S;
150 	uint8_t Rn;
151 	uint8_t Rd;
152 	union arm_shifter_operand shifter_operand;
153 };
154 
155 struct arm_load_store_instr {
156 	uint8_t Rd;
157 	uint8_t Rn;
158 	uint8_t U;
159 	int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */
160 	int offset_mode; /* 0: immediate, 1: (scaled) register */
161 	union {
162 		uint32_t offset;
163 		struct {
164 			uint8_t Rm;
165 			uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
166 			uint8_t shift_imm;
167 		} reg;
168 	} offset;
169 };
170 
171 struct arm_load_store_multiple_instr {
172 	uint8_t Rn;
173 	uint32_t register_list;
174 	uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */
175 	uint8_t S;
176 	uint8_t W;
177 };
178 
179 struct arm_instruction {
180 	enum arm_instruction_type type;
181 	char text[128];
182 	uint32_t opcode;
183 
184 	/* return value ... Thumb-2 sizes vary */
185 	unsigned instruction_size;
186 
187 	union {
188 		struct arm_b_bl_bx_blx_instr b_bl_bx_blx;
189 		struct arm_data_proc_instr data_proc;
190 		struct arm_load_store_instr load_store;
191 		struct arm_load_store_multiple_instr load_store_multiple;
192 	} info;
193 
194 };
195 
196 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
197 		struct arm_instruction *instruction);
198 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address,
199 		struct arm_instruction *instruction);
200 int arm_access_size(struct arm_instruction *instruction);
201 #if HAVE_CAPSTONE
202 int arm_disassemble(struct command_invocation *cmd, struct target *target,
203 		target_addr_t address, size_t count, bool thumb_mode);
204 #endif
205 
206 #define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])
207 
208 #endif /* OPENOCD_TARGET_ARM_DISASSEMBLER_H */
209