cortex_a : optimize apb read/write access.
[openocd.git] / src / target / arm_opcodes.h
1 /*
2 * Copyright (C) 2005 by Dominic Rath
3 * Dominic.Rath@gmx.de
4 *
5 * Copyright (C) 2006 by Magnus Lundin
6 * lundin@mlu.mine.nu
7 *
8 * Copyright (C) 2008 by Spencer Oliver
9 * spen@spen-soft.co.uk
10 *
11 * Copyright (C) 2009 by Øyvind Harboe
12 * oyvind.harboe@zylin.com
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the
26 * Free Software Foundation, Inc.,
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */
29 #ifndef __ARM_OPCODES_H
30 #define __ARM_OPCODES_H
31
32 /**
33 * @file
34 * Macros used to generate various ARM or Thumb opcodes.
35 */
36
37 /* ARM mode instructions */
38
39 /* Store multiple increment after
40 * Rn: base register
41 * List: for each bit in list: store register
42 * S: in priviledged mode: store user-mode registers
43 * W = 1: update the base register. W = 0: leave the base register untouched
44 */
45 #define ARMV4_5_STMIA(Rn, List, S, W) \
46 (0xe8800000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
47
48 /* Load multiple increment after
49 * Rn: base register
50 * List: for each bit in list: store register
51 * S: in priviledged mode: store user-mode registers
52 * W = 1: update the base register. W = 0: leave the base register untouched
53 */
54 #define ARMV4_5_LDMIA(Rn, List, S, W) \
55 (0xe8900000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
56
57 /* MOV r8, r8 */
58 #define ARMV4_5_NOP (0xe1a08008)
59
60 /* Move PSR to general purpose register
61 * R = 1: SPSR R = 0: CPSR
62 * Rn: target register
63 */
64 #define ARMV4_5_MRS(Rn, R) (0xe10f0000 | ((R) << 22) | ((Rn) << 12))
65
66 /* Store register
67 * Rd: register to store
68 * Rn: base register
69 */
70 #define ARMV4_5_STR(Rd, Rn) (0xe5800000 | ((Rd) << 12) | ((Rn) << 16))
71
72 /* Load register
73 * Rd: register to load
74 * Rn: base register
75 */
76 #define ARMV4_5_LDR(Rd, Rn) (0xe5900000 | ((Rd) << 12) | ((Rn) << 16))
77
78 /* Move general purpose register to PSR
79 * R = 1: SPSR R = 0: CPSR
80 * Field: Field mask
81 * 1: control field 2: extension field 4: status field 8: flags field
82 * Rm: source register
83 */
84 #define ARMV4_5_MSR_GP(Rm, Field, R) \
85 (0xe120f000 | (Rm) | ((Field) << 16) | ((R) << 22))
86 #define ARMV4_5_MSR_IM(Im, Rotate, Field, R) \
87 (0xe320f000 | (Im) | ((Rotate) << 8) | ((Field) << 16) | ((R) << 22))
88
89 /* Load Register Word Immediate Post-Index
90 * Rd: register to load
91 * Rn: base register
92 */
93 #define ARMV4_5_LDRW_IP(Rd, Rn) (0xe4900004 | ((Rd) << 12) | ((Rn) << 16))
94
95 /* Load Register Halfword Immediate Post-Index
96 * Rd: register to load
97 * Rn: base register
98 */
99 #define ARMV4_5_LDRH_IP(Rd, Rn) (0xe0d000b2 | ((Rd) << 12) | ((Rn) << 16))
100
101 /* Load Register Byte Immediate Post-Index
102 * Rd: register to load
103 * Rn: base register
104 */
105 #define ARMV4_5_LDRB_IP(Rd, Rn) (0xe4d00001 | ((Rd) << 12) | ((Rn) << 16))
106
107 /* Store register Word Immediate Post-Index
108 * Rd: register to store
109 * Rn: base register
110 */
111 #define ARMV4_5_STRW_IP(Rd, Rn) (0xe4800004 | ((Rd) << 12) | ((Rn) << 16))
112
113 /* Store register Halfword Immediate Post-Index
114 * Rd: register to store
115 * Rn: base register
116 */
117 #define ARMV4_5_STRH_IP(Rd, Rn) (0xe0c000b2 | ((Rd) << 12) | ((Rn) << 16))
118
119 /* Store register Byte Immediate Post-Index
120 * Rd: register to store
121 * Rn: base register
122 */
123 #define ARMV4_5_STRB_IP(Rd, Rn) (0xe4c00001 | ((Rd) << 12) | ((Rn) << 16))
124
125 /* Branch (and Link)
126 * Im: Branch target (left-shifted by 2 bits, added to PC)
127 * L: 1: branch and link 0: branch only
128 */
129 #define ARMV4_5_B(Im, L) (0xea000000 | (Im) | ((L) << 24))
130
131 /* Branch and exchange (ARM state)
132 * Rm: register holding branch target address
133 */
134 #define ARMV4_5_BX(Rm) (0xe12fff10 | (Rm))
135
136 /* Store data from coprocessor to consecutive memory
137 * See Armv7-A arch doc section A8.6.187
138 * P: 1=index mode (offset from Rn)
139 * U: 1=add, 0=subtract Rn address with imm
140 * D: Opcode D encoding
141 * W: write back the offset start address to the Rn register
142 * CP: Coprocessor number (4 bits)
143 * CRd: Coprocessor source register (4 bits)
144 * Rn: Base register for memory address (4 bits)
145 * imm: Immediate value (0 - 1020, must be divisible by 4)
146 */
147 #define ARMV4_5_STC(P, U, D, W, CP, CRd, Rn, imm) \
148 (0xec000000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \
149 ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm)>>2))
150
151 /* Loads data from consecutive memory to coprocessor
152 * See Armv7-A arch doc section A8.6.51
153 * P: 1=index mode (offset from Rn)
154 * U: 1=add, 0=subtract Rn address with imm
155 * D: Opcode D encoding
156 * W: write back the offset start address to the Rn register
157 * CP: Coprocessor number (4 bits)
158 * CRd: Coprocessor dest register (4 bits)
159 * Rn: Base register for memory address (4 bits)
160 * imm: Immediate value (0 - 1020, must be divisible by 4)
161 */
162 #define ARMV4_5_LDC(P, U, D, W, CP, CRd, Rn, imm) \
163 (0xec100000 | ((P) << 24) | ((U) << 23) | ((D) << 22) | \
164 ((W) << 21) | ((Rn) << 16) | ((CRd) << 12) | ((CP) << 8) | ((imm) >> 2))
165
166 /* Move to ARM register from coprocessor
167 * CP: Coprocessor number
168 * op1: Coprocessor opcode
169 * Rd: destination register
170 * CRn: first coprocessor operand
171 * CRm: second coprocessor operand
172 * op2: Second coprocessor opcode
173 */
174 #define ARMV4_5_MRC(CP, op1, Rd, CRn, CRm, op2) \
175 (0xee100010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
176 | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
177
178 /* Move to coprocessor from ARM register
179 * CP: Coprocessor number
180 * op1: Coprocessor opcode
181 * Rd: destination register
182 * CRn: first coprocessor operand
183 * CRm: second coprocessor operand
184 * op2: Second coprocessor opcode
185 */
186 #define ARMV4_5_MCR(CP, op1, Rd, CRn, CRm, op2) \
187 (0xee000010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
188 | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
189
190 /* Breakpoint instruction (ARMv5)
191 * Im: 16-bit immediate
192 */
193 #define ARMV5_BKPT(Im) (0xe1200070 | ((Im & 0xfff0) << 8) | (Im & 0xf))
194
195
196 /* Thumb mode instructions
197 *
198 * NOTE: these 16-bit opcodes fill both halves of a word with the same
199 * value. The reason for this is that when we need to execute Thumb
200 * opcodes on ARM7/ARM9 cores (to switch to ARM state on debug entry),
201 * we must shift 32 bits to the bus using scan chain 1 ... if we write
202 * both halves, we don't need to track which half matters. On ARMv6 and
203 * ARMv7 we don't execute Thumb instructions in debug mode; the ITR
204 * register does not accept Thumb (or Thumb2) opcodes.
205 */
206
207 /* Store register (Thumb mode)
208 * Rd: source register
209 * Rn: base register
210 */
211 #define ARMV4_5_T_STR(Rd, Rn) \
212 ((0x6000 | (Rd) | ((Rn) << 3)) | \
213 ((0x6000 | (Rd) | ((Rn) << 3)) << 16))
214
215 /* Load register (Thumb state)
216 * Rd: destination register
217 * Rn: base register
218 */
219 #define ARMV4_5_T_LDR(Rd, Rn) \
220 ((0x6800 | ((Rn) << 3) | (Rd)) \
221 | ((0x6800 | ((Rn) << 3) | (Rd)) << 16))
222
223 /* Load multiple (Thumb state)
224 * Rn: base register
225 * List: for each bit in list: store register
226 */
227 #define ARMV4_5_T_LDMIA(Rn, List) \
228 ((0xc800 | ((Rn) << 8) | (List)) \
229 | ((0xc800 | ((Rn) << 8) | (List)) << 16))
230
231 /* Load register with PC relative addressing
232 * Rd: register to load
233 */
234 #define ARMV4_5_T_LDR_PCREL(Rd) \
235 ((0x4800 | ((Rd) << 8)) \
236 | ((0x4800 | ((Rd) << 8)) << 16))
237
238 /* Move hi register (Thumb mode)
239 * Rd: destination register
240 * Rm: source register
241 */
242 #define ARMV4_5_T_MOV(Rd, Rm) \
243 ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \
244 (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) \
245 | ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | \
246 (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) << 16))
247
248 /* No operation (Thumb mode)
249 * NOTE: this is "MOV r8, r8" ... Thumb2 adds two
250 * architected NOPs, 16-bit and 32-bit.
251 */
252 #define ARMV4_5_T_NOP (0x46c0 | (0x46c0 << 16))
253
254 /* Move immediate to register (Thumb state)
255 * Rd: destination register
256 * Im: 8-bit immediate value
257 */
258 #define ARMV4_5_T_MOV_IM(Rd, Im) \
259 ((0x2000 | ((Rd) << 8) | (Im)) \
260 | ((0x2000 | ((Rd) << 8) | (Im)) << 16))
261
262 /* Branch and Exchange
263 * Rm: register containing branch target
264 */
265 #define ARMV4_5_T_BX(Rm) \
266 ((0x4700 | ((Rm) << 3)) \
267 | ((0x4700 | ((Rm) << 3)) << 16))
268
269 /* Branch (Thumb state)
270 * Imm: Branch target
271 */
272 #define ARMV4_5_T_B(Imm) \
273 ((0xe000 | (Imm)) \
274 | ((0xe000 | (Imm)) << 16))
275
276 /* Breakpoint instruction (ARMv5) (Thumb state)
277 * Im: 8-bit immediate
278 */
279 #define ARMV5_T_BKPT(Im) \
280 ((0xbe00 | (Im)) \
281 | ((0xbe00 | (Im)) << 16))
282
283 /* Move to Register from Special Register
284 * 32 bit Thumb2 instruction
285 * Rd: destination register
286 * SYSm: source special register
287 */
288 #define ARM_T2_MRS(Rd, SYSm) \
289 ((0xF3EF) | ((0x8000 | (Rd << 8) | SYSm) << 16))
290
291 /* Move from Register from Special Register
292 * 32 bit Thumb2 instruction
293 * Rd: source register
294 * SYSm: destination special register
295 */
296 #define ARM_T2_MSR(SYSm, Rn) \
297 ((0xF380 | (Rn << 8)) | ((0x8800 | SYSm) << 16))
298
299 /* Change Processor State.
300 * 16 bit Thumb2 instruction
301 * Rd: source register
302 * IF: A_FLAG and/or I_FLAG and/or F_FLAG
303 */
304 #define A_FLAG 4
305 #define I_FLAG 2
306 #define F_FLAG 1
307 #define ARM_T2_CPSID(IF) \
308 ((0xB660 | (1 << 8) | ((IF)&0x3)) \
309 | ((0xB660 | (1 << 8) | ((IF)&0x3)) << 16))
310 #define ARM_T2_CPSIE(IF) \
311 ((0xB660 | (0 << 8) | ((IF)&0x3)) \
312 | ((0xB660 | (0 << 8) | ((IF)&0x3)) << 16))
313
314 #endif /* __ARM_OPCODES_H */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)