update files to correct FSF address
[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, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
19  ***************************************************************************/
20
21 #ifndef ARM_DISASSEMBLER_H
22 #define ARM_DISASSEMBLER_H
23
24 enum arm_instruction_type {
25         ARM_UNKNOWN_INSTUCTION,
26
27         /* Branch instructions */
28         ARM_B,
29         ARM_BL,
30         ARM_BX,
31         ARM_BLX,
32
33         /* Data processing instructions */
34         ARM_AND,
35         ARM_EOR,
36         ARM_SUB,
37         ARM_RSB,
38         ARM_ADD,
39         ARM_ADC,
40         ARM_SBC,
41         ARM_RSC,
42         ARM_TST,
43         ARM_TEQ,
44         ARM_CMP,
45         ARM_CMN,
46         ARM_ORR,
47         ARM_MOV,
48         ARM_BIC,
49         ARM_MVN,
50
51         /* Load/store instructions */
52         ARM_LDR,
53         ARM_LDRB,
54         ARM_LDRT,
55         ARM_LDRBT,
56
57         ARM_LDRH,
58         ARM_LDRSB,
59         ARM_LDRSH,
60
61         ARM_LDM,
62
63         ARM_STR,
64         ARM_STRB,
65         ARM_STRT,
66         ARM_STRBT,
67
68         ARM_STRH,
69
70         ARM_STM,
71
72         /* Status register access instructions */
73         ARM_MRS,
74         ARM_MSR,
75
76         /* Multiply instructions */
77         ARM_MUL,
78         ARM_MLA,
79         ARM_SMULL,
80         ARM_SMLAL,
81         ARM_UMULL,
82         ARM_UMLAL,
83
84         /* Miscellaneous instructions */
85         ARM_CLZ,
86
87         /* Exception generating instructions */
88         ARM_BKPT,
89         ARM_SWI,
90
91         /* Coprocessor instructions */
92         ARM_CDP,
93         ARM_LDC,
94         ARM_STC,
95         ARM_MCR,
96         ARM_MRC,
97
98         /* Semaphore instructions */
99         ARM_SWP,
100         ARM_SWPB,
101
102         /* Enhanced DSP extensions */
103         ARM_MCRR,
104         ARM_MRRC,
105         ARM_PLD,
106         ARM_QADD,
107         ARM_QDADD,
108         ARM_QSUB,
109         ARM_QDSUB,
110         ARM_SMLAxy,
111         ARM_SMLALxy,
112         ARM_SMLAWy,
113         ARM_SMULxy,
114         ARM_SMULWy,
115         ARM_LDRD,
116         ARM_STRD,
117
118         ARM_UNDEFINED_INSTRUCTION = 0xffffffff,
119 };
120
121 struct arm_b_bl_bx_blx_instr {
122         int reg_operand;
123         uint32_t target_address;
124 };
125
126 union arm_shifter_operand {
127         struct {
128                 uint32_t immediate;
129         } immediate;
130         struct {
131                 uint8_t Rm;
132                 uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
133                 uint8_t shift_imm;
134         } immediate_shift;
135         struct {
136                 uint8_t Rm;
137                 uint8_t shift;
138                 uint8_t Rs;
139         } register_shift;
140 };
141
142 struct arm_data_proc_instr {
143         int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */
144         uint8_t S;
145         uint8_t Rn;
146         uint8_t Rd;
147         union arm_shifter_operand shifter_operand;
148 };
149
150 struct arm_load_store_instr {
151         uint8_t Rd;
152         uint8_t Rn;
153         uint8_t U;
154         int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */
155         int offset_mode; /* 0: immediate, 1: (scaled) register */
156         union {
157                 uint32_t offset;
158                 struct {
159                         uint8_t Rm;
160                         uint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */
161                         uint8_t shift_imm;
162                 } reg;
163         } offset;
164 };
165
166 struct arm_load_store_multiple_instr {
167         uint8_t Rn;
168         uint32_t register_list;
169         uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */
170         uint8_t S;
171         uint8_t W;
172 };
173
174 struct arm_instruction {
175         enum arm_instruction_type type;
176         char text[128];
177         uint32_t opcode;
178
179         /* return value ... Thumb-2 sizes vary */
180         unsigned instruction_size;
181
182         union {
183                 struct arm_b_bl_bx_blx_instr b_bl_bx_blx;
184                 struct arm_data_proc_instr data_proc;
185                 struct arm_load_store_instr load_store;
186                 struct arm_load_store_multiple_instr load_store_multiple;
187         } info;
188
189 };
190
191 int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
192                 struct arm_instruction *instruction);
193 int thumb_evaluate_opcode(uint16_t opcode, uint32_t address,
194                 struct arm_instruction *instruction);
195 int thumb2_opcode(struct target *target, uint32_t address,
196                 struct arm_instruction *instruction);
197 int arm_access_size(struct arm_instruction *instruction);
198
199 #define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])
200
201 #endif /* ARM_DISASSEMBLER_H */