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