Remove fake operand handling for extended mnemonics.
[binutils-gdb.git] / gdb / arm-nbsd-nat.c
blob3a1ddeaf4e859f68f9f06a0288420e8123f67a94
1 /* Native-dependent code for BSD Unix running on ARM's, for GDB.
3 Copyright (C) 1988-2018 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 (regcache, regno, (char *) &gregset->r[regno]);
55 regcache_raw_supply (regcache, ARM_SP_REGNUM,
56 (char *) &gregset->r_sp);
57 regcache_raw_supply (regcache, ARM_LR_REGNUM,
58 (char *) &gregset->r_lr);
59 /* This is ok: we're running native... */
60 r_pc = gdbarch_addr_bits_remove (regcache->arch (), gregset->r_pc);
61 regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
63 if (arm_apcs_32)
64 regcache_raw_supply (regcache, ARM_PS_REGNUM,
65 (char *) &gregset->r_cpsr);
66 else
67 regcache_raw_supply (regcache, ARM_PS_REGNUM,
68 (char *) &gregset->r_pc);
71 static void
72 arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
74 int regno;
76 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
77 regcache_raw_supply (regcache, regno,
78 (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
80 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
81 (char *) &fparegset->fpr_fpsr);
84 static void
85 fetch_register (struct regcache *regcache, int regno)
87 struct reg inferior_registers;
88 int ret;
90 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
91 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
93 if (ret < 0)
95 warning (_("unable to fetch general register"));
96 return;
99 switch (regno)
101 case ARM_SP_REGNUM:
102 regcache_raw_supply (regcache, ARM_SP_REGNUM,
103 (char *) &inferior_registers.r_sp);
104 break;
106 case ARM_LR_REGNUM:
107 regcache_raw_supply (regcache, ARM_LR_REGNUM,
108 (char *) &inferior_registers.r_lr);
109 break;
111 case ARM_PC_REGNUM:
112 /* This is ok: we're running native... */
113 inferior_registers.r_pc = gdbarch_addr_bits_remove
114 (regcache->arch (),
115 inferior_registers.r_pc);
116 regcache_raw_supply (regcache, ARM_PC_REGNUM,
117 (char *) &inferior_registers.r_pc);
118 break;
120 case ARM_PS_REGNUM:
121 if (arm_apcs_32)
122 regcache_raw_supply (regcache, ARM_PS_REGNUM,
123 (char *) &inferior_registers.r_cpsr);
124 else
125 regcache_raw_supply (regcache, ARM_PS_REGNUM,
126 (char *) &inferior_registers.r_pc);
127 break;
129 default:
130 regcache_raw_supply (regcache, regno,
131 (char *) &inferior_registers.r[regno]);
132 break;
136 static void
137 fetch_regs (struct regcache *regcache)
139 struct reg inferior_registers;
140 int ret;
141 int regno;
143 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
144 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
146 if (ret < 0)
148 warning (_("unable to fetch general registers"));
149 return;
152 arm_supply_gregset (regcache, &inferior_registers);
155 static void
156 fetch_fp_register (struct regcache *regcache, int regno)
158 struct fpreg inferior_fp_registers;
159 int ret;
161 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
162 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
164 if (ret < 0)
166 warning (_("unable to fetch floating-point register"));
167 return;
170 switch (regno)
172 case ARM_FPS_REGNUM:
173 regcache_raw_supply (regcache, ARM_FPS_REGNUM,
174 (char *) &inferior_fp_registers.fpr_fpsr);
175 break;
177 default:
178 regcache_raw_supply (regcache, regno,
179 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
180 break;
184 static void
185 fetch_fp_regs (struct regcache *regcache)
187 struct fpreg inferior_fp_registers;
188 int ret;
189 int regno;
191 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
192 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
194 if (ret < 0)
196 warning (_("unable to fetch general registers"));
197 return;
200 arm_supply_fparegset (regcache, &inferior_fp_registers);
203 void
204 arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
206 if (regno >= 0)
208 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
209 fetch_register (regcache, regno);
210 else
211 fetch_fp_register (regcache, regno);
213 else
215 fetch_regs (regcache);
216 fetch_fp_regs (regcache);
221 static void
222 store_register (const struct regcache *regcache, int regno)
224 struct gdbarch *gdbarch = regcache->arch ();
225 struct reg inferior_registers;
226 int ret;
228 ret = ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
229 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
231 if (ret < 0)
233 warning (_("unable to fetch general registers"));
234 return;
237 switch (regno)
239 case ARM_SP_REGNUM:
240 regcache_raw_collect (regcache, ARM_SP_REGNUM,
241 (char *) &inferior_registers.r_sp);
242 break;
244 case ARM_LR_REGNUM:
245 regcache_raw_collect (regcache, ARM_LR_REGNUM,
246 (char *) &inferior_registers.r_lr);
247 break;
249 case ARM_PC_REGNUM:
250 if (arm_apcs_32)
251 regcache_raw_collect (regcache, ARM_PC_REGNUM,
252 (char *) &inferior_registers.r_pc);
253 else
255 unsigned pc_val;
257 regcache_raw_collect (regcache, ARM_PC_REGNUM,
258 (char *) &pc_val);
260 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
261 inferior_registers.r_pc ^= gdbarch_addr_bits_remove
262 (gdbarch, inferior_registers.r_pc);
263 inferior_registers.r_pc |= pc_val;
265 break;
267 case ARM_PS_REGNUM:
268 if (arm_apcs_32)
269 regcache_raw_collect (regcache, ARM_PS_REGNUM,
270 (char *) &inferior_registers.r_cpsr);
271 else
273 unsigned psr_val;
275 regcache_raw_collect (regcache, ARM_PS_REGNUM,
276 (char *) &psr_val);
278 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
279 inferior_registers.r_pc = gdbarch_addr_bits_remove
280 (gdbarch, inferior_registers.r_pc);
281 inferior_registers.r_pc |= psr_val;
283 break;
285 default:
286 regcache_raw_collect (regcache, regno,
287 (char *) &inferior_registers.r[regno]);
288 break;
291 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
292 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
294 if (ret < 0)
295 warning (_("unable to write register %d to inferior"), regno);
298 static void
299 store_regs (const struct regcache *regcache)
301 struct gdbarch *gdbarch = regcache->arch ();
302 struct reg inferior_registers;
303 int ret;
304 int regno;
307 for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
308 regcache_raw_collect (regcache, regno,
309 (char *) &inferior_registers.r[regno]);
311 regcache_raw_collect (regcache, ARM_SP_REGNUM,
312 (char *) &inferior_registers.r_sp);
313 regcache_raw_collect (regcache, ARM_LR_REGNUM,
314 (char *) &inferior_registers.r_lr);
316 if (arm_apcs_32)
318 regcache_raw_collect (regcache, ARM_PC_REGNUM,
319 (char *) &inferior_registers.r_pc);
320 regcache_raw_collect (regcache, ARM_PS_REGNUM,
321 (char *) &inferior_registers.r_cpsr);
323 else
325 unsigned pc_val;
326 unsigned psr_val;
328 regcache_raw_collect (regcache, ARM_PC_REGNUM,
329 (char *) &pc_val);
330 regcache_raw_collect (regcache, ARM_PS_REGNUM,
331 (char *) &psr_val);
333 pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
334 psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
336 inferior_registers.r_pc = pc_val | psr_val;
339 ret = ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
340 (PTRACE_TYPE_ARG3) &inferior_registers, 0);
342 if (ret < 0)
343 warning (_("unable to store general registers"));
346 static void
347 store_fp_register (const struct regcache *regcache, int regno)
349 struct fpreg inferior_fp_registers;
350 int ret;
352 ret = ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
353 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
355 if (ret < 0)
357 warning (_("unable to fetch floating-point registers"));
358 return;
361 switch (regno)
363 case ARM_FPS_REGNUM:
364 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
365 (char *) &inferior_fp_registers.fpr_fpsr);
366 break;
368 default:
369 regcache_raw_collect (regcache, regno,
370 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
371 break;
374 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
375 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
377 if (ret < 0)
378 warning (_("unable to write register %d to inferior"), regno);
381 static void
382 store_fp_regs (const struct regcache *regcache)
384 struct fpreg inferior_fp_registers;
385 int ret;
386 int regno;
389 for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
390 regcache_raw_collect (regcache, regno,
391 (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
393 regcache_raw_collect (regcache, ARM_FPS_REGNUM,
394 (char *) &inferior_fp_registers.fpr_fpsr);
396 ret = ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
397 (PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
399 if (ret < 0)
400 warning (_("unable to store floating-point registers"));
403 void
404 arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
406 if (regno >= 0)
408 if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
409 store_register (regcache, regno);
410 else
411 store_fp_register (regcache, regno);
413 else
415 store_regs (regcache);
416 store_fp_regs (regcache);
420 static void
421 fetch_elfcore_registers (struct regcache *regcache,
422 char *core_reg_sect, unsigned core_reg_size,
423 int which, CORE_ADDR ignore)
425 struct reg gregset;
426 struct fpreg fparegset;
428 switch (which)
430 case 0: /* Integer registers. */
431 if (core_reg_size != sizeof (struct reg))
432 warning (_("wrong size of register set in core file"));
433 else
435 /* The memcpy may be unnecessary, but we can't really be sure
436 of the alignment of the data in the core file. */
437 memcpy (&gregset, core_reg_sect, sizeof (gregset));
438 arm_supply_gregset (regcache, &gregset);
440 break;
442 case 2:
443 if (core_reg_size != sizeof (struct fpreg))
444 warning (_("wrong size of FPA register set in core file"));
445 else
447 /* The memcpy may be unnecessary, but we can't really be sure
448 of the alignment of the data in the core file. */
449 memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
450 arm_supply_fparegset (regcache, &fparegset);
452 break;
454 default:
455 /* Don't know what kind of register request this is; just ignore it. */
456 break;
460 static struct core_fns arm_netbsd_elfcore_fns =
462 bfd_target_elf_flavour, /* core_flovour. */
463 default_check_format, /* check_format. */
464 default_core_sniffer, /* core_sniffer. */
465 fetch_elfcore_registers, /* core_read_registers. */
466 NULL
469 void
470 _initialize_arm_netbsd_nat (void)
472 add_inf_child_target (&the_arm_netbsd_nat_target);
474 deprecated_add_core_fns (&arm_netbsd_elfcore_fns);