xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/arch/aarch64-insn.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1 /* Copyright (C) 2009-2023 Free Software Foundation, Inc.
2    Contributed by ARM Ltd.
3 
4    This file is part of GDB.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #ifndef ARCH_AARCH64_INSN_H
20 #define ARCH_AARCH64_INSN_H
21 
22 extern bool aarch64_debug;
23 
24 /* Print an "aarch64" debug statement.  */
25 
26 #define aarch64_debug_printf(fmt, ...) \
27   debug_prefixed_printf_cond (aarch64_debug, "aarch64", fmt, ##__VA_ARGS__)
28 
29 /* Support routines for instruction parsing.  */
30 
31 /* Create a mask of X bits.  */
32 #define submask(x) ((1L << ((x) + 1)) - 1)
33 
34 /* Extract the bitfield from OBJ starting at bit ST and ending at bit FN.  */
35 #define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
36 
37 /* Extract bit ST from OBJ.  */
38 #define bit(obj,st) (((obj) >> (st)) & 1)
39 
40 /* Extract the signed bitfield from OBJ starting at bit ST and ending at
41    bit FN.  The result is sign-extended.  */
42 #define sbits(obj,st,fn) \
43   ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
44 
45 /* Prologue analyzer helper macros.  */
46 
47 /* Is the instruction "bti"?  */
48 #define IS_BTI(instruction) ((instruction & 0xffffff3f) == 0xd503241f)
49 
50 /* List of opcodes that we need for building the jump pad and relocating
51    an instruction.  */
52 
53 enum aarch64_opcodes
54 {
55   /* B              0001 01ii iiii iiii iiii iiii iiii iiii */
56   /* BL             1001 01ii iiii iiii iiii iiii iiii iiii */
57   /* B.COND         0101 0100 iiii iiii iiii iiii iii0 cccc */
58   /* CBZ            s011 0100 iiii iiii iiii iiii iiir rrrr */
59   /* CBNZ           s011 0101 iiii iiii iiii iiii iiir rrrr */
60   /* TBZ            b011 0110 bbbb biii iiii iiii iiir rrrr */
61   /* TBNZ           b011 0111 bbbb biii iiii iiii iiir rrrr */
62   B               = 0x14000000,
63   BL              = 0x80000000 | B,
64   BCOND           = 0x40000000 | B,
65   CBZ             = 0x20000000 | B,
66   CBNZ            = 0x21000000 | B,
67   TBZ             = 0x36000000 | B,
68   TBNZ            = 0x37000000 | B,
69   /* BR             1101 0110 0001 1111 0000 00rr rrr0 0000 */
70   /* BLR            1101 0110 0011 1111 0000 00rr rrr0 0000 */
71   BR              = 0xd61f0000,
72   BLR             = 0xd63f0000,
73   /* RET            1101 0110 0101 1111 0000 00rr rrr0 0000 */
74   RET             = 0xd65f0000,
75   /* STP            s010 100o o0ii iiii irrr rrrr rrrr rrrr */
76   /* LDP            s010 100o o1ii iiii irrr rrrr rrrr rrrr */
77   /* STP (SIMD&VFP) ss10 110o o0ii iiii irrr rrrr rrrr rrrr */
78   /* LDP (SIMD&VFP) ss10 110o o1ii iiii irrr rrrr rrrr rrrr */
79   STP             = 0x28000000,
80   LDP             = 0x28400000,
81   STP_SIMD_VFP    = 0x04000000 | STP,
82   LDP_SIMD_VFP    = 0x04000000 | LDP,
83   /* STR            ss11 100o 00xi iiii iiii xxrr rrrr rrrr */
84   /* LDR            ss11 100o 01xi iiii iiii xxrr rrrr rrrr */
85   /* LDRSW          1011 100o 10xi iiii iiii xxrr rrrr rrrr */
86   STR             = 0x38000000,
87   LDR             = 0x00400000 | STR,
88   LDRSW           = 0x80800000 | STR,
89   /* LDAXR          ss00 1000 0101 1111 1111 11rr rrrr rrrr */
90   LDAXR           = 0x085ffc00,
91   /* STXR           ss00 1000 000r rrrr 0111 11rr rrrr rrrr */
92   STXR            = 0x08007c00,
93   /* STLR           ss00 1000 1001 1111 1111 11rr rrrr rrrr */
94   STLR            = 0x089ffc00,
95   /* MOV            s101 0010 1xxi iiii iiii iiii iiir rrrr */
96   /* MOVK           s111 0010 1xxi iiii iiii iiii iiir rrrr */
97   MOV             = 0x52800000,
98   MOVK            = 0x20000000 | MOV,
99   /* ADD            s00o ooo1 xxxx xxxx xxxx xxxx xxxx xxxx */
100   /* SUB            s10o ooo1 xxxx xxxx xxxx xxxx xxxx xxxx */
101   /* SUBS           s11o ooo1 xxxx xxxx xxxx xxxx xxxx xxxx */
102   ADD             = 0x01000000,
103   SUB             = 0x40000000 | ADD,
104   SUBS            = 0x20000000 | SUB,
105   /* AND            s000 1010 xx0x xxxx xxxx xxxx xxxx xxxx */
106   /* ORR            s010 1010 xx0x xxxx xxxx xxxx xxxx xxxx */
107   /* ORN            s010 1010 xx1x xxxx xxxx xxxx xxxx xxxx */
108   /* EOR            s100 1010 xx0x xxxx xxxx xxxx xxxx xxxx */
109   AND             = 0x0a000000,
110   ORR             = 0x20000000 | AND,
111   ORN             = 0x00200000 | ORR,
112   EOR             = 0x40000000 | AND,
113   /* LSLV           s001 1010 110r rrrr 0010 00rr rrrr rrrr */
114   /* LSRV           s001 1010 110r rrrr 0010 01rr rrrr rrrr */
115   /* ASRV           s001 1010 110r rrrr 0010 10rr rrrr rrrr */
116   LSLV             = 0x1ac02000,
117   LSRV             = 0x00000400 | LSLV,
118   ASRV             = 0x00000800 | LSLV,
119   /* SBFM           s001 0011 0nii iiii iiii iirr rrrr rrrr */
120   SBFM            = 0x13000000,
121   /* UBFM           s101 0011 0nii iiii iiii iirr rrrr rrrr */
122   UBFM            = 0x40000000 | SBFM,
123   /* CSINC          s001 1010 100r rrrr cccc 01rr rrrr rrrr */
124   CSINC           = 0x9a800400,
125   /* MUL            s001 1011 000r rrrr 0111 11rr rrrr rrrr */
126   MUL             = 0x1b007c00,
127   /* MSR (register) 1101 0101 0001 oooo oooo oooo ooor rrrr */
128   /* MRS            1101 0101 0011 oooo oooo oooo ooor rrrr */
129   MSR             = 0xd5100000,
130   MRS             = 0x00200000 | MSR,
131   /* HINT           1101 0101 0000 0011 0010 oooo ooo1 1111 */
132   HINT            = 0xd503201f,
133   SEVL            = (5 << 5) | HINT,
134   WFE             = (2 << 5) | HINT,
135   NOP             = (0 << 5) | HINT,
136 };
137 
138 /* List of useful masks.  */
139 enum aarch64_masks
140 {
141   /* Used for masking out an Rn argument from an opcode.  */
142   CLEAR_Rn_MASK = 0xfffffc1f,
143 };
144 
145 /* Representation of a general purpose register of the form xN or wN.
146 
147    This type is used by emitting functions that take registers as operands.  */
148 
149 struct aarch64_register
150 {
151   unsigned num;
152   int is64;
153 };
154 
155 enum aarch64_memory_operand_type
156 {
157   MEMORY_OPERAND_OFFSET,
158   MEMORY_OPERAND_PREINDEX,
159   MEMORY_OPERAND_POSTINDEX,
160 };
161 
162 /* Representation of a memory operand, used for load and store
163    instructions.
164 
165    The types correspond to the following variants:
166 
167    MEMORY_OPERAND_OFFSET:    LDR rt, [rn, #offset]
168    MEMORY_OPERAND_PREINDEX:  LDR rt, [rn, #index]!
169    MEMORY_OPERAND_POSTINDEX: LDR rt, [rn], #index  */
170 
171 struct aarch64_memory_operand
172 {
173   /* Type of the operand.  */
174   enum aarch64_memory_operand_type type;
175 
176   /* Index from the base register.  */
177   int32_t index;
178 };
179 
180 /* Helper macro to mask and shift a value into a bitfield.  */
181 
182 #define ENCODE(val, size, offset) \
183   ((uint32_t) ((val & ((1ULL << size) - 1)) << offset))
184 
185 int aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
186 			unsigned *rd, int32_t *offset);
187 
188 int aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
189 		      int32_t *offset);
190 
191 int aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
192 			  int32_t *offset);
193 
194 int aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64,
195 		       int *is_cbnz, unsigned *rn, int32_t *offset);
196 
197 int aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
198 		       unsigned *bit, unsigned *rt, int32_t *imm);
199 
200 int aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
201 				int *is64, unsigned *rt, int32_t *offset);
202 
203 /* Data passed to each method of aarch64_insn_visitor.  */
204 
205 struct aarch64_insn_data
206 {
207   /* The instruction address.  */
208   CORE_ADDR insn_addr;
209 };
210 
211 /* Visit different instructions by different methods.  */
212 
213 struct aarch64_insn_visitor
214 {
215   /* Visit instruction B/BL OFFSET.  */
216   void (*b) (const int is_bl, const int32_t offset,
217 	     struct aarch64_insn_data *data);
218 
219   /* Visit instruction B.COND OFFSET.  */
220   void (*b_cond) (const unsigned cond, const int32_t offset,
221 		  struct aarch64_insn_data *data);
222 
223   /* Visit instruction CBZ/CBNZ Rn, OFFSET.  */
224   void (*cb) (const int32_t offset, const int is_cbnz,
225 	      const unsigned rn, int is64,
226 	      struct aarch64_insn_data *data);
227 
228   /* Visit instruction TBZ/TBNZ Rt, #BIT, OFFSET.  */
229   void (*tb) (const int32_t offset, int is_tbnz,
230 	      const unsigned rt, unsigned bit,
231 	      struct aarch64_insn_data *data);
232 
233   /* Visit instruction ADR/ADRP Rd, OFFSET.  */
234   void (*adr) (const int32_t offset, const unsigned rd,
235 	       const int is_adrp, struct aarch64_insn_data *data);
236 
237   /* Visit instruction LDR/LDRSW Rt, OFFSET.  */
238   void (*ldr_literal) (const int32_t offset, const int is_sw,
239 		       const unsigned rt, const int is64,
240 		       struct aarch64_insn_data *data);
241 
242   /* Visit instruction INSN of other kinds.  */
243   void (*others) (const uint32_t insn, struct aarch64_insn_data *data);
244 };
245 
246 void aarch64_relocate_instruction (uint32_t insn,
247 				   const struct aarch64_insn_visitor *visitor,
248 				   struct aarch64_insn_data *data);
249 
250 #define can_encode_int32(val, bits)			\
251   (((val) >> (bits)) == 0 || ((val) >> (bits)) == -1)
252 
253 /* Write a B or BL instruction into *BUF.
254 
255      B  #offset
256      BL #offset
257 
258    IS_BL specifies if the link register should be updated.
259    OFFSET is the immediate offset from the current PC.  It is
260    byte-addressed but should be 4 bytes aligned.  It has a limited range of
261    +/- 128MB (26 bits << 2).  */
262 
263 #define emit_b(buf, is_bl, offset) \
264   aarch64_emit_insn (buf, ((is_bl) ? BL : B) | (ENCODE ((offset) >> 2, 26, 0)))
265 
266 /* Write a BCOND instruction into *BUF.
267 
268      B.COND #offset
269 
270    COND specifies the condition field.
271    OFFSET is the immediate offset from the current PC.  It is
272    byte-addressed but should be 4 bytes aligned.  It has a limited range of
273    +/- 1MB (19 bits << 2).  */
274 
275 #define emit_bcond(buf, cond, offset)				\
276   aarch64_emit_insn (buf,					\
277 		     BCOND | ENCODE ((offset) >> 2, 19, 5)	\
278 		     | ENCODE ((cond), 4, 0))
279 
280 /* Write a CBZ or CBNZ instruction into *BUF.
281 
282      CBZ  rt, #offset
283      CBNZ rt, #offset
284 
285    IS_CBNZ distinguishes between CBZ and CBNZ instructions.
286    RN is the register to test.
287    OFFSET is the immediate offset from the current PC.  It is
288    byte-addressed but should be 4 bytes aligned.  It has a limited range of
289    +/- 1MB (19 bits << 2).  */
290 
291 #define emit_cb(buf, is_cbnz, rt, offset)			\
292   aarch64_emit_insn (buf,					\
293 		     ((is_cbnz) ? CBNZ : CBZ)			\
294 		     | ENCODE (rt.is64, 1, 31)  /* sf */	\
295 		     | ENCODE (offset >> 2, 19, 5) /* imm19 */	\
296 		     | ENCODE (rt.num, 5, 0))
297 
298 /* Write a LDR instruction into *BUF.
299 
300      LDR rt, [rn, #offset]
301      LDR rt, [rn, #index]!
302      LDR rt, [rn], #index
303 
304    RT is the register to store.
305    RN is the base address register.
306    OFFSET is the immediate to add to the base address.  It is limited to
307    0 .. 32760 range (12 bits << 3).  */
308 
309 #define emit_ldr(buf, rt, rn, operand) \
310   aarch64_emit_load_store (buf, rt.is64 ? 3 : 2, LDR, rt, rn, operand)
311 
312 /* Write a LDRSW instruction into *BUF.  The register size is 64-bit.
313 
314      LDRSW xt, [rn, #offset]
315      LDRSW xt, [rn, #index]!
316      LDRSW xt, [rn], #index
317 
318    RT is the register to store.
319    RN is the base address register.
320    OFFSET is the immediate to add to the base address.  It is limited to
321    0 .. 16380 range (12 bits << 2).  */
322 
323 #define emit_ldrsw(buf, rt, rn, operand)		\
324   aarch64_emit_load_store (buf, 3, LDRSW, rt, rn, operand)
325 
326 
327 /* Write a TBZ or TBNZ instruction into *BUF.
328 
329    TBZ  rt, #bit, #offset
330    TBNZ rt, #bit, #offset
331 
332    IS_TBNZ distinguishes between TBZ and TBNZ instructions.
333    RT is the register to test.
334    BIT is the index of the bit to test in register RT.
335    OFFSET is the immediate offset from the current PC.  It is
336    byte-addressed but should be 4 bytes aligned.  It has a limited range of
337    +/- 32KB (14 bits << 2).  */
338 
339 #define emit_tb(buf, is_tbnz, bit, rt, offset)		       \
340   aarch64_emit_insn (buf,				       \
341 		     ((is_tbnz) ? TBNZ: TBZ)		       \
342 		     | ENCODE (bit >> 5, 1, 31) /* b5 */       \
343 		     | ENCODE (bit, 5, 19) /* b40 */	       \
344 		     | ENCODE (offset >> 2, 14, 5) /* imm14 */ \
345 		     | ENCODE (rt.num, 5, 0))
346 
347 /* Write a NOP instruction into *BUF.  */
348 
349 #define emit_nop(buf) aarch64_emit_insn (buf, NOP)
350 
351 int aarch64_emit_insn (uint32_t *buf, uint32_t insn);
352 
353 int aarch64_emit_load_store (uint32_t *buf, uint32_t size,
354 			     enum aarch64_opcodes opcode,
355 			     struct aarch64_register rt,
356 			     struct aarch64_register rn,
357 			     struct aarch64_memory_operand operand);
358 
359 #endif /* ARCH_AARCH64_INSN_H */
360