Constify strings in tracepoint.c, lookup_cmd and the completers.
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-ppc-low.c
CommitLineData
0a30fbc4
DJ
1/* GNU/Linux/PowerPC specific low level interface, for the remote server for
2 GDB.
28e7fd62 3 Copyright (C) 1995-2013 Free Software Foundation, Inc.
0a30fbc4
DJ
4
5 This file is part of GDB.
6
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
0a30fbc4
DJ
10 (at your option) any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0a30fbc4
DJ
19
20#include "server.h"
58caa3dc 21#include "linux-low.h"
0a30fbc4 22
b6430ec3 23#include <elf.h>
0a30fbc4
DJ
24#include <asm/ptrace.h>
25
b6430ec3 26/* These are in <asm/cputable.h> in current kernels. */
677c5bb1 27#define PPC_FEATURE_HAS_VSX 0x00000080
b6430ec3
UW
28#define PPC_FEATURE_HAS_ALTIVEC 0x10000000
29#define PPC_FEATURE_HAS_SPE 0x00800000
f4d9bade 30#define PPC_FEATURE_CELL 0x00010000
f04c6d38 31#define PPC_FEATURE_HAS_DFP 0x00000400
b6430ec3
UW
32
33static unsigned long ppc_hwcap;
34
35
7284e1be
UW
36/* Defined in auto-generated file powerpc-32l.c. */
37void init_registers_powerpc_32l (void);
38/* Defined in auto-generated file powerpc-altivec32l.c. */
39void init_registers_powerpc_altivec32l (void);
f4d9bade
UW
40/* Defined in auto-generated file powerpc-cell32l.c. */
41void init_registers_powerpc_cell32l (void);
677c5bb1
LM
42/* Defined in auto-generated file powerpc-vsx32l.c. */
43void init_registers_powerpc_vsx32l (void);
2c4ad781
TJB
44/* Defined in auto-generated file powerpc-isa205-32l.c. */
45void init_registers_powerpc_isa205_32l (void);
46/* Defined in auto-generated file powerpc-isa205-altivec32l.c. */
47void init_registers_powerpc_isa205_altivec32l (void);
48/* Defined in auto-generated file powerpc-isa205-vsx32l.c. */
49void init_registers_powerpc_isa205_vsx32l (void);
7284e1be
UW
50/* Defined in auto-generated file powerpc-e500l.c. */
51void init_registers_powerpc_e500l (void);
52/* Defined in auto-generated file powerpc-64l.c. */
53void init_registers_powerpc_64l (void);
54/* Defined in auto-generated file powerpc-altivec64l.c. */
55void init_registers_powerpc_altivec64l (void);
f4d9bade
UW
56/* Defined in auto-generated file powerpc-cell64l.c. */
57void init_registers_powerpc_cell64l (void);
677c5bb1
LM
58/* Defined in auto-generated file powerpc-vsx64l.c. */
59void init_registers_powerpc_vsx64l (void);
2c4ad781
TJB
60/* Defined in auto-generated file powerpc-isa205-64l.c. */
61void init_registers_powerpc_isa205_64l (void);
62/* Defined in auto-generated file powerpc-isa205-altivec64l.c. */
63void init_registers_powerpc_isa205_altivec64l (void);
64/* Defined in auto-generated file powerpc-isa205-vsx64l.c. */
65void init_registers_powerpc_isa205_vsx64l (void);
7284e1be
UW
66
67#define ppc_num_regs 73
68
69/* This sometimes isn't defined. */
70#ifndef PT_ORIG_R3
71#define PT_ORIG_R3 34
72#endif
73#ifndef PT_TRAP
74#define PT_TRAP 40
75#endif
0a30fbc4 76
5b0a002e
UW
77#ifdef __powerpc64__
78/* We use a constant for FPSCR instead of PT_FPSCR, because
79 many shipped PPC64 kernels had the wrong value in ptrace.h. */
80static int ppc_regmap[] =
81 {PT_R0 * 8, PT_R1 * 8, PT_R2 * 8, PT_R3 * 8,
82 PT_R4 * 8, PT_R5 * 8, PT_R6 * 8, PT_R7 * 8,
83 PT_R8 * 8, PT_R9 * 8, PT_R10 * 8, PT_R11 * 8,
84 PT_R12 * 8, PT_R13 * 8, PT_R14 * 8, PT_R15 * 8,
85 PT_R16 * 8, PT_R17 * 8, PT_R18 * 8, PT_R19 * 8,
86 PT_R20 * 8, PT_R21 * 8, PT_R22 * 8, PT_R23 * 8,
87 PT_R24 * 8, PT_R25 * 8, PT_R26 * 8, PT_R27 * 8,
88 PT_R28 * 8, PT_R29 * 8, PT_R30 * 8, PT_R31 * 8,
89 PT_FPR0*8, PT_FPR0*8 + 8, PT_FPR0*8+16, PT_FPR0*8+24,
90 PT_FPR0*8+32, PT_FPR0*8+40, PT_FPR0*8+48, PT_FPR0*8+56,
91 PT_FPR0*8+64, PT_FPR0*8+72, PT_FPR0*8+80, PT_FPR0*8+88,
92 PT_FPR0*8+96, PT_FPR0*8+104, PT_FPR0*8+112, PT_FPR0*8+120,
93 PT_FPR0*8+128, PT_FPR0*8+136, PT_FPR0*8+144, PT_FPR0*8+152,
94 PT_FPR0*8+160, PT_FPR0*8+168, PT_FPR0*8+176, PT_FPR0*8+184,
95 PT_FPR0*8+192, PT_FPR0*8+200, PT_FPR0*8+208, PT_FPR0*8+216,
96 PT_FPR0*8+224, PT_FPR0*8+232, PT_FPR0*8+240, PT_FPR0*8+248,
97 PT_NIP * 8, PT_MSR * 8, PT_CCR * 8, PT_LNK * 8,
7284e1be
UW
98 PT_CTR * 8, PT_XER * 8, PT_FPR0*8 + 256,
99 PT_ORIG_R3 * 8, PT_TRAP * 8 };
5b0a002e 100#else
0a30fbc4 101/* Currently, don't check/send MQ. */
2ec06d2e 102static int ppc_regmap[] =
0a30fbc4
DJ
103 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
104 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
105 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
106 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
107 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
108 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
109 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
110 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
111 PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24,
112 PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56,
113 PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88,
114 PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120,
115 PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152,
116 PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184,
117 PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216,
118 PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248,
119 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
7284e1be
UW
120 PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4,
121 PT_ORIG_R3 * 4, PT_TRAP * 4
b6430ec3
UW
122 };
123
124static int ppc_regmap_e500[] =
125 {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4,
126 PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4,
127 PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4,
128 PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4,
129 PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4,
130 PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4,
131 PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4,
132 PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4,
133 -1, -1, -1, -1,
134 -1, -1, -1, -1,
135 -1, -1, -1, -1,
136 -1, -1, -1, -1,
137 -1, -1, -1, -1,
138 -1, -1, -1, -1,
139 -1, -1, -1, -1,
140 -1, -1, -1, -1,
141 PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4,
7284e1be
UW
142 PT_CTR * 4, PT_XER * 4, -1,
143 PT_ORIG_R3 * 4, PT_TRAP * 4
30ed0a8f 144 };
5b0a002e 145#endif
0a30fbc4 146
2ec06d2e
DJ
147static int
148ppc_cannot_store_register (int regno)
0a30fbc4 149{
b6430ec3 150#ifndef __powerpc64__
bc1e36ca 151 /* Some kernels do not allow us to store fpscr. */
b6430ec3 152 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE) && regno == find_regno ("fpscr"))
bc1e36ca 153 return 2;
30ed0a8f 154#endif
bc1e36ca 155
7284e1be
UW
156 /* Some kernels do not allow us to store orig_r3 or trap. */
157 if (regno == find_regno ("orig_r3")
158 || regno == find_regno ("trap"))
159 return 2;
160
0a30fbc4
DJ
161 return 0;
162}
163
2ec06d2e
DJ
164static int
165ppc_cannot_fetch_register (int regno)
0a30fbc4
DJ
166{
167 return 0;
168}
169
5b0a002e 170static void
442ea881 171ppc_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
5b0a002e
UW
172{
173 int size = register_size (regno);
76b233dd
UW
174
175 memset (buf, 0, sizeof (long));
176
5b0a002e 177 if (size < sizeof (long))
442ea881 178 collect_register (regcache, regno, buf + sizeof (long) - size);
5b0a002e 179 else
442ea881 180 collect_register (regcache, regno, buf);
5b0a002e
UW
181}
182
183static void
442ea881
PA
184ppc_supply_ptrace_register (struct regcache *regcache,
185 int regno, const char *buf)
5b0a002e
UW
186{
187 int size = register_size (regno);
188 if (size < sizeof (long))
442ea881 189 supply_register (regcache, regno, buf + sizeof (long) - size);
5b0a002e 190 else
442ea881 191 supply_register (regcache, regno, buf);
5b0a002e
UW
192}
193
0b9ff2c0
UW
194
195#define INSTR_SC 0x44000002
196#define NR_spu_run 0x0116
197
198/* If the PPU thread is currently stopped on a spu_run system call,
199 return to FD and ADDR the file handle and NPC parameter address
200 used with the system call. Return non-zero if successful. */
201static int
442ea881 202parse_spufs_run (struct regcache *regcache, int *fd, CORE_ADDR *addr)
0b9ff2c0
UW
203{
204 CORE_ADDR curr_pc;
205 int curr_insn;
206 int curr_r0;
207
208 if (register_size (0) == 4)
209 {
210 unsigned int pc, r0, r3, r4;
442ea881
PA
211 collect_register_by_name (regcache, "pc", &pc);
212 collect_register_by_name (regcache, "r0", &r0);
213 collect_register_by_name (regcache, "orig_r3", &r3);
214 collect_register_by_name (regcache, "r4", &r4);
0b9ff2c0
UW
215 curr_pc = (CORE_ADDR) pc;
216 curr_r0 = (int) r0;
217 *fd = (int) r3;
218 *addr = (CORE_ADDR) r4;
219 }
220 else
221 {
222 unsigned long pc, r0, r3, r4;
442ea881
PA
223 collect_register_by_name (regcache, "pc", &pc);
224 collect_register_by_name (regcache, "r0", &r0);
225 collect_register_by_name (regcache, "orig_r3", &r3);
226 collect_register_by_name (regcache, "r4", &r4);
0b9ff2c0
UW
227 curr_pc = (CORE_ADDR) pc;
228 curr_r0 = (int) r0;
229 *fd = (int) r3;
230 *addr = (CORE_ADDR) r4;
231 }
232
233 /* Fetch instruction preceding current NIP. */
234 if ((*the_target->read_memory) (curr_pc - 4,
235 (unsigned char *) &curr_insn, 4) != 0)
236 return 0;
237 /* It should be a "sc" instruction. */
238 if (curr_insn != INSTR_SC)
239 return 0;
240 /* System call number should be NR_spu_run. */
241 if (curr_r0 != NR_spu_run)
242 return 0;
243
244 return 1;
245}
246
0d62e5e8 247static CORE_ADDR
442ea881 248ppc_get_pc (struct regcache *regcache)
0d62e5e8 249{
0b9ff2c0
UW
250 CORE_ADDR addr;
251 int fd;
252
442ea881 253 if (parse_spufs_run (regcache, &fd, &addr))
0b9ff2c0
UW
254 {
255 unsigned int pc;
256 (*the_target->read_memory) (addr, (unsigned char *) &pc, 4);
493e2a69
MS
257 return ((CORE_ADDR)1 << 63)
258 | ((CORE_ADDR)fd << 32) | (CORE_ADDR) (pc - 4);
0b9ff2c0
UW
259 }
260 else if (register_size (0) == 4)
6fe305f7
UW
261 {
262 unsigned int pc;
442ea881 263 collect_register_by_name (regcache, "pc", &pc);
6fe305f7
UW
264 return (CORE_ADDR) pc;
265 }
266 else
267 {
268 unsigned long pc;
442ea881 269 collect_register_by_name (regcache, "pc", &pc);
6fe305f7
UW
270 return (CORE_ADDR) pc;
271 }
0d62e5e8
DJ
272}
273
274static void
442ea881 275ppc_set_pc (struct regcache *regcache, CORE_ADDR pc)
0d62e5e8 276{
0b9ff2c0
UW
277 CORE_ADDR addr;
278 int fd;
279
442ea881 280 if (parse_spufs_run (regcache, &fd, &addr))
0b9ff2c0
UW
281 {
282 unsigned int newpc = pc;
283 (*the_target->write_memory) (addr, (unsigned char *) &newpc, 4);
284 }
285 else if (register_size (0) == 4)
6fe305f7
UW
286 {
287 unsigned int newpc = pc;
442ea881 288 supply_register_by_name (regcache, "pc", &newpc);
6fe305f7
UW
289 }
290 else
291 {
292 unsigned long newpc = pc;
442ea881 293 supply_register_by_name (regcache, "pc", &newpc);
6fe305f7
UW
294 }
295}
296
b6430ec3
UW
297
298static int
299ppc_get_hwcap (unsigned long *valp)
300{
301 int wordsize = register_size (0);
302 unsigned char *data = alloca (2 * wordsize);
303 int offset = 0;
304
305 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
306 {
307 if (wordsize == 4)
308 {
309 unsigned int *data_p = (unsigned int *)data;
310 if (data_p[0] == AT_HWCAP)
311 {
312 *valp = data_p[1];
313 return 1;
314 }
315 }
316 else
317 {
318 unsigned long *data_p = (unsigned long *)data;
319 if (data_p[0] == AT_HWCAP)
320 {
321 *valp = data_p[1];
322 return 1;
323 }
324 }
325
326 offset += 2 * wordsize;
327 }
328
329 *valp = 0;
330 return 0;
331}
332
6fe305f7
UW
333static void
334ppc_arch_setup (void)
335{
336#ifdef __powerpc64__
337 long msr;
3be029c7 338 struct regcache *regcache;
0d62e5e8 339
c9b2f845
UW
340 /* On a 64-bit host, assume 64-bit inferior process with no
341 AltiVec registers. Reset ppc_hwcap to ensure that the
342 collect_register call below does not fail. */
7284e1be 343 init_registers_powerpc_64l ();
c9b2f845 344 ppc_hwcap = 0;
6fe305f7
UW
345
346 /* Only if the high bit of the MSR is set, we actually have
347 a 64-bit inferior. */
92b72907
UW
348 regcache = new_register_cache ();
349 fetch_inferior_registers (regcache, find_regno ("msr"));
3be029c7 350 collect_register_by_name (regcache, "msr", &msr);
92b72907 351 free_register_cache (regcache);
6fe305f7 352 if (msr < 0)
b6430ec3
UW
353 {
354 ppc_get_hwcap (&ppc_hwcap);
f4d9bade
UW
355 if (ppc_hwcap & PPC_FEATURE_CELL)
356 init_registers_powerpc_cell64l ();
357 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
2c4ad781 358 {
f04c6d38
TJB
359 /* Power ISA 2.05 (implemented by Power 6 and newer processors)
360 increases the FPSCR from 32 bits to 64 bits. Even though Power 7
361 supports this ISA version, it doesn't have PPC_FEATURE_ARCH_2_05
362 set, only PPC_FEATURE_ARCH_2_06. Since for now the only bits
363 used in the higher half of the register are for Decimal Floating
364 Point, we check if that feature is available to decide the size
365 of the FPSCR. */
366 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
2c4ad781
TJB
367 init_registers_powerpc_isa205_vsx64l ();
368 else
369 init_registers_powerpc_vsx64l ();
370 }
677c5bb1 371 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
2c4ad781 372 {
f04c6d38 373 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
2c4ad781
TJB
374 init_registers_powerpc_isa205_altivec64l ();
375 else
376 init_registers_powerpc_altivec64l ();
377 }
378
b6430ec3
UW
379 return;
380 }
6fe305f7
UW
381#endif
382
383 /* OK, we have a 32-bit inferior. */
7284e1be 384 init_registers_powerpc_32l ();
b6430ec3
UW
385
386 ppc_get_hwcap (&ppc_hwcap);
f4d9bade
UW
387 if (ppc_hwcap & PPC_FEATURE_CELL)
388 init_registers_powerpc_cell32l ();
389 else if (ppc_hwcap & PPC_FEATURE_HAS_VSX)
2c4ad781 390 {
f04c6d38 391 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
2c4ad781
TJB
392 init_registers_powerpc_isa205_vsx32l ();
393 else
394 init_registers_powerpc_vsx32l ();
395 }
677c5bb1 396 else if (ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC)
2c4ad781 397 {
f04c6d38 398 if (ppc_hwcap & PPC_FEATURE_HAS_DFP)
2c4ad781
TJB
399 init_registers_powerpc_isa205_altivec32l ();
400 else
401 init_registers_powerpc_altivec32l ();
402 }
677c5bb1 403
b6430ec3
UW
404 /* On 32-bit machines, check for SPE registers.
405 Set the low target's regmap field as appropriately. */
406#ifndef __powerpc64__
407 the_low_target.regmap = ppc_regmap;
408 if (ppc_hwcap & PPC_FEATURE_HAS_SPE)
409 {
7284e1be 410 init_registers_powerpc_e500l ();
b6430ec3
UW
411 the_low_target.regmap = ppc_regmap_e500;
412 }
2c4ad781
TJB
413
414 /* If the FPSCR is 64-bit wide, we need to fetch the whole 64-bit
415 slot and not just its second word. The PT_FPSCR supplied in a
416 32-bit GDB compilation doesn't reflect this. */
417 if (register_size (70) == 8)
418 ppc_regmap[70] = (48 + 2*32) * sizeof (long);
6fe305f7 419#endif
0d62e5e8
DJ
420}
421
5b0a002e 422/* Correct in either endianness.
0d62e5e8
DJ
423 This instruction is "twge r2, r2", which GDB uses as a software
424 breakpoint. */
5b0a002e 425static const unsigned int ppc_breakpoint = 0x7d821008;
0d62e5e8
DJ
426#define ppc_breakpoint_len 4
427
428static int
429ppc_breakpoint_at (CORE_ADDR where)
430{
5b0a002e 431 unsigned int insn;
0d62e5e8 432
0b9ff2c0
UW
433 if (where & ((CORE_ADDR)1 << 63))
434 {
435 char mem_annex[32];
436 sprintf (mem_annex, "%d/mem", (int)((where >> 32) & 0x7fffffff));
437 (*the_target->qxfer_spu) (mem_annex, (unsigned char *) &insn,
438 NULL, where & 0xffffffff, 4);
439 if (insn == 0x3fff)
440 return 1;
441 }
442 else
443 {
444 (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
445 if (insn == ppc_breakpoint)
446 return 1;
447 /* If necessary, recognize more trap instructions here. GDB only uses
448 the one. */
449 }
450
0d62e5e8
DJ
451 return 0;
452}
453
e9d25b98
DJ
454/* Provide only a fill function for the general register set. ps_lgetregs
455 will use this for NPTL support. */
456
442ea881 457static void ppc_fill_gregset (struct regcache *regcache, void *buf)
e9d25b98
DJ
458{
459 int i;
460
461 for (i = 0; i < 32; i++)
442ea881 462 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
e9d25b98
DJ
463
464 for (i = 64; i < 70; i++)
442ea881 465 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
7284e1be
UW
466
467 for (i = 71; i < 73; i++)
442ea881 468 ppc_collect_ptrace_register (regcache, i, (char *) buf + ppc_regmap[i]);
e9d25b98
DJ
469}
470
677c5bb1
LM
471#ifndef PTRACE_GETVSXREGS
472#define PTRACE_GETVSXREGS 27
473#define PTRACE_SETVSXREGS 28
474#endif
475
476#define SIZEOF_VSXREGS 32*8
477
478static void
442ea881 479ppc_fill_vsxregset (struct regcache *regcache, void *buf)
677c5bb1
LM
480{
481 int i, base;
482 char *regset = buf;
483
484 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
485 return;
486
487 base = find_regno ("vs0h");
488 for (i = 0; i < 32; i++)
442ea881 489 collect_register (regcache, base + i, &regset[i * 8]);
677c5bb1
LM
490}
491
492static void
442ea881 493ppc_store_vsxregset (struct regcache *regcache, const void *buf)
677c5bb1
LM
494{
495 int i, base;
496 const char *regset = buf;
497
498 if (!(ppc_hwcap & PPC_FEATURE_HAS_VSX))
499 return;
500
501 base = find_regno ("vs0h");
502 for (i = 0; i < 32; i++)
442ea881 503 supply_register (regcache, base + i, &regset[i * 8]);
677c5bb1
LM
504}
505
30ed0a8f
DJ
506#ifndef PTRACE_GETVRREGS
507#define PTRACE_GETVRREGS 18
508#define PTRACE_SETVRREGS 19
509#endif
510
511#define SIZEOF_VRREGS 33*16+4
512
513static void
442ea881 514ppc_fill_vrregset (struct regcache *regcache, void *buf)
30ed0a8f
DJ
515{
516 int i, base;
517 char *regset = buf;
518
b6430ec3
UW
519 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
520 return;
521
30ed0a8f
DJ
522 base = find_regno ("vr0");
523 for (i = 0; i < 32; i++)
442ea881 524 collect_register (regcache, base + i, &regset[i * 16]);
30ed0a8f 525
442ea881
PA
526 collect_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
527 collect_register_by_name (regcache, "vrsave", &regset[33 * 16]);
30ed0a8f
DJ
528}
529
530static void
442ea881 531ppc_store_vrregset (struct regcache *regcache, const void *buf)
30ed0a8f
DJ
532{
533 int i, base;
534 const char *regset = buf;
535
b6430ec3
UW
536 if (!(ppc_hwcap & PPC_FEATURE_HAS_ALTIVEC))
537 return;
538
30ed0a8f
DJ
539 base = find_regno ("vr0");
540 for (i = 0; i < 32; i++)
442ea881 541 supply_register (regcache, base + i, &regset[i * 16]);
30ed0a8f 542
442ea881
PA
543 supply_register_by_name (regcache, "vscr", &regset[32 * 16 + 12]);
544 supply_register_by_name (regcache, "vrsave", &regset[33 * 16]);
30ed0a8f
DJ
545}
546
30ed0a8f
DJ
547#ifndef PTRACE_GETEVRREGS
548#define PTRACE_GETEVRREGS 20
549#define PTRACE_SETEVRREGS 21
550#endif
551
552struct gdb_evrregset_t
553{
554 unsigned long evr[32];
555 unsigned long long acc;
556 unsigned long spefscr;
557};
558
559static void
442ea881 560ppc_fill_evrregset (struct regcache *regcache, void *buf)
30ed0a8f
DJ
561{
562 int i, ev0;
563 struct gdb_evrregset_t *regset = buf;
564
b6430ec3
UW
565 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
566 return;
567
30ed0a8f
DJ
568 ev0 = find_regno ("ev0h");
569 for (i = 0; i < 32; i++)
442ea881 570 collect_register (regcache, ev0 + i, &regset->evr[i]);
30ed0a8f 571
442ea881
PA
572 collect_register_by_name (regcache, "acc", &regset->acc);
573 collect_register_by_name (regcache, "spefscr", &regset->spefscr);
30ed0a8f
DJ
574}
575
576static void
442ea881 577ppc_store_evrregset (struct regcache *regcache, const void *buf)
30ed0a8f
DJ
578{
579 int i, ev0;
580 const struct gdb_evrregset_t *regset = buf;
581
b6430ec3
UW
582 if (!(ppc_hwcap & PPC_FEATURE_HAS_SPE))
583 return;
584
30ed0a8f
DJ
585 ev0 = find_regno ("ev0h");
586 for (i = 0; i < 32; i++)
442ea881 587 supply_register (regcache, ev0 + i, &regset->evr[i]);
30ed0a8f 588
442ea881
PA
589 supply_register_by_name (regcache, "acc", &regset->acc);
590 supply_register_by_name (regcache, "spefscr", &regset->spefscr);
30ed0a8f 591}
30ed0a8f 592
e9d25b98 593struct regset_info target_regsets[] = {
30ed0a8f
DJ
594 /* List the extra register sets before GENERAL_REGS. That way we will
595 fetch them every time, but still fall back to PTRACE_PEEKUSER for the
596 general registers. Some kernels support these, but not the newer
597 PPC_PTRACE_GETREGS. */
1570b33e 598 { PTRACE_GETVSXREGS, PTRACE_SETVSXREGS, 0, SIZEOF_VSXREGS, EXTENDED_REGS,
677c5bb1 599 ppc_fill_vsxregset, ppc_store_vsxregset },
1570b33e 600 { PTRACE_GETVRREGS, PTRACE_SETVRREGS, 0, SIZEOF_VRREGS, EXTENDED_REGS,
30ed0a8f 601 ppc_fill_vrregset, ppc_store_vrregset },
1570b33e 602 { PTRACE_GETEVRREGS, PTRACE_SETEVRREGS, 0, 32 * 4 + 8 + 4, EXTENDED_REGS,
30ed0a8f 603 ppc_fill_evrregset, ppc_store_evrregset },
1570b33e
L
604 { 0, 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
605 { 0, 0, 0, -1, -1, NULL, NULL }
e9d25b98
DJ
606};
607
2ec06d2e 608struct linux_target_ops the_low_target = {
6fe305f7 609 ppc_arch_setup,
2ec06d2e
DJ
610 ppc_num_regs,
611 ppc_regmap,
1faeff08 612 NULL,
2ec06d2e
DJ
613 ppc_cannot_fetch_register,
614 ppc_cannot_store_register,
c14dfd32 615 NULL, /* fetch_register */
0d62e5e8
DJ
616 ppc_get_pc,
617 ppc_set_pc,
f450004a 618 (const unsigned char *) &ppc_breakpoint,
0d62e5e8
DJ
619 ppc_breakpoint_len,
620 NULL,
621 0,
622 ppc_breakpoint_at,
5b0a002e
UW
623 NULL,
624 NULL,
625 NULL,
626 NULL,
627 ppc_collect_ptrace_register,
628 ppc_supply_ptrace_register,
2ec06d2e 629};
This page took 0.91692 seconds and 4 git commands to generate.