gdbserver/linux-low: turn 'regs_info' into a method
[deliverable/binutils-gdb.git] / gdbserver / linux-s390-low.cc
1 /* GNU/Linux S/390 specific low level interface, for the remote server
2 for GDB.
3 Copyright (C) 2001-2020 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 3 of the License, or
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* This file is used for both 31-bit and 64-bit S/390 systems. */
21
22 #include "server.h"
23 #include "linux-low.h"
24 #include "elf/common.h"
25 #include "ax.h"
26 #include "tracepoint.h"
27
28 #include <asm/ptrace.h>
29 #include "nat/gdb_ptrace.h"
30 #include <sys/uio.h>
31 #include <elf.h>
32 #include <inttypes.h>
33
34 #include "linux-s390-tdesc.h"
35
36 #ifndef HWCAP_S390_HIGH_GPRS
37 #define HWCAP_S390_HIGH_GPRS 512
38 #endif
39
40 #ifndef HWCAP_S390_TE
41 #define HWCAP_S390_TE 1024
42 #endif
43
44 #ifndef HWCAP_S390_VX
45 #define HWCAP_S390_VX 2048
46 #endif
47
48 #ifndef HWCAP_S390_GS
49 #define HWCAP_S390_GS 16384
50 #endif
51
52 #define s390_num_regs 52
53
54 /* Linux target op definitions for the S/390 architecture. */
55
56 class s390_target : public linux_process_target
57 {
58 public:
59
60 const regs_info *get_regs_info () override;
61
62 protected:
63
64 void low_arch_setup () override;
65 };
66
67 /* The singleton target ops object. */
68
69 static s390_target the_s390_target;
70
71 static int s390_regmap[] = {
72 PT_PSWMASK, PT_PSWADDR,
73
74 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
75 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
76 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
77 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
78
79 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
80 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
81 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
82 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
83
84 PT_FPC,
85
86 #ifndef __s390x__
87 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
88 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
89 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
90 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
91 #else
92 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
93 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
94 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
95 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
96 #endif
97
98 PT_ORIGGPR2,
99 };
100
101 #define s390_num_regs_3264 68
102
103 #ifdef __s390x__
104 static int s390_regmap_3264[] = {
105 PT_PSWMASK, PT_PSWADDR,
106
107 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
108 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
109 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
110 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
111 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
112 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
113 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
114 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
115
116 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
117 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
118 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
119 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
120
121 PT_FPC,
122
123 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
124 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
125 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
126 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
127
128 PT_ORIGGPR2,
129 };
130 #else
131 static int s390_regmap_3264[] = {
132 PT_PSWMASK, PT_PSWADDR,
133
134 -1, PT_GPR0, -1, PT_GPR1,
135 -1, PT_GPR2, -1, PT_GPR3,
136 -1, PT_GPR4, -1, PT_GPR5,
137 -1, PT_GPR6, -1, PT_GPR7,
138 -1, PT_GPR8, -1, PT_GPR9,
139 -1, PT_GPR10, -1, PT_GPR11,
140 -1, PT_GPR12, -1, PT_GPR13,
141 -1, PT_GPR14, -1, PT_GPR15,
142
143 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
144 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
145 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
146 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
147
148 PT_FPC,
149
150 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
151 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
152 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
153 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
154
155 PT_ORIGGPR2,
156 };
157 #endif
158
159
160 static int
161 s390_cannot_fetch_register (int regno)
162 {
163 return 0;
164 }
165
166 static int
167 s390_cannot_store_register (int regno)
168 {
169 return 0;
170 }
171
172 static void
173 s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
174 {
175 int size = register_size (regcache->tdesc, regno);
176 const struct regs_info *regs_info = the_linux_target->get_regs_info ();
177 struct usrregs_info *usr = regs_info->usrregs;
178 int regaddr = usr->regmap[regno];
179
180 if (size < sizeof (long))
181 {
182 memset (buf, 0, sizeof (long));
183
184 if ((regno ^ 1) < usr->num_regs
185 && usr->regmap[regno ^ 1] == regaddr)
186 {
187 collect_register (regcache, regno & ~1, buf);
188 collect_register (regcache, (regno & ~1) + 1,
189 buf + sizeof (long) - size);
190 }
191 else if (regaddr == PT_PSWMASK)
192 {
193 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
194 the basic addressing mode bit from the PSW address. */
195 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
196 collect_register (regcache, regno, buf);
197 collect_register (regcache, regno ^ 1, addr);
198 buf[1] &= ~0x8;
199 buf[size] |= (addr[0] & 0x80);
200 }
201 else if (regaddr == PT_PSWADDR)
202 {
203 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
204 mode bit (which gets copied to the PSW mask instead). */
205 collect_register (regcache, regno, buf + sizeof (long) - size);
206 buf[sizeof (long) - size] &= ~0x80;
207 }
208 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
209 || regaddr == PT_ORIGGPR2)
210 collect_register (regcache, regno, buf + sizeof (long) - size);
211 else
212 collect_register (regcache, regno, buf);
213 }
214 else if (regaddr != -1)
215 collect_register (regcache, regno, buf);
216 }
217
218 static void
219 s390_supply_ptrace_register (struct regcache *regcache,
220 int regno, const char *buf)
221 {
222 int size = register_size (regcache->tdesc, regno);
223 const struct regs_info *regs_info = the_linux_target->get_regs_info ();
224 struct usrregs_info *usr = regs_info->usrregs;
225 int regaddr = usr->regmap[regno];
226
227 if (size < sizeof (long))
228 {
229 if ((regno ^ 1) < usr->num_regs
230 && usr->regmap[regno ^ 1] == regaddr)
231 {
232 supply_register (regcache, regno & ~1, buf);
233 supply_register (regcache, (regno & ~1) + 1,
234 buf + sizeof (long) - size);
235 }
236 else if (regaddr == PT_PSWMASK)
237 {
238 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
239 the basic addressing mode into the PSW address. */
240 gdb_byte *mask = (gdb_byte *) alloca (size);
241 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
242 memcpy (mask, buf, size);
243 mask[1] |= 0x8;
244 supply_register (regcache, regno, mask);
245
246 collect_register (regcache, regno ^ 1, addr);
247 addr[0] &= ~0x80;
248 addr[0] |= (buf[size] & 0x80);
249 supply_register (regcache, regno ^ 1, addr);
250 }
251 else if (regaddr == PT_PSWADDR)
252 {
253 /* Convert 8-byte PSW address to 4 bytes by truncating, but
254 keeping the addressing mode bit (which was set from the mask). */
255 gdb_byte *addr = (gdb_byte *) alloca (size);
256 char amode;
257 collect_register (regcache, regno, addr);
258 amode = addr[0] & 0x80;
259 memcpy (addr, buf + sizeof (long) - size, size);
260 addr[0] &= ~0x80;
261 addr[0] |= amode;
262 supply_register (regcache, regno, addr);
263 }
264 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
265 || regaddr == PT_ORIGGPR2)
266 supply_register (regcache, regno, buf + sizeof (long) - size);
267 else
268 supply_register (regcache, regno, buf);
269 }
270 else if (regaddr != -1)
271 supply_register (regcache, regno, buf);
272 }
273
274 /* Provide only a fill function for the general register set. ps_lgetregs
275 will use this for NPTL support. */
276
277 static void
278 s390_fill_gregset (struct regcache *regcache, void *buf)
279 {
280 int i;
281 const struct regs_info *regs_info = the_linux_target->get_regs_info ();
282 struct usrregs_info *usr = regs_info->usrregs;
283
284 for (i = 0; i < usr->num_regs; i++)
285 {
286 if (usr->regmap[i] < PT_PSWMASK
287 || usr->regmap[i] > PT_ACR15)
288 continue;
289
290 s390_collect_ptrace_register (regcache, i,
291 (char *) buf + usr->regmap[i]);
292 }
293 }
294
295 /* Fill and store functions for extended register sets. */
296
297 #ifndef __s390x__
298 static void
299 s390_fill_gprs_high (struct regcache *regcache, void *buf)
300 {
301 int r0h = find_regno (regcache->tdesc, "r0h");
302 int i;
303
304 for (i = 0; i < 16; i++)
305 collect_register (regcache, r0h + 2 * i, (char *) buf + 4 * i);
306 }
307
308 static void
309 s390_store_gprs_high (struct regcache *regcache, const void *buf)
310 {
311 int r0h = find_regno (regcache->tdesc, "r0h");
312 int i;
313
314 for (i = 0; i < 16; i++)
315 supply_register (regcache, r0h + 2 * i, (const char *) buf + 4 * i);
316 }
317 #endif
318
319 static void
320 s390_store_last_break (struct regcache *regcache, const void *buf)
321 {
322 const char *p;
323
324 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
325 supply_register_by_name (regcache, "last_break", p);
326 }
327
328 static void
329 s390_fill_system_call (struct regcache *regcache, void *buf)
330 {
331 collect_register_by_name (regcache, "system_call", buf);
332 }
333
334 static void
335 s390_store_system_call (struct regcache *regcache, const void *buf)
336 {
337 supply_register_by_name (regcache, "system_call", buf);
338 }
339
340 static void
341 s390_store_tdb (struct regcache *regcache, const void *buf)
342 {
343 int tdb0 = find_regno (regcache->tdesc, "tdb0");
344 int tr0 = find_regno (regcache->tdesc, "tr0");
345 int i;
346
347 for (i = 0; i < 4; i++)
348 supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
349
350 for (i = 0; i < 16; i++)
351 supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
352 }
353
354 static void
355 s390_fill_vxrs_low (struct regcache *regcache, void *buf)
356 {
357 int v0 = find_regno (regcache->tdesc, "v0l");
358 int i;
359
360 for (i = 0; i < 16; i++)
361 collect_register (regcache, v0 + i, (char *) buf + 8 * i);
362 }
363
364 static void
365 s390_store_vxrs_low (struct regcache *regcache, const void *buf)
366 {
367 int v0 = find_regno (regcache->tdesc, "v0l");
368 int i;
369
370 for (i = 0; i < 16; i++)
371 supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
372 }
373
374 static void
375 s390_fill_vxrs_high (struct regcache *regcache, void *buf)
376 {
377 int v16 = find_regno (regcache->tdesc, "v16");
378 int i;
379
380 for (i = 0; i < 16; i++)
381 collect_register (regcache, v16 + i, (char *) buf + 16 * i);
382 }
383
384 static void
385 s390_store_vxrs_high (struct regcache *regcache, const void *buf)
386 {
387 int v16 = find_regno (regcache->tdesc, "v16");
388 int i;
389
390 for (i = 0; i < 16; i++)
391 supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
392 }
393
394 static void
395 s390_store_gs (struct regcache *regcache, const void *buf)
396 {
397 int gsd = find_regno (regcache->tdesc, "gsd");
398 int i;
399
400 for (i = 0; i < 3; i++)
401 supply_register (regcache, gsd + i, (const char *) buf + 8 * (i + 1));
402 }
403
404 static void
405 s390_store_gsbc (struct regcache *regcache, const void *buf)
406 {
407 int bc_gsd = find_regno (regcache->tdesc, "bc_gsd");
408 int i;
409
410 for (i = 0; i < 3; i++)
411 supply_register (regcache, bc_gsd + i, (const char *) buf + 8 * (i + 1));
412 }
413
414 static struct regset_info s390_regsets[] = {
415 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
416 #ifndef __s390x__
417 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_HIGH_GPRS, 0,
418 EXTENDED_REGS, s390_fill_gprs_high, s390_store_gprs_high },
419 #endif
420 /* Last break address is read-only; no fill function. */
421 { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
422 NULL, s390_store_last_break },
423 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
424 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
425 /* TDB is read-only. */
426 { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
427 NULL, s390_store_tdb },
428 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
429 EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
430 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
431 EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
432 /* Guarded storage registers are read-only. */
433 { PTRACE_GETREGSET, -1, NT_S390_GS_CB, 0, EXTENDED_REGS,
434 NULL, s390_store_gs },
435 { PTRACE_GETREGSET, -1, NT_S390_GS_BC, 0, EXTENDED_REGS,
436 NULL, s390_store_gsbc },
437 NULL_REGSET
438 };
439
440
441 static const gdb_byte s390_breakpoint[] = { 0, 1 };
442 #define s390_breakpoint_len 2
443
444 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
445
446 static const gdb_byte *
447 s390_sw_breakpoint_from_kind (int kind, int *size)
448 {
449 *size = s390_breakpoint_len;
450 return s390_breakpoint;
451 }
452
453 static CORE_ADDR
454 s390_get_pc (struct regcache *regcache)
455 {
456 if (register_size (regcache->tdesc, 0) == 4)
457 {
458 unsigned int pswa;
459 collect_register_by_name (regcache, "pswa", &pswa);
460 return pswa & 0x7fffffff;
461 }
462 else
463 {
464 unsigned long pc;
465 collect_register_by_name (regcache, "pswa", &pc);
466 return pc;
467 }
468 }
469
470 static void
471 s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
472 {
473 if (register_size (regcache->tdesc, 0) == 4)
474 {
475 unsigned int pswa;
476 collect_register_by_name (regcache, "pswa", &pswa);
477 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
478 supply_register_by_name (regcache, "pswa", &pswa);
479 }
480 else
481 {
482 unsigned long pc = newpc;
483 supply_register_by_name (regcache, "pswa", &pc);
484 }
485 }
486
487 /* Determine the word size for the given PID, in bytes. */
488
489 #ifdef __s390x__
490 static int
491 s390_get_wordsize (int pid)
492 {
493 errno = 0;
494 PTRACE_XFER_TYPE pswm = ptrace (PTRACE_PEEKUSER, pid,
495 (PTRACE_TYPE_ARG3) 0,
496 (PTRACE_TYPE_ARG4) 0);
497 if (errno != 0)
498 {
499 warning (_("Couldn't determine word size, assuming 64-bit."));
500 return 8;
501 }
502 /* Derive word size from extended addressing mode (PSW bit 31). */
503 return pswm & (1L << 32) ? 8 : 4;
504 }
505 #else
506 #define s390_get_wordsize(pid) 4
507 #endif
508
509 static int
510 s390_check_regset (int pid, int regset, int regsize)
511 {
512 void *buf = alloca (regsize);
513 struct iovec iov;
514
515 iov.iov_base = buf;
516 iov.iov_len = regsize;
517
518 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
519 || errno == ENODATA)
520 return 1;
521 return 0;
522 }
523
524 /* For a 31-bit inferior, whether the kernel supports using the full
525 64-bit GPRs. */
526 static int have_hwcap_s390_high_gprs = 0;
527 static int have_hwcap_s390_vx = 0;
528
529 void
530 s390_target::low_arch_setup ()
531 {
532 const struct target_desc *tdesc;
533 struct regset_info *regset;
534
535 /* Determine word size and HWCAP. */
536 int pid = pid_of (current_thread);
537 int wordsize = s390_get_wordsize (pid);
538 unsigned long hwcap = linux_get_hwcap (wordsize);
539
540 /* Check whether the kernel supports extra register sets. */
541 int have_regset_last_break
542 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
543 int have_regset_system_call
544 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
545 int have_regset_tdb
546 = (s390_check_regset (pid, NT_S390_TDB, 256)
547 && (hwcap & HWCAP_S390_TE) != 0);
548 int have_regset_vxrs
549 = (s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
550 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256)
551 && (hwcap & HWCAP_S390_VX) != 0);
552 int have_regset_gs
553 = (s390_check_regset (pid, NT_S390_GS_CB, 32)
554 && s390_check_regset (pid, NT_S390_GS_BC, 32)
555 && (hwcap & HWCAP_S390_GS) != 0);
556
557 {
558 #ifdef __s390x__
559 if (wordsize == 8)
560 {
561 if (have_regset_gs)
562 tdesc = tdesc_s390x_gs_linux64;
563 else if (have_regset_vxrs)
564 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
565 tdesc_s390x_vx_linux64);
566 else if (have_regset_tdb)
567 tdesc = tdesc_s390x_te_linux64;
568 else if (have_regset_system_call)
569 tdesc = tdesc_s390x_linux64v2;
570 else if (have_regset_last_break)
571 tdesc = tdesc_s390x_linux64v1;
572 else
573 tdesc = tdesc_s390x_linux64;
574 }
575
576 /* For a 31-bit inferior, check whether the kernel supports
577 using the full 64-bit GPRs. */
578 else
579 #endif
580 if (hwcap & HWCAP_S390_HIGH_GPRS)
581 {
582 have_hwcap_s390_high_gprs = 1;
583 if (have_regset_gs)
584 tdesc = tdesc_s390_gs_linux64;
585 else if (have_regset_vxrs)
586 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
587 tdesc_s390_vx_linux64);
588 else if (have_regset_tdb)
589 tdesc = tdesc_s390_te_linux64;
590 else if (have_regset_system_call)
591 tdesc = tdesc_s390_linux64v2;
592 else if (have_regset_last_break)
593 tdesc = tdesc_s390_linux64v1;
594 else
595 tdesc = tdesc_s390_linux64;
596 }
597 else
598 {
599 /* Assume 31-bit inferior process. */
600 if (have_regset_system_call)
601 tdesc = tdesc_s390_linux32v2;
602 else if (have_regset_last_break)
603 tdesc = tdesc_s390_linux32v1;
604 else
605 tdesc = tdesc_s390_linux32;
606 }
607
608 have_hwcap_s390_vx = have_regset_vxrs;
609 }
610
611 /* Update target_regsets according to available register sets. */
612 for (regset = s390_regsets; regset->size >= 0; regset++)
613 if (regset->get_request == PTRACE_GETREGSET)
614 switch (regset->nt_type)
615 {
616 #ifndef __s390x__
617 case NT_S390_HIGH_GPRS:
618 regset->size = have_hwcap_s390_high_gprs ? 64 : 0;
619 break;
620 #endif
621 case NT_S390_LAST_BREAK:
622 regset->size = have_regset_last_break ? 8 : 0;
623 break;
624 case NT_S390_SYSTEM_CALL:
625 regset->size = have_regset_system_call ? 4 : 0;
626 break;
627 case NT_S390_TDB:
628 regset->size = have_regset_tdb ? 256 : 0;
629 break;
630 case NT_S390_VXRS_LOW:
631 regset->size = have_regset_vxrs ? 128 : 0;
632 break;
633 case NT_S390_VXRS_HIGH:
634 regset->size = have_regset_vxrs ? 256 : 0;
635 break;
636 case NT_S390_GS_CB:
637 case NT_S390_GS_BC:
638 regset->size = have_regset_gs ? 32 : 0;
639 default:
640 break;
641 }
642
643 current_process ()->tdesc = tdesc;
644 }
645
646
647 static int
648 s390_breakpoint_at (CORE_ADDR pc)
649 {
650 unsigned char c[s390_breakpoint_len];
651 read_inferior_memory (pc, c, s390_breakpoint_len);
652 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
653 }
654
655 /* Breakpoint/Watchpoint support. */
656
657 /* The "supports_z_point_type" linux_target_ops method. */
658
659 static int
660 s390_supports_z_point_type (char z_type)
661 {
662 switch (z_type)
663 {
664 case Z_PACKET_SW_BP:
665 return 1;
666 default:
667 return 0;
668 }
669 }
670
671 /* Support for hardware single step. */
672
673 static int
674 s390_supports_hardware_single_step (void)
675 {
676 return 1;
677 }
678
679 static struct usrregs_info s390_usrregs_info =
680 {
681 s390_num_regs,
682 s390_regmap,
683 };
684
685 static struct regsets_info s390_regsets_info =
686 {
687 s390_regsets, /* regsets */
688 0, /* num_regsets */
689 NULL, /* disabled_regsets */
690 };
691
692 static struct regs_info myregs_info =
693 {
694 NULL, /* regset_bitmap */
695 &s390_usrregs_info,
696 &s390_regsets_info
697 };
698
699 static struct usrregs_info s390_usrregs_info_3264 =
700 {
701 s390_num_regs_3264,
702 s390_regmap_3264
703 };
704
705 static struct regsets_info s390_regsets_info_3264 =
706 {
707 s390_regsets, /* regsets */
708 0, /* num_regsets */
709 NULL, /* disabled_regsets */
710 };
711
712 static struct regs_info regs_info_3264 =
713 {
714 NULL, /* regset_bitmap */
715 &s390_usrregs_info_3264,
716 &s390_regsets_info_3264
717 };
718
719 const regs_info *
720 s390_target::get_regs_info ()
721 {
722 if (have_hwcap_s390_high_gprs)
723 {
724 #ifdef __s390x__
725 const struct target_desc *tdesc = current_process ()->tdesc;
726
727 if (register_size (tdesc, 0) == 4)
728 return &regs_info_3264;
729 #else
730 return &regs_info_3264;
731 #endif
732 }
733 return &myregs_info;
734 }
735
736 /* The "supports_tracepoints" linux_target_ops method. */
737
738 static int
739 s390_supports_tracepoints (void)
740 {
741 return 1;
742 }
743
744 /* Implementation of linux_target_ops method "get_thread_area". */
745
746 static int
747 s390_get_thread_area (int lwpid, CORE_ADDR *addrp)
748 {
749 CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, (long) 0);
750 #ifdef __s390x__
751 struct regcache *regcache = get_thread_regcache (current_thread, 0);
752
753 if (register_size (regcache->tdesc, 0) == 4)
754 res &= 0xffffffffull;
755 #endif
756 *addrp = res;
757 return 0;
758 }
759
760
761 /* Fast tracepoint support.
762
763 The register save area on stack is identical for all targets:
764
765 0x000+i*0x10: VR0-VR31
766 0x200+i*8: GR0-GR15
767 0x280+i*4: AR0-AR15
768 0x2c0: PSWM [64-bit]
769 0x2c8: PSWA [64-bit]
770 0x2d0: FPC
771
772 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
773 Likewise, if there's no VX support, we just store the FRs into the slots
774 of low VR halves. The agent code is responsible for rearranging that
775 into regcache. */
776
777 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
778 one trick used at the very beginning: since there's no way to allocate
779 stack space without destroying CC (lay instruction can do it, but it's
780 only supported on later CPUs), we take 4 different execution paths for
781 every possible value of CC, allocate stack space, save %r0, stuff the
782 CC value in %r0 (shifted to match its position in PSWM high word),
783 then branch to common path. */
784
785 static const unsigned char s390_ft_entry_gpr_esa[] = {
786 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
787 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
788 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
789 /* CC = 0 */
790 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
791 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
792 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
793 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
794 /* .Lcc1: */
795 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
796 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
797 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
798 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
799 /* .Lcc2: */
800 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
801 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
802 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
803 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
804 /* .Lcc3: */
805 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
806 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
807 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
808 /* .Lccdone: */
809 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
810 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
811 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
812 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
813 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
814 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
815 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
816 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
817 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
818 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
819 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
820 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
821 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
822 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
823 /* Compute original value of %r15 and store it. We use ahi instead
824 of la to preserve the whole value, and not just the low 31 bits.
825 This is not particularly important here, but essential in the
826 zarch case where someone might be using the high word of %r15
827 as an extra register. */
828 0x18, 0x1f, /* lr %r1, %r15 */
829 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
830 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
831 };
832
833 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
834 target. Same as above, except this time we can use load/store multiple,
835 since the 64-bit regs are tightly packed. */
836
837 static const unsigned char s390_ft_entry_gpr_zarch[] = {
838 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
839 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
840 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
841 /* CC = 0 */
842 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
843 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
844 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
845 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
846 /* .Lcc1: */
847 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
848 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
849 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
850 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
851 /* .Lcc2: */
852 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
853 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
854 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
855 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
856 /* .Lcc3: */
857 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
858 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
859 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
860 /* .Lccdone: */
861 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
862 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
863 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
864 };
865
866 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
867 current PSWM (read by epsw) and CC from entry (in %r0). */
868
869 static const unsigned char s390_ft_entry_misc[] = {
870 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
871 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
872 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
873 0x14, 0x21, /* nr %r2, %r1 */
874 0x16, 0x20, /* or %r2, %r0 */
875 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
876 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
877 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
878 };
879
880 /* Code sequence saving FRs, used if VX not supported. */
881
882 static const unsigned char s390_ft_entry_fr[] = {
883 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
884 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
885 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
886 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
887 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
888 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
889 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
890 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
891 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
892 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
893 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
894 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
895 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
896 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
897 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
898 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
899 };
900
901 /* Code sequence saving VRs, used if VX not supported. */
902
903 static const unsigned char s390_ft_entry_vr[] = {
904 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
905 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
906 };
907
908 /* Code sequence doing the collection call for 31-bit target. %r1 contains
909 the address of the literal pool. */
910
911 static const unsigned char s390_ft_main_31[] = {
912 /* Load the literals into registers. */
913 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
914 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
915 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
916 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
917 /* Save original PSWA (tracepoint address | 0x80000000). */
918 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
919 /* Construct a collecting_t object at %r15+0x2e0. */
920 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
921 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
922 /* Move its address to %r0. */
923 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
924 /* Take the lock. */
925 /* .Lloop: */
926 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
927 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
928 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
929 /* Address of the register save block to %r3. */
930 0x18, 0x3f, /* lr %r3, %r15 */
931 /* Make a stack frame, so that we can call the collector. */
932 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
933 /* Call it. */
934 0x0d, 0xe4, /* basr %r14, %r4 */
935 /* And get rid of the stack frame again. */
936 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
937 /* Leave the lock. */
938 0x07, 0xf0, /* br %r0 */
939 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
940 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
941 };
942
943 /* Code sequence doing the collection call for 64-bit target. %r1 contains
944 the address of the literal pool. */
945
946 static const unsigned char s390_ft_main_64[] = {
947 /* Load the literals into registers. */
948 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
949 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
950 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
951 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
952 /* Save original PSWA (tracepoint address). */
953 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
954 /* Construct a collecting_t object at %r15+0x2e0. */
955 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
956 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
957 /* Move its address to %r0. */
958 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
959 /* Take the lock. */
960 /* .Lloop: */
961 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
962 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
963 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
964 /* Address of the register save block to %r3. */
965 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
966 /* Make a stack frame, so that we can call the collector. */
967 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
968 /* Call it. */
969 0x0d, 0xe4, /* basr %r14, %r4 */
970 /* And get rid of the stack frame again. */
971 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
972 /* Leave the lock. */
973 0x07, 0xf0, /* br %r0 */
974 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
975 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
976 };
977
978 /* Code sequence restoring FRs, for targets with no VX support. */
979
980 static const unsigned char s390_ft_exit_fr[] = {
981 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
982 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
983 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
984 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
985 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
986 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
987 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
988 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
989 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
990 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
991 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
992 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
993 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
994 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
995 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
996 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
997 };
998
999 /* Code sequence restoring VRs. */
1000
1001 static const unsigned char s390_ft_exit_vr[] = {
1002 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1003 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1004 };
1005
1006 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1007 modified by C code, so we use the alr instruction to restore it by
1008 manufacturing an operand that'll result in the original flags. */
1009
1010 static const unsigned char s390_ft_exit_misc[] = {
1011 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1012 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1013 /* Extract CC to high 2 bits of %r0. */
1014 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1015 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1016 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1017 will have carry iff CC bit 1 is set - resulting in the same flags
1018 as the original. */
1019 0x1e, 0x00, /* alr %r0, %r0 */
1020 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1021 };
1022
1023 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1024
1025 static const unsigned char s390_ft_exit_gpr_esa[] = {
1026 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1027 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1028 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1029 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1030 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1031 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1032 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1033 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1034 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1035 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1036 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1037 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1038 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1039 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1040 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1041 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1042 };
1043
1044 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1045 with high GPRs. */
1046
1047 static const unsigned char s390_ft_exit_gpr_zarch[] = {
1048 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1049 };
1050
1051 /* Writes instructions to target, updating the to pointer. */
1052
1053 static void
1054 append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
1055 {
1056 target_write_memory (*to, buf, len);
1057 *to += len;
1058 }
1059
1060 /* Relocates an instruction from oldloc to *to, updating to. */
1061
1062 static int
1063 s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64)
1064 {
1065 gdb_byte buf[6];
1066 int ilen;
1067 int op2;
1068 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1069 int mode = 0;
1070 int is_bras = 0;
1071 read_inferior_memory (oldloc, buf, sizeof buf);
1072 if (buf[0] < 0x40)
1073 ilen = 2;
1074 else if (buf[0] < 0xc0)
1075 ilen = 4;
1076 else
1077 ilen = 6;
1078 switch (buf[0])
1079 {
1080 case 0x05: /* BALR */
1081 case 0x0c: /* BASSM */
1082 case 0x0d: /* BASR */
1083 case 0x45: /* BAL */
1084 case 0x4d: /* BAS */
1085 /* These save a return address and mess around with registers.
1086 We can't relocate them. */
1087 return 1;
1088 case 0x84: /* BRXH */
1089 case 0x85: /* BRXLE */
1090 mode = 1;
1091 break;
1092 case 0xa7:
1093 op2 = buf[1] & 0xf;
1094 /* BRC, BRAS, BRCT, BRCTG */
1095 if (op2 >= 4 && op2 <= 7)
1096 mode = 1;
1097 /* BRAS */
1098 if (op2 == 5)
1099 is_bras = 1;
1100 break;
1101 case 0xc0:
1102 op2 = buf[1] & 0xf;
1103 /* LARL, BRCL, BRASL */
1104 if (op2 == 0 || op2 == 4 || op2 == 5)
1105 mode = 2;
1106 /* BRASL */
1107 if (op2 == 5)
1108 is_bras = 1;
1109 break;
1110 case 0xc4:
1111 case 0xc6:
1112 /* PC-relative addressing instructions. */
1113 mode = 2;
1114 break;
1115 case 0xc5: /* BPRP */
1116 case 0xc7: /* BPP */
1117 /* Branch prediction - just skip it. */
1118 return 0;
1119 case 0xcc:
1120 op2 = buf[1] & 0xf;
1121 /* BRCTH */
1122 if (op2 == 6)
1123 mode = 2;
1124 break;
1125 case 0xec:
1126 op2 = buf[5];
1127 switch (op2)
1128 {
1129 case 0x44: /* BRXHG */
1130 case 0x45: /* BRXLG */
1131 case 0x64: /* CGRJ */
1132 case 0x65: /* CLGRJ */
1133 case 0x76: /* CRJ */
1134 case 0x77: /* CLRJ */
1135 mode = 1;
1136 break;
1137 }
1138 break;
1139 }
1140
1141 if (mode != 0)
1142 {
1143 /* We'll have to relocate an instruction with a PC-relative field.
1144 First, compute the target. */
1145 int64_t loffset = 0;
1146 CORE_ADDR target;
1147 if (mode == 1)
1148 {
1149 int16_t soffset = 0;
1150 memcpy (&soffset, buf + 2, 2);
1151 loffset = soffset;
1152 }
1153 else if (mode == 2)
1154 {
1155 int32_t soffset = 0;
1156 memcpy (&soffset, buf + 2, 4);
1157 loffset = soffset;
1158 }
1159 target = oldloc + loffset * 2;
1160 if (!is_64)
1161 target &= 0x7fffffff;
1162
1163 if (is_bras)
1164 {
1165 /* BRAS or BRASL was used. We cannot just relocate those, since
1166 they save the return address in a register. We can, however,
1167 replace them with a LARL+JG sequence. */
1168
1169 /* Make the LARL. */
1170 int32_t soffset;
1171 buf[0] = 0xc0;
1172 buf[1] &= 0xf0;
1173 loffset = oldloc + ilen - *to;
1174 loffset >>= 1;
1175 soffset = loffset;
1176 if (soffset != loffset && is_64)
1177 return 1;
1178 memcpy (buf + 2, &soffset, 4);
1179 append_insns (to, 6, buf);
1180
1181 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1182 an address with the top bit 0, while BRAS/BRASL will write it
1183 with top bit 1. It should not matter much, since linux compilers
1184 use BR and not BSM to return from functions, but it could confuse
1185 some poor stack unwinder. */
1186
1187 /* We'll now be writing a JG. */
1188 mode = 2;
1189 buf[0] = 0xc0;
1190 buf[1] = 0xf4;
1191 ilen = 6;
1192 }
1193
1194 /* Compute the new offset and write it to the buffer. */
1195 loffset = target - *to;
1196 loffset >>= 1;
1197
1198 if (mode == 1)
1199 {
1200 int16_t soffset = loffset;
1201 if (soffset != loffset)
1202 return 1;
1203 memcpy (buf + 2, &soffset, 2);
1204 }
1205 else if (mode == 2)
1206 {
1207 int32_t soffset = loffset;
1208 if (soffset != loffset && is_64)
1209 return 1;
1210 memcpy (buf + 2, &soffset, 4);
1211 }
1212 }
1213 append_insns (to, ilen, buf);
1214 return 0;
1215 }
1216
1217 /* Implementation of linux_target_ops method
1218 "install_fast_tracepoint_jump_pad". */
1219
1220 static int
1221 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint,
1222 CORE_ADDR tpaddr,
1223 CORE_ADDR collector,
1224 CORE_ADDR lockaddr,
1225 ULONGEST orig_size,
1226 CORE_ADDR *jump_entry,
1227 CORE_ADDR *trampoline,
1228 ULONGEST *trampoline_size,
1229 unsigned char *jjump_pad_insn,
1230 ULONGEST *jjump_pad_insn_size,
1231 CORE_ADDR *adjusted_insn_addr,
1232 CORE_ADDR *adjusted_insn_addr_end,
1233 char *err)
1234 {
1235 int i;
1236 int64_t loffset;
1237 int32_t offset;
1238 unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1239 CORE_ADDR buildaddr = *jump_entry;
1240 #ifdef __s390x__
1241 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1242 int is_64 = register_size (regcache->tdesc, 0) == 8;
1243 int is_zarch = is_64 || have_hwcap_s390_high_gprs;
1244 int has_vx = have_hwcap_s390_vx;
1245 #else
1246 int is_64 = 0, is_zarch = 0, has_vx = 0;
1247 #endif
1248 CORE_ADDR literals[4] = {
1249 tpaddr,
1250 tpoint,
1251 collector,
1252 lockaddr,
1253 };
1254
1255 /* First, store the GPRs. */
1256 if (is_zarch)
1257 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch,
1258 s390_ft_entry_gpr_zarch);
1259 else
1260 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa,
1261 s390_ft_entry_gpr_esa);
1262
1263 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1264 append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc);
1265
1266 /* Third, FRs or VRs. */
1267 if (has_vx)
1268 append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr);
1269 else
1270 append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr);
1271
1272 /* Now, the main part of code - store PSWA, take lock, call collector,
1273 leave lock. First, we'll need to fetch 4 literals. */
1274 if (is_64) {
1275 unsigned char buf[] = {
1276 0x07, 0x07, /* nopr %r7 */
1277 0x07, 0x07, /* nopr %r7 */
1278 0x07, 0x07, /* nopr %r7 */
1279 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1280 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1281 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1282 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1283 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1284 /* .Lend: */
1285 };
1286 /* Find the proper start place in buf, so that literals will be
1287 aligned. */
1288 int bufpos = (buildaddr + 2) & 7;
1289 /* Stuff the literals into the buffer. */
1290 for (i = 0; i < 4; i++) {
1291 uint64_t lit = literals[i];
1292 memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8);
1293 }
1294 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1295 append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64);
1296 } else {
1297 unsigned char buf[] = {
1298 0x07, 0x07, /* nopr %r7 */
1299 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1300 0, 0, 0, 0, /* tpaddr */
1301 0, 0, 0, 0, /* tpoint */
1302 0, 0, 0, 0, /* collector */
1303 0, 0, 0, 0, /* lockaddr */
1304 /* .Lend: */
1305 };
1306 /* Find the proper start place in buf, so that literals will be
1307 aligned. */
1308 int bufpos = (buildaddr + 2) & 3;
1309 /* First literal will be saved as the PSWA, make sure it has the high bit
1310 set. */
1311 literals[0] |= 0x80000000;
1312 /* Stuff the literals into the buffer. */
1313 for (i = 0; i < 4; i++) {
1314 uint32_t lit = literals[i];
1315 memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4);
1316 }
1317 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1318 append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31);
1319 }
1320
1321 /* Restore FRs or VRs. */
1322 if (has_vx)
1323 append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr);
1324 else
1325 append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr);
1326
1327 /* Restore misc registers. */
1328 append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc);
1329
1330 /* Restore the GPRs. */
1331 if (is_zarch)
1332 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch,
1333 s390_ft_exit_gpr_zarch);
1334 else
1335 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa,
1336 s390_ft_exit_gpr_esa);
1337
1338 /* Now, adjust the original instruction to execute in the jump
1339 pad. */
1340 *adjusted_insn_addr = buildaddr;
1341 if (s390_relocate_instruction (&buildaddr, tpaddr, is_64))
1342 {
1343 sprintf (err, "E.Could not relocate instruction for tracepoint.");
1344 return 1;
1345 }
1346 *adjusted_insn_addr_end = buildaddr;
1347
1348 /* Finally, write a jump back to the program. */
1349
1350 loffset = (tpaddr + orig_size) - buildaddr;
1351 loffset >>= 1;
1352 offset = loffset;
1353 if (is_64 && offset != loffset)
1354 {
1355 sprintf (err,
1356 "E.Jump back from jump pad too far from tracepoint "
1357 "(offset 0x%" PRIx64 " > int33).", loffset);
1358 return 1;
1359 }
1360 memcpy (jbuf + 2, &offset, 4);
1361 append_insns (&buildaddr, sizeof jbuf, jbuf);
1362
1363 /* The jump pad is now built. Wire in a jump to our jump pad. This
1364 is always done last (by our caller actually), so that we can
1365 install fast tracepoints with threads running. This relies on
1366 the agent's atomic write support. */
1367 loffset = *jump_entry - tpaddr;
1368 loffset >>= 1;
1369 offset = loffset;
1370 if (is_64 && offset != loffset)
1371 {
1372 sprintf (err,
1373 "E.Jump back from jump pad too far from tracepoint "
1374 "(offset 0x%" PRIx64 " > int33).", loffset);
1375 return 1;
1376 }
1377 memcpy (jbuf + 2, &offset, 4);
1378 memcpy (jjump_pad_insn, jbuf, sizeof jbuf);
1379 *jjump_pad_insn_size = sizeof jbuf;
1380
1381 /* Return the end address of our pad. */
1382 *jump_entry = buildaddr;
1383
1384 return 0;
1385 }
1386
1387 /* Implementation of linux_target_ops method
1388 "get_min_fast_tracepoint_insn_len". */
1389
1390 static int
1391 s390_get_min_fast_tracepoint_insn_len (void)
1392 {
1393 /* We only support using 6-byte jumps to reach the tracepoint code.
1394 If the tracepoint buffer were allocated sufficiently close (64kiB)
1395 to the executable code, and the traced instruction itself was close
1396 enough to the beginning, we could use 4-byte jumps, but this doesn't
1397 seem to be worth the effort. */
1398 return 6;
1399 }
1400
1401 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1402
1403 static int
1404 s390_get_ipa_tdesc_idx (void)
1405 {
1406 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1407 const struct target_desc *tdesc = regcache->tdesc;
1408
1409 #ifdef __s390x__
1410 if (tdesc == tdesc_s390x_linux64)
1411 return S390_TDESC_64;
1412 if (tdesc == tdesc_s390x_linux64v1)
1413 return S390_TDESC_64V1;
1414 if (tdesc == tdesc_s390x_linux64v2)
1415 return S390_TDESC_64V2;
1416 if (tdesc == tdesc_s390x_te_linux64)
1417 return S390_TDESC_TE;
1418 if (tdesc == tdesc_s390x_vx_linux64)
1419 return S390_TDESC_VX;
1420 if (tdesc == tdesc_s390x_tevx_linux64)
1421 return S390_TDESC_TEVX;
1422 if (tdesc == tdesc_s390x_gs_linux64)
1423 return S390_TDESC_GS;
1424 #endif
1425
1426 if (tdesc == tdesc_s390_linux32)
1427 return S390_TDESC_32;
1428 if (tdesc == tdesc_s390_linux32v1)
1429 return S390_TDESC_32V1;
1430 if (tdesc == tdesc_s390_linux32v2)
1431 return S390_TDESC_32V2;
1432 if (tdesc == tdesc_s390_linux64)
1433 return S390_TDESC_64;
1434 if (tdesc == tdesc_s390_linux64v1)
1435 return S390_TDESC_64V1;
1436 if (tdesc == tdesc_s390_linux64v2)
1437 return S390_TDESC_64V2;
1438 if (tdesc == tdesc_s390_te_linux64)
1439 return S390_TDESC_TE;
1440 if (tdesc == tdesc_s390_vx_linux64)
1441 return S390_TDESC_VX;
1442 if (tdesc == tdesc_s390_tevx_linux64)
1443 return S390_TDESC_TEVX;
1444 if (tdesc == tdesc_s390_gs_linux64)
1445 return S390_TDESC_GS;
1446
1447 return 0;
1448 }
1449
1450 /* Appends given buffer to current_insn_ptr in the target. */
1451
1452 static void
1453 add_insns (const unsigned char *start, int len)
1454 {
1455 CORE_ADDR buildaddr = current_insn_ptr;
1456
1457 if (debug_threads)
1458 debug_printf ("Adding %d bytes of insn at %s\n",
1459 len, paddress (buildaddr));
1460
1461 append_insns (&buildaddr, len, start);
1462 current_insn_ptr = buildaddr;
1463 }
1464
1465 /* Register usage in emit:
1466
1467 - %r0, %r1: temp
1468 - %r2: top of stack (high word for 31-bit)
1469 - %r3: low word of top of stack (for 31-bit)
1470 - %r4, %r5: temp
1471 - %r6, %r7, %r8: don't use
1472 - %r9: saved arg1
1473 - %r10: saved arg2
1474 - %r11: frame pointer
1475 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1476 - %r13: low word of saved top of stack (for 31-bit)
1477 - %r14: return address for calls
1478 - %r15: stack pointer
1479
1480 */
1481
1482 /* The "emit_prologue" emit_ops method for s390. */
1483
1484 static void
1485 s390_emit_prologue (void)
1486 {
1487 static const unsigned char buf[] = {
1488 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1489 0x18, 0x92, /* lr %r9, %r2 */
1490 0x18, 0xa3, /* lr %r10, %r3 */
1491 0x18, 0xbf, /* lr %r11, %r15 */
1492 };
1493 add_insns (buf, sizeof buf);
1494 }
1495
1496 /* The "emit_epilogue" emit_ops method for s390. */
1497
1498 static void
1499 s390_emit_epilogue (void)
1500 {
1501 static const unsigned char buf[] = {
1502 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1503 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1504 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1505 0x07, 0xfe, /* br %r14 */
1506 };
1507 add_insns (buf, sizeof buf);
1508 }
1509
1510 /* The "emit_add" emit_ops method for s390. */
1511
1512 static void
1513 s390_emit_add (void)
1514 {
1515 static const unsigned char buf[] = {
1516 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1517 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1518 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1519 };
1520 add_insns (buf, sizeof buf);
1521 }
1522
1523 /* The "emit_sub" emit_ops method for s390. */
1524
1525 static void
1526 s390_emit_sub (void)
1527 {
1528 static const unsigned char buf[] = {
1529 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1530 0x1f, 0x53, /* slr %r5, %r3 */
1531 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1532 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1533 0x18, 0x35, /* lr %r3, %r5 */
1534 0x18, 0x24, /* lr %r2, %r4 */
1535 };
1536 add_insns (buf, sizeof buf);
1537 }
1538
1539 /* The "emit_mul" emit_ops method for s390. */
1540
1541 static void
1542 s390_emit_mul (void)
1543 {
1544 emit_error = 1;
1545 }
1546
1547 /* The "emit_lsh" emit_ops method for s390. */
1548
1549 static void
1550 s390_emit_lsh (void)
1551 {
1552 static const unsigned char buf[] = {
1553 0x18, 0x43, /* lr %r4, %r3 */
1554 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1555 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1556 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1557 };
1558 add_insns (buf, sizeof buf);
1559 }
1560
1561 /* The "emit_rsh_signed" emit_ops method for s390. */
1562
1563 static void
1564 s390_emit_rsh_signed (void)
1565 {
1566 static const unsigned char buf[] = {
1567 0x18, 0x43, /* lr %r4, %r3 */
1568 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1569 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1570 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1571 };
1572 add_insns (buf, sizeof buf);
1573 }
1574
1575 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1576
1577 static void
1578 s390_emit_rsh_unsigned (void)
1579 {
1580 static const unsigned char buf[] = {
1581 0x18, 0x43, /* lr %r4, %r3 */
1582 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1583 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1584 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1585 };
1586 add_insns (buf, sizeof buf);
1587 }
1588
1589 /* The "emit_ext" emit_ops method for s390. */
1590
1591 static void
1592 s390_emit_ext (int arg)
1593 {
1594 unsigned char buf[] = {
1595 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1596 0x8e, 0x20, 0x00, (unsigned char) (64 - arg), /* srda %r2, <64-arg> */
1597 };
1598 add_insns (buf, sizeof buf);
1599 }
1600
1601 /* The "emit_log_not" emit_ops method for s390. */
1602
1603 static void
1604 s390_emit_log_not (void)
1605 {
1606 static const unsigned char buf[] = {
1607 0x16, 0x23, /* or %r2, %r3 */
1608 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1609 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1610 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1611 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1612 /* .Lskip: */
1613 };
1614 add_insns (buf, sizeof buf);
1615 }
1616
1617 /* The "emit_bit_and" emit_ops method for s390. */
1618
1619 static void
1620 s390_emit_bit_and (void)
1621 {
1622 static const unsigned char buf[] = {
1623 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1624 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1625 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1626 };
1627 add_insns (buf, sizeof buf);
1628 }
1629
1630 /* The "emit_bit_or" emit_ops method for s390. */
1631
1632 static void
1633 s390_emit_bit_or (void)
1634 {
1635 static const unsigned char buf[] = {
1636 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1637 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1638 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1639 };
1640 add_insns (buf, sizeof buf);
1641 }
1642
1643 /* The "emit_bit_xor" emit_ops method for s390. */
1644
1645 static void
1646 s390_emit_bit_xor (void)
1647 {
1648 static const unsigned char buf[] = {
1649 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1650 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1651 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1652 };
1653 add_insns (buf, sizeof buf);
1654 }
1655
1656 /* The "emit_bit_not" emit_ops method for s390. */
1657
1658 static void
1659 s390_emit_bit_not (void)
1660 {
1661 static const unsigned char buf[] = {
1662 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1663 0x17, 0x24, /* xr %r2, %r4 */
1664 0x17, 0x34, /* xr %r3, %r4 */
1665 };
1666 add_insns (buf, sizeof buf);
1667 }
1668
1669 /* The "emit_equal" emit_ops method for s390. */
1670
1671 static void
1672 s390_emit_equal (void)
1673 {
1674 s390_emit_bit_xor ();
1675 s390_emit_log_not ();
1676 }
1677
1678 /* The "emit_less_signed" emit_ops method for s390. */
1679
1680 static void
1681 s390_emit_less_signed (void)
1682 {
1683 static const unsigned char buf[] = {
1684 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1685 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1686 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1687 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1688 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1689 /* .Lhigh: */
1690 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1691 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1692 /* .Lless: */
1693 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1694 /* .Lend: */
1695 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1696 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1697 };
1698 add_insns (buf, sizeof buf);
1699 }
1700
1701 /* The "emit_less_unsigned" emit_ops method for s390. */
1702
1703 static void
1704 s390_emit_less_unsigned (void)
1705 {
1706 static const unsigned char buf[] = {
1707 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1708 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1709 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1710 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1711 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1712 /* .Lhigh: */
1713 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1714 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1715 /* .Lless: */
1716 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1717 /* .Lend: */
1718 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1719 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1720 };
1721 add_insns (buf, sizeof buf);
1722 }
1723
1724 /* The "emit_ref" emit_ops method for s390. */
1725
1726 static void
1727 s390_emit_ref (int size)
1728 {
1729 static const unsigned char buf1[] = {
1730 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1731 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1732 };
1733 static const unsigned char buf2[] = {
1734 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1735 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1736 };
1737 static const unsigned char buf4[] = {
1738 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1739 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1740 };
1741 static const unsigned char buf8[] = {
1742 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1743 };
1744 switch (size)
1745 {
1746 case 1:
1747 add_insns (buf1, sizeof buf1);
1748 break;
1749 case 2:
1750 add_insns (buf2, sizeof buf2);
1751 break;
1752 case 4:
1753 add_insns (buf4, sizeof buf4);
1754 break;
1755 case 8:
1756 add_insns (buf8, sizeof buf8);
1757 break;
1758 default:
1759 emit_error = 1;
1760 }
1761 }
1762
1763 /* The "emit_if_goto" emit_ops method for s390. */
1764
1765 static void
1766 s390_emit_if_goto (int *offset_p, int *size_p)
1767 {
1768 static const unsigned char buf[] = {
1769 0x16, 0x23, /* or %r2, %r3 */
1770 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1771 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1772 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1773 };
1774 add_insns (buf, sizeof buf);
1775 if (offset_p)
1776 *offset_p = 12;
1777 if (size_p)
1778 *size_p = 4;
1779 }
1780
1781 /* The "emit_goto" emit_ops method for s390 and s390x. */
1782
1783 static void
1784 s390_emit_goto (int *offset_p, int *size_p)
1785 {
1786 static const unsigned char buf[] = {
1787 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1788 };
1789 add_insns (buf, sizeof buf);
1790 if (offset_p)
1791 *offset_p = 2;
1792 if (size_p)
1793 *size_p = 4;
1794 }
1795
1796 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1797
1798 static void
1799 s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
1800 {
1801 long diff = ((long) (to - (from - 2))) / 2;
1802 int sdiff = diff;
1803 unsigned char buf[sizeof sdiff];
1804
1805 /* We're only doing 4-byte sizes at the moment. */
1806 if (size != sizeof sdiff || sdiff != diff)
1807 {
1808 emit_error = 1;
1809 return;
1810 }
1811
1812 memcpy (buf, &sdiff, sizeof sdiff);
1813 target_write_memory (from, buf, sizeof sdiff);
1814 }
1815
1816 /* Preparation for emitting a literal pool of given size. Loads the address
1817 of the pool into %r1, and jumps over it. Called should emit the pool data
1818 immediately afterwards. Used for both s390 and s390x. */
1819
1820 static void
1821 s390_emit_litpool (int size)
1822 {
1823 static const unsigned char nop[] = {
1824 0x07, 0x07,
1825 };
1826 unsigned char buf[] = {
1827 0xa7, 0x15, 0x00,
1828 (unsigned char) ((size + 4) / 2), /* bras %r1, .Lend+size */
1829 /* .Lend: */
1830 };
1831 if (size == 4)
1832 {
1833 /* buf needs to start at even halfword for litpool to be aligned */
1834 if (current_insn_ptr & 2)
1835 add_insns (nop, sizeof nop);
1836 }
1837 else
1838 {
1839 while ((current_insn_ptr & 6) != 4)
1840 add_insns (nop, sizeof nop);
1841 }
1842 add_insns (buf, sizeof buf);
1843 }
1844
1845 /* The "emit_const" emit_ops method for s390. */
1846
1847 static void
1848 s390_emit_const (LONGEST num)
1849 {
1850 unsigned long long n = num;
1851 unsigned char buf_s[] = {
1852 /* lhi %r3, <num> */
1853 0xa7, 0x38,
1854 (unsigned char) (num >> 8), (unsigned char) num,
1855 /* xr %r2, %r2 */
1856 0x17, 0x22,
1857 };
1858 static const unsigned char buf_l[] = {
1859 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1860 };
1861 if (num < 0x8000 && num >= 0)
1862 {
1863 add_insns (buf_s, sizeof buf_s);
1864 }
1865 else
1866 {
1867 s390_emit_litpool (8);
1868 add_insns ((unsigned char *) &n, sizeof n);
1869 add_insns (buf_l, sizeof buf_l);
1870 }
1871 }
1872
1873 /* The "emit_call" emit_ops method for s390. */
1874
1875 static void
1876 s390_emit_call (CORE_ADDR fn)
1877 {
1878 unsigned int n = fn;
1879 static const unsigned char buf[] = {
1880 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1881 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1882 0x0d, 0xe1, /* basr %r14, %r1 */
1883 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1884 };
1885 s390_emit_litpool (4);
1886 add_insns ((unsigned char *) &n, sizeof n);
1887 add_insns (buf, sizeof buf);
1888 }
1889
1890 /* The "emit_reg" emit_ops method for s390. */
1891
1892 static void
1893 s390_emit_reg (int reg)
1894 {
1895 unsigned char bufpre[] = {
1896 /* lr %r2, %r9 */
1897 0x18, 0x29,
1898 /* lhi %r3, <reg> */
1899 0xa7, 0x38, (unsigned char) (reg >> 8), (unsigned char) reg,
1900 };
1901 add_insns (bufpre, sizeof bufpre);
1902 s390_emit_call (get_raw_reg_func_addr ());
1903 }
1904
1905 /* The "emit_pop" emit_ops method for s390. */
1906
1907 static void
1908 s390_emit_pop (void)
1909 {
1910 static const unsigned char buf[] = {
1911 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1912 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1913 };
1914 add_insns (buf, sizeof buf);
1915 }
1916
1917 /* The "emit_stack_flush" emit_ops method for s390. */
1918
1919 static void
1920 s390_emit_stack_flush (void)
1921 {
1922 static const unsigned char buf[] = {
1923 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1924 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1925 };
1926 add_insns (buf, sizeof buf);
1927 }
1928
1929 /* The "emit_zero_ext" emit_ops method for s390. */
1930
1931 static void
1932 s390_emit_zero_ext (int arg)
1933 {
1934 unsigned char buf[] = {
1935 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1936 0x8c, 0x20, 0x00, (unsigned char) (64 - arg), /* srdl %r2, <64-arg> */
1937 };
1938 add_insns (buf, sizeof buf);
1939 }
1940
1941 /* The "emit_swap" emit_ops method for s390. */
1942
1943 static void
1944 s390_emit_swap (void)
1945 {
1946 static const unsigned char buf[] = {
1947 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1948 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1949 0x18, 0x24, /* lr %r2, %r4 */
1950 0x18, 0x35, /* lr %r3, %r5 */
1951 };
1952 add_insns (buf, sizeof buf);
1953 }
1954
1955 /* The "emit_stack_adjust" emit_ops method for s390. */
1956
1957 static void
1958 s390_emit_stack_adjust (int n)
1959 {
1960 unsigned char buf[] = {
1961 /* ahi %r15, 8*n */
1962 0xa7, 0xfa,
1963 (unsigned char ) (n * 8 >> 8), (unsigned char) (n * 8),
1964 };
1965 add_insns (buf, sizeof buf);
1966 }
1967
1968 /* Sets %r2 to a 32-bit constant. */
1969
1970 static void
1971 s390_emit_set_r2 (int arg1)
1972 {
1973 unsigned char buf_s[] = {
1974 /* lhi %r2, <arg1> */
1975 0xa7, 0x28, (unsigned char) (arg1 >> 8), (unsigned char) arg1,
1976 };
1977 static const unsigned char buf_l[] = {
1978 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1979 };
1980 if (arg1 < 0x8000 && arg1 >= -0x8000)
1981 {
1982 add_insns (buf_s, sizeof buf_s);
1983 }
1984 else
1985 {
1986 s390_emit_litpool (4);
1987 add_insns ((unsigned char *) &arg1, sizeof arg1);
1988 add_insns (buf_l, sizeof buf_l);
1989 }
1990 }
1991
1992 /* The "emit_int_call_1" emit_ops method for s390. */
1993
1994 static void
1995 s390_emit_int_call_1 (CORE_ADDR fn, int arg1)
1996 {
1997 /* FN's prototype is `LONGEST(*fn)(int)'. */
1998 s390_emit_set_r2 (arg1);
1999 s390_emit_call (fn);
2000 }
2001
2002 /* The "emit_void_call_2" emit_ops method for s390. */
2003
2004 static void
2005 s390_emit_void_call_2 (CORE_ADDR fn, int arg1)
2006 {
2007 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2008 static const unsigned char buf[] = {
2009 0x18, 0xc2, /* lr %r12, %r2 */
2010 0x18, 0xd3, /* lr %r13, %r3 */
2011 0x18, 0x43, /* lr %r4, %r3 */
2012 0x18, 0x32, /* lr %r3, %r2 */
2013 };
2014 static const unsigned char buf2[] = {
2015 0x18, 0x2c, /* lr %r2, %r12 */
2016 0x18, 0x3d, /* lr %r3, %r13 */
2017 };
2018 add_insns (buf, sizeof buf);
2019 s390_emit_set_r2 (arg1);
2020 s390_emit_call (fn);
2021 add_insns (buf2, sizeof buf2);
2022 }
2023
2024 /* The "emit_eq_goto" emit_ops method for s390. */
2025
2026 static void
2027 s390_emit_eq_goto (int *offset_p, int *size_p)
2028 {
2029 static const unsigned char buf[] = {
2030 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2031 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2032 0x16, 0x23, /* or %r2, %r3 */
2033 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2034 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2035 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2036 };
2037 add_insns (buf, sizeof buf);
2038 if (offset_p)
2039 *offset_p = 20;
2040 if (size_p)
2041 *size_p = 4;
2042 }
2043
2044 /* The "emit_ne_goto" emit_ops method for s390. */
2045
2046 static void
2047 s390_emit_ne_goto (int *offset_p, int *size_p)
2048 {
2049 static const unsigned char buf[] = {
2050 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2051 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2052 0x16, 0x23, /* or %r2, %r3 */
2053 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2054 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2055 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2056 };
2057 add_insns (buf, sizeof buf);
2058 if (offset_p)
2059 *offset_p = 20;
2060 if (size_p)
2061 *size_p = 4;
2062 }
2063
2064 /* The "emit_lt_goto" emit_ops method for s390. */
2065
2066 static void
2067 s390_emit_lt_goto (int *offset_p, int *size_p)
2068 {
2069 static const unsigned char buf[] = {
2070 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2071 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2072 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2073 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2074 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2075 /* .Lfalse: */
2076 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2077 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2078 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2079 /* .Ltrue: */
2080 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2081 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2082 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2083 /* .Lend: */
2084 };
2085 add_insns (buf, sizeof buf);
2086 if (offset_p)
2087 *offset_p = 42;
2088 if (size_p)
2089 *size_p = 4;
2090 }
2091
2092 /* The "emit_le_goto" emit_ops method for s390. */
2093
2094 static void
2095 s390_emit_le_goto (int *offset_p, int *size_p)
2096 {
2097 static const unsigned char buf[] = {
2098 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2099 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2100 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2101 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2102 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2103 /* .Lfalse: */
2104 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2105 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2106 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2107 /* .Ltrue: */
2108 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2109 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2110 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2111 /* .Lend: */
2112 };
2113 add_insns (buf, sizeof buf);
2114 if (offset_p)
2115 *offset_p = 42;
2116 if (size_p)
2117 *size_p = 4;
2118 }
2119
2120 /* The "emit_gt_goto" emit_ops method for s390. */
2121
2122 static void
2123 s390_emit_gt_goto (int *offset_p, int *size_p)
2124 {
2125 static const unsigned char buf[] = {
2126 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2127 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2128 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2129 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2130 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2131 /* .Lfalse: */
2132 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2133 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2134 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2135 /* .Ltrue: */
2136 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2137 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2138 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2139 /* .Lend: */
2140 };
2141 add_insns (buf, sizeof buf);
2142 if (offset_p)
2143 *offset_p = 42;
2144 if (size_p)
2145 *size_p = 4;
2146 }
2147
2148 /* The "emit_ge_goto" emit_ops method for s390. */
2149
2150 static void
2151 s390_emit_ge_goto (int *offset_p, int *size_p)
2152 {
2153 static const unsigned char buf[] = {
2154 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2155 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2156 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2157 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2158 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2159 /* .Lfalse: */
2160 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2161 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2162 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2163 /* .Ltrue: */
2164 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2165 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2166 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2167 /* .Lend: */
2168 };
2169 add_insns (buf, sizeof buf);
2170 if (offset_p)
2171 *offset_p = 42;
2172 if (size_p)
2173 *size_p = 4;
2174 }
2175
2176 /* The "emit_ops" structure for s390. Named _impl to avoid name
2177 collision with s390_emit_ops function. */
2178
2179 static struct emit_ops s390_emit_ops_impl =
2180 {
2181 s390_emit_prologue,
2182 s390_emit_epilogue,
2183 s390_emit_add,
2184 s390_emit_sub,
2185 s390_emit_mul,
2186 s390_emit_lsh,
2187 s390_emit_rsh_signed,
2188 s390_emit_rsh_unsigned,
2189 s390_emit_ext,
2190 s390_emit_log_not,
2191 s390_emit_bit_and,
2192 s390_emit_bit_or,
2193 s390_emit_bit_xor,
2194 s390_emit_bit_not,
2195 s390_emit_equal,
2196 s390_emit_less_signed,
2197 s390_emit_less_unsigned,
2198 s390_emit_ref,
2199 s390_emit_if_goto,
2200 s390_emit_goto,
2201 s390_write_goto_address,
2202 s390_emit_const,
2203 s390_emit_call,
2204 s390_emit_reg,
2205 s390_emit_pop,
2206 s390_emit_stack_flush,
2207 s390_emit_zero_ext,
2208 s390_emit_swap,
2209 s390_emit_stack_adjust,
2210 s390_emit_int_call_1,
2211 s390_emit_void_call_2,
2212 s390_emit_eq_goto,
2213 s390_emit_ne_goto,
2214 s390_emit_lt_goto,
2215 s390_emit_le_goto,
2216 s390_emit_gt_goto,
2217 s390_emit_ge_goto
2218 };
2219
2220 #ifdef __s390x__
2221
2222 /* The "emit_prologue" emit_ops method for s390x. */
2223
2224 static void
2225 s390x_emit_prologue (void)
2226 {
2227 static const unsigned char buf[] = {
2228 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2229 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2230 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2231 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2232 };
2233 add_insns (buf, sizeof buf);
2234 }
2235
2236 /* The "emit_epilogue" emit_ops method for s390x. */
2237
2238 static void
2239 s390x_emit_epilogue (void)
2240 {
2241 static const unsigned char buf[] = {
2242 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2243 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2244 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2245 0x07, 0xfe, /* br %r14 */
2246 };
2247 add_insns (buf, sizeof buf);
2248 }
2249
2250 /* The "emit_add" emit_ops method for s390x. */
2251
2252 static void
2253 s390x_emit_add (void)
2254 {
2255 static const unsigned char buf[] = {
2256 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2257 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2258 };
2259 add_insns (buf, sizeof buf);
2260 }
2261
2262 /* The "emit_sub" emit_ops method for s390x. */
2263
2264 static void
2265 s390x_emit_sub (void)
2266 {
2267 static const unsigned char buf[] = {
2268 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2269 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2270 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2271 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2272 };
2273 add_insns (buf, sizeof buf);
2274 }
2275
2276 /* The "emit_mul" emit_ops method for s390x. */
2277
2278 static void
2279 s390x_emit_mul (void)
2280 {
2281 emit_error = 1;
2282 }
2283
2284 /* The "emit_lsh" emit_ops method for s390x. */
2285
2286 static void
2287 s390x_emit_lsh (void)
2288 {
2289 static const unsigned char buf[] = {
2290 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2291 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2292 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2293 };
2294 add_insns (buf, sizeof buf);
2295 }
2296
2297 /* The "emit_rsh_signed" emit_ops method for s390x. */
2298
2299 static void
2300 s390x_emit_rsh_signed (void)
2301 {
2302 static const unsigned char buf[] = {
2303 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2304 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2305 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2306 };
2307 add_insns (buf, sizeof buf);
2308 }
2309
2310 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2311
2312 static void
2313 s390x_emit_rsh_unsigned (void)
2314 {
2315 static const unsigned char buf[] = {
2316 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2317 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2318 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2319 };
2320 add_insns (buf, sizeof buf);
2321 }
2322
2323 /* The "emit_ext" emit_ops method for s390x. */
2324
2325 static void
2326 s390x_emit_ext (int arg)
2327 {
2328 unsigned char buf[] = {
2329 /* sllg %r2, %r2, <64-arg> */
2330 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2331 /* srag %r2, %r2, <64-arg> */
2332 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0a,
2333 };
2334 add_insns (buf, sizeof buf);
2335 }
2336
2337 /* The "emit_log_not" emit_ops method for s390x. */
2338
2339 static void
2340 s390x_emit_log_not (void)
2341 {
2342 static const unsigned char buf[] = {
2343 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2344 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2345 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2346 };
2347 add_insns (buf, sizeof buf);
2348 }
2349
2350 /* The "emit_bit_and" emit_ops method for s390x. */
2351
2352 static void
2353 s390x_emit_bit_and (void)
2354 {
2355 static const unsigned char buf[] = {
2356 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2357 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2358 };
2359 add_insns (buf, sizeof buf);
2360 }
2361
2362 /* The "emit_bit_or" emit_ops method for s390x. */
2363
2364 static void
2365 s390x_emit_bit_or (void)
2366 {
2367 static const unsigned char buf[] = {
2368 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2369 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2370 };
2371 add_insns (buf, sizeof buf);
2372 }
2373
2374 /* The "emit_bit_xor" emit_ops method for s390x. */
2375
2376 static void
2377 s390x_emit_bit_xor (void)
2378 {
2379 static const unsigned char buf[] = {
2380 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2381 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2382 };
2383 add_insns (buf, sizeof buf);
2384 }
2385
2386 /* The "emit_bit_not" emit_ops method for s390x. */
2387
2388 static void
2389 s390x_emit_bit_not (void)
2390 {
2391 static const unsigned char buf[] = {
2392 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2393 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2394 };
2395 add_insns (buf, sizeof buf);
2396 }
2397
2398 /* The "emit_equal" emit_ops method for s390x. */
2399
2400 static void
2401 s390x_emit_equal (void)
2402 {
2403 s390x_emit_bit_xor ();
2404 s390x_emit_log_not ();
2405 }
2406
2407 /* The "emit_less_signed" emit_ops method for s390x. */
2408
2409 static void
2410 s390x_emit_less_signed (void)
2411 {
2412 static const unsigned char buf[] = {
2413 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2414 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2415 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2416 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2417 /* .Lend: */
2418 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2419 };
2420 add_insns (buf, sizeof buf);
2421 }
2422
2423 /* The "emit_less_unsigned" emit_ops method for s390x. */
2424
2425 static void
2426 s390x_emit_less_unsigned (void)
2427 {
2428 static const unsigned char buf[] = {
2429 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2430 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2431 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2432 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2433 /* .Lend: */
2434 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2435 };
2436 add_insns (buf, sizeof buf);
2437 }
2438
2439 /* The "emit_ref" emit_ops method for s390x. */
2440
2441 static void
2442 s390x_emit_ref (int size)
2443 {
2444 static const unsigned char buf1[] = {
2445 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2446 };
2447 static const unsigned char buf2[] = {
2448 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2449 };
2450 static const unsigned char buf4[] = {
2451 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2452 };
2453 static const unsigned char buf8[] = {
2454 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2455 };
2456 switch (size)
2457 {
2458 case 1:
2459 add_insns (buf1, sizeof buf1);
2460 break;
2461 case 2:
2462 add_insns (buf2, sizeof buf2);
2463 break;
2464 case 4:
2465 add_insns (buf4, sizeof buf4);
2466 break;
2467 case 8:
2468 add_insns (buf8, sizeof buf8);
2469 break;
2470 default:
2471 emit_error = 1;
2472 }
2473 }
2474
2475 /* The "emit_if_goto" emit_ops method for s390x. */
2476
2477 static void
2478 s390x_emit_if_goto (int *offset_p, int *size_p)
2479 {
2480 static const unsigned char buf[] = {
2481 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2482 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2483 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2484 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2485 };
2486 add_insns (buf, sizeof buf);
2487 if (offset_p)
2488 *offset_p = 16;
2489 if (size_p)
2490 *size_p = 4;
2491 }
2492
2493 /* The "emit_const" emit_ops method for s390x. */
2494
2495 static void
2496 s390x_emit_const (LONGEST num)
2497 {
2498 unsigned long long n = num;
2499 unsigned char buf_s[] = {
2500 /* lghi %r2, <num> */
2501 0xa7, 0x29, (unsigned char) (num >> 8), (unsigned char) num,
2502 };
2503 static const unsigned char buf_l[] = {
2504 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2505 };
2506 if (num < 0x8000 && num >= -0x8000)
2507 {
2508 add_insns (buf_s, sizeof buf_s);
2509 }
2510 else
2511 {
2512 s390_emit_litpool (8);
2513 add_insns ((unsigned char *) &n, sizeof n);
2514 add_insns (buf_l, sizeof buf_l);
2515 }
2516 }
2517
2518 /* The "emit_call" emit_ops method for s390x. */
2519
2520 static void
2521 s390x_emit_call (CORE_ADDR fn)
2522 {
2523 unsigned long n = fn;
2524 static const unsigned char buf[] = {
2525 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2526 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2527 0x0d, 0xe1, /* basr %r14, %r1 */
2528 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2529 };
2530 s390_emit_litpool (8);
2531 add_insns ((unsigned char *) &n, sizeof n);
2532 add_insns (buf, sizeof buf);
2533 }
2534
2535 /* The "emit_reg" emit_ops method for s390x. */
2536
2537 static void
2538 s390x_emit_reg (int reg)
2539 {
2540 unsigned char buf[] = {
2541 /* lgr %r2, %r9 */
2542 0xb9, 0x04, 0x00, 0x29,
2543 /* lghi %r3, <reg> */
2544 0xa7, 0x39, (unsigned char) (reg >> 8), (unsigned char) reg,
2545 };
2546 add_insns (buf, sizeof buf);
2547 s390x_emit_call (get_raw_reg_func_addr ());
2548 }
2549
2550 /* The "emit_pop" emit_ops method for s390x. */
2551
2552 static void
2553 s390x_emit_pop (void)
2554 {
2555 static const unsigned char buf[] = {
2556 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2557 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2558 };
2559 add_insns (buf, sizeof buf);
2560 }
2561
2562 /* The "emit_stack_flush" emit_ops method for s390x. */
2563
2564 static void
2565 s390x_emit_stack_flush (void)
2566 {
2567 static const unsigned char buf[] = {
2568 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2569 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2570 };
2571 add_insns (buf, sizeof buf);
2572 }
2573
2574 /* The "emit_zero_ext" emit_ops method for s390x. */
2575
2576 static void
2577 s390x_emit_zero_ext (int arg)
2578 {
2579 unsigned char buf[] = {
2580 /* sllg %r2, %r2, <64-arg> */
2581 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2582 /* srlg %r2, %r2, <64-arg> */
2583 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0c,
2584 };
2585 add_insns (buf, sizeof buf);
2586 }
2587
2588 /* The "emit_swap" emit_ops method for s390x. */
2589
2590 static void
2591 s390x_emit_swap (void)
2592 {
2593 static const unsigned char buf[] = {
2594 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2595 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2596 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2597 };
2598 add_insns (buf, sizeof buf);
2599 }
2600
2601 /* The "emit_stack_adjust" emit_ops method for s390x. */
2602
2603 static void
2604 s390x_emit_stack_adjust (int n)
2605 {
2606 unsigned char buf[] = {
2607 /* aghi %r15, 8*n */
2608 0xa7, 0xfb,
2609 (unsigned char) (n * 8 >> 8), (unsigned char) (n * 8),
2610 };
2611 add_insns (buf, sizeof buf);
2612 }
2613
2614 /* The "emit_int_call_1" emit_ops method for s390x. */
2615
2616 static void
2617 s390x_emit_int_call_1 (CORE_ADDR fn, int arg1)
2618 {
2619 /* FN's prototype is `LONGEST(*fn)(int)'. */
2620 s390x_emit_const (arg1);
2621 s390x_emit_call (fn);
2622 }
2623
2624 /* The "emit_void_call_2" emit_ops method for s390x. */
2625
2626 static void
2627 s390x_emit_void_call_2 (CORE_ADDR fn, int arg1)
2628 {
2629 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2630 static const unsigned char buf[] = {
2631 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2632 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2633 };
2634 static const unsigned char buf2[] = {
2635 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2636 };
2637 add_insns (buf, sizeof buf);
2638 s390x_emit_const (arg1);
2639 s390x_emit_call (fn);
2640 add_insns (buf2, sizeof buf2);
2641 }
2642
2643 /* The "emit_eq_goto" emit_ops method for s390x. */
2644
2645 static void
2646 s390x_emit_eq_goto (int *offset_p, int *size_p)
2647 {
2648 static const unsigned char buf[] = {
2649 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2650 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2651 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2652 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2653 };
2654 add_insns (buf, sizeof buf);
2655 if (offset_p)
2656 *offset_p = 18;
2657 if (size_p)
2658 *size_p = 4;
2659 }
2660
2661 /* The "emit_ne_goto" emit_ops method for s390x. */
2662
2663 static void
2664 s390x_emit_ne_goto (int *offset_p, int *size_p)
2665 {
2666 static const unsigned char buf[] = {
2667 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2668 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2669 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2670 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2671 };
2672 add_insns (buf, sizeof buf);
2673 if (offset_p)
2674 *offset_p = 18;
2675 if (size_p)
2676 *size_p = 4;
2677 }
2678
2679 /* The "emit_lt_goto" emit_ops method for s390x. */
2680
2681 static void
2682 s390x_emit_lt_goto (int *offset_p, int *size_p)
2683 {
2684 static const unsigned char buf[] = {
2685 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2686 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2687 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2688 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2689 };
2690 add_insns (buf, sizeof buf);
2691 if (offset_p)
2692 *offset_p = 18;
2693 if (size_p)
2694 *size_p = 4;
2695 }
2696
2697 /* The "emit_le_goto" emit_ops method for s390x. */
2698
2699 static void
2700 s390x_emit_le_goto (int *offset_p, int *size_p)
2701 {
2702 static const unsigned char buf[] = {
2703 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2704 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2705 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2706 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2707 };
2708 add_insns (buf, sizeof buf);
2709 if (offset_p)
2710 *offset_p = 18;
2711 if (size_p)
2712 *size_p = 4;
2713 }
2714
2715 /* The "emit_gt_goto" emit_ops method for s390x. */
2716
2717 static void
2718 s390x_emit_gt_goto (int *offset_p, int *size_p)
2719 {
2720 static const unsigned char buf[] = {
2721 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2722 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2723 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2724 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2725 };
2726 add_insns (buf, sizeof buf);
2727 if (offset_p)
2728 *offset_p = 18;
2729 if (size_p)
2730 *size_p = 4;
2731 }
2732
2733 /* The "emit_ge_goto" emit_ops method for s390x. */
2734
2735 static void
2736 s390x_emit_ge_goto (int *offset_p, int *size_p)
2737 {
2738 static const unsigned char buf[] = {
2739 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2740 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2741 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2742 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2743 };
2744 add_insns (buf, sizeof buf);
2745 if (offset_p)
2746 *offset_p = 18;
2747 if (size_p)
2748 *size_p = 4;
2749 }
2750
2751 /* The "emit_ops" structure for s390x. */
2752
2753 static struct emit_ops s390x_emit_ops =
2754 {
2755 s390x_emit_prologue,
2756 s390x_emit_epilogue,
2757 s390x_emit_add,
2758 s390x_emit_sub,
2759 s390x_emit_mul,
2760 s390x_emit_lsh,
2761 s390x_emit_rsh_signed,
2762 s390x_emit_rsh_unsigned,
2763 s390x_emit_ext,
2764 s390x_emit_log_not,
2765 s390x_emit_bit_and,
2766 s390x_emit_bit_or,
2767 s390x_emit_bit_xor,
2768 s390x_emit_bit_not,
2769 s390x_emit_equal,
2770 s390x_emit_less_signed,
2771 s390x_emit_less_unsigned,
2772 s390x_emit_ref,
2773 s390x_emit_if_goto,
2774 s390_emit_goto,
2775 s390_write_goto_address,
2776 s390x_emit_const,
2777 s390x_emit_call,
2778 s390x_emit_reg,
2779 s390x_emit_pop,
2780 s390x_emit_stack_flush,
2781 s390x_emit_zero_ext,
2782 s390x_emit_swap,
2783 s390x_emit_stack_adjust,
2784 s390x_emit_int_call_1,
2785 s390x_emit_void_call_2,
2786 s390x_emit_eq_goto,
2787 s390x_emit_ne_goto,
2788 s390x_emit_lt_goto,
2789 s390x_emit_le_goto,
2790 s390x_emit_gt_goto,
2791 s390x_emit_ge_goto
2792 };
2793 #endif
2794
2795 /* The "emit_ops" linux_target_ops method. */
2796
2797 static struct emit_ops *
2798 s390_emit_ops (void)
2799 {
2800 #ifdef __s390x__
2801 struct regcache *regcache = get_thread_regcache (current_thread, 0);
2802
2803 if (register_size (regcache->tdesc, 0) == 8)
2804 return &s390x_emit_ops;
2805 else
2806 #endif
2807 return &s390_emit_ops_impl;
2808 }
2809
2810 struct linux_target_ops the_low_target = {
2811 s390_cannot_fetch_register,
2812 s390_cannot_store_register,
2813 NULL, /* fetch_register */
2814 s390_get_pc,
2815 s390_set_pc,
2816 NULL, /* breakpoint_kind_from_pc */
2817 s390_sw_breakpoint_from_kind,
2818 NULL,
2819 s390_breakpoint_len,
2820 s390_breakpoint_at,
2821 s390_supports_z_point_type,
2822 NULL,
2823 NULL,
2824 NULL,
2825 NULL,
2826 s390_collect_ptrace_register,
2827 s390_supply_ptrace_register,
2828 NULL, /* siginfo_fixup */
2829 NULL, /* new_process */
2830 NULL, /* delete_process */
2831 NULL, /* new_thread */
2832 NULL, /* delete_thread */
2833 NULL, /* new_fork */
2834 NULL, /* prepare_to_resume */
2835 NULL, /* process_qsupported */
2836 s390_supports_tracepoints,
2837 s390_get_thread_area,
2838 s390_install_fast_tracepoint_jump_pad,
2839 s390_emit_ops,
2840 s390_get_min_fast_tracepoint_insn_len,
2841 NULL, /* supports_range_stepping */
2842 NULL, /* breakpoint_kind_from_current_state */
2843 s390_supports_hardware_single_step,
2844 NULL, /* get_syscall_trapinfo */
2845 s390_get_ipa_tdesc_idx,
2846 };
2847
2848 /* The linux target ops object. */
2849
2850 linux_process_target *the_linux_target = &the_s390_target;
2851
2852 void
2853 initialize_low_arch (void)
2854 {
2855 /* Initialize the Linux target descriptions. */
2856
2857 init_registers_s390_linux32 ();
2858 init_registers_s390_linux32v1 ();
2859 init_registers_s390_linux32v2 ();
2860 init_registers_s390_linux64 ();
2861 init_registers_s390_linux64v1 ();
2862 init_registers_s390_linux64v2 ();
2863 init_registers_s390_te_linux64 ();
2864 init_registers_s390_vx_linux64 ();
2865 init_registers_s390_tevx_linux64 ();
2866 init_registers_s390_gs_linux64 ();
2867 #ifdef __s390x__
2868 init_registers_s390x_linux64 ();
2869 init_registers_s390x_linux64v1 ();
2870 init_registers_s390x_linux64v2 ();
2871 init_registers_s390x_te_linux64 ();
2872 init_registers_s390x_vx_linux64 ();
2873 init_registers_s390x_tevx_linux64 ();
2874 init_registers_s390x_gs_linux64 ();
2875 #endif
2876
2877 initialize_regsets_info (&s390_regsets_info);
2878 initialize_regsets_info (&s390_regsets_info_3264);
2879 }
This page took 0.191914 seconds and 4 git commands to generate.