target: arm: disassembler: decode v6T2 ARM DSB instruction
[fw/openocd] / src / target / arm_disassembler.h
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_INSTUCTION,
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_QADD,
111         ARM_QDADD,
112         ARM_QSUB,
113         ARM_QDSUB,
114         ARM_SMLAxy,
115         ARM_SMLALxy,
116         ARM_SMLAWy,
117         ARM_SMULxy,
118         ARM_SMULWy,
119         ARM_LDRD,
120         ARM_STRD,
121
122         ARM_UNDEFINED_INSTRUCTION = 0xffffffff,
123 };
124
125 struct arm_b_bl_bx_blx_instr {
126         int reg_operand;
127         uint32_t target_address;
128 };
129
130 union arm_shifter_operand {
131         struct {
132                 uint32_t immediate;
133         } immediate;
134         struct {
135                 uint8_t Rm;
136                 uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
137                 uint8_t shift_imm;
138         } immediate_shift;
139         struct {
140                 uint8_t Rm;
141                 uint8_t shift;
142                 uint8_t Rs;
143         } register_shift;
144 };
145
146 struct arm_data_proc_instr {
147         int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */
148         uint8_t S;
149         uint8_t Rn;
150         uint8_t Rd;
151         union arm_shifter_operand shifter_operand;
152 };
153
154 struct arm_load_store_instr {
155         uint8_t Rd;
156         uint8_t Rn;
157         uint8_t U;
158         int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */
159         int offset_mode; /* 0: immediate, 1: (scaled) register */
160         union {
161                 uint32_t offset;
162                 struct {
163                         uint8_t Rm;
164                         uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
165                         uint8_t shift_imm;
166                 } reg;
167         } offset;
168 };
169
170 struct arm_load_store_multiple_instr {
171         uint8_t Rn;
172         uint32_t register_list;
173         uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */
174         uint8_t S;
175         uint8_t W;
176 };
177
178 struct arm_instruction {
179         enum arm_instruction_type type;
180         char text[128];
181         uint32_t opcode;
182
183         /* return value ... Thumb-2 sizes vary */
184         unsigned instruction_size;
185
186         union {
187                 struct arm_b_bl_bx_blx_instr b_bl_bx_blx;
188                 struct arm_data_proc_instr data_proc;
189                 struct arm_load_store_instr load_store;
190                 struct arm_load_store_multiple_instr load_store_multiple;
191         } info;
192
193 };
194
195 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
196                 struct arm_instruction *instruction);
197 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address,
198                 struct arm_instruction *instruction);
199 int thumb2_opcode(struct target *target, uint32_t address,
200                 struct arm_instruction *instruction);
201 int arm_access_size(struct arm_instruction *instruction);
202
203 #define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])
204
205 #endif /* OPENOCD_TARGET_ARM_DISASSEMBLER_H */