linux-aarch64-low.cc revision 1.1 1 1.1 christos /* GNU/Linux/AArch64 specific low level interface, for the remote server for
2 1.1 christos GDB.
3 1.1 christos
4 1.1 christos Copyright (C) 2009-2020 Free Software Foundation, Inc.
5 1.1 christos Contributed by ARM Ltd.
6 1.1 christos
7 1.1 christos This file is part of GDB.
8 1.1 christos
9 1.1 christos This program is free software; you can redistribute it and/or modify
10 1.1 christos it under the terms of the GNU General Public License as published by
11 1.1 christos the Free Software Foundation; either version 3 of the License, or
12 1.1 christos (at your option) any later version.
13 1.1 christos
14 1.1 christos This program is distributed in the hope that it will be useful,
15 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
16 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 1.1 christos GNU General Public License for more details.
18 1.1 christos
19 1.1 christos You should have received a copy of the GNU General Public License
20 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 1.1 christos
22 1.1 christos #include "server.h"
23 1.1 christos #include "linux-low.h"
24 1.1 christos #include "nat/aarch64-linux.h"
25 1.1 christos #include "nat/aarch64-linux-hw-point.h"
26 1.1 christos #include "arch/aarch64-insn.h"
27 1.1 christos #include "linux-aarch32-low.h"
28 1.1 christos #include "elf/common.h"
29 1.1 christos #include "ax.h"
30 1.1 christos #include "tracepoint.h"
31 1.1 christos #include "debug.h"
32 1.1 christos
33 1.1 christos #include <signal.h>
34 1.1 christos #include <sys/user.h>
35 1.1 christos #include "nat/gdb_ptrace.h"
36 1.1 christos #include <asm/ptrace.h>
37 1.1 christos #include <inttypes.h>
38 1.1 christos #include <endian.h>
39 1.1 christos #include <sys/uio.h>
40 1.1 christos
41 1.1 christos #include "gdb_proc_service.h"
42 1.1 christos #include "arch/aarch64.h"
43 1.1 christos #include "linux-aarch32-tdesc.h"
44 1.1 christos #include "linux-aarch64-tdesc.h"
45 1.1 christos #include "nat/aarch64-sve-linux-ptrace.h"
46 1.1 christos #include "tdesc.h"
47 1.1 christos
48 1.1 christos #ifdef HAVE_SYS_REG_H
49 1.1 christos #include <sys/reg.h>
50 1.1 christos #endif
51 1.1 christos
52 1.1 christos /* Linux target op definitions for the AArch64 architecture. */
53 1.1 christos
54 1.1 christos class aarch64_target : public linux_process_target
55 1.1 christos {
56 1.1 christos public:
57 1.1 christos
58 1.1 christos const regs_info *get_regs_info () override;
59 1.1 christos
60 1.1 christos int breakpoint_kind_from_pc (CORE_ADDR *pcptr) override;
61 1.1 christos
62 1.1 christos int breakpoint_kind_from_current_state (CORE_ADDR *pcptr) override;
63 1.1 christos
64 1.1 christos const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
65 1.1 christos
66 1.1 christos bool supports_z_point_type (char z_type) override;
67 1.1 christos
68 1.1 christos bool supports_tracepoints () override;
69 1.1 christos
70 1.1 christos bool supports_fast_tracepoints () override;
71 1.1 christos
72 1.1 christos int install_fast_tracepoint_jump_pad
73 1.1 christos (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
74 1.1 christos CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
75 1.1 christos CORE_ADDR *trampoline, ULONGEST *trampoline_size,
76 1.1 christos unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
77 1.1 christos CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
78 1.1 christos char *err) override;
79 1.1 christos
80 1.1 christos int get_min_fast_tracepoint_insn_len () override;
81 1.1 christos
82 1.1 christos struct emit_ops *emit_ops () override;
83 1.1 christos
84 1.1 christos protected:
85 1.1 christos
86 1.1 christos void low_arch_setup () override;
87 1.1 christos
88 1.1 christos bool low_cannot_fetch_register (int regno) override;
89 1.1 christos
90 1.1 christos bool low_cannot_store_register (int regno) override;
91 1.1 christos
92 1.1 christos bool low_supports_breakpoints () override;
93 1.1 christos
94 1.1 christos CORE_ADDR low_get_pc (regcache *regcache) override;
95 1.1 christos
96 1.1 christos void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
97 1.1 christos
98 1.1 christos bool low_breakpoint_at (CORE_ADDR pc) override;
99 1.1 christos
100 1.1 christos int low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
101 1.1 christos int size, raw_breakpoint *bp) override;
102 1.1 christos
103 1.1 christos int low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
104 1.1 christos int size, raw_breakpoint *bp) override;
105 1.1 christos
106 1.1 christos bool low_stopped_by_watchpoint () override;
107 1.1 christos
108 1.1 christos CORE_ADDR low_stopped_data_address () override;
109 1.1 christos
110 1.1 christos bool low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
111 1.1 christos int direction) override;
112 1.1 christos
113 1.1 christos arch_process_info *low_new_process () override;
114 1.1 christos
115 1.1 christos void low_delete_process (arch_process_info *info) override;
116 1.1 christos
117 1.1 christos void low_new_thread (lwp_info *) override;
118 1.1 christos
119 1.1 christos void low_delete_thread (arch_lwp_info *) override;
120 1.1 christos
121 1.1 christos void low_new_fork (process_info *parent, process_info *child) override;
122 1.1 christos
123 1.1 christos void low_prepare_to_resume (lwp_info *lwp) override;
124 1.1 christos
125 1.1 christos int low_get_thread_area (int lwpid, CORE_ADDR *addrp) override;
126 1.1 christos
127 1.1 christos bool low_supports_range_stepping () override;
128 1.1 christos
129 1.1 christos bool low_supports_catch_syscall () override;
130 1.1 christos
131 1.1 christos void low_get_syscall_trapinfo (regcache *regcache, int *sysno) override;
132 1.1 christos };
133 1.1 christos
134 1.1 christos /* The singleton target ops object. */
135 1.1 christos
136 1.1 christos static aarch64_target the_aarch64_target;
137 1.1 christos
138 1.1 christos bool
139 1.1 christos aarch64_target::low_cannot_fetch_register (int regno)
140 1.1 christos {
141 1.1 christos gdb_assert_not_reached ("linux target op low_cannot_fetch_register "
142 1.1 christos "is not implemented by the target");
143 1.1 christos }
144 1.1 christos
145 1.1 christos bool
146 1.1 christos aarch64_target::low_cannot_store_register (int regno)
147 1.1 christos {
148 1.1 christos gdb_assert_not_reached ("linux target op low_cannot_store_register "
149 1.1 christos "is not implemented by the target");
150 1.1 christos }
151 1.1 christos
152 1.1 christos void
153 1.1 christos aarch64_target::low_prepare_to_resume (lwp_info *lwp)
154 1.1 christos {
155 1.1 christos aarch64_linux_prepare_to_resume (lwp);
156 1.1 christos }
157 1.1 christos
158 1.1 christos /* Per-process arch-specific data we want to keep. */
159 1.1 christos
160 1.1 christos struct arch_process_info
161 1.1 christos {
162 1.1 christos /* Hardware breakpoint/watchpoint data.
163 1.1 christos The reason for them to be per-process rather than per-thread is
164 1.1 christos due to the lack of information in the gdbserver environment;
165 1.1 christos gdbserver is not told that whether a requested hardware
166 1.1 christos breakpoint/watchpoint is thread specific or not, so it has to set
167 1.1 christos each hw bp/wp for every thread in the current process. The
168 1.1 christos higher level bp/wp management in gdb will resume a thread if a hw
169 1.1 christos bp/wp trap is not expected for it. Since the hw bp/wp setting is
170 1.1 christos same for each thread, it is reasonable for the data to live here.
171 1.1 christos */
172 1.1 christos struct aarch64_debug_reg_state debug_reg_state;
173 1.1 christos };
174 1.1 christos
175 1.1 christos /* Return true if the size of register 0 is 8 byte. */
176 1.1 christos
177 1.1 christos static int
178 1.1 christos is_64bit_tdesc (void)
179 1.1 christos {
180 1.1 christos struct regcache *regcache = get_thread_regcache (current_thread, 0);
181 1.1 christos
182 1.1 christos return register_size (regcache->tdesc, 0) == 8;
183 1.1 christos }
184 1.1 christos
185 1.1 christos /* Return true if the regcache contains the number of SVE registers. */
186 1.1 christos
187 1.1 christos static bool
188 1.1 christos is_sve_tdesc (void)
189 1.1 christos {
190 1.1 christos struct regcache *regcache = get_thread_regcache (current_thread, 0);
191 1.1 christos
192 1.1 christos return tdesc_contains_feature (regcache->tdesc, "org.gnu.gdb.aarch64.sve");
193 1.1 christos }
194 1.1 christos
195 1.1 christos static void
196 1.1 christos aarch64_fill_gregset (struct regcache *regcache, void *buf)
197 1.1 christos {
198 1.1 christos struct user_pt_regs *regset = (struct user_pt_regs *) buf;
199 1.1 christos int i;
200 1.1 christos
201 1.1 christos for (i = 0; i < AARCH64_X_REGS_NUM; i++)
202 1.1 christos collect_register (regcache, AARCH64_X0_REGNUM + i, ®set->regs[i]);
203 1.1 christos collect_register (regcache, AARCH64_SP_REGNUM, ®set->sp);
204 1.1 christos collect_register (regcache, AARCH64_PC_REGNUM, ®set->pc);
205 1.1 christos collect_register (regcache, AARCH64_CPSR_REGNUM, ®set->pstate);
206 1.1 christos }
207 1.1 christos
208 1.1 christos static void
209 1.1 christos aarch64_store_gregset (struct regcache *regcache, const void *buf)
210 1.1 christos {
211 1.1 christos const struct user_pt_regs *regset = (const struct user_pt_regs *) buf;
212 1.1 christos int i;
213 1.1 christos
214 1.1 christos for (i = 0; i < AARCH64_X_REGS_NUM; i++)
215 1.1 christos supply_register (regcache, AARCH64_X0_REGNUM + i, ®set->regs[i]);
216 1.1 christos supply_register (regcache, AARCH64_SP_REGNUM, ®set->sp);
217 1.1 christos supply_register (regcache, AARCH64_PC_REGNUM, ®set->pc);
218 1.1 christos supply_register (regcache, AARCH64_CPSR_REGNUM, ®set->pstate);
219 1.1 christos }
220 1.1 christos
221 1.1 christos static void
222 1.1 christos aarch64_fill_fpregset (struct regcache *regcache, void *buf)
223 1.1 christos {
224 1.1 christos struct user_fpsimd_state *regset = (struct user_fpsimd_state *) buf;
225 1.1 christos int i;
226 1.1 christos
227 1.1 christos for (i = 0; i < AARCH64_V_REGS_NUM; i++)
228 1.1 christos collect_register (regcache, AARCH64_V0_REGNUM + i, ®set->vregs[i]);
229 1.1 christos collect_register (regcache, AARCH64_FPSR_REGNUM, ®set->fpsr);
230 1.1 christos collect_register (regcache, AARCH64_FPCR_REGNUM, ®set->fpcr);
231 1.1 christos }
232 1.1 christos
233 1.1 christos static void
234 1.1 christos aarch64_store_fpregset (struct regcache *regcache, const void *buf)
235 1.1 christos {
236 1.1 christos const struct user_fpsimd_state *regset
237 1.1 christos = (const struct user_fpsimd_state *) buf;
238 1.1 christos int i;
239 1.1 christos
240 1.1 christos for (i = 0; i < AARCH64_V_REGS_NUM; i++)
241 1.1 christos supply_register (regcache, AARCH64_V0_REGNUM + i, ®set->vregs[i]);
242 1.1 christos supply_register (regcache, AARCH64_FPSR_REGNUM, ®set->fpsr);
243 1.1 christos supply_register (regcache, AARCH64_FPCR_REGNUM, ®set->fpcr);
244 1.1 christos }
245 1.1 christos
246 1.1 christos /* Store the pauth registers to regcache. */
247 1.1 christos
248 1.1 christos static void
249 1.1 christos aarch64_store_pauthregset (struct regcache *regcache, const void *buf)
250 1.1 christos {
251 1.1 christos uint64_t *pauth_regset = (uint64_t *) buf;
252 1.1 christos int pauth_base = find_regno (regcache->tdesc, "pauth_dmask");
253 1.1 christos
254 1.1 christos if (pauth_base == 0)
255 1.1 christos return;
256 1.1 christos
257 1.1 christos supply_register (regcache, AARCH64_PAUTH_DMASK_REGNUM (pauth_base),
258 1.1 christos &pauth_regset[0]);
259 1.1 christos supply_register (regcache, AARCH64_PAUTH_CMASK_REGNUM (pauth_base),
260 1.1 christos &pauth_regset[1]);
261 1.1 christos }
262 1.1 christos
263 1.1 christos bool
264 1.1 christos aarch64_target::low_supports_breakpoints ()
265 1.1 christos {
266 1.1 christos return true;
267 1.1 christos }
268 1.1 christos
269 1.1 christos /* Implementation of linux target ops method "low_get_pc". */
270 1.1 christos
271 1.1 christos CORE_ADDR
272 1.1 christos aarch64_target::low_get_pc (regcache *regcache)
273 1.1 christos {
274 1.1 christos if (register_size (regcache->tdesc, 0) == 8)
275 1.1 christos return linux_get_pc_64bit (regcache);
276 1.1 christos else
277 1.1 christos return linux_get_pc_32bit (regcache);
278 1.1 christos }
279 1.1 christos
280 1.1 christos /* Implementation of linux target ops method "low_set_pc". */
281 1.1 christos
282 1.1 christos void
283 1.1 christos aarch64_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
284 1.1 christos {
285 1.1 christos if (register_size (regcache->tdesc, 0) == 8)
286 1.1 christos linux_set_pc_64bit (regcache, pc);
287 1.1 christos else
288 1.1 christos linux_set_pc_32bit (regcache, pc);
289 1.1 christos }
290 1.1 christos
291 1.1 christos #define aarch64_breakpoint_len 4
292 1.1 christos
293 1.1 christos /* AArch64 BRK software debug mode instruction.
294 1.1 christos This instruction needs to match gdb/aarch64-tdep.c
295 1.1 christos (aarch64_default_breakpoint). */
296 1.1 christos static const gdb_byte aarch64_breakpoint[] = {0x00, 0x00, 0x20, 0xd4};
297 1.1 christos
298 1.1 christos /* Implementation of linux target ops method "low_breakpoint_at". */
299 1.1 christos
300 1.1 christos bool
301 1.1 christos aarch64_target::low_breakpoint_at (CORE_ADDR where)
302 1.1 christos {
303 1.1 christos if (is_64bit_tdesc ())
304 1.1 christos {
305 1.1 christos gdb_byte insn[aarch64_breakpoint_len];
306 1.1 christos
307 1.1 christos read_memory (where, (unsigned char *) &insn, aarch64_breakpoint_len);
308 1.1 christos if (memcmp (insn, aarch64_breakpoint, aarch64_breakpoint_len) == 0)
309 1.1 christos return true;
310 1.1 christos
311 1.1 christos return false;
312 1.1 christos }
313 1.1 christos else
314 1.1 christos return arm_breakpoint_at (where);
315 1.1 christos }
316 1.1 christos
317 1.1 christos static void
318 1.1 christos aarch64_init_debug_reg_state (struct aarch64_debug_reg_state *state)
319 1.1 christos {
320 1.1 christos int i;
321 1.1 christos
322 1.1 christos for (i = 0; i < AARCH64_HBP_MAX_NUM; ++i)
323 1.1 christos {
324 1.1 christos state->dr_addr_bp[i] = 0;
325 1.1 christos state->dr_ctrl_bp[i] = 0;
326 1.1 christos state->dr_ref_count_bp[i] = 0;
327 1.1 christos }
328 1.1 christos
329 1.1 christos for (i = 0; i < AARCH64_HWP_MAX_NUM; ++i)
330 1.1 christos {
331 1.1 christos state->dr_addr_wp[i] = 0;
332 1.1 christos state->dr_ctrl_wp[i] = 0;
333 1.1 christos state->dr_ref_count_wp[i] = 0;
334 1.1 christos }
335 1.1 christos }
336 1.1 christos
337 1.1 christos /* Return the pointer to the debug register state structure in the
338 1.1 christos current process' arch-specific data area. */
339 1.1 christos
340 1.1 christos struct aarch64_debug_reg_state *
341 1.1 christos aarch64_get_debug_reg_state (pid_t pid)
342 1.1 christos {
343 1.1 christos struct process_info *proc = find_process_pid (pid);
344 1.1 christos
345 1.1 christos return &proc->priv->arch_private->debug_reg_state;
346 1.1 christos }
347 1.1 christos
348 1.1 christos /* Implementation of target ops method "supports_z_point_type". */
349 1.1 christos
350 1.1 christos bool
351 1.1 christos aarch64_target::supports_z_point_type (char z_type)
352 1.1 christos {
353 1.1 christos switch (z_type)
354 1.1 christos {
355 1.1 christos case Z_PACKET_SW_BP:
356 1.1 christos case Z_PACKET_HW_BP:
357 1.1 christos case Z_PACKET_WRITE_WP:
358 1.1 christos case Z_PACKET_READ_WP:
359 1.1 christos case Z_PACKET_ACCESS_WP:
360 1.1 christos return true;
361 1.1 christos default:
362 1.1 christos return false;
363 1.1 christos }
364 1.1 christos }
365 1.1 christos
366 1.1 christos /* Implementation of linux target ops method "low_insert_point".
367 1.1 christos
368 1.1 christos It actually only records the info of the to-be-inserted bp/wp;
369 1.1 christos the actual insertion will happen when threads are resumed. */
370 1.1 christos
371 1.1 christos int
372 1.1 christos aarch64_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
373 1.1 christos int len, raw_breakpoint *bp)
374 1.1 christos {
375 1.1 christos int ret;
376 1.1 christos enum target_hw_bp_type targ_type;
377 1.1 christos struct aarch64_debug_reg_state *state
378 1.1 christos = aarch64_get_debug_reg_state (pid_of (current_thread));
379 1.1 christos
380 1.1 christos if (show_debug_regs)
381 1.1 christos fprintf (stderr, "insert_point on entry (addr=0x%08lx, len=%d)\n",
382 1.1 christos (unsigned long) addr, len);
383 1.1 christos
384 1.1 christos /* Determine the type from the raw breakpoint type. */
385 1.1 christos targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
386 1.1 christos
387 1.1 christos if (targ_type != hw_execute)
388 1.1 christos {
389 1.1 christos if (aarch64_linux_region_ok_for_watchpoint (addr, len))
390 1.1 christos ret = aarch64_handle_watchpoint (targ_type, addr, len,
391 1.1 christos 1 /* is_insert */, state);
392 1.1 christos else
393 1.1 christos ret = -1;
394 1.1 christos }
395 1.1 christos else
396 1.1 christos {
397 1.1 christos if (len == 3)
398 1.1 christos {
399 1.1 christos /* LEN is 3 means the breakpoint is set on a 32-bit thumb
400 1.1 christos instruction. Set it to 2 to correctly encode length bit
401 1.1 christos mask in hardware/watchpoint control register. */
402 1.1 christos len = 2;
403 1.1 christos }
404 1.1 christos ret = aarch64_handle_breakpoint (targ_type, addr, len,
405 1.1 christos 1 /* is_insert */, state);
406 1.1 christos }
407 1.1 christos
408 1.1 christos if (show_debug_regs)
409 1.1 christos aarch64_show_debug_reg_state (state, "insert_point", addr, len,
410 1.1 christos targ_type);
411 1.1 christos
412 1.1 christos return ret;
413 1.1 christos }
414 1.1 christos
415 1.1 christos /* Implementation of linux target ops method "low_remove_point".
416 1.1 christos
417 1.1 christos It actually only records the info of the to-be-removed bp/wp,
418 1.1 christos the actual removal will be done when threads are resumed. */
419 1.1 christos
420 1.1 christos int
421 1.1 christos aarch64_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
422 1.1 christos int len, raw_breakpoint *bp)
423 1.1 christos {
424 1.1 christos int ret;
425 1.1 christos enum target_hw_bp_type targ_type;
426 1.1 christos struct aarch64_debug_reg_state *state
427 1.1 christos = aarch64_get_debug_reg_state (pid_of (current_thread));
428 1.1 christos
429 1.1 christos if (show_debug_regs)
430 1.1 christos fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
431 1.1 christos (unsigned long) addr, len);
432 1.1 christos
433 1.1 christos /* Determine the type from the raw breakpoint type. */
434 1.1 christos targ_type = raw_bkpt_type_to_target_hw_bp_type (type);
435 1.1 christos
436 1.1 christos /* Set up state pointers. */
437 1.1 christos if (targ_type != hw_execute)
438 1.1 christos ret =
439 1.1 christos aarch64_handle_watchpoint (targ_type, addr, len, 0 /* is_insert */,
440 1.1 christos state);
441 1.1 christos else
442 1.1 christos {
443 1.1 christos if (len == 3)
444 1.1 christos {
445 1.1 christos /* LEN is 3 means the breakpoint is set on a 32-bit thumb
446 1.1 christos instruction. Set it to 2 to correctly encode length bit
447 1.1 christos mask in hardware/watchpoint control register. */
448 1.1 christos len = 2;
449 1.1 christos }
450 1.1 christos ret = aarch64_handle_breakpoint (targ_type, addr, len,
451 1.1 christos 0 /* is_insert */, state);
452 1.1 christos }
453 1.1 christos
454 1.1 christos if (show_debug_regs)
455 1.1 christos aarch64_show_debug_reg_state (state, "remove_point", addr, len,
456 1.1 christos targ_type);
457 1.1 christos
458 1.1 christos return ret;
459 1.1 christos }
460 1.1 christos
461 1.1 christos /* Implementation of linux target ops method "low_stopped_data_address". */
462 1.1 christos
463 1.1 christos CORE_ADDR
464 1.1 christos aarch64_target::low_stopped_data_address ()
465 1.1 christos {
466 1.1 christos siginfo_t siginfo;
467 1.1 christos int pid, i;
468 1.1 christos struct aarch64_debug_reg_state *state;
469 1.1 christos
470 1.1 christos pid = lwpid_of (current_thread);
471 1.1 christos
472 1.1 christos /* Get the siginfo. */
473 1.1 christos if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
474 1.1 christos return (CORE_ADDR) 0;
475 1.1 christos
476 1.1 christos /* Need to be a hardware breakpoint/watchpoint trap. */
477 1.1 christos if (siginfo.si_signo != SIGTRAP
478 1.1 christos || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
479 1.1 christos return (CORE_ADDR) 0;
480 1.1 christos
481 1.1 christos /* Check if the address matches any watched address. */
482 1.1 christos state = aarch64_get_debug_reg_state (pid_of (current_thread));
483 1.1 christos for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
484 1.1 christos {
485 1.1 christos const unsigned int offset
486 1.1 christos = aarch64_watchpoint_offset (state->dr_ctrl_wp[i]);
487 1.1 christos const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
488 1.1 christos const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
489 1.1 christos const CORE_ADDR addr_watch = state->dr_addr_wp[i] + offset;
490 1.1 christos const CORE_ADDR addr_watch_aligned = align_down (state->dr_addr_wp[i], 8);
491 1.1 christos const CORE_ADDR addr_orig = state->dr_addr_orig_wp[i];
492 1.1 christos
493 1.1 christos if (state->dr_ref_count_wp[i]
494 1.1 christos && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
495 1.1 christos && addr_trap >= addr_watch_aligned
496 1.1 christos && addr_trap < addr_watch + len)
497 1.1 christos {
498 1.1 christos /* ADDR_TRAP reports the first address of the memory range
499 1.1 christos accessed by the CPU, regardless of what was the memory
500 1.1 christos range watched. Thus, a large CPU access that straddles
501 1.1 christos the ADDR_WATCH..ADDR_WATCH+LEN range may result in an
502 1.1 christos ADDR_TRAP that is lower than the
503 1.1 christos ADDR_WATCH..ADDR_WATCH+LEN range. E.g.:
504 1.1 christos
505 1.1 christos addr: | 4 | 5 | 6 | 7 | 8 |
506 1.1 christos |---- range watched ----|
507 1.1 christos |----------- range accessed ------------|
508 1.1 christos
509 1.1 christos In this case, ADDR_TRAP will be 4.
510 1.1 christos
511 1.1 christos To match a watchpoint known to GDB core, we must never
512 1.1 christos report *ADDR_P outside of any ADDR_WATCH..ADDR_WATCH+LEN
513 1.1 christos range. ADDR_WATCH <= ADDR_TRAP < ADDR_ORIG is a false
514 1.1 christos positive on kernels older than 4.10. See PR
515 1.1 christos external/20207. */
516 1.1 christos return addr_orig;
517 1.1 christos }
518 1.1 christos }
519 1.1 christos
520 1.1 christos return (CORE_ADDR) 0;
521 1.1 christos }
522 1.1 christos
523 1.1 christos /* Implementation of linux target ops method "low_stopped_by_watchpoint". */
524 1.1 christos
525 1.1 christos bool
526 1.1 christos aarch64_target::low_stopped_by_watchpoint ()
527 1.1 christos {
528 1.1 christos return (low_stopped_data_address () != 0);
529 1.1 christos }
530 1.1 christos
531 1.1 christos /* Fetch the thread-local storage pointer for libthread_db. */
532 1.1 christos
533 1.1 christos ps_err_e
534 1.1 christos ps_get_thread_area (struct ps_prochandle *ph,
535 1.1 christos lwpid_t lwpid, int idx, void **base)
536 1.1 christos {
537 1.1 christos return aarch64_ps_get_thread_area (ph, lwpid, idx, base,
538 1.1 christos is_64bit_tdesc ());
539 1.1 christos }
540 1.1 christos
541 1.1 christos /* Implementation of linux target ops method "low_siginfo_fixup". */
542 1.1 christos
543 1.1 christos bool
544 1.1 christos aarch64_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
545 1.1 christos int direction)
546 1.1 christos {
547 1.1 christos /* Is the inferior 32-bit? If so, then fixup the siginfo object. */
548 1.1 christos if (!is_64bit_tdesc ())
549 1.1 christos {
550 1.1 christos if (direction == 0)
551 1.1 christos aarch64_compat_siginfo_from_siginfo ((struct compat_siginfo *) inf,
552 1.1 christos native);
553 1.1 christos else
554 1.1 christos aarch64_siginfo_from_compat_siginfo (native,
555 1.1 christos (struct compat_siginfo *) inf);
556 1.1 christos
557 1.1 christos return true;
558 1.1 christos }
559 1.1 christos
560 1.1 christos return false;
561 1.1 christos }
562 1.1 christos
563 1.1 christos /* Implementation of linux target ops method "low_new_process". */
564 1.1 christos
565 1.1 christos arch_process_info *
566 1.1 christos aarch64_target::low_new_process ()
567 1.1 christos {
568 1.1 christos struct arch_process_info *info = XCNEW (struct arch_process_info);
569 1.1 christos
570 1.1 christos aarch64_init_debug_reg_state (&info->debug_reg_state);
571 1.1 christos
572 1.1 christos return info;
573 1.1 christos }
574 1.1 christos
575 1.1 christos /* Implementation of linux target ops method "low_delete_process". */
576 1.1 christos
577 1.1 christos void
578 1.1 christos aarch64_target::low_delete_process (arch_process_info *info)
579 1.1 christos {
580 1.1 christos xfree (info);
581 1.1 christos }
582 1.1 christos
583 1.1 christos void
584 1.1 christos aarch64_target::low_new_thread (lwp_info *lwp)
585 1.1 christos {
586 1.1 christos aarch64_linux_new_thread (lwp);
587 1.1 christos }
588 1.1 christos
589 1.1 christos void
590 1.1 christos aarch64_target::low_delete_thread (arch_lwp_info *arch_lwp)
591 1.1 christos {
592 1.1 christos aarch64_linux_delete_thread (arch_lwp);
593 1.1 christos }
594 1.1 christos
595 1.1 christos /* Implementation of linux target ops method "low_new_fork". */
596 1.1 christos
597 1.1 christos void
598 1.1 christos aarch64_target::low_new_fork (process_info *parent,
599 1.1 christos process_info *child)
600 1.1 christos {
601 1.1 christos /* These are allocated by linux_add_process. */
602 1.1 christos gdb_assert (parent->priv != NULL
603 1.1 christos && parent->priv->arch_private != NULL);
604 1.1 christos gdb_assert (child->priv != NULL
605 1.1 christos && child->priv->arch_private != NULL);
606 1.1 christos
607 1.1 christos /* Linux kernel before 2.6.33 commit
608 1.1 christos 72f674d203cd230426437cdcf7dd6f681dad8b0d
609 1.1 christos will inherit hardware debug registers from parent
610 1.1 christos on fork/vfork/clone. Newer Linux kernels create such tasks with
611 1.1 christos zeroed debug registers.
612 1.1 christos
613 1.1 christos GDB core assumes the child inherits the watchpoints/hw
614 1.1 christos breakpoints of the parent, and will remove them all from the
615 1.1 christos forked off process. Copy the debug registers mirrors into the
616 1.1 christos new process so that all breakpoints and watchpoints can be
617 1.1 christos removed together. The debug registers mirror will become zeroed
618 1.1 christos in the end before detaching the forked off process, thus making
619 1.1 christos this compatible with older Linux kernels too. */
620 1.1 christos
621 1.1 christos *child->priv->arch_private = *parent->priv->arch_private;
622 1.1 christos }
623 1.1 christos
624 1.1 christos /* Matches HWCAP_PACA in kernel header arch/arm64/include/uapi/asm/hwcap.h. */
625 1.1 christos #define AARCH64_HWCAP_PACA (1 << 30)
626 1.1 christos
627 1.1 christos /* Implementation of linux target ops method "low_arch_setup". */
628 1.1 christos
629 1.1 christos void
630 1.1 christos aarch64_target::low_arch_setup ()
631 1.1 christos {
632 1.1 christos unsigned int machine;
633 1.1 christos int is_elf64;
634 1.1 christos int tid;
635 1.1 christos
636 1.1 christos tid = lwpid_of (current_thread);
637 1.1 christos
638 1.1 christos is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
639 1.1 christos
640 1.1 christos if (is_elf64)
641 1.1 christos {
642 1.1 christos uint64_t vq = aarch64_sve_get_vq (tid);
643 1.1 christos unsigned long hwcap = linux_get_hwcap (8);
644 1.1 christos bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
645 1.1 christos
646 1.1 christos current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p);
647 1.1 christos }
648 1.1 christos else
649 1.1 christos current_process ()->tdesc = aarch32_linux_read_description ();
650 1.1 christos
651 1.1 christos aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
652 1.1 christos }
653 1.1 christos
654 1.1 christos /* Wrapper for aarch64_sve_regs_copy_to_reg_buf. */
655 1.1 christos
656 1.1 christos static void
657 1.1 christos aarch64_sve_regs_copy_to_regcache (struct regcache *regcache, const void *buf)
658 1.1 christos {
659 1.1 christos return aarch64_sve_regs_copy_to_reg_buf (regcache, buf);
660 1.1 christos }
661 1.1 christos
662 1.1 christos /* Wrapper for aarch64_sve_regs_copy_from_reg_buf. */
663 1.1 christos
664 1.1 christos static void
665 1.1 christos aarch64_sve_regs_copy_from_regcache (struct regcache *regcache, void *buf)
666 1.1 christos {
667 1.1 christos return aarch64_sve_regs_copy_from_reg_buf (regcache, buf);
668 1.1 christos }
669 1.1 christos
670 1.1 christos static struct regset_info aarch64_regsets[] =
671 1.1 christos {
672 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
673 1.1 christos sizeof (struct user_pt_regs), GENERAL_REGS,
674 1.1 christos aarch64_fill_gregset, aarch64_store_gregset },
675 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
676 1.1 christos sizeof (struct user_fpsimd_state), FP_REGS,
677 1.1 christos aarch64_fill_fpregset, aarch64_store_fpregset
678 1.1 christos },
679 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
680 1.1 christos AARCH64_PAUTH_REGS_SIZE, OPTIONAL_REGS,
681 1.1 christos NULL, aarch64_store_pauthregset },
682 1.1 christos NULL_REGSET
683 1.1 christos };
684 1.1 christos
685 1.1 christos static struct regsets_info aarch64_regsets_info =
686 1.1 christos {
687 1.1 christos aarch64_regsets, /* regsets */
688 1.1 christos 0, /* num_regsets */
689 1.1 christos NULL, /* disabled_regsets */
690 1.1 christos };
691 1.1 christos
692 1.1 christos static struct regs_info regs_info_aarch64 =
693 1.1 christos {
694 1.1 christos NULL, /* regset_bitmap */
695 1.1 christos NULL, /* usrregs */
696 1.1 christos &aarch64_regsets_info,
697 1.1 christos };
698 1.1 christos
699 1.1 christos static struct regset_info aarch64_sve_regsets[] =
700 1.1 christos {
701 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
702 1.1 christos sizeof (struct user_pt_regs), GENERAL_REGS,
703 1.1 christos aarch64_fill_gregset, aarch64_store_gregset },
704 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_SVE,
705 1.1 christos SVE_PT_SIZE (AARCH64_MAX_SVE_VQ, SVE_PT_REGS_SVE), EXTENDED_REGS,
706 1.1 christos aarch64_sve_regs_copy_from_regcache, aarch64_sve_regs_copy_to_regcache
707 1.1 christos },
708 1.1 christos { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
709 1.1 christos AARCH64_PAUTH_REGS_SIZE, OPTIONAL_REGS,
710 1.1 christos NULL, aarch64_store_pauthregset },
711 1.1 christos NULL_REGSET
712 1.1 christos };
713 1.1 christos
714 1.1 christos static struct regsets_info aarch64_sve_regsets_info =
715 1.1 christos {
716 1.1 christos aarch64_sve_regsets, /* regsets. */
717 1.1 christos 0, /* num_regsets. */
718 1.1 christos NULL, /* disabled_regsets. */
719 1.1 christos };
720 1.1 christos
721 1.1 christos static struct regs_info regs_info_aarch64_sve =
722 1.1 christos {
723 1.1 christos NULL, /* regset_bitmap. */
724 1.1 christos NULL, /* usrregs. */
725 1.1 christos &aarch64_sve_regsets_info,
726 1.1 christos };
727 1.1 christos
728 1.1 christos /* Implementation of linux target ops method "get_regs_info". */
729 1.1 christos
730 1.1 christos const regs_info *
731 1.1 christos aarch64_target::get_regs_info ()
732 1.1 christos {
733 1.1 christos if (!is_64bit_tdesc ())
734 1.1 christos return ®s_info_aarch32;
735 1.1 christos
736 1.1 christos if (is_sve_tdesc ())
737 1.1 christos return ®s_info_aarch64_sve;
738 1.1 christos
739 1.1 christos return ®s_info_aarch64;
740 1.1 christos }
741 1.1 christos
742 1.1 christos /* Implementation of target ops method "supports_tracepoints". */
743 1.1 christos
744 1.1 christos bool
745 1.1 christos aarch64_target::supports_tracepoints ()
746 1.1 christos {
747 1.1 christos if (current_thread == NULL)
748 1.1 christos return true;
749 1.1 christos else
750 1.1 christos {
751 1.1 christos /* We don't support tracepoints on aarch32 now. */
752 1.1 christos return is_64bit_tdesc ();
753 1.1 christos }
754 1.1 christos }
755 1.1 christos
756 1.1 christos /* Implementation of linux target ops method "low_get_thread_area". */
757 1.1 christos
758 1.1 christos int
759 1.1 christos aarch64_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
760 1.1 christos {
761 1.1 christos struct iovec iovec;
762 1.1 christos uint64_t reg;
763 1.1 christos
764 1.1 christos iovec.iov_base = ®
765 1.1 christos iovec.iov_len = sizeof (reg);
766 1.1 christos
767 1.1 christos if (ptrace (PTRACE_GETREGSET, lwpid, NT_ARM_TLS, &iovec) != 0)
768 1.1 christos return -1;
769 1.1 christos
770 1.1 christos *addrp = reg;
771 1.1 christos
772 1.1 christos return 0;
773 1.1 christos }
774 1.1 christos
775 1.1 christos bool
776 1.1 christos aarch64_target::low_supports_catch_syscall ()
777 1.1 christos {
778 1.1 christos return true;
779 1.1 christos }
780 1.1 christos
781 1.1 christos /* Implementation of linux target ops method "low_get_syscall_trapinfo". */
782 1.1 christos
783 1.1 christos void
784 1.1 christos aarch64_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno)
785 1.1 christos {
786 1.1 christos int use_64bit = register_size (regcache->tdesc, 0) == 8;
787 1.1 christos
788 1.1 christos if (use_64bit)
789 1.1 christos {
790 1.1 christos long l_sysno;
791 1.1 christos
792 1.1 christos collect_register_by_name (regcache, "x8", &l_sysno);
793 1.1 christos *sysno = (int) l_sysno;
794 1.1 christos }
795 1.1 christos else
796 1.1 christos collect_register_by_name (regcache, "r7", sysno);
797 1.1 christos }
798 1.1 christos
799 1.1 christos /* List of condition codes that we need. */
800 1.1 christos
801 1.1 christos enum aarch64_condition_codes
802 1.1 christos {
803 1.1 christos EQ = 0x0,
804 1.1 christos NE = 0x1,
805 1.1 christos LO = 0x3,
806 1.1 christos GE = 0xa,
807 1.1 christos LT = 0xb,
808 1.1 christos GT = 0xc,
809 1.1 christos LE = 0xd,
810 1.1 christos };
811 1.1 christos
812 1.1 christos enum aarch64_operand_type
813 1.1 christos {
814 1.1 christos OPERAND_IMMEDIATE,
815 1.1 christos OPERAND_REGISTER,
816 1.1 christos };
817 1.1 christos
818 1.1 christos /* Representation of an operand. At this time, it only supports register
819 1.1 christos and immediate types. */
820 1.1 christos
821 1.1 christos struct aarch64_operand
822 1.1 christos {
823 1.1 christos /* Type of the operand. */
824 1.1 christos enum aarch64_operand_type type;
825 1.1 christos
826 1.1 christos /* Value of the operand according to the type. */
827 1.1 christos union
828 1.1 christos {
829 1.1 christos uint32_t imm;
830 1.1 christos struct aarch64_register reg;
831 1.1 christos };
832 1.1 christos };
833 1.1 christos
834 1.1 christos /* List of registers that we are currently using, we can add more here as
835 1.1 christos we need to use them. */
836 1.1 christos
837 1.1 christos /* General purpose scratch registers (64 bit). */
838 1.1 christos static const struct aarch64_register x0 = { 0, 1 };
839 1.1 christos static const struct aarch64_register x1 = { 1, 1 };
840 1.1 christos static const struct aarch64_register x2 = { 2, 1 };
841 1.1 christos static const struct aarch64_register x3 = { 3, 1 };
842 1.1 christos static const struct aarch64_register x4 = { 4, 1 };
843 1.1 christos
844 1.1 christos /* General purpose scratch registers (32 bit). */
845 1.1 christos static const struct aarch64_register w0 = { 0, 0 };
846 1.1 christos static const struct aarch64_register w2 = { 2, 0 };
847 1.1 christos
848 1.1 christos /* Intra-procedure scratch registers. */
849 1.1 christos static const struct aarch64_register ip0 = { 16, 1 };
850 1.1 christos
851 1.1 christos /* Special purpose registers. */
852 1.1 christos static const struct aarch64_register fp = { 29, 1 };
853 1.1 christos static const struct aarch64_register lr = { 30, 1 };
854 1.1 christos static const struct aarch64_register sp = { 31, 1 };
855 1.1 christos static const struct aarch64_register xzr = { 31, 1 };
856 1.1 christos
857 1.1 christos /* Dynamically allocate a new register. If we know the register
858 1.1 christos statically, we should make it a global as above instead of using this
859 1.1 christos helper function. */
860 1.1 christos
861 1.1 christos static struct aarch64_register
862 1.1 christos aarch64_register (unsigned num, int is64)
863 1.1 christos {
864 1.1 christos return (struct aarch64_register) { num, is64 };
865 1.1 christos }
866 1.1 christos
867 1.1 christos /* Helper function to create a register operand, for instructions with
868 1.1 christos different types of operands.
869 1.1 christos
870 1.1 christos For example:
871 1.1 christos p += emit_mov (p, x0, register_operand (x1)); */
872 1.1 christos
873 1.1 christos static struct aarch64_operand
874 1.1 christos register_operand (struct aarch64_register reg)
875 1.1 christos {
876 1.1 christos struct aarch64_operand operand;
877 1.1 christos
878 1.1 christos operand.type = OPERAND_REGISTER;
879 1.1 christos operand.reg = reg;
880 1.1 christos
881 1.1 christos return operand;
882 1.1 christos }
883 1.1 christos
884 1.1 christos /* Helper function to create an immediate operand, for instructions with
885 1.1 christos different types of operands.
886 1.1 christos
887 1.1 christos For example:
888 1.1 christos p += emit_mov (p, x0, immediate_operand (12)); */
889 1.1 christos
890 1.1 christos static struct aarch64_operand
891 1.1 christos immediate_operand (uint32_t imm)
892 1.1 christos {
893 1.1 christos struct aarch64_operand operand;
894 1.1 christos
895 1.1 christos operand.type = OPERAND_IMMEDIATE;
896 1.1 christos operand.imm = imm;
897 1.1 christos
898 1.1 christos return operand;
899 1.1 christos }
900 1.1 christos
901 1.1 christos /* Helper function to create an offset memory operand.
902 1.1 christos
903 1.1 christos For example:
904 1.1 christos p += emit_ldr (p, x0, sp, offset_memory_operand (16)); */
905 1.1 christos
906 1.1 christos static struct aarch64_memory_operand
907 1.1 christos offset_memory_operand (int32_t offset)
908 1.1 christos {
909 1.1 christos return (struct aarch64_memory_operand) { MEMORY_OPERAND_OFFSET, offset };
910 1.1 christos }
911 1.1 christos
912 1.1 christos /* Helper function to create a pre-index memory operand.
913 1.1 christos
914 1.1 christos For example:
915 1.1 christos p += emit_ldr (p, x0, sp, preindex_memory_operand (16)); */
916 1.1 christos
917 1.1 christos static struct aarch64_memory_operand
918 1.1 christos preindex_memory_operand (int32_t index)
919 1.1 christos {
920 1.1 christos return (struct aarch64_memory_operand) { MEMORY_OPERAND_PREINDEX, index };
921 1.1 christos }
922 1.1 christos
923 1.1 christos /* Helper function to create a post-index memory operand.
924 1.1 christos
925 1.1 christos For example:
926 1.1 christos p += emit_ldr (p, x0, sp, postindex_memory_operand (16)); */
927 1.1 christos
928 1.1 christos static struct aarch64_memory_operand
929 1.1 christos postindex_memory_operand (int32_t index)
930 1.1 christos {
931 1.1 christos return (struct aarch64_memory_operand) { MEMORY_OPERAND_POSTINDEX, index };
932 1.1 christos }
933 1.1 christos
934 1.1 christos /* System control registers. These special registers can be written and
935 1.1 christos read with the MRS and MSR instructions.
936 1.1 christos
937 1.1 christos - NZCV: Condition flags. GDB refers to this register under the CPSR
938 1.1 christos name.
939 1.1 christos - FPSR: Floating-point status register.
940 1.1 christos - FPCR: Floating-point control registers.
941 1.1 christos - TPIDR_EL0: Software thread ID register. */
942 1.1 christos
943 1.1 christos enum aarch64_system_control_registers
944 1.1 christos {
945 1.1 christos /* op0 op1 crn crm op2 */
946 1.1 christos NZCV = (0x1 << 14) | (0x3 << 11) | (0x4 << 7) | (0x2 << 3) | 0x0,
947 1.1 christos FPSR = (0x1 << 14) | (0x3 << 11) | (0x4 << 7) | (0x4 << 3) | 0x1,
948 1.1 christos FPCR = (0x1 << 14) | (0x3 << 11) | (0x4 << 7) | (0x4 << 3) | 0x0,
949 1.1 christos TPIDR_EL0 = (0x1 << 14) | (0x3 << 11) | (0xd << 7) | (0x0 << 3) | 0x2
950 1.1 christos };
951 1.1 christos
952 1.1 christos /* Write a BLR instruction into *BUF.
953 1.1 christos
954 1.1 christos BLR rn
955 1.1 christos
956 1.1 christos RN is the register to branch to. */
957 1.1 christos
958 1.1 christos static int
959 1.1 christos emit_blr (uint32_t *buf, struct aarch64_register rn)
960 1.1 christos {
961 1.1 christos return aarch64_emit_insn (buf, BLR | ENCODE (rn.num, 5, 5));
962 1.1 christos }
963 1.1 christos
964 1.1 christos /* Write a RET instruction into *BUF.
965 1.1 christos
966 1.1 christos RET xn
967 1.1 christos
968 1.1 christos RN is the register to branch to. */
969 1.1 christos
970 1.1 christos static int
971 1.1 christos emit_ret (uint32_t *buf, struct aarch64_register rn)
972 1.1 christos {
973 1.1 christos return aarch64_emit_insn (buf, RET | ENCODE (rn.num, 5, 5));
974 1.1 christos }
975 1.1 christos
976 1.1 christos static int
977 1.1 christos emit_load_store_pair (uint32_t *buf, enum aarch64_opcodes opcode,
978 1.1 christos struct aarch64_register rt,
979 1.1 christos struct aarch64_register rt2,
980 1.1 christos struct aarch64_register rn,
981 1.1 christos struct aarch64_memory_operand operand)
982 1.1 christos {
983 1.1 christos uint32_t opc;
984 1.1 christos uint32_t pre_index;
985 1.1 christos uint32_t write_back;
986 1.1 christos
987 1.1 christos if (rt.is64)
988 1.1 christos opc = ENCODE (2, 2, 30);
989 1.1 christos else
990 1.1 christos opc = ENCODE (0, 2, 30);
991 1.1 christos
992 1.1 christos switch (operand.type)
993 1.1 christos {
994 1.1 christos case MEMORY_OPERAND_OFFSET:
995 1.1 christos {
996 1.1 christos pre_index = ENCODE (1, 1, 24);
997 1.1 christos write_back = ENCODE (0, 1, 23);
998 1.1 christos break;
999 1.1 christos }
1000 1.1 christos case MEMORY_OPERAND_POSTINDEX:
1001 1.1 christos {
1002 1.1 christos pre_index = ENCODE (0, 1, 24);
1003 1.1 christos write_back = ENCODE (1, 1, 23);
1004 1.1 christos break;
1005 1.1 christos }
1006 1.1 christos case MEMORY_OPERAND_PREINDEX:
1007 1.1 christos {
1008 1.1 christos pre_index = ENCODE (1, 1, 24);
1009 1.1 christos write_back = ENCODE (1, 1, 23);
1010 1.1 christos break;
1011 1.1 christos }
1012 1.1 christos default:
1013 1.1 christos return 0;
1014 1.1 christos }
1015 1.1 christos
1016 1.1 christos return aarch64_emit_insn (buf, opcode | opc | pre_index | write_back
1017 1.1 christos | ENCODE (operand.index >> 3, 7, 15)
1018 1.1 christos | ENCODE (rt2.num, 5, 10)
1019 1.1 christos | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
1020 1.1 christos }
1021 1.1 christos
1022 1.1 christos /* Write a STP instruction into *BUF.
1023 1.1 christos
1024 1.1 christos STP rt, rt2, [rn, #offset]
1025 1.1 christos STP rt, rt2, [rn, #index]!
1026 1.1 christos STP rt, rt2, [rn], #index
1027 1.1 christos
1028 1.1 christos RT and RT2 are the registers to store.
1029 1.1 christos RN is the base address register.
1030 1.1 christos OFFSET is the immediate to add to the base address. It is limited to a
1031 1.1 christos -512 .. 504 range (7 bits << 3). */
1032 1.1 christos
1033 1.1 christos static int
1034 1.1 christos emit_stp (uint32_t *buf, struct aarch64_register rt,
1035 1.1 christos struct aarch64_register rt2, struct aarch64_register rn,
1036 1.1 christos struct aarch64_memory_operand operand)
1037 1.1 christos {
1038 1.1 christos return emit_load_store_pair (buf, STP, rt, rt2, rn, operand);
1039 1.1 christos }
1040 1.1 christos
1041 1.1 christos /* Write a LDP instruction into *BUF.
1042 1.1 christos
1043 1.1 christos LDP rt, rt2, [rn, #offset]
1044 1.1 christos LDP rt, rt2, [rn, #index]!
1045 1.1 christos LDP rt, rt2, [rn], #index
1046 1.1 christos
1047 1.1 christos RT and RT2 are the registers to store.
1048 1.1 christos RN is the base address register.
1049 1.1 christos OFFSET is the immediate to add to the base address. It is limited to a
1050 1.1 christos -512 .. 504 range (7 bits << 3). */
1051 1.1 christos
1052 1.1 christos static int
1053 1.1 christos emit_ldp (uint32_t *buf, struct aarch64_register rt,
1054 1.1 christos struct aarch64_register rt2, struct aarch64_register rn,
1055 1.1 christos struct aarch64_memory_operand operand)
1056 1.1 christos {
1057 1.1 christos return emit_load_store_pair (buf, LDP, rt, rt2, rn, operand);
1058 1.1 christos }
1059 1.1 christos
1060 1.1 christos /* Write a LDP (SIMD&VFP) instruction using Q registers into *BUF.
1061 1.1 christos
1062 1.1 christos LDP qt, qt2, [rn, #offset]
1063 1.1 christos
1064 1.1 christos RT and RT2 are the Q registers to store.
1065 1.1 christos RN is the base address register.
1066 1.1 christos OFFSET is the immediate to add to the base address. It is limited to
1067 1.1 christos -1024 .. 1008 range (7 bits << 4). */
1068 1.1 christos
1069 1.1 christos static int
1070 1.1 christos emit_ldp_q_offset (uint32_t *buf, unsigned rt, unsigned rt2,
1071 1.1 christos struct aarch64_register rn, int32_t offset)
1072 1.1 christos {
1073 1.1 christos uint32_t opc = ENCODE (2, 2, 30);
1074 1.1 christos uint32_t pre_index = ENCODE (1, 1, 24);
1075 1.1 christos
1076 1.1 christos return aarch64_emit_insn (buf, LDP_SIMD_VFP | opc | pre_index
1077 1.1 christos | ENCODE (offset >> 4, 7, 15)
1078 1.1 christos | ENCODE (rt2, 5, 10)
1079 1.1 christos | ENCODE (rn.num, 5, 5) | ENCODE (rt, 5, 0));
1080 1.1 christos }
1081 1.1 christos
1082 1.1 christos /* Write a STP (SIMD&VFP) instruction using Q registers into *BUF.
1083 1.1 christos
1084 1.1 christos STP qt, qt2, [rn, #offset]
1085 1.1 christos
1086 1.1 christos RT and RT2 are the Q registers to store.
1087 1.1 christos RN is the base address register.
1088 1.1 christos OFFSET is the immediate to add to the base address. It is limited to
1089 1.1 christos -1024 .. 1008 range (7 bits << 4). */
1090 1.1 christos
1091 1.1 christos static int
1092 1.1 christos emit_stp_q_offset (uint32_t *buf, unsigned rt, unsigned rt2,
1093 1.1 christos struct aarch64_register rn, int32_t offset)
1094 1.1 christos {
1095 1.1 christos uint32_t opc = ENCODE (2, 2, 30);
1096 1.1 christos uint32_t pre_index = ENCODE (1, 1, 24);
1097 1.1 christos
1098 1.1 christos return aarch64_emit_insn (buf, STP_SIMD_VFP | opc | pre_index
1099 1.1 christos | ENCODE (offset >> 4, 7, 15)
1100 1.1 christos | ENCODE (rt2, 5, 10)
1101 1.1 christos | ENCODE (rn.num, 5, 5) | ENCODE (rt, 5, 0));
1102 1.1 christos }
1103 1.1 christos
1104 1.1 christos /* Write a LDRH instruction into *BUF.
1105 1.1 christos
1106 1.1 christos LDRH wt, [xn, #offset]
1107 1.1 christos LDRH wt, [xn, #index]!
1108 1.1 christos LDRH wt, [xn], #index
1109 1.1 christos
1110 1.1 christos RT is the register to store.
1111 1.1 christos RN is the base address register.
1112 1.1 christos OFFSET is the immediate to add to the base address. It is limited to
1113 1.1 christos 0 .. 32760 range (12 bits << 3). */
1114 1.1 christos
1115 1.1 christos static int
1116 1.1 christos emit_ldrh (uint32_t *buf, struct aarch64_register rt,
1117 1.1 christos struct aarch64_register rn,
1118 1.1 christos struct aarch64_memory_operand operand)
1119 1.1 christos {
1120 1.1 christos return aarch64_emit_load_store (buf, 1, LDR, rt, rn, operand);
1121 1.1 christos }
1122 1.1 christos
1123 1.1 christos /* Write a LDRB instruction into *BUF.
1124 1.1 christos
1125 1.1 christos LDRB wt, [xn, #offset]
1126 1.1 christos LDRB wt, [xn, #index]!
1127 1.1 christos LDRB wt, [xn], #index
1128 1.1 christos
1129 1.1 christos RT is the register to store.
1130 1.1 christos RN is the base address register.
1131 1.1 christos OFFSET is the immediate to add to the base address. It is limited to
1132 1.1 christos 0 .. 32760 range (12 bits << 3). */
1133 1.1 christos
1134 1.1 christos static int
1135 1.1 christos emit_ldrb (uint32_t *buf, struct aarch64_register rt,
1136 1.1 christos struct aarch64_register rn,
1137 1.1 christos struct aarch64_memory_operand operand)
1138 1.1 christos {
1139 1.1 christos return aarch64_emit_load_store (buf, 0, LDR, rt, rn, operand);
1140 1.1 christos }
1141 1.1 christos
1142 1.1 christos
1143 1.1 christos
1144 1.1 christos /* Write a STR instruction into *BUF.
1145 1.1 christos
1146 1.1 christos STR rt, [rn, #offset]
1147 1.1 christos STR rt, [rn, #index]!
1148 1.1 christos STR rt, [rn], #index
1149 1.1 christos
1150 1.1 christos RT is the register to store.
1151 1.1 christos RN is the base address register.
1152 1.1 christos OFFSET is the immediate to add to the base address. It is limited to
1153 1.1 christos 0 .. 32760 range (12 bits << 3). */
1154 1.1 christos
1155 1.1 christos static int
1156 1.1 christos emit_str (uint32_t *buf, struct aarch64_register rt,
1157 1.1 christos struct aarch64_register rn,
1158 1.1 christos struct aarch64_memory_operand operand)
1159 1.1 christos {
1160 1.1 christos return aarch64_emit_load_store (buf, rt.is64 ? 3 : 2, STR, rt, rn, operand);
1161 1.1 christos }
1162 1.1 christos
1163 1.1 christos /* Helper function emitting an exclusive load or store instruction. */
1164 1.1 christos
1165 1.1 christos static int
1166 1.1 christos emit_load_store_exclusive (uint32_t *buf, uint32_t size,
1167 1.1 christos enum aarch64_opcodes opcode,
1168 1.1 christos struct aarch64_register rs,
1169 1.1 christos struct aarch64_register rt,
1170 1.1 christos struct aarch64_register rt2,
1171 1.1 christos struct aarch64_register rn)
1172 1.1 christos {
1173 1.1 christos return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30)
1174 1.1 christos | ENCODE (rs.num, 5, 16) | ENCODE (rt2.num, 5, 10)
1175 1.1 christos | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
1176 1.1 christos }
1177 1.1 christos
1178 1.1 christos /* Write a LAXR instruction into *BUF.
1179 1.1 christos
1180 1.1 christos LDAXR rt, [xn]
1181 1.1 christos
1182 1.1 christos RT is the destination register.
1183 1.1 christos RN is the base address register. */
1184 1.1 christos
1185 1.1 christos static int
1186 1.1 christos emit_ldaxr (uint32_t *buf, struct aarch64_register rt,
1187 1.1 christos struct aarch64_register rn)
1188 1.1 christos {
1189 1.1 christos return emit_load_store_exclusive (buf, rt.is64 ? 3 : 2, LDAXR, xzr, rt,
1190 1.1 christos xzr, rn);
1191 1.1 christos }
1192 1.1 christos
1193 1.1 christos /* Write a STXR instruction into *BUF.
1194 1.1 christos
1195 1.1 christos STXR ws, rt, [xn]
1196 1.1 christos
1197 1.1 christos RS is the result register, it indicates if the store succeeded or not.
1198 1.1 christos RT is the destination register.
1199 1.1 christos RN is the base address register. */
1200 1.1 christos
1201 1.1 christos static int
1202 1.1 christos emit_stxr (uint32_t *buf, struct aarch64_register rs,
1203 1.1 christos struct aarch64_register rt, struct aarch64_register rn)
1204 1.1 christos {
1205 1.1 christos return emit_load_store_exclusive (buf, rt.is64 ? 3 : 2, STXR, rs, rt,
1206 1.1 christos xzr, rn);
1207 1.1 christos }
1208 1.1 christos
1209 1.1 christos /* Write a STLR instruction into *BUF.
1210 1.1 christos
1211 1.1 christos STLR rt, [xn]
1212 1.1 christos
1213 1.1 christos RT is the register to store.
1214 1.1 christos RN is the base address register. */
1215 1.1 christos
1216 1.1 christos static int
1217 1.1 christos emit_stlr (uint32_t *buf, struct aarch64_register rt,
1218 1.1 christos struct aarch64_register rn)
1219 1.1 christos {
1220 1.1 christos return emit_load_store_exclusive (buf, rt.is64 ? 3 : 2, STLR, xzr, rt,
1221 1.1 christos xzr, rn);
1222 1.1 christos }
1223 1.1 christos
1224 1.1 christos /* Helper function for data processing instructions with register sources. */
1225 1.1 christos
1226 1.1 christos static int
1227 1.1 christos emit_data_processing_reg (uint32_t *buf, uint32_t opcode,
1228 1.1 christos struct aarch64_register rd,
1229 1.1 christos struct aarch64_register rn,
1230 1.1 christos struct aarch64_register rm)
1231 1.1 christos {
1232 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1233 1.1 christos
1234 1.1 christos return aarch64_emit_insn (buf, opcode | size | ENCODE (rm.num, 5, 16)
1235 1.1 christos | ENCODE (rn.num, 5, 5) | ENCODE (rd.num, 5, 0));
1236 1.1 christos }
1237 1.1 christos
1238 1.1 christos /* Helper function for data processing instructions taking either a register
1239 1.1 christos or an immediate. */
1240 1.1 christos
1241 1.1 christos static int
1242 1.1 christos emit_data_processing (uint32_t *buf, enum aarch64_opcodes opcode,
1243 1.1 christos struct aarch64_register rd,
1244 1.1 christos struct aarch64_register rn,
1245 1.1 christos struct aarch64_operand operand)
1246 1.1 christos {
1247 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1248 1.1 christos /* The opcode is different for register and immediate source operands. */
1249 1.1 christos uint32_t operand_opcode;
1250 1.1 christos
1251 1.1 christos if (operand.type == OPERAND_IMMEDIATE)
1252 1.1 christos {
1253 1.1 christos /* xxx1 000x xxxx xxxx xxxx xxxx xxxx xxxx */
1254 1.1 christos operand_opcode = ENCODE (8, 4, 25);
1255 1.1 christos
1256 1.1 christos return aarch64_emit_insn (buf, opcode | operand_opcode | size
1257 1.1 christos | ENCODE (operand.imm, 12, 10)
1258 1.1 christos | ENCODE (rn.num, 5, 5)
1259 1.1 christos | ENCODE (rd.num, 5, 0));
1260 1.1 christos }
1261 1.1 christos else
1262 1.1 christos {
1263 1.1 christos /* xxx0 101x xxxx xxxx xxxx xxxx xxxx xxxx */
1264 1.1 christos operand_opcode = ENCODE (5, 4, 25);
1265 1.1 christos
1266 1.1 christos return emit_data_processing_reg (buf, opcode | operand_opcode, rd,
1267 1.1 christos rn, operand.reg);
1268 1.1 christos }
1269 1.1 christos }
1270 1.1 christos
1271 1.1 christos /* Write an ADD instruction into *BUF.
1272 1.1 christos
1273 1.1 christos ADD rd, rn, #imm
1274 1.1 christos ADD rd, rn, rm
1275 1.1 christos
1276 1.1 christos This function handles both an immediate and register add.
1277 1.1 christos
1278 1.1 christos RD is the destination register.
1279 1.1 christos RN is the input register.
1280 1.1 christos OPERAND is the source operand, either of type OPERAND_IMMEDIATE or
1281 1.1 christos OPERAND_REGISTER. */
1282 1.1 christos
1283 1.1 christos static int
1284 1.1 christos emit_add (uint32_t *buf, struct aarch64_register rd,
1285 1.1 christos struct aarch64_register rn, struct aarch64_operand operand)
1286 1.1 christos {
1287 1.1 christos return emit_data_processing (buf, ADD, rd, rn, operand);
1288 1.1 christos }
1289 1.1 christos
1290 1.1 christos /* Write a SUB instruction into *BUF.
1291 1.1 christos
1292 1.1 christos SUB rd, rn, #imm
1293 1.1 christos SUB rd, rn, rm
1294 1.1 christos
1295 1.1 christos This function handles both an immediate and register sub.
1296 1.1 christos
1297 1.1 christos RD is the destination register.
1298 1.1 christos RN is the input register.
1299 1.1 christos IMM is the immediate to substract to RN. */
1300 1.1 christos
1301 1.1 christos static int
1302 1.1 christos emit_sub (uint32_t *buf, struct aarch64_register rd,
1303 1.1 christos struct aarch64_register rn, struct aarch64_operand operand)
1304 1.1 christos {
1305 1.1 christos return emit_data_processing (buf, SUB, rd, rn, operand);
1306 1.1 christos }
1307 1.1 christos
1308 1.1 christos /* Write a MOV instruction into *BUF.
1309 1.1 christos
1310 1.1 christos MOV rd, #imm
1311 1.1 christos MOV rd, rm
1312 1.1 christos
1313 1.1 christos This function handles both a wide immediate move and a register move,
1314 1.1 christos with the condition that the source register is not xzr. xzr and the
1315 1.1 christos stack pointer share the same encoding and this function only supports
1316 1.1 christos the stack pointer.
1317 1.1 christos
1318 1.1 christos RD is the destination register.
1319 1.1 christos OPERAND is the source operand, either of type OPERAND_IMMEDIATE or
1320 1.1 christos OPERAND_REGISTER. */
1321 1.1 christos
1322 1.1 christos static int
1323 1.1 christos emit_mov (uint32_t *buf, struct aarch64_register rd,
1324 1.1 christos struct aarch64_operand operand)
1325 1.1 christos {
1326 1.1 christos if (operand.type == OPERAND_IMMEDIATE)
1327 1.1 christos {
1328 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1329 1.1 christos /* Do not shift the immediate. */
1330 1.1 christos uint32_t shift = ENCODE (0, 2, 21);
1331 1.1 christos
1332 1.1 christos return aarch64_emit_insn (buf, MOV | size | shift
1333 1.1 christos | ENCODE (operand.imm, 16, 5)
1334 1.1 christos | ENCODE (rd.num, 5, 0));
1335 1.1 christos }
1336 1.1 christos else
1337 1.1 christos return emit_add (buf, rd, operand.reg, immediate_operand (0));
1338 1.1 christos }
1339 1.1 christos
1340 1.1 christos /* Write a MOVK instruction into *BUF.
1341 1.1 christos
1342 1.1 christos MOVK rd, #imm, lsl #shift
1343 1.1 christos
1344 1.1 christos RD is the destination register.
1345 1.1 christos IMM is the immediate.
1346 1.1 christos SHIFT is the logical shift left to apply to IMM. */
1347 1.1 christos
1348 1.1 christos static int
1349 1.1 christos emit_movk (uint32_t *buf, struct aarch64_register rd, uint32_t imm,
1350 1.1 christos unsigned shift)
1351 1.1 christos {
1352 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1353 1.1 christos
1354 1.1 christos return aarch64_emit_insn (buf, MOVK | size | ENCODE (shift, 2, 21) |
1355 1.1 christos ENCODE (imm, 16, 5) | ENCODE (rd.num, 5, 0));
1356 1.1 christos }
1357 1.1 christos
1358 1.1 christos /* Write instructions into *BUF in order to move ADDR into a register.
1359 1.1 christos ADDR can be a 64-bit value.
1360 1.1 christos
1361 1.1 christos This function will emit a series of MOV and MOVK instructions, such as:
1362 1.1 christos
1363 1.1 christos MOV xd, #(addr)
1364 1.1 christos MOVK xd, #(addr >> 16), lsl #16
1365 1.1 christos MOVK xd, #(addr >> 32), lsl #32
1366 1.1 christos MOVK xd, #(addr >> 48), lsl #48 */
1367 1.1 christos
1368 1.1 christos static int
1369 1.1 christos emit_mov_addr (uint32_t *buf, struct aarch64_register rd, CORE_ADDR addr)
1370 1.1 christos {
1371 1.1 christos uint32_t *p = buf;
1372 1.1 christos
1373 1.1 christos /* The MOV (wide immediate) instruction clears to top bits of the
1374 1.1 christos register. */
1375 1.1 christos p += emit_mov (p, rd, immediate_operand (addr & 0xffff));
1376 1.1 christos
1377 1.1 christos if ((addr >> 16) != 0)
1378 1.1 christos p += emit_movk (p, rd, (addr >> 16) & 0xffff, 1);
1379 1.1 christos else
1380 1.1 christos return p - buf;
1381 1.1 christos
1382 1.1 christos if ((addr >> 32) != 0)
1383 1.1 christos p += emit_movk (p, rd, (addr >> 32) & 0xffff, 2);
1384 1.1 christos else
1385 1.1 christos return p - buf;
1386 1.1 christos
1387 1.1 christos if ((addr >> 48) != 0)
1388 1.1 christos p += emit_movk (p, rd, (addr >> 48) & 0xffff, 3);
1389 1.1 christos
1390 1.1 christos return p - buf;
1391 1.1 christos }
1392 1.1 christos
1393 1.1 christos /* Write a SUBS instruction into *BUF.
1394 1.1 christos
1395 1.1 christos SUBS rd, rn, rm
1396 1.1 christos
1397 1.1 christos This instruction update the condition flags.
1398 1.1 christos
1399 1.1 christos RD is the destination register.
1400 1.1 christos RN and RM are the source registers. */
1401 1.1 christos
1402 1.1 christos static int
1403 1.1 christos emit_subs (uint32_t *buf, struct aarch64_register rd,
1404 1.1 christos struct aarch64_register rn, struct aarch64_operand operand)
1405 1.1 christos {
1406 1.1 christos return emit_data_processing (buf, SUBS, rd, rn, operand);
1407 1.1 christos }
1408 1.1 christos
1409 1.1 christos /* Write a CMP instruction into *BUF.
1410 1.1 christos
1411 1.1 christos CMP rn, rm
1412 1.1 christos
1413 1.1 christos This instruction is an alias of SUBS xzr, rn, rm.
1414 1.1 christos
1415 1.1 christos RN and RM are the registers to compare. */
1416 1.1 christos
1417 1.1 christos static int
1418 1.1 christos emit_cmp (uint32_t *buf, struct aarch64_register rn,
1419 1.1 christos struct aarch64_operand operand)
1420 1.1 christos {
1421 1.1 christos return emit_subs (buf, xzr, rn, operand);
1422 1.1 christos }
1423 1.1 christos
1424 1.1 christos /* Write a AND instruction into *BUF.
1425 1.1 christos
1426 1.1 christos AND rd, rn, rm
1427 1.1 christos
1428 1.1 christos RD is the destination register.
1429 1.1 christos RN and RM are the source registers. */
1430 1.1 christos
1431 1.1 christos static int
1432 1.1 christos emit_and (uint32_t *buf, struct aarch64_register rd,
1433 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1434 1.1 christos {
1435 1.1 christos return emit_data_processing_reg (buf, AND, rd, rn, rm);
1436 1.1 christos }
1437 1.1 christos
1438 1.1 christos /* Write a ORR instruction into *BUF.
1439 1.1 christos
1440 1.1 christos ORR rd, rn, rm
1441 1.1 christos
1442 1.1 christos RD is the destination register.
1443 1.1 christos RN and RM are the source registers. */
1444 1.1 christos
1445 1.1 christos static int
1446 1.1 christos emit_orr (uint32_t *buf, struct aarch64_register rd,
1447 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1448 1.1 christos {
1449 1.1 christos return emit_data_processing_reg (buf, ORR, rd, rn, rm);
1450 1.1 christos }
1451 1.1 christos
1452 1.1 christos /* Write a ORN instruction into *BUF.
1453 1.1 christos
1454 1.1 christos ORN rd, rn, rm
1455 1.1 christos
1456 1.1 christos RD is the destination register.
1457 1.1 christos RN and RM are the source registers. */
1458 1.1 christos
1459 1.1 christos static int
1460 1.1 christos emit_orn (uint32_t *buf, struct aarch64_register rd,
1461 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1462 1.1 christos {
1463 1.1 christos return emit_data_processing_reg (buf, ORN, rd, rn, rm);
1464 1.1 christos }
1465 1.1 christos
1466 1.1 christos /* Write a EOR instruction into *BUF.
1467 1.1 christos
1468 1.1 christos EOR rd, rn, rm
1469 1.1 christos
1470 1.1 christos RD is the destination register.
1471 1.1 christos RN and RM are the source registers. */
1472 1.1 christos
1473 1.1 christos static int
1474 1.1 christos emit_eor (uint32_t *buf, struct aarch64_register rd,
1475 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1476 1.1 christos {
1477 1.1 christos return emit_data_processing_reg (buf, EOR, rd, rn, rm);
1478 1.1 christos }
1479 1.1 christos
1480 1.1 christos /* Write a MVN instruction into *BUF.
1481 1.1 christos
1482 1.1 christos MVN rd, rm
1483 1.1 christos
1484 1.1 christos This is an alias for ORN rd, xzr, rm.
1485 1.1 christos
1486 1.1 christos RD is the destination register.
1487 1.1 christos RM is the source register. */
1488 1.1 christos
1489 1.1 christos static int
1490 1.1 christos emit_mvn (uint32_t *buf, struct aarch64_register rd,
1491 1.1 christos struct aarch64_register rm)
1492 1.1 christos {
1493 1.1 christos return emit_orn (buf, rd, xzr, rm);
1494 1.1 christos }
1495 1.1 christos
1496 1.1 christos /* Write a LSLV instruction into *BUF.
1497 1.1 christos
1498 1.1 christos LSLV rd, rn, rm
1499 1.1 christos
1500 1.1 christos RD is the destination register.
1501 1.1 christos RN and RM are the source registers. */
1502 1.1 christos
1503 1.1 christos static int
1504 1.1 christos emit_lslv (uint32_t *buf, struct aarch64_register rd,
1505 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1506 1.1 christos {
1507 1.1 christos return emit_data_processing_reg (buf, LSLV, rd, rn, rm);
1508 1.1 christos }
1509 1.1 christos
1510 1.1 christos /* Write a LSRV instruction into *BUF.
1511 1.1 christos
1512 1.1 christos LSRV rd, rn, rm
1513 1.1 christos
1514 1.1 christos RD is the destination register.
1515 1.1 christos RN and RM are the source registers. */
1516 1.1 christos
1517 1.1 christos static int
1518 1.1 christos emit_lsrv (uint32_t *buf, struct aarch64_register rd,
1519 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1520 1.1 christos {
1521 1.1 christos return emit_data_processing_reg (buf, LSRV, rd, rn, rm);
1522 1.1 christos }
1523 1.1 christos
1524 1.1 christos /* Write a ASRV instruction into *BUF.
1525 1.1 christos
1526 1.1 christos ASRV rd, rn, rm
1527 1.1 christos
1528 1.1 christos RD is the destination register.
1529 1.1 christos RN and RM are the source registers. */
1530 1.1 christos
1531 1.1 christos static int
1532 1.1 christos emit_asrv (uint32_t *buf, struct aarch64_register rd,
1533 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1534 1.1 christos {
1535 1.1 christos return emit_data_processing_reg (buf, ASRV, rd, rn, rm);
1536 1.1 christos }
1537 1.1 christos
1538 1.1 christos /* Write a MUL instruction into *BUF.
1539 1.1 christos
1540 1.1 christos MUL rd, rn, rm
1541 1.1 christos
1542 1.1 christos RD is the destination register.
1543 1.1 christos RN and RM are the source registers. */
1544 1.1 christos
1545 1.1 christos static int
1546 1.1 christos emit_mul (uint32_t *buf, struct aarch64_register rd,
1547 1.1 christos struct aarch64_register rn, struct aarch64_register rm)
1548 1.1 christos {
1549 1.1 christos return emit_data_processing_reg (buf, MUL, rd, rn, rm);
1550 1.1 christos }
1551 1.1 christos
1552 1.1 christos /* Write a MRS instruction into *BUF. The register size is 64-bit.
1553 1.1 christos
1554 1.1 christos MRS xt, system_reg
1555 1.1 christos
1556 1.1 christos RT is the destination register.
1557 1.1 christos SYSTEM_REG is special purpose register to read. */
1558 1.1 christos
1559 1.1 christos static int
1560 1.1 christos emit_mrs (uint32_t *buf, struct aarch64_register rt,
1561 1.1 christos enum aarch64_system_control_registers system_reg)
1562 1.1 christos {
1563 1.1 christos return aarch64_emit_insn (buf, MRS | ENCODE (system_reg, 15, 5)
1564 1.1 christos | ENCODE (rt.num, 5, 0));
1565 1.1 christos }
1566 1.1 christos
1567 1.1 christos /* Write a MSR instruction into *BUF. The register size is 64-bit.
1568 1.1 christos
1569 1.1 christos MSR system_reg, xt
1570 1.1 christos
1571 1.1 christos SYSTEM_REG is special purpose register to write.
1572 1.1 christos RT is the input register. */
1573 1.1 christos
1574 1.1 christos static int
1575 1.1 christos emit_msr (uint32_t *buf, enum aarch64_system_control_registers system_reg,
1576 1.1 christos struct aarch64_register rt)
1577 1.1 christos {
1578 1.1 christos return aarch64_emit_insn (buf, MSR | ENCODE (system_reg, 15, 5)
1579 1.1 christos | ENCODE (rt.num, 5, 0));
1580 1.1 christos }
1581 1.1 christos
1582 1.1 christos /* Write a SEVL instruction into *BUF.
1583 1.1 christos
1584 1.1 christos This is a hint instruction telling the hardware to trigger an event. */
1585 1.1 christos
1586 1.1 christos static int
1587 1.1 christos emit_sevl (uint32_t *buf)
1588 1.1 christos {
1589 1.1 christos return aarch64_emit_insn (buf, SEVL);
1590 1.1 christos }
1591 1.1 christos
1592 1.1 christos /* Write a WFE instruction into *BUF.
1593 1.1 christos
1594 1.1 christos This is a hint instruction telling the hardware to wait for an event. */
1595 1.1 christos
1596 1.1 christos static int
1597 1.1 christos emit_wfe (uint32_t *buf)
1598 1.1 christos {
1599 1.1 christos return aarch64_emit_insn (buf, WFE);
1600 1.1 christos }
1601 1.1 christos
1602 1.1 christos /* Write a SBFM instruction into *BUF.
1603 1.1 christos
1604 1.1 christos SBFM rd, rn, #immr, #imms
1605 1.1 christos
1606 1.1 christos This instruction moves the bits from #immr to #imms into the
1607 1.1 christos destination, sign extending the result.
1608 1.1 christos
1609 1.1 christos RD is the destination register.
1610 1.1 christos RN is the source register.
1611 1.1 christos IMMR is the bit number to start at (least significant bit).
1612 1.1 christos IMMS is the bit number to stop at (most significant bit). */
1613 1.1 christos
1614 1.1 christos static int
1615 1.1 christos emit_sbfm (uint32_t *buf, struct aarch64_register rd,
1616 1.1 christos struct aarch64_register rn, uint32_t immr, uint32_t imms)
1617 1.1 christos {
1618 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1619 1.1 christos uint32_t n = ENCODE (rd.is64, 1, 22);
1620 1.1 christos
1621 1.1 christos return aarch64_emit_insn (buf, SBFM | size | n | ENCODE (immr, 6, 16)
1622 1.1 christos | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
1623 1.1 christos | ENCODE (rd.num, 5, 0));
1624 1.1 christos }
1625 1.1 christos
1626 1.1 christos /* Write a SBFX instruction into *BUF.
1627 1.1 christos
1628 1.1 christos SBFX rd, rn, #lsb, #width
1629 1.1 christos
1630 1.1 christos This instruction moves #width bits from #lsb into the destination, sign
1631 1.1 christos extending the result. This is an alias for:
1632 1.1 christos
1633 1.1 christos SBFM rd, rn, #lsb, #(lsb + width - 1)
1634 1.1 christos
1635 1.1 christos RD is the destination register.
1636 1.1 christos RN is the source register.
1637 1.1 christos LSB is the bit number to start at (least significant bit).
1638 1.1 christos WIDTH is the number of bits to move. */
1639 1.1 christos
1640 1.1 christos static int
1641 1.1 christos emit_sbfx (uint32_t *buf, struct aarch64_register rd,
1642 1.1 christos struct aarch64_register rn, uint32_t lsb, uint32_t width)
1643 1.1 christos {
1644 1.1 christos return emit_sbfm (buf, rd, rn, lsb, lsb + width - 1);
1645 1.1 christos }
1646 1.1 christos
1647 1.1 christos /* Write a UBFM instruction into *BUF.
1648 1.1 christos
1649 1.1 christos UBFM rd, rn, #immr, #imms
1650 1.1 christos
1651 1.1 christos This instruction moves the bits from #immr to #imms into the
1652 1.1 christos destination, extending the result with zeros.
1653 1.1 christos
1654 1.1 christos RD is the destination register.
1655 1.1 christos RN is the source register.
1656 1.1 christos IMMR is the bit number to start at (least significant bit).
1657 1.1 christos IMMS is the bit number to stop at (most significant bit). */
1658 1.1 christos
1659 1.1 christos static int
1660 1.1 christos emit_ubfm (uint32_t *buf, struct aarch64_register rd,
1661 1.1 christos struct aarch64_register rn, uint32_t immr, uint32_t imms)
1662 1.1 christos {
1663 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1664 1.1 christos uint32_t n = ENCODE (rd.is64, 1, 22);
1665 1.1 christos
1666 1.1 christos return aarch64_emit_insn (buf, UBFM | size | n | ENCODE (immr, 6, 16)
1667 1.1 christos | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
1668 1.1 christos | ENCODE (rd.num, 5, 0));
1669 1.1 christos }
1670 1.1 christos
1671 1.1 christos /* Write a UBFX instruction into *BUF.
1672 1.1 christos
1673 1.1 christos UBFX rd, rn, #lsb, #width
1674 1.1 christos
1675 1.1 christos This instruction moves #width bits from #lsb into the destination,
1676 1.1 christos extending the result with zeros. This is an alias for:
1677 1.1 christos
1678 1.1 christos UBFM rd, rn, #lsb, #(lsb + width - 1)
1679 1.1 christos
1680 1.1 christos RD is the destination register.
1681 1.1 christos RN is the source register.
1682 1.1 christos LSB is the bit number to start at (least significant bit).
1683 1.1 christos WIDTH is the number of bits to move. */
1684 1.1 christos
1685 1.1 christos static int
1686 1.1 christos emit_ubfx (uint32_t *buf, struct aarch64_register rd,
1687 1.1 christos struct aarch64_register rn, uint32_t lsb, uint32_t width)
1688 1.1 christos {
1689 1.1 christos return emit_ubfm (buf, rd, rn, lsb, lsb + width - 1);
1690 1.1 christos }
1691 1.1 christos
1692 1.1 christos /* Write a CSINC instruction into *BUF.
1693 1.1 christos
1694 1.1 christos CSINC rd, rn, rm, cond
1695 1.1 christos
1696 1.1 christos This instruction conditionally increments rn or rm and places the result
1697 1.1 christos in rd. rn is chosen is the condition is true.
1698 1.1 christos
1699 1.1 christos RD is the destination register.
1700 1.1 christos RN and RM are the source registers.
1701 1.1 christos COND is the encoded condition. */
1702 1.1 christos
1703 1.1 christos static int
1704 1.1 christos emit_csinc (uint32_t *buf, struct aarch64_register rd,
1705 1.1 christos struct aarch64_register rn, struct aarch64_register rm,
1706 1.1 christos unsigned cond)
1707 1.1 christos {
1708 1.1 christos uint32_t size = ENCODE (rd.is64, 1, 31);
1709 1.1 christos
1710 1.1 christos return aarch64_emit_insn (buf, CSINC | size | ENCODE (rm.num, 5, 16)
1711 1.1 christos | ENCODE (cond, 4, 12) | ENCODE (rn.num, 5, 5)
1712 1.1 christos | ENCODE (rd.num, 5, 0));
1713 1.1 christos }
1714 1.1 christos
1715 1.1 christos /* Write a CSET instruction into *BUF.
1716 1.1 christos
1717 1.1 christos CSET rd, cond
1718 1.1 christos
1719 1.1 christos This instruction conditionally write 1 or 0 in the destination register.
1720 1.1 christos 1 is written if the condition is true. This is an alias for:
1721 1.1 christos
1722 1.1 christos CSINC rd, xzr, xzr, !cond
1723 1.1 christos
1724 1.1 christos Note that the condition needs to be inverted.
1725 1.1 christos
1726 1.1 christos RD is the destination register.
1727 1.1 christos RN and RM are the source registers.
1728 1.1 christos COND is the encoded condition. */
1729 1.1 christos
1730 1.1 christos static int
1731 1.1 christos emit_cset (uint32_t *buf, struct aarch64_register rd, unsigned cond)
1732 1.1 christos {
1733 1.1 christos /* The least significant bit of the condition needs toggling in order to
1734 1.1 christos invert it. */
1735 1.1 christos return emit_csinc (buf, rd, xzr, xzr, cond ^ 0x1);
1736 1.1 christos }
1737 1.1 christos
1738 1.1 christos /* Write LEN instructions from BUF into the inferior memory at *TO.
1739 1.1 christos
1740 1.1 christos Note instructions are always little endian on AArch64, unlike data. */
1741 1.1 christos
1742 1.1 christos static void
1743 1.1 christos append_insns (CORE_ADDR *to, size_t len, const uint32_t *buf)
1744 1.1 christos {
1745 1.1 christos size_t byte_len = len * sizeof (uint32_t);
1746 1.1 christos #if (__BYTE_ORDER == __BIG_ENDIAN)
1747 1.1 christos uint32_t *le_buf = (uint32_t *) xmalloc (byte_len);
1748 1.1 christos size_t i;
1749 1.1 christos
1750 1.1 christos for (i = 0; i < len; i++)
1751 1.1 christos le_buf[i] = htole32 (buf[i]);
1752 1.1 christos
1753 1.1 christos target_write_memory (*to, (const unsigned char *) le_buf, byte_len);
1754 1.1 christos
1755 1.1 christos xfree (le_buf);
1756 1.1 christos #else
1757 1.1 christos target_write_memory (*to, (const unsigned char *) buf, byte_len);
1758 1.1 christos #endif
1759 1.1 christos
1760 1.1 christos *to += byte_len;
1761 1.1 christos }
1762 1.1 christos
1763 1.1 christos /* Sub-class of struct aarch64_insn_data, store information of
1764 1.1 christos instruction relocation for fast tracepoint. Visitor can
1765 1.1 christos relocate an instruction from BASE.INSN_ADDR to NEW_ADDR and save
1766 1.1 christos the relocated instructions in buffer pointed by INSN_PTR. */
1767 1.1 christos
1768 1.1 christos struct aarch64_insn_relocation_data
1769 1.1 christos {
1770 1.1 christos struct aarch64_insn_data base;
1771 1.1 christos
1772 1.1 christos /* The new address the instruction is relocated to. */
1773 1.1 christos CORE_ADDR new_addr;
1774 1.1 christos /* Pointer to the buffer of relocated instruction(s). */
1775 1.1 christos uint32_t *insn_ptr;
1776 1.1 christos };
1777 1.1 christos
1778 1.1 christos /* Implementation of aarch64_insn_visitor method "b". */
1779 1.1 christos
1780 1.1 christos static void
1781 1.1 christos aarch64_ftrace_insn_reloc_b (const int is_bl, const int32_t offset,
1782 1.1 christos struct aarch64_insn_data *data)
1783 1.1 christos {
1784 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1785 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1786 1.1 christos int64_t new_offset
1787 1.1 christos = insn_reloc->base.insn_addr - insn_reloc->new_addr + offset;
1788 1.1 christos
1789 1.1 christos if (can_encode_int32 (new_offset, 28))
1790 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, is_bl, new_offset);
1791 1.1 christos }
1792 1.1 christos
1793 1.1 christos /* Implementation of aarch64_insn_visitor method "b_cond". */
1794 1.1 christos
1795 1.1 christos static void
1796 1.1 christos aarch64_ftrace_insn_reloc_b_cond (const unsigned cond, const int32_t offset,
1797 1.1 christos struct aarch64_insn_data *data)
1798 1.1 christos {
1799 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1800 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1801 1.1 christos int64_t new_offset
1802 1.1 christos = insn_reloc->base.insn_addr - insn_reloc->new_addr + offset;
1803 1.1 christos
1804 1.1 christos if (can_encode_int32 (new_offset, 21))
1805 1.1 christos {
1806 1.1 christos insn_reloc->insn_ptr += emit_bcond (insn_reloc->insn_ptr, cond,
1807 1.1 christos new_offset);
1808 1.1 christos }
1809 1.1 christos else if (can_encode_int32 (new_offset, 28))
1810 1.1 christos {
1811 1.1 christos /* The offset is out of range for a conditional branch
1812 1.1 christos instruction but not for a unconditional branch. We can use
1813 1.1 christos the following instructions instead:
1814 1.1 christos
1815 1.1 christos B.COND TAKEN ; If cond is true, then jump to TAKEN.
1816 1.1 christos B NOT_TAKEN ; Else jump over TAKEN and continue.
1817 1.1 christos TAKEN:
1818 1.1 christos B #(offset - 8)
1819 1.1 christos NOT_TAKEN:
1820 1.1 christos
1821 1.1 christos */
1822 1.1 christos
1823 1.1 christos insn_reloc->insn_ptr += emit_bcond (insn_reloc->insn_ptr, cond, 8);
1824 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0, 8);
1825 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0, new_offset - 8);
1826 1.1 christos }
1827 1.1 christos }
1828 1.1 christos
1829 1.1 christos /* Implementation of aarch64_insn_visitor method "cb". */
1830 1.1 christos
1831 1.1 christos static void
1832 1.1 christos aarch64_ftrace_insn_reloc_cb (const int32_t offset, const int is_cbnz,
1833 1.1 christos const unsigned rn, int is64,
1834 1.1 christos struct aarch64_insn_data *data)
1835 1.1 christos {
1836 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1837 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1838 1.1 christos int64_t new_offset
1839 1.1 christos = insn_reloc->base.insn_addr - insn_reloc->new_addr + offset;
1840 1.1 christos
1841 1.1 christos if (can_encode_int32 (new_offset, 21))
1842 1.1 christos {
1843 1.1 christos insn_reloc->insn_ptr += emit_cb (insn_reloc->insn_ptr, is_cbnz,
1844 1.1 christos aarch64_register (rn, is64), new_offset);
1845 1.1 christos }
1846 1.1 christos else if (can_encode_int32 (new_offset, 28))
1847 1.1 christos {
1848 1.1 christos /* The offset is out of range for a compare and branch
1849 1.1 christos instruction but not for a unconditional branch. We can use
1850 1.1 christos the following instructions instead:
1851 1.1 christos
1852 1.1 christos CBZ xn, TAKEN ; xn == 0, then jump to TAKEN.
1853 1.1 christos B NOT_TAKEN ; Else jump over TAKEN and continue.
1854 1.1 christos TAKEN:
1855 1.1 christos B #(offset - 8)
1856 1.1 christos NOT_TAKEN:
1857 1.1 christos
1858 1.1 christos */
1859 1.1 christos insn_reloc->insn_ptr += emit_cb (insn_reloc->insn_ptr, is_cbnz,
1860 1.1 christos aarch64_register (rn, is64), 8);
1861 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0, 8);
1862 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0, new_offset - 8);
1863 1.1 christos }
1864 1.1 christos }
1865 1.1 christos
1866 1.1 christos /* Implementation of aarch64_insn_visitor method "tb". */
1867 1.1 christos
1868 1.1 christos static void
1869 1.1 christos aarch64_ftrace_insn_reloc_tb (const int32_t offset, int is_tbnz,
1870 1.1 christos const unsigned rt, unsigned bit,
1871 1.1 christos struct aarch64_insn_data *data)
1872 1.1 christos {
1873 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1874 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1875 1.1 christos int64_t new_offset
1876 1.1 christos = insn_reloc->base.insn_addr - insn_reloc->new_addr + offset;
1877 1.1 christos
1878 1.1 christos if (can_encode_int32 (new_offset, 16))
1879 1.1 christos {
1880 1.1 christos insn_reloc->insn_ptr += emit_tb (insn_reloc->insn_ptr, is_tbnz, bit,
1881 1.1 christos aarch64_register (rt, 1), new_offset);
1882 1.1 christos }
1883 1.1 christos else if (can_encode_int32 (new_offset, 28))
1884 1.1 christos {
1885 1.1 christos /* The offset is out of range for a test bit and branch
1886 1.1 christos instruction but not for a unconditional branch. We can use
1887 1.1 christos the following instructions instead:
1888 1.1 christos
1889 1.1 christos TBZ xn, #bit, TAKEN ; xn[bit] == 0, then jump to TAKEN.
1890 1.1 christos B NOT_TAKEN ; Else jump over TAKEN and continue.
1891 1.1 christos TAKEN:
1892 1.1 christos B #(offset - 8)
1893 1.1 christos NOT_TAKEN:
1894 1.1 christos
1895 1.1 christos */
1896 1.1 christos insn_reloc->insn_ptr += emit_tb (insn_reloc->insn_ptr, is_tbnz, bit,
1897 1.1 christos aarch64_register (rt, 1), 8);
1898 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0, 8);
1899 1.1 christos insn_reloc->insn_ptr += emit_b (insn_reloc->insn_ptr, 0,
1900 1.1 christos new_offset - 8);
1901 1.1 christos }
1902 1.1 christos }
1903 1.1 christos
1904 1.1 christos /* Implementation of aarch64_insn_visitor method "adr". */
1905 1.1 christos
1906 1.1 christos static void
1907 1.1 christos aarch64_ftrace_insn_reloc_adr (const int32_t offset, const unsigned rd,
1908 1.1 christos const int is_adrp,
1909 1.1 christos struct aarch64_insn_data *data)
1910 1.1 christos {
1911 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1912 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1913 1.1 christos /* We know exactly the address the ADR{P,} instruction will compute.
1914 1.1 christos We can just write it to the destination register. */
1915 1.1 christos CORE_ADDR address = data->insn_addr + offset;
1916 1.1 christos
1917 1.1 christos if (is_adrp)
1918 1.1 christos {
1919 1.1 christos /* Clear the lower 12 bits of the offset to get the 4K page. */
1920 1.1 christos insn_reloc->insn_ptr += emit_mov_addr (insn_reloc->insn_ptr,
1921 1.1 christos aarch64_register (rd, 1),
1922 1.1 christos address & ~0xfff);
1923 1.1 christos }
1924 1.1 christos else
1925 1.1 christos insn_reloc->insn_ptr += emit_mov_addr (insn_reloc->insn_ptr,
1926 1.1 christos aarch64_register (rd, 1), address);
1927 1.1 christos }
1928 1.1 christos
1929 1.1 christos /* Implementation of aarch64_insn_visitor method "ldr_literal". */
1930 1.1 christos
1931 1.1 christos static void
1932 1.1 christos aarch64_ftrace_insn_reloc_ldr_literal (const int32_t offset, const int is_sw,
1933 1.1 christos const unsigned rt, const int is64,
1934 1.1 christos struct aarch64_insn_data *data)
1935 1.1 christos {
1936 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1937 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1938 1.1 christos CORE_ADDR address = data->insn_addr + offset;
1939 1.1 christos
1940 1.1 christos insn_reloc->insn_ptr += emit_mov_addr (insn_reloc->insn_ptr,
1941 1.1 christos aarch64_register (rt, 1), address);
1942 1.1 christos
1943 1.1 christos /* We know exactly what address to load from, and what register we
1944 1.1 christos can use:
1945 1.1 christos
1946 1.1 christos MOV xd, #(oldloc + offset)
1947 1.1 christos MOVK xd, #((oldloc + offset) >> 16), lsl #16
1948 1.1 christos ...
1949 1.1 christos
1950 1.1 christos LDR xd, [xd] ; or LDRSW xd, [xd]
1951 1.1 christos
1952 1.1 christos */
1953 1.1 christos
1954 1.1 christos if (is_sw)
1955 1.1 christos insn_reloc->insn_ptr += emit_ldrsw (insn_reloc->insn_ptr,
1956 1.1 christos aarch64_register (rt, 1),
1957 1.1 christos aarch64_register (rt, 1),
1958 1.1 christos offset_memory_operand (0));
1959 1.1 christos else
1960 1.1 christos insn_reloc->insn_ptr += emit_ldr (insn_reloc->insn_ptr,
1961 1.1 christos aarch64_register (rt, is64),
1962 1.1 christos aarch64_register (rt, 1),
1963 1.1 christos offset_memory_operand (0));
1964 1.1 christos }
1965 1.1 christos
1966 1.1 christos /* Implementation of aarch64_insn_visitor method "others". */
1967 1.1 christos
1968 1.1 christos static void
1969 1.1 christos aarch64_ftrace_insn_reloc_others (const uint32_t insn,
1970 1.1 christos struct aarch64_insn_data *data)
1971 1.1 christos {
1972 1.1 christos struct aarch64_insn_relocation_data *insn_reloc
1973 1.1 christos = (struct aarch64_insn_relocation_data *) data;
1974 1.1 christos
1975 1.1 christos /* The instruction is not PC relative. Just re-emit it at the new
1976 1.1 christos location. */
1977 1.1 christos insn_reloc->insn_ptr += aarch64_emit_insn (insn_reloc->insn_ptr, insn);
1978 1.1 christos }
1979 1.1 christos
1980 1.1 christos static const struct aarch64_insn_visitor visitor =
1981 1.1 christos {
1982 1.1 christos aarch64_ftrace_insn_reloc_b,
1983 1.1 christos aarch64_ftrace_insn_reloc_b_cond,
1984 1.1 christos aarch64_ftrace_insn_reloc_cb,
1985 1.1 christos aarch64_ftrace_insn_reloc_tb,
1986 1.1 christos aarch64_ftrace_insn_reloc_adr,
1987 1.1 christos aarch64_ftrace_insn_reloc_ldr_literal,
1988 1.1 christos aarch64_ftrace_insn_reloc_others,
1989 1.1 christos };
1990 1.1 christos
1991 1.1 christos bool
1992 1.1 christos aarch64_target::supports_fast_tracepoints ()
1993 1.1 christos {
1994 1.1 christos return true;
1995 1.1 christos }
1996 1.1 christos
1997 1.1 christos /* Implementation of target ops method
1998 1.1 christos "install_fast_tracepoint_jump_pad". */
1999 1.1 christos
2000 1.1 christos int
2001 1.1 christos aarch64_target::install_fast_tracepoint_jump_pad
2002 1.1 christos (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
2003 1.1 christos CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
2004 1.1 christos CORE_ADDR *trampoline, ULONGEST *trampoline_size,
2005 1.1 christos unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
2006 1.1 christos CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
2007 1.1 christos char *err)
2008 1.1 christos {
2009 1.1 christos uint32_t buf[256];
2010 1.1 christos uint32_t *p = buf;
2011 1.1 christos int64_t offset;
2012 1.1 christos int i;
2013 1.1 christos uint32_t insn;
2014 1.1 christos CORE_ADDR buildaddr = *jump_entry;
2015 1.1 christos struct aarch64_insn_relocation_data insn_data;
2016 1.1 christos
2017 1.1 christos /* We need to save the current state on the stack both to restore it
2018 1.1 christos later and to collect register values when the tracepoint is hit.
2019 1.1 christos
2020 1.1 christos The saved registers are pushed in a layout that needs to be in sync
2021 1.1 christos with aarch64_ft_collect_regmap (see linux-aarch64-ipa.c). Later on
2022 1.1 christos the supply_fast_tracepoint_registers function will fill in the
2023 1.1 christos register cache from a pointer to saved registers on the stack we build
2024 1.1 christos here.
2025 1.1 christos
2026 1.1 christos For simplicity, we set the size of each cell on the stack to 16 bytes.
2027 1.1 christos This way one cell can hold any register type, from system registers
2028 1.1 christos to the 128 bit SIMD&FP registers. Furthermore, the stack pointer
2029 1.1 christos has to be 16 bytes aligned anyway.
2030 1.1 christos
2031 1.1 christos Note that the CPSR register does not exist on AArch64. Instead we
2032 1.1 christos can access system bits describing the process state with the
2033 1.1 christos MRS/MSR instructions, namely the condition flags. We save them as
2034 1.1 christos if they are part of a CPSR register because that's how GDB
2035 1.1 christos interprets these system bits. At the moment, only the condition
2036 1.1 christos flags are saved in CPSR (NZCV).
2037 1.1 christos
2038 1.1 christos Stack layout, each cell is 16 bytes (descending):
2039 1.1 christos
2040 1.1 christos High *-------- SIMD&FP registers from 31 down to 0. --------*
2041 1.1 christos | q31 |
2042 1.1 christos . .
2043 1.1 christos . . 32 cells
2044 1.1 christos . .
2045 1.1 christos | q0 |
2046 1.1 christos *---- General purpose registers from 30 down to 0. ----*
2047 1.1 christos | x30 |
2048 1.1 christos . .
2049 1.1 christos . . 31 cells
2050 1.1 christos . .
2051 1.1 christos | x0 |
2052 1.1 christos *------------- Special purpose registers. -------------*
2053 1.1 christos | SP |
2054 1.1 christos | PC |
2055 1.1 christos | CPSR (NZCV) | 5 cells
2056 1.1 christos | FPSR |
2057 1.1 christos | FPCR | <- SP + 16
2058 1.1 christos *------------- collecting_t object --------------------*
2059 1.1 christos | TPIDR_EL0 | struct tracepoint * |
2060 1.1 christos Low *------------------------------------------------------*
2061 1.1 christos
2062 1.1 christos After this stack is set up, we issue a call to the collector, passing
2063 1.1 christos it the saved registers at (SP + 16). */
2064 1.1 christos
2065 1.1 christos /* Push SIMD&FP registers on the stack:
2066 1.1 christos
2067 1.1 christos SUB sp, sp, #(32 * 16)
2068 1.1 christos
2069 1.1 christos STP q30, q31, [sp, #(30 * 16)]
2070 1.1 christos ...
2071 1.1 christos STP q0, q1, [sp]
2072 1.1 christos
2073 1.1 christos */
2074 1.1 christos p += emit_sub (p, sp, sp, immediate_operand (32 * 16));
2075 1.1 christos for (i = 30; i >= 0; i -= 2)
2076 1.1 christos p += emit_stp_q_offset (p, i, i + 1, sp, i * 16);
2077 1.1 christos
2078 1.1 christos /* Push general purpose registers on the stack. Note that we do not need
2079 1.1 christos to push x31 as it represents the xzr register and not the stack
2080 1.1 christos pointer in a STR instruction.
2081 1.1 christos
2082 1.1 christos SUB sp, sp, #(31 * 16)
2083 1.1 christos
2084 1.1 christos STR x30, [sp, #(30 * 16)]
2085 1.1 christos ...
2086 1.1 christos STR x0, [sp]
2087 1.1 christos
2088 1.1 christos */
2089 1.1 christos p += emit_sub (p, sp, sp, immediate_operand (31 * 16));
2090 1.1 christos for (i = 30; i >= 0; i -= 1)
2091 1.1 christos p += emit_str (p, aarch64_register (i, 1), sp,
2092 1.1 christos offset_memory_operand (i * 16));
2093 1.1 christos
2094 1.1 christos /* Make space for 5 more cells.
2095 1.1 christos
2096 1.1 christos SUB sp, sp, #(5 * 16)
2097 1.1 christos
2098 1.1 christos */
2099 1.1 christos p += emit_sub (p, sp, sp, immediate_operand (5 * 16));
2100 1.1 christos
2101 1.1 christos
2102 1.1 christos /* Save SP:
2103 1.1 christos
2104 1.1 christos ADD x4, sp, #((32 + 31 + 5) * 16)
2105 1.1 christos STR x4, [sp, #(4 * 16)]
2106 1.1 christos
2107 1.1 christos */
2108 1.1 christos p += emit_add (p, x4, sp, immediate_operand ((32 + 31 + 5) * 16));
2109 1.1 christos p += emit_str (p, x4, sp, offset_memory_operand (4 * 16));
2110 1.1 christos
2111 1.1 christos /* Save PC (tracepoint address):
2112 1.1 christos
2113 1.1 christos MOV x3, #(tpaddr)
2114 1.1 christos ...
2115 1.1 christos
2116 1.1 christos STR x3, [sp, #(3 * 16)]
2117 1.1 christos
2118 1.1 christos */
2119 1.1 christos
2120 1.1 christos p += emit_mov_addr (p, x3, tpaddr);
2121 1.1 christos p += emit_str (p, x3, sp, offset_memory_operand (3 * 16));
2122 1.1 christos
2123 1.1 christos /* Save CPSR (NZCV), FPSR and FPCR:
2124 1.1 christos
2125 1.1 christos MRS x2, nzcv
2126 1.1 christos MRS x1, fpsr
2127 1.1 christos MRS x0, fpcr
2128 1.1 christos
2129 1.1 christos STR x2, [sp, #(2 * 16)]
2130 1.1 christos STR x1, [sp, #(1 * 16)]
2131 1.1 christos STR x0, [sp, #(0 * 16)]
2132 1.1 christos
2133 1.1 christos */
2134 1.1 christos p += emit_mrs (p, x2, NZCV);
2135 1.1 christos p += emit_mrs (p, x1, FPSR);
2136 1.1 christos p += emit_mrs (p, x0, FPCR);
2137 1.1 christos p += emit_str (p, x2, sp, offset_memory_operand (2 * 16));
2138 1.1 christos p += emit_str (p, x1, sp, offset_memory_operand (1 * 16));
2139 1.1 christos p += emit_str (p, x0, sp, offset_memory_operand (0 * 16));
2140 1.1 christos
2141 1.1 christos /* Push the collecting_t object. It consist of the address of the
2142 1.1 christos tracepoint and an ID for the current thread. We get the latter by
2143 1.1 christos reading the tpidr_el0 system register. It corresponds to the
2144 1.1 christos NT_ARM_TLS register accessible with ptrace.
2145 1.1 christos
2146 1.1 christos MOV x0, #(tpoint)
2147 1.1 christos ...
2148 1.1 christos
2149 1.1 christos MRS x1, tpidr_el0
2150 1.1 christos
2151 1.1 christos STP x0, x1, [sp, #-16]!
2152 1.1 christos
2153 1.1 christos */
2154 1.1 christos
2155 1.1 christos p += emit_mov_addr (p, x0, tpoint);
2156 1.1 christos p += emit_mrs (p, x1, TPIDR_EL0);
2157 1.1 christos p += emit_stp (p, x0, x1, sp, preindex_memory_operand (-16));
2158 1.1 christos
2159 1.1 christos /* Spin-lock:
2160 1.1 christos
2161 1.1 christos The shared memory for the lock is at lockaddr. It will hold zero
2162 1.1 christos if no-one is holding the lock, otherwise it contains the address of
2163 1.1 christos the collecting_t object on the stack of the thread which acquired it.
2164 1.1 christos
2165 1.1 christos At this stage, the stack pointer points to this thread's collecting_t
2166 1.1 christos object.
2167 1.1 christos
2168 1.1 christos We use the following registers:
2169 1.1 christos - x0: Address of the lock.
2170 1.1 christos - x1: Pointer to collecting_t object.
2171 1.1 christos - x2: Scratch register.
2172 1.1 christos
2173 1.1 christos MOV x0, #(lockaddr)
2174 1.1 christos ...
2175 1.1 christos MOV x1, sp
2176 1.1 christos
2177 1.1 christos ; Trigger an event local to this core. So the following WFE
2178 1.1 christos ; instruction is ignored.
2179 1.1 christos SEVL
2180 1.1 christos again:
2181 1.1 christos ; Wait for an event. The event is triggered by either the SEVL
2182 1.1 christos ; or STLR instructions (store release).
2183 1.1 christos WFE
2184 1.1 christos
2185 1.1 christos ; Atomically read at lockaddr. This marks the memory location as
2186 1.1 christos ; exclusive. This instruction also has memory constraints which
2187 1.1 christos ; make sure all previous data reads and writes are done before
2188 1.1 christos ; executing it.
2189 1.1 christos LDAXR x2, [x0]
2190 1.1 christos
2191 1.1 christos ; Try again if another thread holds the lock.
2192 1.1 christos CBNZ x2, again
2193 1.1 christos
2194 1.1 christos ; We can lock it! Write the address of the collecting_t object.
2195 1.1 christos ; This instruction will fail if the memory location is not marked
2196 1.1 christos ; as exclusive anymore. If it succeeds, it will remove the
2197 1.1 christos ; exclusive mark on the memory location. This way, if another
2198 1.1 christos ; thread executes this instruction before us, we will fail and try
2199 1.1 christos ; all over again.
2200 1.1 christos STXR w2, x1, [x0]
2201 1.1 christos CBNZ w2, again
2202 1.1 christos
2203 1.1 christos */
2204 1.1 christos
2205 1.1 christos p += emit_mov_addr (p, x0, lockaddr);
2206 1.1 christos p += emit_mov (p, x1, register_operand (sp));
2207 1.1 christos
2208 1.1 christos p += emit_sevl (p);
2209 1.1 christos p += emit_wfe (p);
2210 1.1 christos p += emit_ldaxr (p, x2, x0);
2211 1.1 christos p += emit_cb (p, 1, w2, -2 * 4);
2212 1.1 christos p += emit_stxr (p, w2, x1, x0);
2213 1.1 christos p += emit_cb (p, 1, x2, -4 * 4);
2214 1.1 christos
2215 1.1 christos /* Call collector (struct tracepoint *, unsigned char *):
2216 1.1 christos
2217 1.1 christos MOV x0, #(tpoint)
2218 1.1 christos ...
2219 1.1 christos
2220 1.1 christos ; Saved registers start after the collecting_t object.
2221 1.1 christos ADD x1, sp, #16
2222 1.1 christos
2223 1.1 christos ; We use an intra-procedure-call scratch register.
2224 1.1 christos MOV ip0, #(collector)
2225 1.1 christos ...
2226 1.1 christos
2227 1.1 christos ; And call back to C!
2228 1.1 christos BLR ip0
2229 1.1 christos
2230 1.1 christos */
2231 1.1 christos
2232 1.1 christos p += emit_mov_addr (p, x0, tpoint);
2233 1.1 christos p += emit_add (p, x1, sp, immediate_operand (16));
2234 1.1 christos
2235 1.1 christos p += emit_mov_addr (p, ip0, collector);
2236 1.1 christos p += emit_blr (p, ip0);
2237 1.1 christos
2238 1.1 christos /* Release the lock.
2239 1.1 christos
2240 1.1 christos MOV x0, #(lockaddr)
2241 1.1 christos ...
2242 1.1 christos
2243 1.1 christos ; This instruction is a normal store with memory ordering
2244 1.1 christos ; constraints. Thanks to this we do not have to put a data
2245 1.1 christos ; barrier instruction to make sure all data read and writes are done
2246 1.1 christos ; before this instruction is executed. Furthermore, this instruction
2247 1.1 christos ; will trigger an event, letting other threads know they can grab
2248 1.1 christos ; the lock.
2249 1.1 christos STLR xzr, [x0]
2250 1.1 christos
2251 1.1 christos */
2252 1.1 christos p += emit_mov_addr (p, x0, lockaddr);
2253 1.1 christos p += emit_stlr (p, xzr, x0);
2254 1.1 christos
2255 1.1 christos /* Free collecting_t object:
2256 1.1 christos
2257 1.1 christos ADD sp, sp, #16
2258 1.1 christos
2259 1.1 christos */
2260 1.1 christos p += emit_add (p, sp, sp, immediate_operand (16));
2261 1.1 christos
2262 1.1 christos /* Restore CPSR (NZCV), FPSR and FPCR. And free all special purpose
2263 1.1 christos registers from the stack.
2264 1.1 christos
2265 1.1 christos LDR x2, [sp, #(2 * 16)]
2266 1.1 christos LDR x1, [sp, #(1 * 16)]
2267 1.1 christos LDR x0, [sp, #(0 * 16)]
2268 1.1 christos
2269 1.1 christos MSR NZCV, x2
2270 1.1 christos MSR FPSR, x1
2271 1.1 christos MSR FPCR, x0
2272 1.1 christos
2273 1.1 christos ADD sp, sp #(5 * 16)
2274 1.1 christos
2275 1.1 christos */
2276 1.1 christos p += emit_ldr (p, x2, sp, offset_memory_operand (2 * 16));
2277 1.1 christos p += emit_ldr (p, x1, sp, offset_memory_operand (1 * 16));
2278 1.1 christos p += emit_ldr (p, x0, sp, offset_memory_operand (0 * 16));
2279 1.1 christos p += emit_msr (p, NZCV, x2);
2280 1.1 christos p += emit_msr (p, FPSR, x1);
2281 1.1 christos p += emit_msr (p, FPCR, x0);
2282 1.1 christos
2283 1.1 christos p += emit_add (p, sp, sp, immediate_operand (5 * 16));
2284 1.1 christos
2285 1.1 christos /* Pop general purpose registers:
2286 1.1 christos
2287 1.1 christos LDR x0, [sp]
2288 1.1 christos ...
2289 1.1 christos LDR x30, [sp, #(30 * 16)]
2290 1.1 christos
2291 1.1 christos ADD sp, sp, #(31 * 16)
2292 1.1 christos
2293 1.1 christos */
2294 1.1 christos for (i = 0; i <= 30; i += 1)
2295 1.1 christos p += emit_ldr (p, aarch64_register (i, 1), sp,
2296 1.1 christos offset_memory_operand (i * 16));
2297 1.1 christos p += emit_add (p, sp, sp, immediate_operand (31 * 16));
2298 1.1 christos
2299 1.1 christos /* Pop SIMD&FP registers:
2300 1.1 christos
2301 1.1 christos LDP q0, q1, [sp]
2302 1.1 christos ...
2303 1.1 christos LDP q30, q31, [sp, #(30 * 16)]
2304 1.1 christos
2305 1.1 christos ADD sp, sp, #(32 * 16)
2306 1.1 christos
2307 1.1 christos */
2308 1.1 christos for (i = 0; i <= 30; i += 2)
2309 1.1 christos p += emit_ldp_q_offset (p, i, i + 1, sp, i * 16);
2310 1.1 christos p += emit_add (p, sp, sp, immediate_operand (32 * 16));
2311 1.1 christos
2312 1.1 christos /* Write the code into the inferior memory. */
2313 1.1 christos append_insns (&buildaddr, p - buf, buf);
2314 1.1 christos
2315 1.1 christos /* Now emit the relocated instruction. */
2316 1.1 christos *adjusted_insn_addr = buildaddr;
2317 1.1 christos target_read_uint32 (tpaddr, &insn);
2318 1.1 christos
2319 1.1 christos insn_data.base.insn_addr = tpaddr;
2320 1.1 christos insn_data.new_addr = buildaddr;
2321 1.1 christos insn_data.insn_ptr = buf;
2322 1.1 christos
2323 1.1 christos aarch64_relocate_instruction (insn, &visitor,
2324 1.1 christos (struct aarch64_insn_data *) &insn_data);
2325 1.1 christos
2326 1.1 christos /* We may not have been able to relocate the instruction. */
2327 1.1 christos if (insn_data.insn_ptr == buf)
2328 1.1 christos {
2329 1.1 christos sprintf (err,
2330 1.1 christos "E.Could not relocate instruction from %s to %s.",
2331 1.1 christos core_addr_to_string_nz (tpaddr),
2332 1.1 christos core_addr_to_string_nz (buildaddr));
2333 1.1 christos return 1;
2334 1.1 christos }
2335 1.1 christos else
2336 1.1 christos append_insns (&buildaddr, insn_data.insn_ptr - buf, buf);
2337 1.1 christos *adjusted_insn_addr_end = buildaddr;
2338 1.1 christos
2339 1.1 christos /* Go back to the start of the buffer. */
2340 1.1 christos p = buf;
2341 1.1 christos
2342 1.1 christos /* Emit a branch back from the jump pad. */
2343 1.1 christos offset = (tpaddr + orig_size - buildaddr);
2344 1.1 christos if (!can_encode_int32 (offset, 28))
2345 1.1 christos {
2346 1.1 christos sprintf (err,
2347 1.1 christos "E.Jump back from jump pad too far from tracepoint "
2348 1.1 christos "(offset 0x%" PRIx64 " cannot be encoded in 28 bits).",
2349 1.1 christos offset);
2350 1.1 christos return 1;
2351 1.1 christos }
2352 1.1 christos
2353 1.1 christos p += emit_b (p, 0, offset);
2354 1.1 christos append_insns (&buildaddr, p - buf, buf);
2355 1.1 christos
2356 1.1 christos /* Give the caller a branch instruction into the jump pad. */
2357 1.1 christos offset = (*jump_entry - tpaddr);
2358 1.1 christos if (!can_encode_int32 (offset, 28))
2359 1.1 christos {
2360 1.1 christos sprintf (err,
2361 1.1 christos "E.Jump pad too far from tracepoint "
2362 1.1 christos "(offset 0x%" PRIx64 " cannot be encoded in 28 bits).",
2363 1.1 christos offset);
2364 1.1 christos return 1;
2365 1.1 christos }
2366 1.1 christos
2367 1.1 christos emit_b ((uint32_t *) jjump_pad_insn, 0, offset);
2368 1.1 christos *jjump_pad_insn_size = 4;
2369 1.1 christos
2370 1.1 christos /* Return the end address of our pad. */
2371 1.1 christos *jump_entry = buildaddr;
2372 1.1 christos
2373 1.1 christos return 0;
2374 1.1 christos }
2375 1.1 christos
2376 1.1 christos /* Helper function writing LEN instructions from START into
2377 1.1 christos current_insn_ptr. */
2378 1.1 christos
2379 1.1 christos static void
2380 1.1 christos emit_ops_insns (const uint32_t *start, int len)
2381 1.1 christos {
2382 1.1 christos CORE_ADDR buildaddr = current_insn_ptr;
2383 1.1 christos
2384 1.1 christos if (debug_threads)
2385 1.1 christos debug_printf ("Adding %d instrucions at %s\n",
2386 1.1 christos len, paddress (buildaddr));
2387 1.1 christos
2388 1.1 christos append_insns (&buildaddr, len, start);
2389 1.1 christos current_insn_ptr = buildaddr;
2390 1.1 christos }
2391 1.1 christos
2392 1.1 christos /* Pop a register from the stack. */
2393 1.1 christos
2394 1.1 christos static int
2395 1.1 christos emit_pop (uint32_t *buf, struct aarch64_register rt)
2396 1.1 christos {
2397 1.1 christos return emit_ldr (buf, rt, sp, postindex_memory_operand (1 * 16));
2398 1.1 christos }
2399 1.1 christos
2400 1.1 christos /* Push a register on the stack. */
2401 1.1 christos
2402 1.1 christos static int
2403 1.1 christos emit_push (uint32_t *buf, struct aarch64_register rt)
2404 1.1 christos {
2405 1.1 christos return emit_str (buf, rt, sp, preindex_memory_operand (-1 * 16));
2406 1.1 christos }
2407 1.1 christos
2408 1.1 christos /* Implementation of emit_ops method "emit_prologue". */
2409 1.1 christos
2410 1.1 christos static void
2411 1.1 christos aarch64_emit_prologue (void)
2412 1.1 christos {
2413 1.1 christos uint32_t buf[16];
2414 1.1 christos uint32_t *p = buf;
2415 1.1 christos
2416 1.1 christos /* This function emit a prologue for the following function prototype:
2417 1.1 christos
2418 1.1 christos enum eval_result_type f (unsigned char *regs,
2419 1.1 christos ULONGEST *value);
2420 1.1 christos
2421 1.1 christos The first argument is a buffer of raw registers. The second
2422 1.1 christos argument is the result of
2423 1.1 christos evaluating the expression, which will be set to whatever is on top of
2424 1.1 christos the stack at the end.
2425 1.1 christos
2426 1.1 christos The stack set up by the prologue is as such:
2427 1.1 christos
2428 1.1 christos High *------------------------------------------------------*
2429 1.1 christos | LR |
2430 1.1 christos | FP | <- FP
2431 1.1 christos | x1 (ULONGEST *value) |
2432 1.1 christos | x0 (unsigned char *regs) |
2433 1.1 christos Low *------------------------------------------------------*
2434 1.1 christos
2435 1.1 christos As we are implementing a stack machine, each opcode can expand the
2436 1.1 christos stack so we never know how far we are from the data saved by this
2437 1.1 christos prologue. In order to be able refer to value and regs later, we save
2438 1.1 christos the current stack pointer in the frame pointer. This way, it is not
2439 1.1 christos clobbered when calling C functions.
2440 1.1 christos
2441 1.1 christos Finally, throughout every operation, we are using register x0 as the
2442 1.1 christos top of the stack, and x1 as a scratch register. */
2443 1.1 christos
2444 1.1 christos p += emit_stp (p, x0, x1, sp, preindex_memory_operand (-2 * 16));
2445 1.1 christos p += emit_str (p, lr, sp, offset_memory_operand (3 * 8));
2446 1.1 christos p += emit_str (p, fp, sp, offset_memory_operand (2 * 8));
2447 1.1 christos
2448 1.1 christos p += emit_add (p, fp, sp, immediate_operand (2 * 8));
2449 1.1 christos
2450 1.1 christos
2451 1.1 christos emit_ops_insns (buf, p - buf);
2452 1.1 christos }
2453 1.1 christos
2454 1.1 christos /* Implementation of emit_ops method "emit_epilogue". */
2455 1.1 christos
2456 1.1 christos static void
2457 1.1 christos aarch64_emit_epilogue (void)
2458 1.1 christos {
2459 1.1 christos uint32_t buf[16];
2460 1.1 christos uint32_t *p = buf;
2461 1.1 christos
2462 1.1 christos /* Store the result of the expression (x0) in *value. */
2463 1.1 christos p += emit_sub (p, x1, fp, immediate_operand (1 * 8));
2464 1.1 christos p += emit_ldr (p, x1, x1, offset_memory_operand (0));
2465 1.1 christos p += emit_str (p, x0, x1, offset_memory_operand (0));
2466 1.1 christos
2467 1.1 christos /* Restore the previous state. */
2468 1.1 christos p += emit_add (p, sp, fp, immediate_operand (2 * 8));
2469 1.1 christos p += emit_ldp (p, fp, lr, fp, offset_memory_operand (0));
2470 1.1 christos
2471 1.1 christos /* Return expr_eval_no_error. */
2472 1.1 christos p += emit_mov (p, x0, immediate_operand (expr_eval_no_error));
2473 1.1 christos p += emit_ret (p, lr);
2474 1.1 christos
2475 1.1 christos emit_ops_insns (buf, p - buf);
2476 1.1 christos }
2477 1.1 christos
2478 1.1 christos /* Implementation of emit_ops method "emit_add". */
2479 1.1 christos
2480 1.1 christos static void
2481 1.1 christos aarch64_emit_add (void)
2482 1.1 christos {
2483 1.1 christos uint32_t buf[16];
2484 1.1 christos uint32_t *p = buf;
2485 1.1 christos
2486 1.1 christos p += emit_pop (p, x1);
2487 1.1 christos p += emit_add (p, x0, x1, register_operand (x0));
2488 1.1 christos
2489 1.1 christos emit_ops_insns (buf, p - buf);
2490 1.1 christos }
2491 1.1 christos
2492 1.1 christos /* Implementation of emit_ops method "emit_sub". */
2493 1.1 christos
2494 1.1 christos static void
2495 1.1 christos aarch64_emit_sub (void)
2496 1.1 christos {
2497 1.1 christos uint32_t buf[16];
2498 1.1 christos uint32_t *p = buf;
2499 1.1 christos
2500 1.1 christos p += emit_pop (p, x1);
2501 1.1 christos p += emit_sub (p, x0, x1, register_operand (x0));
2502 1.1 christos
2503 1.1 christos emit_ops_insns (buf, p - buf);
2504 1.1 christos }
2505 1.1 christos
2506 1.1 christos /* Implementation of emit_ops method "emit_mul". */
2507 1.1 christos
2508 1.1 christos static void
2509 1.1 christos aarch64_emit_mul (void)
2510 1.1 christos {
2511 1.1 christos uint32_t buf[16];
2512 1.1 christos uint32_t *p = buf;
2513 1.1 christos
2514 1.1 christos p += emit_pop (p, x1);
2515 1.1 christos p += emit_mul (p, x0, x1, x0);
2516 1.1 christos
2517 1.1 christos emit_ops_insns (buf, p - buf);
2518 1.1 christos }
2519 1.1 christos
2520 1.1 christos /* Implementation of emit_ops method "emit_lsh". */
2521 1.1 christos
2522 1.1 christos static void
2523 1.1 christos aarch64_emit_lsh (void)
2524 1.1 christos {
2525 1.1 christos uint32_t buf[16];
2526 1.1 christos uint32_t *p = buf;
2527 1.1 christos
2528 1.1 christos p += emit_pop (p, x1);
2529 1.1 christos p += emit_lslv (p, x0, x1, x0);
2530 1.1 christos
2531 1.1 christos emit_ops_insns (buf, p - buf);
2532 1.1 christos }
2533 1.1 christos
2534 1.1 christos /* Implementation of emit_ops method "emit_rsh_signed". */
2535 1.1 christos
2536 1.1 christos static void
2537 1.1 christos aarch64_emit_rsh_signed (void)
2538 1.1 christos {
2539 1.1 christos uint32_t buf[16];
2540 1.1 christos uint32_t *p = buf;
2541 1.1 christos
2542 1.1 christos p += emit_pop (p, x1);
2543 1.1 christos p += emit_asrv (p, x0, x1, x0);
2544 1.1 christos
2545 1.1 christos emit_ops_insns (buf, p - buf);
2546 1.1 christos }
2547 1.1 christos
2548 1.1 christos /* Implementation of emit_ops method "emit_rsh_unsigned". */
2549 1.1 christos
2550 1.1 christos static void
2551 1.1 christos aarch64_emit_rsh_unsigned (void)
2552 1.1 christos {
2553 1.1 christos uint32_t buf[16];
2554 1.1 christos uint32_t *p = buf;
2555 1.1 christos
2556 1.1 christos p += emit_pop (p, x1);
2557 1.1 christos p += emit_lsrv (p, x0, x1, x0);
2558 1.1 christos
2559 1.1 christos emit_ops_insns (buf, p - buf);
2560 1.1 christos }
2561 1.1 christos
2562 1.1 christos /* Implementation of emit_ops method "emit_ext". */
2563 1.1 christos
2564 1.1 christos static void
2565 1.1 christos aarch64_emit_ext (int arg)
2566 1.1 christos {
2567 1.1 christos uint32_t buf[16];
2568 1.1 christos uint32_t *p = buf;
2569 1.1 christos
2570 1.1 christos p += emit_sbfx (p, x0, x0, 0, arg);
2571 1.1 christos
2572 1.1 christos emit_ops_insns (buf, p - buf);
2573 1.1 christos }
2574 1.1 christos
2575 1.1 christos /* Implementation of emit_ops method "emit_log_not". */
2576 1.1 christos
2577 1.1 christos static void
2578 1.1 christos aarch64_emit_log_not (void)
2579 1.1 christos {
2580 1.1 christos uint32_t buf[16];
2581 1.1 christos uint32_t *p = buf;
2582 1.1 christos
2583 1.1 christos /* If the top of the stack is 0, replace it with 1. Else replace it with
2584 1.1 christos 0. */
2585 1.1 christos
2586 1.1 christos p += emit_cmp (p, x0, immediate_operand (0));
2587 1.1 christos p += emit_cset (p, x0, EQ);
2588 1.1 christos
2589 1.1 christos emit_ops_insns (buf, p - buf);
2590 1.1 christos }
2591 1.1 christos
2592 1.1 christos /* Implementation of emit_ops method "emit_bit_and". */
2593 1.1 christos
2594 1.1 christos static void
2595 1.1 christos aarch64_emit_bit_and (void)
2596 1.1 christos {
2597 1.1 christos uint32_t buf[16];
2598 1.1 christos uint32_t *p = buf;
2599 1.1 christos
2600 1.1 christos p += emit_pop (p, x1);
2601 1.1 christos p += emit_and (p, x0, x0, x1);
2602 1.1 christos
2603 1.1 christos emit_ops_insns (buf, p - buf);
2604 1.1 christos }
2605 1.1 christos
2606 1.1 christos /* Implementation of emit_ops method "emit_bit_or". */
2607 1.1 christos
2608 1.1 christos static void
2609 1.1 christos aarch64_emit_bit_or (void)
2610 1.1 christos {
2611 1.1 christos uint32_t buf[16];
2612 1.1 christos uint32_t *p = buf;
2613 1.1 christos
2614 1.1 christos p += emit_pop (p, x1);
2615 1.1 christos p += emit_orr (p, x0, x0, x1);
2616 1.1 christos
2617 1.1 christos emit_ops_insns (buf, p - buf);
2618 1.1 christos }
2619 1.1 christos
2620 1.1 christos /* Implementation of emit_ops method "emit_bit_xor". */
2621 1.1 christos
2622 1.1 christos static void
2623 1.1 christos aarch64_emit_bit_xor (void)
2624 1.1 christos {
2625 1.1 christos uint32_t buf[16];
2626 1.1 christos uint32_t *p = buf;
2627 1.1 christos
2628 1.1 christos p += emit_pop (p, x1);
2629 1.1 christos p += emit_eor (p, x0, x0, x1);
2630 1.1 christos
2631 1.1 christos emit_ops_insns (buf, p - buf);
2632 1.1 christos }
2633 1.1 christos
2634 1.1 christos /* Implementation of emit_ops method "emit_bit_not". */
2635 1.1 christos
2636 1.1 christos static void
2637 1.1 christos aarch64_emit_bit_not (void)
2638 1.1 christos {
2639 1.1 christos uint32_t buf[16];
2640 1.1 christos uint32_t *p = buf;
2641 1.1 christos
2642 1.1 christos p += emit_mvn (p, x0, x0);
2643 1.1 christos
2644 1.1 christos emit_ops_insns (buf, p - buf);
2645 1.1 christos }
2646 1.1 christos
2647 1.1 christos /* Implementation of emit_ops method "emit_equal". */
2648 1.1 christos
2649 1.1 christos static void
2650 1.1 christos aarch64_emit_equal (void)
2651 1.1 christos {
2652 1.1 christos uint32_t buf[16];
2653 1.1 christos uint32_t *p = buf;
2654 1.1 christos
2655 1.1 christos p += emit_pop (p, x1);
2656 1.1 christos p += emit_cmp (p, x0, register_operand (x1));
2657 1.1 christos p += emit_cset (p, x0, EQ);
2658 1.1 christos
2659 1.1 christos emit_ops_insns (buf, p - buf);
2660 1.1 christos }
2661 1.1 christos
2662 1.1 christos /* Implementation of emit_ops method "emit_less_signed". */
2663 1.1 christos
2664 1.1 christos static void
2665 1.1 christos aarch64_emit_less_signed (void)
2666 1.1 christos {
2667 1.1 christos uint32_t buf[16];
2668 1.1 christos uint32_t *p = buf;
2669 1.1 christos
2670 1.1 christos p += emit_pop (p, x1);
2671 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
2672 1.1 christos p += emit_cset (p, x0, LT);
2673 1.1 christos
2674 1.1 christos emit_ops_insns (buf, p - buf);
2675 1.1 christos }
2676 1.1 christos
2677 1.1 christos /* Implementation of emit_ops method "emit_less_unsigned". */
2678 1.1 christos
2679 1.1 christos static void
2680 1.1 christos aarch64_emit_less_unsigned (void)
2681 1.1 christos {
2682 1.1 christos uint32_t buf[16];
2683 1.1 christos uint32_t *p = buf;
2684 1.1 christos
2685 1.1 christos p += emit_pop (p, x1);
2686 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
2687 1.1 christos p += emit_cset (p, x0, LO);
2688 1.1 christos
2689 1.1 christos emit_ops_insns (buf, p - buf);
2690 1.1 christos }
2691 1.1 christos
2692 1.1 christos /* Implementation of emit_ops method "emit_ref". */
2693 1.1 christos
2694 1.1 christos static void
2695 1.1 christos aarch64_emit_ref (int size)
2696 1.1 christos {
2697 1.1 christos uint32_t buf[16];
2698 1.1 christos uint32_t *p = buf;
2699 1.1 christos
2700 1.1 christos switch (size)
2701 1.1 christos {
2702 1.1 christos case 1:
2703 1.1 christos p += emit_ldrb (p, w0, x0, offset_memory_operand (0));
2704 1.1 christos break;
2705 1.1 christos case 2:
2706 1.1 christos p += emit_ldrh (p, w0, x0, offset_memory_operand (0));
2707 1.1 christos break;
2708 1.1 christos case 4:
2709 1.1 christos p += emit_ldr (p, w0, x0, offset_memory_operand (0));
2710 1.1 christos break;
2711 1.1 christos case 8:
2712 1.1 christos p += emit_ldr (p, x0, x0, offset_memory_operand (0));
2713 1.1 christos break;
2714 1.1 christos default:
2715 1.1 christos /* Unknown size, bail on compilation. */
2716 1.1 christos emit_error = 1;
2717 1.1 christos break;
2718 1.1 christos }
2719 1.1 christos
2720 1.1 christos emit_ops_insns (buf, p - buf);
2721 1.1 christos }
2722 1.1 christos
2723 1.1 christos /* Implementation of emit_ops method "emit_if_goto". */
2724 1.1 christos
2725 1.1 christos static void
2726 1.1 christos aarch64_emit_if_goto (int *offset_p, int *size_p)
2727 1.1 christos {
2728 1.1 christos uint32_t buf[16];
2729 1.1 christos uint32_t *p = buf;
2730 1.1 christos
2731 1.1 christos /* The Z flag is set or cleared here. */
2732 1.1 christos p += emit_cmp (p, x0, immediate_operand (0));
2733 1.1 christos /* This instruction must not change the Z flag. */
2734 1.1 christos p += emit_pop (p, x0);
2735 1.1 christos /* Branch over the next instruction if x0 == 0. */
2736 1.1 christos p += emit_bcond (p, EQ, 8);
2737 1.1 christos
2738 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
2739 1.1 christos if (offset_p)
2740 1.1 christos *offset_p = (p - buf) * 4;
2741 1.1 christos if (size_p)
2742 1.1 christos *size_p = 4;
2743 1.1 christos p += emit_nop (p);
2744 1.1 christos
2745 1.1 christos emit_ops_insns (buf, p - buf);
2746 1.1 christos }
2747 1.1 christos
2748 1.1 christos /* Implementation of emit_ops method "emit_goto". */
2749 1.1 christos
2750 1.1 christos static void
2751 1.1 christos aarch64_emit_goto (int *offset_p, int *size_p)
2752 1.1 christos {
2753 1.1 christos uint32_t buf[16];
2754 1.1 christos uint32_t *p = buf;
2755 1.1 christos
2756 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
2757 1.1 christos if (offset_p)
2758 1.1 christos *offset_p = 0;
2759 1.1 christos if (size_p)
2760 1.1 christos *size_p = 4;
2761 1.1 christos p += emit_nop (p);
2762 1.1 christos
2763 1.1 christos emit_ops_insns (buf, p - buf);
2764 1.1 christos }
2765 1.1 christos
2766 1.1 christos /* Implementation of emit_ops method "write_goto_address". */
2767 1.1 christos
2768 1.1 christos static void
2769 1.1 christos aarch64_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
2770 1.1 christos {
2771 1.1 christos uint32_t insn;
2772 1.1 christos
2773 1.1 christos emit_b (&insn, 0, to - from);
2774 1.1 christos append_insns (&from, 1, &insn);
2775 1.1 christos }
2776 1.1 christos
2777 1.1 christos /* Implementation of emit_ops method "emit_const". */
2778 1.1 christos
2779 1.1 christos static void
2780 1.1 christos aarch64_emit_const (LONGEST num)
2781 1.1 christos {
2782 1.1 christos uint32_t buf[16];
2783 1.1 christos uint32_t *p = buf;
2784 1.1 christos
2785 1.1 christos p += emit_mov_addr (p, x0, num);
2786 1.1 christos
2787 1.1 christos emit_ops_insns (buf, p - buf);
2788 1.1 christos }
2789 1.1 christos
2790 1.1 christos /* Implementation of emit_ops method "emit_call". */
2791 1.1 christos
2792 1.1 christos static void
2793 1.1 christos aarch64_emit_call (CORE_ADDR fn)
2794 1.1 christos {
2795 1.1 christos uint32_t buf[16];
2796 1.1 christos uint32_t *p = buf;
2797 1.1 christos
2798 1.1 christos p += emit_mov_addr (p, ip0, fn);
2799 1.1 christos p += emit_blr (p, ip0);
2800 1.1 christos
2801 1.1 christos emit_ops_insns (buf, p - buf);
2802 1.1 christos }
2803 1.1 christos
2804 1.1 christos /* Implementation of emit_ops method "emit_reg". */
2805 1.1 christos
2806 1.1 christos static void
2807 1.1 christos aarch64_emit_reg (int reg)
2808 1.1 christos {
2809 1.1 christos uint32_t buf[16];
2810 1.1 christos uint32_t *p = buf;
2811 1.1 christos
2812 1.1 christos /* Set x0 to unsigned char *regs. */
2813 1.1 christos p += emit_sub (p, x0, fp, immediate_operand (2 * 8));
2814 1.1 christos p += emit_ldr (p, x0, x0, offset_memory_operand (0));
2815 1.1 christos p += emit_mov (p, x1, immediate_operand (reg));
2816 1.1 christos
2817 1.1 christos emit_ops_insns (buf, p - buf);
2818 1.1 christos
2819 1.1 christos aarch64_emit_call (get_raw_reg_func_addr ());
2820 1.1 christos }
2821 1.1 christos
2822 1.1 christos /* Implementation of emit_ops method "emit_pop". */
2823 1.1 christos
2824 1.1 christos static void
2825 1.1 christos aarch64_emit_pop (void)
2826 1.1 christos {
2827 1.1 christos uint32_t buf[16];
2828 1.1 christos uint32_t *p = buf;
2829 1.1 christos
2830 1.1 christos p += emit_pop (p, x0);
2831 1.1 christos
2832 1.1 christos emit_ops_insns (buf, p - buf);
2833 1.1 christos }
2834 1.1 christos
2835 1.1 christos /* Implementation of emit_ops method "emit_stack_flush". */
2836 1.1 christos
2837 1.1 christos static void
2838 1.1 christos aarch64_emit_stack_flush (void)
2839 1.1 christos {
2840 1.1 christos uint32_t buf[16];
2841 1.1 christos uint32_t *p = buf;
2842 1.1 christos
2843 1.1 christos p += emit_push (p, x0);
2844 1.1 christos
2845 1.1 christos emit_ops_insns (buf, p - buf);
2846 1.1 christos }
2847 1.1 christos
2848 1.1 christos /* Implementation of emit_ops method "emit_zero_ext". */
2849 1.1 christos
2850 1.1 christos static void
2851 1.1 christos aarch64_emit_zero_ext (int arg)
2852 1.1 christos {
2853 1.1 christos uint32_t buf[16];
2854 1.1 christos uint32_t *p = buf;
2855 1.1 christos
2856 1.1 christos p += emit_ubfx (p, x0, x0, 0, arg);
2857 1.1 christos
2858 1.1 christos emit_ops_insns (buf, p - buf);
2859 1.1 christos }
2860 1.1 christos
2861 1.1 christos /* Implementation of emit_ops method "emit_swap". */
2862 1.1 christos
2863 1.1 christos static void
2864 1.1 christos aarch64_emit_swap (void)
2865 1.1 christos {
2866 1.1 christos uint32_t buf[16];
2867 1.1 christos uint32_t *p = buf;
2868 1.1 christos
2869 1.1 christos p += emit_ldr (p, x1, sp, offset_memory_operand (0 * 16));
2870 1.1 christos p += emit_str (p, x0, sp, offset_memory_operand (0 * 16));
2871 1.1 christos p += emit_mov (p, x0, register_operand (x1));
2872 1.1 christos
2873 1.1 christos emit_ops_insns (buf, p - buf);
2874 1.1 christos }
2875 1.1 christos
2876 1.1 christos /* Implementation of emit_ops method "emit_stack_adjust". */
2877 1.1 christos
2878 1.1 christos static void
2879 1.1 christos aarch64_emit_stack_adjust (int n)
2880 1.1 christos {
2881 1.1 christos /* This is not needed with our design. */
2882 1.1 christos uint32_t buf[16];
2883 1.1 christos uint32_t *p = buf;
2884 1.1 christos
2885 1.1 christos p += emit_add (p, sp, sp, immediate_operand (n * 16));
2886 1.1 christos
2887 1.1 christos emit_ops_insns (buf, p - buf);
2888 1.1 christos }
2889 1.1 christos
2890 1.1 christos /* Implementation of emit_ops method "emit_int_call_1". */
2891 1.1 christos
2892 1.1 christos static void
2893 1.1 christos aarch64_emit_int_call_1 (CORE_ADDR fn, int arg1)
2894 1.1 christos {
2895 1.1 christos uint32_t buf[16];
2896 1.1 christos uint32_t *p = buf;
2897 1.1 christos
2898 1.1 christos p += emit_mov (p, x0, immediate_operand (arg1));
2899 1.1 christos
2900 1.1 christos emit_ops_insns (buf, p - buf);
2901 1.1 christos
2902 1.1 christos aarch64_emit_call (fn);
2903 1.1 christos }
2904 1.1 christos
2905 1.1 christos /* Implementation of emit_ops method "emit_void_call_2". */
2906 1.1 christos
2907 1.1 christos static void
2908 1.1 christos aarch64_emit_void_call_2 (CORE_ADDR fn, int arg1)
2909 1.1 christos {
2910 1.1 christos uint32_t buf[16];
2911 1.1 christos uint32_t *p = buf;
2912 1.1 christos
2913 1.1 christos /* Push x0 on the stack. */
2914 1.1 christos aarch64_emit_stack_flush ();
2915 1.1 christos
2916 1.1 christos /* Setup arguments for the function call:
2917 1.1 christos
2918 1.1 christos x0: arg1
2919 1.1 christos x1: top of the stack
2920 1.1 christos
2921 1.1 christos MOV x1, x0
2922 1.1 christos MOV x0, #arg1 */
2923 1.1 christos
2924 1.1 christos p += emit_mov (p, x1, register_operand (x0));
2925 1.1 christos p += emit_mov (p, x0, immediate_operand (arg1));
2926 1.1 christos
2927 1.1 christos emit_ops_insns (buf, p - buf);
2928 1.1 christos
2929 1.1 christos aarch64_emit_call (fn);
2930 1.1 christos
2931 1.1 christos /* Restore x0. */
2932 1.1 christos aarch64_emit_pop ();
2933 1.1 christos }
2934 1.1 christos
2935 1.1 christos /* Implementation of emit_ops method "emit_eq_goto". */
2936 1.1 christos
2937 1.1 christos static void
2938 1.1 christos aarch64_emit_eq_goto (int *offset_p, int *size_p)
2939 1.1 christos {
2940 1.1 christos uint32_t buf[16];
2941 1.1 christos uint32_t *p = buf;
2942 1.1 christos
2943 1.1 christos p += emit_pop (p, x1);
2944 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
2945 1.1 christos /* Branch over the next instruction if x0 != x1. */
2946 1.1 christos p += emit_bcond (p, NE, 8);
2947 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
2948 1.1 christos if (offset_p)
2949 1.1 christos *offset_p = (p - buf) * 4;
2950 1.1 christos if (size_p)
2951 1.1 christos *size_p = 4;
2952 1.1 christos p += emit_nop (p);
2953 1.1 christos
2954 1.1 christos emit_ops_insns (buf, p - buf);
2955 1.1 christos }
2956 1.1 christos
2957 1.1 christos /* Implementation of emit_ops method "emit_ne_goto". */
2958 1.1 christos
2959 1.1 christos static void
2960 1.1 christos aarch64_emit_ne_goto (int *offset_p, int *size_p)
2961 1.1 christos {
2962 1.1 christos uint32_t buf[16];
2963 1.1 christos uint32_t *p = buf;
2964 1.1 christos
2965 1.1 christos p += emit_pop (p, x1);
2966 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
2967 1.1 christos /* Branch over the next instruction if x0 == x1. */
2968 1.1 christos p += emit_bcond (p, EQ, 8);
2969 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
2970 1.1 christos if (offset_p)
2971 1.1 christos *offset_p = (p - buf) * 4;
2972 1.1 christos if (size_p)
2973 1.1 christos *size_p = 4;
2974 1.1 christos p += emit_nop (p);
2975 1.1 christos
2976 1.1 christos emit_ops_insns (buf, p - buf);
2977 1.1 christos }
2978 1.1 christos
2979 1.1 christos /* Implementation of emit_ops method "emit_lt_goto". */
2980 1.1 christos
2981 1.1 christos static void
2982 1.1 christos aarch64_emit_lt_goto (int *offset_p, int *size_p)
2983 1.1 christos {
2984 1.1 christos uint32_t buf[16];
2985 1.1 christos uint32_t *p = buf;
2986 1.1 christos
2987 1.1 christos p += emit_pop (p, x1);
2988 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
2989 1.1 christos /* Branch over the next instruction if x0 >= x1. */
2990 1.1 christos p += emit_bcond (p, GE, 8);
2991 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
2992 1.1 christos if (offset_p)
2993 1.1 christos *offset_p = (p - buf) * 4;
2994 1.1 christos if (size_p)
2995 1.1 christos *size_p = 4;
2996 1.1 christos p += emit_nop (p);
2997 1.1 christos
2998 1.1 christos emit_ops_insns (buf, p - buf);
2999 1.1 christos }
3000 1.1 christos
3001 1.1 christos /* Implementation of emit_ops method "emit_le_goto". */
3002 1.1 christos
3003 1.1 christos static void
3004 1.1 christos aarch64_emit_le_goto (int *offset_p, int *size_p)
3005 1.1 christos {
3006 1.1 christos uint32_t buf[16];
3007 1.1 christos uint32_t *p = buf;
3008 1.1 christos
3009 1.1 christos p += emit_pop (p, x1);
3010 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
3011 1.1 christos /* Branch over the next instruction if x0 > x1. */
3012 1.1 christos p += emit_bcond (p, GT, 8);
3013 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
3014 1.1 christos if (offset_p)
3015 1.1 christos *offset_p = (p - buf) * 4;
3016 1.1 christos if (size_p)
3017 1.1 christos *size_p = 4;
3018 1.1 christos p += emit_nop (p);
3019 1.1 christos
3020 1.1 christos emit_ops_insns (buf, p - buf);
3021 1.1 christos }
3022 1.1 christos
3023 1.1 christos /* Implementation of emit_ops method "emit_gt_goto". */
3024 1.1 christos
3025 1.1 christos static void
3026 1.1 christos aarch64_emit_gt_goto (int *offset_p, int *size_p)
3027 1.1 christos {
3028 1.1 christos uint32_t buf[16];
3029 1.1 christos uint32_t *p = buf;
3030 1.1 christos
3031 1.1 christos p += emit_pop (p, x1);
3032 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
3033 1.1 christos /* Branch over the next instruction if x0 <= x1. */
3034 1.1 christos p += emit_bcond (p, LE, 8);
3035 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
3036 1.1 christos if (offset_p)
3037 1.1 christos *offset_p = (p - buf) * 4;
3038 1.1 christos if (size_p)
3039 1.1 christos *size_p = 4;
3040 1.1 christos p += emit_nop (p);
3041 1.1 christos
3042 1.1 christos emit_ops_insns (buf, p - buf);
3043 1.1 christos }
3044 1.1 christos
3045 1.1 christos /* Implementation of emit_ops method "emit_ge_got". */
3046 1.1 christos
3047 1.1 christos static void
3048 1.1 christos aarch64_emit_ge_got (int *offset_p, int *size_p)
3049 1.1 christos {
3050 1.1 christos uint32_t buf[16];
3051 1.1 christos uint32_t *p = buf;
3052 1.1 christos
3053 1.1 christos p += emit_pop (p, x1);
3054 1.1 christos p += emit_cmp (p, x1, register_operand (x0));
3055 1.1 christos /* Branch over the next instruction if x0 <= x1. */
3056 1.1 christos p += emit_bcond (p, LT, 8);
3057 1.1 christos /* The NOP instruction will be patched with an unconditional branch. */
3058 1.1 christos if (offset_p)
3059 1.1 christos *offset_p = (p - buf) * 4;
3060 1.1 christos if (size_p)
3061 1.1 christos *size_p = 4;
3062 1.1 christos p += emit_nop (p);
3063 1.1 christos
3064 1.1 christos emit_ops_insns (buf, p - buf);
3065 1.1 christos }
3066 1.1 christos
3067 1.1 christos static struct emit_ops aarch64_emit_ops_impl =
3068 1.1 christos {
3069 1.1 christos aarch64_emit_prologue,
3070 1.1 christos aarch64_emit_epilogue,
3071 1.1 christos aarch64_emit_add,
3072 1.1 christos aarch64_emit_sub,
3073 1.1 christos aarch64_emit_mul,
3074 1.1 christos aarch64_emit_lsh,
3075 1.1 christos aarch64_emit_rsh_signed,
3076 1.1 christos aarch64_emit_rsh_unsigned,
3077 1.1 christos aarch64_emit_ext,
3078 1.1 christos aarch64_emit_log_not,
3079 1.1 christos aarch64_emit_bit_and,
3080 1.1 christos aarch64_emit_bit_or,
3081 1.1 christos aarch64_emit_bit_xor,
3082 1.1 christos aarch64_emit_bit_not,
3083 1.1 christos aarch64_emit_equal,
3084 1.1 christos aarch64_emit_less_signed,
3085 1.1 christos aarch64_emit_less_unsigned,
3086 1.1 christos aarch64_emit_ref,
3087 1.1 christos aarch64_emit_if_goto,
3088 1.1 christos aarch64_emit_goto,
3089 1.1 christos aarch64_write_goto_address,
3090 1.1 christos aarch64_emit_const,
3091 1.1 christos aarch64_emit_call,
3092 1.1 christos aarch64_emit_reg,
3093 1.1 christos aarch64_emit_pop,
3094 1.1 christos aarch64_emit_stack_flush,
3095 1.1 christos aarch64_emit_zero_ext,
3096 1.1 christos aarch64_emit_swap,
3097 1.1 christos aarch64_emit_stack_adjust,
3098 1.1 christos aarch64_emit_int_call_1,
3099 1.1 christos aarch64_emit_void_call_2,
3100 1.1 christos aarch64_emit_eq_goto,
3101 1.1 christos aarch64_emit_ne_goto,
3102 1.1 christos aarch64_emit_lt_goto,
3103 1.1 christos aarch64_emit_le_goto,
3104 1.1 christos aarch64_emit_gt_goto,
3105 1.1 christos aarch64_emit_ge_got,
3106 1.1 christos };
3107 1.1 christos
3108 1.1 christos /* Implementation of target ops method "emit_ops". */
3109 1.1 christos
3110 1.1 christos emit_ops *
3111 1.1 christos aarch64_target::emit_ops ()
3112 1.1 christos {
3113 1.1 christos return &aarch64_emit_ops_impl;
3114 1.1 christos }
3115 1.1 christos
3116 1.1 christos /* Implementation of target ops method
3117 1.1 christos "get_min_fast_tracepoint_insn_len". */
3118 1.1 christos
3119 1.1 christos int
3120 1.1 christos aarch64_target::get_min_fast_tracepoint_insn_len ()
3121 1.1 christos {
3122 1.1 christos return 4;
3123 1.1 christos }
3124 1.1 christos
3125 1.1 christos /* Implementation of linux target ops method "low_supports_range_stepping". */
3126 1.1 christos
3127 1.1 christos bool
3128 1.1 christos aarch64_target::low_supports_range_stepping ()
3129 1.1 christos {
3130 1.1 christos return true;
3131 1.1 christos }
3132 1.1 christos
3133 1.1 christos /* Implementation of target ops method "sw_breakpoint_from_kind". */
3134 1.1 christos
3135 1.1 christos const gdb_byte *
3136 1.1 christos aarch64_target::sw_breakpoint_from_kind (int kind, int *size)
3137 1.1 christos {
3138 1.1 christos if (is_64bit_tdesc ())
3139 1.1 christos {
3140 1.1 christos *size = aarch64_breakpoint_len;
3141 1.1 christos return aarch64_breakpoint;
3142 1.1 christos }
3143 1.1 christos else
3144 1.1 christos return arm_sw_breakpoint_from_kind (kind, size);
3145 1.1 christos }
3146 1.1 christos
3147 1.1 christos /* Implementation of target ops method "breakpoint_kind_from_pc". */
3148 1.1 christos
3149 1.1 christos int
3150 1.1 christos aarch64_target::breakpoint_kind_from_pc (CORE_ADDR *pcptr)
3151 1.1 christos {
3152 1.1 christos if (is_64bit_tdesc ())
3153 1.1 christos return aarch64_breakpoint_len;
3154 1.1 christos else
3155 1.1 christos return arm_breakpoint_kind_from_pc (pcptr);
3156 1.1 christos }
3157 1.1 christos
3158 1.1 christos /* Implementation of the target ops method
3159 1.1 christos "breakpoint_kind_from_current_state". */
3160 1.1 christos
3161 1.1 christos int
3162 1.1 christos aarch64_target::breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
3163 1.1 christos {
3164 1.1 christos if (is_64bit_tdesc ())
3165 1.1 christos return aarch64_breakpoint_len;
3166 1.1 christos else
3167 1.1 christos return arm_breakpoint_kind_from_current_state (pcptr);
3168 1.1 christos }
3169 1.1 christos
3170 1.1 christos /* The linux target ops object. */
3171 1.1 christos
3172 1.1 christos linux_process_target *the_linux_target = &the_aarch64_target;
3173 1.1 christos
3174 1.1 christos void
3175 1.1 christos initialize_low_arch (void)
3176 1.1 christos {
3177 1.1 christos initialize_low_arch_aarch32 ();
3178 1.1 christos
3179 1.1 christos initialize_regsets_info (&aarch64_regsets_info);
3180 1.1 christos initialize_regsets_info (&aarch64_sve_regsets_info);
3181 1.1 christos }
3182