[PATCH 7/57][Arm][GAS] Add support for MVE instructions: vstr/vldr
[binutils-gdb.git] / gdb / arm-nbsd-nat.c
blob2a83553a3fe23e07e07fe64cd24e9fa206a68307
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2019 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "inferior.h"
23 #include "regcache.h"
24 #include "target.h"
25 #include <sys/types.h>
26 #include <sys/ptrace.h>
27 #include <machine/reg.h>
28 #include <machine/frame.h>
30 #include "arm-tdep.h"
31 #include "inf-ptrace.h"
33 class arm_netbsd_nat_target final : public inf_ptrace_target
35 public:
36 /* Add our register access methods. */
37 void fetch_registers (struct regcache *, int) override;
38 void store_registers (struct regcache *, int) override;
41 static arm_netbsd_nat_target the_arm_netbsd_nat_target;
43 extern int arm_apcs_32;
45 static void
46 arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
48 int regno;
49 CORE_ADDR r_pc;
51 /* Integer registers. */
52 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
53 regcache->raw_supply (regno, (char *) &gregset->r[regno]);
55 regcache->raw_supply (ARM_SP_REGNUM, (char *) &gregset->r_sp);
56 regcache->raw_supply (ARM_LR_REGNUM, (char *) &gregset->r_lr);
57 /* This is ok: we're running native... */
58 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
59 regcache->raw_supply (ARM_PC_REGNUM, (char *) &r_pc);
61 if (arm_apcs_32)
62 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
63 else
64 regcache->raw_supply (ARM_PS_REGNUM, (char *) &gregset->r_pc);
67 static void
68 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
70 int regno;
72 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
73 regcache->raw_supply (regno,
74 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
76 regcache->raw_supply (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
79 static void
80 fetch_register (struct regcache *regcache, int regno)
82 struct reg inferior_registers;
83 int ret;
85 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
86 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
88 if (ret < 0)
90 warning (_("unable to fetch general register"));
91 return;
94 switch (regno)
96 case ARM_SP_REGNUM:
97 regcache->raw_supply (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
98 break;
100 case ARM_LR_REGNUM:
101 regcache->raw_supply (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
102 break;
104 case ARM_PC_REGNUM:
105 /* This is ok: we're running native... */
106 inferior_registers.r_pc = gdbarch_addr_bits_remove
107 (regcache->arch (),
108 inferior_registers.r_pc);
109 regcache->raw_supply (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
110 break;
112 case ARM_PS_REGNUM:
113 if (arm_apcs_32)
114 regcache->raw_supply (ARM_PS_REGNUM,
115 (char *) &inferior_registers.r_cpsr);
116 else
117 regcache->raw_supply (ARM_PS_REGNUM,
118 (char *) &inferior_registers.r_pc);
119 break;
121 default:
122 regcache->raw_supply (regno, (char *) &inferior_registers.r[regno]);
123 break;
127 static void
128 fetch_regs (struct regcache *regcache)
130 struct reg inferior_registers;
131 int ret;
132 int regno;
134 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
135 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
137 if (ret < 0)
139 warning (_("unable to fetch general registers"));
140 return;
143 arm_supply_gregset (regcache, &inferior_registers);
146 static void
147 fetch_fp_register (struct regcache *regcache, int regno)
149 struct fpreg inferior_fp_registers;
150 int ret;
152 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
153 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
155 if (ret < 0)
157 warning (_("unable to fetch floating-point register"));
158 return;
161 switch (regno)
163 case ARM_FPS_REGNUM:
164 regcache->raw_supply (ARM_FPS_REGNUM,
165 (char *) &inferior_fp_registers.fpr_fpsr);
166 break;
168 default:
169 regcache->raw_supply
170 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
171 break;
175 static void
176 fetch_fp_regs (struct regcache *regcache)
178 struct fpreg inferior_fp_registers;
179 int ret;
180 int regno;
182 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
183 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
185 if (ret < 0)
187 warning (_("unable to fetch general registers"));
188 return;
191 arm_supply_fparegset (regcache, &inferior_fp_registers);
194 void
195 arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
197 if (regno >= 0)
199 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
200 fetch_register (regcache, regno);
201 else
202 fetch_fp_register (regcache, regno);
204 else
206 fetch_regs (regcache);
207 fetch_fp_regs (regcache);
212 static void
213 store_register (const struct regcache *regcache, int regno)
215 struct gdbarch *gdbarch = regcache->arch ();
216 struct reg inferior_registers;
217 int ret;
219 ret = ptrace (PT_GETREGS, regcache->ptid ().pid (),
220 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
222 if (ret < 0)
224 warning (_("unable to fetch general registers"));
225 return;
228 switch (regno)
230 case ARM_SP_REGNUM:
231 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
232 break;
234 case ARM_LR_REGNUM:
235 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
236 break;
238 case ARM_PC_REGNUM:
239 if (arm_apcs_32)
240 regcache->raw_collect (ARM_PC_REGNUM,
241 (char *) &inferior_registers.r_pc);
242 else
244 unsigned pc_val;
246 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
248 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
249 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
250 (gdbarch, inferior_registers.r_pc);
251 inferior_registers.r_pc |= pc_val;
253 break;
255 case ARM_PS_REGNUM:
256 if (arm_apcs_32)
257 regcache->raw_collect (ARM_PS_REGNUM,
258 (char *) &inferior_registers.r_cpsr);
259 else
261 unsigned psr_val;
263 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
265 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
266 inferior_registers.r_pc = gdbarch_addr_bits_remove
267 (gdbarch, inferior_registers.r_pc);
268 inferior_registers.r_pc |= psr_val;
270 break;
272 default:
273 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
274 break;
277 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
278 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
280 if (ret < 0)
281 warning (_("unable to write register %d to inferior"), regno);
284 static void
285 store_regs (const struct regcache *regcache)
287 struct gdbarch *gdbarch = regcache->arch ();
288 struct reg inferior_registers;
289 int ret;
290 int regno;
293 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
294 regcache->raw_collect (regno, (char *) &inferior_registers.r[regno]);
296 regcache->raw_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
297 regcache->raw_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
299 if (arm_apcs_32)
301 regcache->raw_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
302 regcache->raw_collect (ARM_PS_REGNUM,
303 (char *) &inferior_registers.r_cpsr);
305 else
307 unsigned pc_val;
308 unsigned psr_val;
310 regcache->raw_collect (ARM_PC_REGNUM, (char *) &pc_val);
311 regcache->raw_collect (ARM_PS_REGNUM, (char *) &psr_val);
313 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
314 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
316 inferior_registers.r_pc = pc_val | psr_val;
319 ret = ptrace (PT_SETREGS, regcache->ptid ().pid (),
320 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
322 if (ret < 0)
323 warning (_("unable to store general registers"));
326 static void
327 store_fp_register (const struct regcache *regcache, int regno)
329 struct fpreg inferior_fp_registers;
330 int ret;
332 ret = ptrace (PT_GETFPREGS, regcache->ptid ().pid (),
333 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
335 if (ret < 0)
337 warning (_("unable to fetch floating-point registers"));
338 return;
341 switch (regno)
343 case ARM_FPS_REGNUM:
344 regcache->raw_collect (ARM_FPS_REGNUM,
345 (char *) &inferior_fp_registers.fpr_fpsr);
346 break;
348 default:
349 regcache->raw_collect
350 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
351 break;
354 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
355 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
357 if (ret < 0)
358 warning (_("unable to write register %d to inferior"), regno);
361 static void
362 store_fp_regs (const struct regcache *regcache)
364 struct fpreg inferior_fp_registers;
365 int ret;
366 int regno;
369 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
370 regcache->raw_collect
371 (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
373 regcache->raw_collect (ARM_FPS_REGNUM,
374 (char *) &inferior_fp_registers.fpr_fpsr);
376 ret = ptrace (PT_SETFPREGS, regcache->ptid ().pid (),
377 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
379 if (ret < 0)
380 warning (_("unable to store floating-point registers"));
383 void
384 arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
386 if (regno >= 0)
388 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
389 store_register (regcache, regno);
390 else
391 store_fp_register (regcache, regno);
393 else
395 store_regs (regcache);
396 store_fp_regs (regcache);
400 static void
401 fetch_elfcore_registers (struct regcache *regcache,
402 char *core_reg_sect, unsigned core_reg_size,
403 int which, CORE_ADDR ignore)
405 struct reg gregset;
406 struct fpreg fparegset;
408 switch (which)
410 case 0: /* Integer registers. */
411 if (core_reg_size != sizeof (struct reg))
412 warning (_("wrong size of register set in core file"));
413 else
415 /* The memcpy may be unnecessary, but we can't really be sure
416 of the alignment of the data in the core file. */
417 memcpy (&gregset, core_reg_sect, sizeof (gregset));
418 arm_supply_gregset (regcache, &gregset);
420 break;
422 case 2:
423 if (core_reg_size != sizeof (struct fpreg))
424 warning (_("wrong size of FPA register set in core file"));
425 else
427 /* The memcpy may be unnecessary, but we can't really be sure
428 of the alignment of the data in the core file. */
429 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
430 arm_supply_fparegset (regcache, &fparegset);
432 break;
434 default:
435 /* Don't know what kind of register request this is; just ignore it. */
436 break;
440 static struct core_fns arm_netbsd_elfcore_fns =
442 bfd_target_elf_flavour, /* core_flovour. */
443 default_check_format, /* check_format. */
444 default_core_sniffer, /* core_sniffer. */
445 fetch_elfcore_registers, /* core_read_registers. */
446 NULL
449 void
450 _initialize_arm_netbsd_nat (void)
452 add_inf_child_target (&the_arm_netbsd_nat_target);
454 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);