1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* This file is used for both 31-bit and 64-bit S/390 systems. */
23 #include "linux-low.h"
24 #include "elf/common.h"
26 #include "tracepoint.h"
28 #include <asm/ptrace.h>
29 #include "nat/gdb_ptrace.h"
34 #include "linux-s390-tdesc.h"
36 #ifndef HWCAP_S390_HIGH_GPRS
37 #define HWCAP_S390_HIGH_GPRS 512
41 #define HWCAP_S390_TE 1024
45 #define HWCAP_S390_VX 2048
49 #define HWCAP_S390_GS 16384
52 #define s390_num_regs 52
54 static int s390_regmap[] = {
55 PT_PSWMASK, PT_PSWADDR,
57 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
58 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
59 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
60 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
62 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
63 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
64 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
65 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
70 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
71 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
72 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
73 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
75 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
76 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
77 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
78 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
84 #define s390_num_regs_3264 68
87 static int s390_regmap_3264[] = {
88 PT_PSWMASK, PT_PSWADDR,
90 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
91 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
92 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
93 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
94 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
95 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
96 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
97 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
99 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
100 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
101 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
102 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
106 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
107 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
108 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
109 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
114 static int s390_regmap_3264[] = {
115 PT_PSWMASK, PT_PSWADDR,
117 -1, PT_GPR0, -1, PT_GPR1,
118 -1, PT_GPR2, -1, PT_GPR3,
119 -1, PT_GPR4, -1, PT_GPR5,
120 -1, PT_GPR6, -1, PT_GPR7,
121 -1, PT_GPR8, -1, PT_GPR9,
122 -1, PT_GPR10, -1, PT_GPR11,
123 -1, PT_GPR12, -1, PT_GPR13,
124 -1, PT_GPR14, -1, PT_GPR15,
126 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
127 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
128 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
129 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
133 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
134 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
135 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
136 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
144 s390_cannot_fetch_register (int regno)
150 s390_cannot_store_register (int regno)
156 s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
158 int size = register_size (regcache->tdesc, regno);
159 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
160 struct usrregs_info *usr = regs_info->usrregs;
161 int regaddr = usr->regmap[regno];
163 if (size < sizeof (long))
165 memset (buf, 0, sizeof (long));
167 if ((regno ^ 1) < usr->num_regs
168 && usr->regmap[regno ^ 1] == regaddr)
170 collect_register (regcache, regno & ~1, buf);
171 collect_register (regcache, (regno & ~1) + 1,
172 buf + sizeof (long) - size);
174 else if (regaddr == PT_PSWMASK)
176 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
177 the basic addressing mode bit from the PSW address. */
178 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
179 collect_register (regcache, regno, buf);
180 collect_register (regcache, regno ^ 1, addr);
182 buf[size] |= (addr[0] & 0x80);
184 else if (regaddr == PT_PSWADDR)
186 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
187 mode bit (which gets copied to the PSW mask instead). */
188 collect_register (regcache, regno, buf + sizeof (long) - size);
189 buf[sizeof (long) - size] &= ~0x80;
191 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
192 || regaddr == PT_ORIGGPR2)
193 collect_register (regcache, regno, buf + sizeof (long) - size);
195 collect_register (regcache, regno, buf);
197 else if (regaddr != -1)
198 collect_register (regcache, regno, buf);
202 s390_supply_ptrace_register (struct regcache *regcache,
203 int regno, const char *buf)
205 int size = register_size (regcache->tdesc, regno);
206 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
207 struct usrregs_info *usr = regs_info->usrregs;
208 int regaddr = usr->regmap[regno];
210 if (size < sizeof (long))
212 if ((regno ^ 1) < usr->num_regs
213 && usr->regmap[regno ^ 1] == regaddr)
215 supply_register (regcache, regno & ~1, buf);
216 supply_register (regcache, (regno & ~1) + 1,
217 buf + sizeof (long) - size);
219 else if (regaddr == PT_PSWMASK)
221 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
222 the basic addressing mode into the PSW address. */
223 gdb_byte *mask = (gdb_byte *) alloca (size);
224 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
225 memcpy (mask, buf, size);
227 supply_register (regcache, regno, mask);
229 collect_register (regcache, regno ^ 1, addr);
231 addr[0] |= (buf[size] & 0x80);
232 supply_register (regcache, regno ^ 1, addr);
234 else if (regaddr == PT_PSWADDR)
236 /* Convert 8-byte PSW address to 4 bytes by truncating, but
237 keeping the addressing mode bit (which was set from the mask). */
238 gdb_byte *addr = (gdb_byte *) alloca (size);
240 collect_register (regcache, regno, addr);
241 amode = addr[0] & 0x80;
242 memcpy (addr, buf + sizeof (long) - size, size);
245 supply_register (regcache, regno, addr);
247 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
248 || regaddr == PT_ORIGGPR2)
249 supply_register (regcache, regno, buf + sizeof (long) - size);
251 supply_register (regcache, regno, buf);
253 else if (regaddr != -1)
254 supply_register (regcache, regno, buf);
257 /* Provide only a fill function for the general register set. ps_lgetregs
258 will use this for NPTL support. */
261 s390_fill_gregset (struct regcache *regcache, void *buf)
264 const struct regs_info *regs_info = (*the_low_target.regs_info) ();
265 struct usrregs_info *usr = regs_info->usrregs;
267 for (i = 0; i < usr->num_regs; i++)
269 if (usr->regmap[i] < PT_PSWMASK
270 || usr->regmap[i] > PT_ACR15)
273 s390_collect_ptrace_register (regcache, i,
274 (char *) buf + usr->regmap[i]);
278 /* Fill and store functions for extended register sets. */
282 s390_fill_gprs_high (struct regcache *regcache, void *buf)
284 int r0h = find_regno (regcache->tdesc, "r0h");
287 for (i = 0; i < 16; i++)
288 collect_register (regcache, r0h + 2 * i, (char *) buf + 4 * i);
292 s390_store_gprs_high (struct regcache *regcache, const void *buf)
294 int r0h = find_regno (regcache->tdesc, "r0h");
297 for (i = 0; i < 16; i++)
298 supply_register (regcache, r0h + 2 * i, (const char *) buf + 4 * i);
303 s390_store_last_break (struct regcache *regcache, const void *buf)
307 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
308 supply_register_by_name (regcache, "last_break", p);
312 s390_fill_system_call (struct regcache *regcache, void *buf)
314 collect_register_by_name (regcache, "system_call", buf);
318 s390_store_system_call (struct regcache *regcache, const void *buf)
320 supply_register_by_name (regcache, "system_call", buf);
324 s390_store_tdb (struct regcache *regcache, const void *buf)
326 int tdb0 = find_regno (regcache->tdesc, "tdb0");
327 int tr0 = find_regno (regcache->tdesc, "tr0");
330 for (i = 0; i < 4; i++)
331 supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
333 for (i = 0; i < 16; i++)
334 supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
338 s390_fill_vxrs_low (struct regcache *regcache, void *buf)
340 int v0 = find_regno (regcache->tdesc, "v0l");
343 for (i = 0; i < 16; i++)
344 collect_register (regcache, v0 + i, (char *) buf + 8 * i);
348 s390_store_vxrs_low (struct regcache *regcache, const void *buf)
350 int v0 = find_regno (regcache->tdesc, "v0l");
353 for (i = 0; i < 16; i++)
354 supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
358 s390_fill_vxrs_high (struct regcache *regcache, void *buf)
360 int v16 = find_regno (regcache->tdesc, "v16");
363 for (i = 0; i < 16; i++)
364 collect_register (regcache, v16 + i, (char *) buf + 16 * i);
368 s390_store_vxrs_high (struct regcache *regcache, const void *buf)
370 int v16 = find_regno (regcache->tdesc, "v16");
373 for (i = 0; i < 16; i++)
374 supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
378 s390_fill_gs (struct regcache *regcache, void *buf)
380 int gsd = find_regno (regcache->tdesc, "gsd");
383 for (i = 0; i < 3; i++)
384 collect_register (regcache, gsd + i, (char *) buf + 8 * (i + 1));
388 s390_store_gs (struct regcache *regcache, const void *buf)
390 int gsd = find_regno (regcache->tdesc, "gsd");
393 for (i = 0; i < 3; i++)
394 supply_register (regcache, gsd + i, (const char *) buf + 8 * (i + 1));
398 s390_fill_gsbc (struct regcache *regcache, void *buf)
400 int bc_gsd = find_regno (regcache->tdesc, "bc_gsd");
403 for (i = 0; i < 3; i++)
404 collect_register (regcache, bc_gsd + i, (char *) buf + 8 * (i + 1));
408 s390_store_gsbc (struct regcache *regcache, const void *buf)
410 int bc_gsd = find_regno (regcache->tdesc, "bc_gsd");
413 for (i = 0; i < 3; i++)
414 supply_register (regcache, bc_gsd + i, (const char *) buf + 8 * (i + 1));
417 static struct regset_info s390_regsets[] = {
418 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
420 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_HIGH_GPRS, 0,
421 EXTENDED_REGS, s390_fill_gprs_high, s390_store_gprs_high },
423 /* Last break address is read-only; no fill function. */
424 { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
425 NULL, s390_store_last_break },
426 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
427 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
428 /* TDB is read-only. */
429 { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
430 NULL, s390_store_tdb },
431 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
432 EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
433 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
434 EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
435 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_GS_CB, 0,
436 EXTENDED_REGS, s390_fill_gs, s390_store_gs },
437 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_GS_BC, 0,
438 EXTENDED_REGS, s390_fill_gsbc, s390_store_gsbc },
443 static const gdb_byte s390_breakpoint[] = { 0, 1 };
444 #define s390_breakpoint_len 2
446 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
448 static const gdb_byte *
449 s390_sw_breakpoint_from_kind (int kind, int *size)
451 *size = s390_breakpoint_len;
452 return s390_breakpoint;
456 s390_get_pc (struct regcache *regcache)
458 if (register_size (regcache->tdesc, 0) == 4)
461 collect_register_by_name (regcache, "pswa", &pswa);
462 return pswa & 0x7fffffff;
467 collect_register_by_name (regcache, "pswa", &pc);
473 s390_set_pc (struct regcache *regcache, CORE_ADDR newpc)
475 if (register_size (regcache->tdesc, 0) == 4)
478 collect_register_by_name (regcache, "pswa", &pswa);
479 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
480 supply_register_by_name (regcache, "pswa", &pswa);
484 unsigned long pc = newpc;
485 supply_register_by_name (regcache, "pswa", &pc);
490 s390_get_hwcap (const struct target_desc *tdesc)
492 int wordsize = register_size (tdesc, 0);
493 gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
496 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
500 unsigned int *data_p = (unsigned int *)data;
501 if (data_p[0] == AT_HWCAP)
506 unsigned long *data_p = (unsigned long *)data;
507 if (data_p[0] == AT_HWCAP)
511 offset += 2 * wordsize;
518 s390_check_regset (int pid, int regset, int regsize)
520 void *buf = alloca (regsize);
524 iov.iov_len = regsize;
526 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
532 /* For a 31-bit inferior, whether the kernel supports using the full
534 static int have_hwcap_s390_high_gprs = 0;
535 static int have_hwcap_s390_vx = 0;
538 s390_arch_setup (void)
540 const struct target_desc *tdesc;
541 struct regset_info *regset;
543 /* Check whether the kernel supports extra register sets. */
544 int pid = pid_of (current_thread);
545 int have_regset_last_break
546 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
547 int have_regset_system_call
548 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
549 int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);
550 int have_regset_vxrs = s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
551 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256);
552 int have_regset_gs = s390_check_regset (pid, NT_S390_GS_CB, 32)
553 && s390_check_regset (pid, NT_S390_GS_BC, 32);
555 /* Assume 31-bit inferior process. */
556 if (have_regset_system_call)
557 tdesc = tdesc_s390_linux32v2;
558 else if (have_regset_last_break)
559 tdesc = tdesc_s390_linux32v1;
561 tdesc = tdesc_s390_linux32;
563 /* On a 64-bit host, check the low bit of the (31-bit) PSWM
564 -- if this is one, we actually have a 64-bit inferior. */
568 struct regcache *regcache = new_register_cache (tdesc);
570 fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
571 collect_register_by_name (regcache, "pswm", &pswm);
572 free_register_cache (regcache);
578 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_TE) != 0;
579 if (have_regset_vxrs)
581 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_VX) != 0;
584 (s390_get_hwcap (tdesc_s390x_linux64v2) & HWCAP_S390_GS) != 0;
587 tdesc = tdesc_s390x_gs_linux64;
588 else if (have_regset_vxrs)
589 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
590 tdesc_s390x_vx_linux64);
591 else if (have_regset_tdb)
592 tdesc = tdesc_s390x_te_linux64;
593 else if (have_regset_system_call)
594 tdesc = tdesc_s390x_linux64v2;
595 else if (have_regset_last_break)
596 tdesc = tdesc_s390x_linux64v1;
598 tdesc = tdesc_s390x_linux64;
601 /* For a 31-bit inferior, check whether the kernel supports
602 using the full 64-bit GPRs. */
605 if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
607 have_hwcap_s390_high_gprs = 1;
609 have_regset_tdb = (s390_get_hwcap (tdesc) & HWCAP_S390_TE) != 0;
610 if (have_regset_vxrs)
611 have_regset_vxrs = (s390_get_hwcap (tdesc) & HWCAP_S390_VX) != 0;
613 have_regset_gs = (s390_get_hwcap (tdesc) & HWCAP_S390_GS) != 0;
616 tdesc = tdesc_s390_gs_linux64;
617 else if (have_regset_vxrs)
618 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
619 tdesc_s390_vx_linux64);
620 else if (have_regset_tdb)
621 tdesc = tdesc_s390_te_linux64;
622 else if (have_regset_system_call)
623 tdesc = tdesc_s390_linux64v2;
624 else if (have_regset_last_break)
625 tdesc = tdesc_s390_linux64v1;
627 tdesc = tdesc_s390_linux64;
630 have_hwcap_s390_vx = have_regset_vxrs;
633 /* Update target_regsets according to available register sets. */
634 for (regset = s390_regsets; regset->size >= 0; regset++)
635 if (regset->get_request == PTRACE_GETREGSET)
636 switch (regset->nt_type)
639 case NT_S390_HIGH_GPRS:
640 regset->size = have_hwcap_s390_high_gprs ? 64 : 0;
643 case NT_S390_LAST_BREAK:
644 regset->size = have_regset_last_break ? 8 : 0;
646 case NT_S390_SYSTEM_CALL:
647 regset->size = have_regset_system_call ? 4 : 0;
650 regset->size = have_regset_tdb ? 256 : 0;
652 case NT_S390_VXRS_LOW:
653 regset->size = have_regset_vxrs ? 128 : 0;
655 case NT_S390_VXRS_HIGH:
656 regset->size = have_regset_vxrs ? 256 : 0;
660 regset->size = have_regset_gs ? 32 : 0;
665 current_process ()->tdesc = tdesc;
670 s390_breakpoint_at (CORE_ADDR pc)
672 unsigned char c[s390_breakpoint_len];
673 read_inferior_memory (pc, c, s390_breakpoint_len);
674 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
677 /* Breakpoint/Watchpoint support. */
679 /* The "supports_z_point_type" linux_target_ops method. */
682 s390_supports_z_point_type (char z_type)
693 /* Support for hardware single step. */
696 s390_supports_hardware_single_step (void)
701 static struct usrregs_info s390_usrregs_info =
707 static struct regsets_info s390_regsets_info =
709 s390_regsets, /* regsets */
711 NULL, /* disabled_regsets */
714 static struct regs_info regs_info =
716 NULL, /* regset_bitmap */
721 static struct usrregs_info s390_usrregs_info_3264 =
727 static struct regsets_info s390_regsets_info_3264 =
729 s390_regsets, /* regsets */
731 NULL, /* disabled_regsets */
734 static struct regs_info regs_info_3264 =
736 NULL, /* regset_bitmap */
737 &s390_usrregs_info_3264,
738 &s390_regsets_info_3264
741 static const struct regs_info *
742 s390_regs_info (void)
744 if (have_hwcap_s390_high_gprs)
747 const struct target_desc *tdesc = current_process ()->tdesc;
749 if (register_size (tdesc, 0) == 4)
750 return ®s_info_3264;
752 return ®s_info_3264;
758 /* The "supports_tracepoints" linux_target_ops method. */
761 s390_supports_tracepoints (void)
766 /* Implementation of linux_target_ops method "get_thread_area". */
769 s390_get_thread_area (int lwpid, CORE_ADDR *addrp)
771 CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, (long) 0);
773 struct regcache *regcache = get_thread_regcache (current_thread, 0);
775 if (register_size (regcache->tdesc, 0) == 4)
776 res &= 0xffffffffull;
783 /* Fast tracepoint support.
785 The register save area on stack is identical for all targets:
787 0x000+i*0x10: VR0-VR31
794 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
795 Likewise, if there's no VX support, we just store the FRs into the slots
796 of low VR halves. The agent code is responsible for rearranging that
799 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
800 one trick used at the very beginning: since there's no way to allocate
801 stack space without destroying CC (lay instruction can do it, but it's
802 only supported on later CPUs), we take 4 different execution paths for
803 every possible value of CC, allocate stack space, save %r0, stuff the
804 CC value in %r0 (shifted to match its position in PSWM high word),
805 then branch to common path. */
807 static const unsigned char s390_ft_entry_gpr_esa[] = {
808 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
809 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
810 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
812 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
813 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
814 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
815 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
817 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
818 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
819 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
820 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
822 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
823 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
824 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
825 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
827 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
828 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
829 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
831 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
832 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
833 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
834 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
835 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
836 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
837 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
838 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
839 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
840 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
841 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
842 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
843 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
844 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
845 /* Compute original value of %r15 and store it. We use ahi instead
846 of la to preserve the whole value, and not just the low 31 bits.
847 This is not particularly important here, but essential in the
848 zarch case where someone might be using the high word of %r15
849 as an extra register. */
850 0x18, 0x1f, /* lr %r1, %r15 */
851 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
852 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
855 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
856 target. Same as above, except this time we can use load/store multiple,
857 since the 64-bit regs are tightly packed. */
859 static const unsigned char s390_ft_entry_gpr_zarch[] = {
860 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
861 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
862 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
864 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
865 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
866 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
867 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
869 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
870 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
871 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
872 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
874 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
875 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
876 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
877 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
879 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
880 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
881 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
883 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
884 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
885 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
888 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
889 current PSWM (read by epsw) and CC from entry (in %r0). */
891 static const unsigned char s390_ft_entry_misc[] = {
892 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
893 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
894 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
895 0x14, 0x21, /* nr %r2, %r1 */
896 0x16, 0x20, /* or %r2, %r0 */
897 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
898 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
899 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
902 /* Code sequence saving FRs, used if VX not supported. */
904 static const unsigned char s390_ft_entry_fr[] = {
905 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
906 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
907 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
908 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
909 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
910 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
911 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
912 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
913 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
914 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
915 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
916 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
917 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
918 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
919 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
920 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
923 /* Code sequence saving VRs, used if VX not supported. */
925 static const unsigned char s390_ft_entry_vr[] = {
926 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
927 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
930 /* Code sequence doing the collection call for 31-bit target. %r1 contains
931 the address of the literal pool. */
933 static const unsigned char s390_ft_main_31[] = {
934 /* Load the literals into registers. */
935 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
936 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
937 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
938 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
939 /* Save original PSWA (tracepoint address | 0x80000000). */
940 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
941 /* Construct a collecting_t object at %r15+0x2e0. */
942 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
943 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
944 /* Move its address to %r0. */
945 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
948 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
949 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
950 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
951 /* Address of the register save block to %r3. */
952 0x18, 0x3f, /* lr %r3, %r15 */
953 /* Make a stack frame, so that we can call the collector. */
954 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
956 0x0d, 0xe4, /* basr %r14, %r4 */
957 /* And get rid of the stack frame again. */
958 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
959 /* Leave the lock. */
960 0x07, 0xf0, /* br %r0 */
961 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
962 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
965 /* Code sequence doing the collection call for 64-bit target. %r1 contains
966 the address of the literal pool. */
968 static const unsigned char s390_ft_main_64[] = {
969 /* Load the literals into registers. */
970 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
971 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
972 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
973 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
974 /* Save original PSWA (tracepoint address). */
975 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
976 /* Construct a collecting_t object at %r15+0x2e0. */
977 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
978 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
979 /* Move its address to %r0. */
980 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
983 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
984 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
985 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
986 /* Address of the register save block to %r3. */
987 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
988 /* Make a stack frame, so that we can call the collector. */
989 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
991 0x0d, 0xe4, /* basr %r14, %r4 */
992 /* And get rid of the stack frame again. */
993 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
994 /* Leave the lock. */
995 0x07, 0xf0, /* br %r0 */
996 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
997 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1000 /* Code sequence restoring FRs, for targets with no VX support. */
1002 static const unsigned char s390_ft_exit_fr[] = {
1003 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1004 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1005 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1006 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1007 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1008 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1009 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1010 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1011 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1012 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1013 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1014 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1015 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1016 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1017 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1018 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1021 /* Code sequence restoring VRs. */
1023 static const unsigned char s390_ft_exit_vr[] = {
1024 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1025 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1028 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1029 modified by C code, so we use the alr instruction to restore it by
1030 manufacturing an operand that'll result in the original flags. */
1032 static const unsigned char s390_ft_exit_misc[] = {
1033 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1034 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1035 /* Extract CC to high 2 bits of %r0. */
1036 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1037 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1038 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1039 will have carry iff CC bit 1 is set - resulting in the same flags
1041 0x1e, 0x00, /* alr %r0, %r0 */
1042 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1045 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1047 static const unsigned char s390_ft_exit_gpr_esa[] = {
1048 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1049 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1050 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1051 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1052 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1053 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1054 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1055 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1056 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1057 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1058 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1059 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1060 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1061 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1062 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1063 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1066 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1069 static const unsigned char s390_ft_exit_gpr_zarch[] = {
1070 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1073 /* Writes instructions to target, updating the to pointer. */
1076 append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
1078 write_inferior_memory (*to, buf, len);
1082 /* Relocates an instruction from oldloc to *to, updating to. */
1085 s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64)
1090 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1093 read_inferior_memory (oldloc, buf, sizeof buf);
1096 else if (buf[0] < 0xc0)
1102 case 0x05: /* BALR */
1103 case 0x0c: /* BASSM */
1104 case 0x0d: /* BASR */
1105 case 0x45: /* BAL */
1106 case 0x4d: /* BAS */
1107 /* These save a return address and mess around with registers.
1108 We can't relocate them. */
1110 case 0x84: /* BRXH */
1111 case 0x85: /* BRXLE */
1116 /* BRC, BRAS, BRCT, BRCTG */
1117 if (op2 >= 4 && op2 <= 7)
1125 /* LARL, BRCL, BRASL */
1126 if (op2 == 0 || op2 == 4 || op2 == 5)
1134 /* PC-relative addressing instructions. */
1137 case 0xc5: /* BPRP */
1138 case 0xc7: /* BPP */
1139 /* Branch prediction - just skip it. */
1151 case 0x44: /* BRXHG */
1152 case 0x45: /* BRXLG */
1153 case 0x64: /* CGRJ */
1154 case 0x65: /* CLGRJ */
1155 case 0x76: /* CRJ */
1156 case 0x77: /* CLRJ */
1165 /* We'll have to relocate an instruction with a PC-relative field.
1166 First, compute the target. */
1167 int64_t loffset = 0;
1171 int16_t soffset = 0;
1172 memcpy (&soffset, buf + 2, 2);
1177 int32_t soffset = 0;
1178 memcpy (&soffset, buf + 2, 4);
1181 target = oldloc + loffset * 2;
1183 target &= 0x7fffffff;
1187 /* BRAS or BRASL was used. We cannot just relocate those, since
1188 they save the return address in a register. We can, however,
1189 replace them with a LARL+JG sequence. */
1191 /* Make the LARL. */
1195 loffset = oldloc + ilen - *to;
1198 if (soffset != loffset && is_64)
1200 memcpy (buf + 2, &soffset, 4);
1201 append_insns (to, 6, buf);
1203 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1204 an address with the top bit 0, while BRAS/BRASL will write it
1205 with top bit 1. It should not matter much, since linux compilers
1206 use BR and not BSM to return from functions, but it could confuse
1207 some poor stack unwinder. */
1209 /* We'll now be writing a JG. */
1216 /* Compute the new offset and write it to the buffer. */
1217 loffset = target - *to;
1222 int16_t soffset = loffset;
1223 if (soffset != loffset)
1225 memcpy (buf + 2, &soffset, 2);
1229 int32_t soffset = loffset;
1230 if (soffset != loffset && is_64)
1232 memcpy (buf + 2, &soffset, 4);
1235 append_insns (to, ilen, buf);
1239 /* Implementation of linux_target_ops method
1240 "install_fast_tracepoint_jump_pad". */
1243 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint,
1245 CORE_ADDR collector,
1248 CORE_ADDR *jump_entry,
1249 CORE_ADDR *trampoline,
1250 ULONGEST *trampoline_size,
1251 unsigned char *jjump_pad_insn,
1252 ULONGEST *jjump_pad_insn_size,
1253 CORE_ADDR *adjusted_insn_addr,
1254 CORE_ADDR *adjusted_insn_addr_end,
1260 unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1261 CORE_ADDR buildaddr = *jump_entry;
1263 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1264 int is_64 = register_size (regcache->tdesc, 0) == 8;
1265 int is_zarch = is_64 || have_hwcap_s390_high_gprs;
1266 int has_vx = have_hwcap_s390_vx;
1268 int is_64 = 0, is_zarch = 0, has_vx = 0;
1270 CORE_ADDR literals[4] = {
1277 /* First, store the GPRs. */
1279 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch,
1280 s390_ft_entry_gpr_zarch);
1282 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa,
1283 s390_ft_entry_gpr_esa);
1285 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1286 append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc);
1288 /* Third, FRs or VRs. */
1290 append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr);
1292 append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr);
1294 /* Now, the main part of code - store PSWA, take lock, call collector,
1295 leave lock. First, we'll need to fetch 4 literals. */
1297 unsigned char buf[] = {
1298 0x07, 0x07, /* nopr %r7 */
1299 0x07, 0x07, /* nopr %r7 */
1300 0x07, 0x07, /* nopr %r7 */
1301 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1302 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1303 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1304 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1305 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1308 /* Find the proper start place in buf, so that literals will be
1310 int bufpos = (buildaddr + 2) & 7;
1311 /* Stuff the literals into the buffer. */
1312 for (i = 0; i < 4; i++) {
1313 uint64_t lit = literals[i];
1314 memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8);
1316 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1317 append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64);
1319 unsigned char buf[] = {
1320 0x07, 0x07, /* nopr %r7 */
1321 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1322 0, 0, 0, 0, /* tpaddr */
1323 0, 0, 0, 0, /* tpoint */
1324 0, 0, 0, 0, /* collector */
1325 0, 0, 0, 0, /* lockaddr */
1328 /* Find the proper start place in buf, so that literals will be
1330 int bufpos = (buildaddr + 2) & 3;
1331 /* First literal will be saved as the PSWA, make sure it has the high bit
1333 literals[0] |= 0x80000000;
1334 /* Stuff the literals into the buffer. */
1335 for (i = 0; i < 4; i++) {
1336 uint32_t lit = literals[i];
1337 memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4);
1339 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1340 append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31);
1343 /* Restore FRs or VRs. */
1345 append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr);
1347 append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr);
1349 /* Restore misc registers. */
1350 append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc);
1352 /* Restore the GPRs. */
1354 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch,
1355 s390_ft_exit_gpr_zarch);
1357 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa,
1358 s390_ft_exit_gpr_esa);
1360 /* Now, adjust the original instruction to execute in the jump
1362 *adjusted_insn_addr = buildaddr;
1363 if (s390_relocate_instruction (&buildaddr, tpaddr, is_64))
1365 sprintf (err, "E.Could not relocate instruction for tracepoint.");
1368 *adjusted_insn_addr_end = buildaddr;
1370 /* Finally, write a jump back to the program. */
1372 loffset = (tpaddr + orig_size) - buildaddr;
1375 if (is_64 && offset != loffset)
1378 "E.Jump back from jump pad too far from tracepoint "
1379 "(offset 0x%" PRIx64 " > int33).", loffset);
1382 memcpy (jbuf + 2, &offset, 4);
1383 append_insns (&buildaddr, sizeof jbuf, jbuf);
1385 /* The jump pad is now built. Wire in a jump to our jump pad. This
1386 is always done last (by our caller actually), so that we can
1387 install fast tracepoints with threads running. This relies on
1388 the agent's atomic write support. */
1389 loffset = *jump_entry - tpaddr;
1392 if (is_64 && offset != loffset)
1395 "E.Jump back from jump pad too far from tracepoint "
1396 "(offset 0x%" PRIx64 " > int33).", loffset);
1399 memcpy (jbuf + 2, &offset, 4);
1400 memcpy (jjump_pad_insn, jbuf, sizeof jbuf);
1401 *jjump_pad_insn_size = sizeof jbuf;
1403 /* Return the end address of our pad. */
1404 *jump_entry = buildaddr;
1409 /* Implementation of linux_target_ops method
1410 "get_min_fast_tracepoint_insn_len". */
1413 s390_get_min_fast_tracepoint_insn_len (void)
1415 /* We only support using 6-byte jumps to reach the tracepoint code.
1416 If the tracepoint buffer were allocated sufficiently close (64kiB)
1417 to the executable code, and the traced instruction itself was close
1418 enough to the beginning, we could use 4-byte jumps, but this doesn't
1419 seem to be worth the effort. */
1423 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1426 s390_get_ipa_tdesc_idx (void)
1428 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1429 const struct target_desc *tdesc = regcache->tdesc;
1432 if (tdesc == tdesc_s390x_linux64)
1433 return S390_TDESC_64;
1434 if (tdesc == tdesc_s390x_linux64v1)
1435 return S390_TDESC_64V1;
1436 if (tdesc == tdesc_s390x_linux64v2)
1437 return S390_TDESC_64V2;
1438 if (tdesc == tdesc_s390x_te_linux64)
1439 return S390_TDESC_TE;
1440 if (tdesc == tdesc_s390x_vx_linux64)
1441 return S390_TDESC_VX;
1442 if (tdesc == tdesc_s390x_tevx_linux64)
1443 return S390_TDESC_TEVX;
1446 if (tdesc == tdesc_s390_linux32)
1447 return S390_TDESC_32;
1448 if (tdesc == tdesc_s390_linux32v1)
1449 return S390_TDESC_32V1;
1450 if (tdesc == tdesc_s390_linux32v2)
1451 return S390_TDESC_32V2;
1452 if (tdesc == tdesc_s390_linux64)
1453 return S390_TDESC_64;
1454 if (tdesc == tdesc_s390_linux64v1)
1455 return S390_TDESC_64V1;
1456 if (tdesc == tdesc_s390_linux64v2)
1457 return S390_TDESC_64V2;
1458 if (tdesc == tdesc_s390_te_linux64)
1459 return S390_TDESC_TE;
1460 if (tdesc == tdesc_s390_vx_linux64)
1461 return S390_TDESC_VX;
1462 if (tdesc == tdesc_s390_tevx_linux64)
1463 return S390_TDESC_TEVX;
1468 /* Appends given buffer to current_insn_ptr in the target. */
1471 add_insns (const unsigned char *start, int len)
1473 CORE_ADDR buildaddr = current_insn_ptr;
1476 debug_printf ("Adding %d bytes of insn at %s\n",
1477 len, paddress (buildaddr));
1479 append_insns (&buildaddr, len, start);
1480 current_insn_ptr = buildaddr;
1483 /* Register usage in emit:
1486 - %r2: top of stack (high word for 31-bit)
1487 - %r3: low word of top of stack (for 31-bit)
1489 - %r6, %r7, %r8: don't use
1492 - %r11: frame pointer
1493 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1494 - %r13: low word of saved top of stack (for 31-bit)
1495 - %r14: return address for calls
1496 - %r15: stack pointer
1500 /* The "emit_prologue" emit_ops method for s390. */
1503 s390_emit_prologue (void)
1505 static const unsigned char buf[] = {
1506 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1507 0x18, 0x92, /* lr %r9, %r2 */
1508 0x18, 0xa3, /* lr %r10, %r3 */
1509 0x18, 0xbf, /* lr %r11, %r15 */
1511 add_insns (buf, sizeof buf);
1514 /* The "emit_epilogue" emit_ops method for s390. */
1517 s390_emit_epilogue (void)
1519 static const unsigned char buf[] = {
1520 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1521 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1522 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1523 0x07, 0xfe, /* br %r14 */
1525 add_insns (buf, sizeof buf);
1528 /* The "emit_add" emit_ops method for s390. */
1531 s390_emit_add (void)
1533 static const unsigned char buf[] = {
1534 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1535 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1536 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1538 add_insns (buf, sizeof buf);
1541 /* The "emit_sub" emit_ops method for s390. */
1544 s390_emit_sub (void)
1546 static const unsigned char buf[] = {
1547 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1548 0x1f, 0x53, /* slr %r5, %r3 */
1549 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1550 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1551 0x18, 0x35, /* lr %r3, %r5 */
1552 0x18, 0x24, /* lr %r2, %r4 */
1554 add_insns (buf, sizeof buf);
1557 /* The "emit_mul" emit_ops method for s390. */
1560 s390_emit_mul (void)
1565 /* The "emit_lsh" emit_ops method for s390. */
1568 s390_emit_lsh (void)
1570 static const unsigned char buf[] = {
1571 0x18, 0x43, /* lr %r4, %r3 */
1572 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1573 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1574 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1576 add_insns (buf, sizeof buf);
1579 /* The "emit_rsh_signed" emit_ops method for s390. */
1582 s390_emit_rsh_signed (void)
1584 static const unsigned char buf[] = {
1585 0x18, 0x43, /* lr %r4, %r3 */
1586 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1587 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1588 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1590 add_insns (buf, sizeof buf);
1593 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1596 s390_emit_rsh_unsigned (void)
1598 static const unsigned char buf[] = {
1599 0x18, 0x43, /* lr %r4, %r3 */
1600 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1601 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1602 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1604 add_insns (buf, sizeof buf);
1607 /* The "emit_ext" emit_ops method for s390. */
1610 s390_emit_ext (int arg)
1612 unsigned char buf[] = {
1613 0x8d, 0x20, 0x00, 64 - arg, /* sldl %r2, <64-arg> */
1614 0x8e, 0x20, 0x00, 64 - arg, /* srda %r2, <64-arg> */
1616 add_insns (buf, sizeof buf);
1619 /* The "emit_log_not" emit_ops method for s390. */
1622 s390_emit_log_not (void)
1624 static const unsigned char buf[] = {
1625 0x16, 0x23, /* or %r2, %r3 */
1626 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1627 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1628 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1629 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1632 add_insns (buf, sizeof buf);
1635 /* The "emit_bit_and" emit_ops method for s390. */
1638 s390_emit_bit_and (void)
1640 static const unsigned char buf[] = {
1641 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1642 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1643 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1645 add_insns (buf, sizeof buf);
1648 /* The "emit_bit_or" emit_ops method for s390. */
1651 s390_emit_bit_or (void)
1653 static const unsigned char buf[] = {
1654 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1655 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1656 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1658 add_insns (buf, sizeof buf);
1661 /* The "emit_bit_xor" emit_ops method for s390. */
1664 s390_emit_bit_xor (void)
1666 static const unsigned char buf[] = {
1667 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1668 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1669 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1671 add_insns (buf, sizeof buf);
1674 /* The "emit_bit_not" emit_ops method for s390. */
1677 s390_emit_bit_not (void)
1679 static const unsigned char buf[] = {
1680 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1681 0x17, 0x24, /* xr %r2, %r4 */
1682 0x17, 0x34, /* xr %r3, %r4 */
1684 add_insns (buf, sizeof buf);
1687 /* The "emit_equal" emit_ops method for s390. */
1690 s390_emit_equal (void)
1692 s390_emit_bit_xor ();
1693 s390_emit_log_not ();
1696 /* The "emit_less_signed" emit_ops method for s390. */
1699 s390_emit_less_signed (void)
1701 static const unsigned char buf[] = {
1702 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1703 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1704 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1705 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1706 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1708 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1709 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1711 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1713 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1714 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1716 add_insns (buf, sizeof buf);
1719 /* The "emit_less_unsigned" emit_ops method for s390. */
1722 s390_emit_less_unsigned (void)
1724 static const unsigned char buf[] = {
1725 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1726 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1727 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1728 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1729 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1731 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1732 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1734 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1736 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1737 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1739 add_insns (buf, sizeof buf);
1742 /* The "emit_ref" emit_ops method for s390. */
1745 s390_emit_ref (int size)
1747 static const unsigned char buf1[] = {
1748 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1749 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1751 static const unsigned char buf2[] = {
1752 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1753 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1755 static const unsigned char buf4[] = {
1756 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1757 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1759 static const unsigned char buf8[] = {
1760 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1765 add_insns (buf1, sizeof buf1);
1768 add_insns (buf2, sizeof buf2);
1771 add_insns (buf4, sizeof buf4);
1774 add_insns (buf8, sizeof buf8);
1781 /* The "emit_if_goto" emit_ops method for s390. */
1784 s390_emit_if_goto (int *offset_p, int *size_p)
1786 static const unsigned char buf[] = {
1787 0x16, 0x23, /* or %r2, %r3 */
1788 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1789 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1790 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1792 add_insns (buf, sizeof buf);
1799 /* The "emit_goto" emit_ops method for s390 and s390x. */
1802 s390_emit_goto (int *offset_p, int *size_p)
1804 static const unsigned char buf[] = {
1805 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1807 add_insns (buf, sizeof buf);
1814 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1817 s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
1819 long diff = ((long) (to - (from - 2))) / 2;
1821 unsigned char buf[sizeof sdiff];
1823 /* We're only doing 4-byte sizes at the moment. */
1824 if (size != sizeof sdiff || sdiff != diff)
1830 memcpy (buf, &sdiff, sizeof sdiff);
1831 write_inferior_memory (from, buf, sizeof sdiff);
1834 /* Preparation for emitting a literal pool of given size. Loads the address
1835 of the pool into %r1, and jumps over it. Called should emit the pool data
1836 immediately afterwards. Used for both s390 and s390x. */
1839 s390_emit_litpool (int size)
1841 static const unsigned char nop[] = {
1844 unsigned char buf[] = {
1845 0xa7, 0x15, 0x00, (size + 4) / 2, /* bras %r1, .Lend+size */
1850 /* buf needs to start at even halfword for litpool to be aligned */
1851 if (current_insn_ptr & 2)
1852 add_insns (nop, sizeof nop);
1856 while ((current_insn_ptr & 6) != 4)
1857 add_insns (nop, sizeof nop);
1859 add_insns (buf, sizeof buf);
1862 /* The "emit_const" emit_ops method for s390. */
1865 s390_emit_const (LONGEST num)
1867 unsigned long long n = num;
1868 unsigned char buf_s[] = {
1869 0xa7, 0x38, num >> 8, num, /* lhi %r3, <num> */
1870 0x17, 0x22, /* xr %r2, %r2 */
1872 static const unsigned char buf_l[] = {
1873 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1875 if (num < 0x8000 && num >= 0)
1877 add_insns (buf_s, sizeof buf_s);
1881 s390_emit_litpool (8);
1882 add_insns ((unsigned char *) &n, sizeof n);
1883 add_insns (buf_l, sizeof buf_l);
1887 /* The "emit_call" emit_ops method for s390. */
1890 s390_emit_call (CORE_ADDR fn)
1892 unsigned int n = fn;
1893 static const unsigned char buf[] = {
1894 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1895 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1896 0x0d, 0xe1, /* basr %r14, %r1 */
1897 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1899 s390_emit_litpool (4);
1900 add_insns ((unsigned char *) &n, sizeof n);
1901 add_insns (buf, sizeof buf);
1904 /* The "emit_reg" emit_ops method for s390. */
1907 s390_emit_reg (int reg)
1909 unsigned char bufpre[] = {
1910 0x18, 0x29, /* lr %r2, %r9 */
1911 0xa7, 0x38, reg >> 8, reg, /* lhi %r3, <reg> */
1913 add_insns (bufpre, sizeof bufpre);
1914 s390_emit_call (get_raw_reg_func_addr ());
1917 /* The "emit_pop" emit_ops method for s390. */
1920 s390_emit_pop (void)
1922 static const unsigned char buf[] = {
1923 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1924 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1926 add_insns (buf, sizeof buf);
1929 /* The "emit_stack_flush" emit_ops method for s390. */
1932 s390_emit_stack_flush (void)
1934 static const unsigned char buf[] = {
1935 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1936 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1938 add_insns (buf, sizeof buf);
1941 /* The "emit_zero_ext" emit_ops method for s390. */
1944 s390_emit_zero_ext (int arg)
1946 unsigned char buf[] = {
1947 0x8d, 0x20, 0x00, 64 - arg, /* sldl %r2, <64-arg> */
1948 0x8c, 0x20, 0x00, 64 - arg, /* srdl %r2, <64-arg> */
1950 add_insns (buf, sizeof buf);
1953 /* The "emit_swap" emit_ops method for s390. */
1956 s390_emit_swap (void)
1958 static const unsigned char buf[] = {
1959 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1960 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1961 0x18, 0x24, /* lr %r2, %r4 */
1962 0x18, 0x35, /* lr %r3, %r5 */
1964 add_insns (buf, sizeof buf);
1967 /* The "emit_stack_adjust" emit_ops method for s390. */
1970 s390_emit_stack_adjust (int n)
1972 unsigned char buf[] = {
1973 0xa7, 0xfa, n * 8 >> 8, n * 8, /* ahi %r15, 8*n */
1975 add_insns (buf, sizeof buf);
1978 /* Sets %r2 to a 32-bit constant. */
1981 s390_emit_set_r2 (int arg1)
1983 unsigned char buf_s[] = {
1984 0xa7, 0x28, arg1 >> 8, arg1, /* lhi %r2, <arg1> */
1986 static const unsigned char buf_l[] = {
1987 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1989 if (arg1 < 0x8000 && arg1 >= -0x8000)
1991 add_insns (buf_s, sizeof buf_s);
1995 s390_emit_litpool (4);
1996 add_insns ((unsigned char *) &arg1, sizeof arg1);
1997 add_insns (buf_l, sizeof buf_l);
2001 /* The "emit_int_call_1" emit_ops method for s390. */
2004 s390_emit_int_call_1 (CORE_ADDR fn, int arg1)
2006 /* FN's prototype is `LONGEST(*fn)(int)'. */
2007 s390_emit_set_r2 (arg1);
2008 s390_emit_call (fn);
2011 /* The "emit_void_call_2" emit_ops method for s390. */
2014 s390_emit_void_call_2 (CORE_ADDR fn, int arg1)
2016 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2017 static const unsigned char buf[] = {
2018 0x18, 0xc2, /* lr %r12, %r2 */
2019 0x18, 0xd3, /* lr %r13, %r3 */
2020 0x18, 0x43, /* lr %r4, %r3 */
2021 0x18, 0x32, /* lr %r3, %r2 */
2023 static const unsigned char buf2[] = {
2024 0x18, 0x2c, /* lr %r2, %r12 */
2025 0x18, 0x3d, /* lr %r3, %r13 */
2027 add_insns (buf, sizeof buf);
2028 s390_emit_set_r2 (arg1);
2029 s390_emit_call (fn);
2030 add_insns (buf2, sizeof buf2);
2033 /* The "emit_eq_goto" emit_ops method for s390. */
2036 s390_emit_eq_goto (int *offset_p, int *size_p)
2038 static const unsigned char buf[] = {
2039 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2040 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2041 0x16, 0x23, /* or %r2, %r3 */
2042 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2043 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2044 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2046 add_insns (buf, sizeof buf);
2053 /* The "emit_ne_goto" emit_ops method for s390. */
2056 s390_emit_ne_goto (int *offset_p, int *size_p)
2058 static const unsigned char buf[] = {
2059 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2060 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2061 0x16, 0x23, /* or %r2, %r3 */
2062 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2063 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2064 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2066 add_insns (buf, sizeof buf);
2073 /* The "emit_lt_goto" emit_ops method for s390. */
2076 s390_emit_lt_goto (int *offset_p, int *size_p)
2078 static const unsigned char buf[] = {
2079 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2080 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2081 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2082 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2083 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2085 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2086 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2087 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2089 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2090 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2091 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2094 add_insns (buf, sizeof buf);
2101 /* The "emit_le_goto" emit_ops method for s390. */
2104 s390_emit_le_goto (int *offset_p, int *size_p)
2106 static const unsigned char buf[] = {
2107 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2108 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2109 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2110 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2111 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2113 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2114 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2115 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2117 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2118 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2119 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2122 add_insns (buf, sizeof buf);
2129 /* The "emit_gt_goto" emit_ops method for s390. */
2132 s390_emit_gt_goto (int *offset_p, int *size_p)
2134 static const unsigned char buf[] = {
2135 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2136 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2137 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2138 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2139 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2141 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2142 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2143 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2145 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2146 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2147 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2150 add_insns (buf, sizeof buf);
2157 /* The "emit_ge_goto" emit_ops method for s390. */
2160 s390_emit_ge_goto (int *offset_p, int *size_p)
2162 static const unsigned char buf[] = {
2163 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2164 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2165 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2166 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2167 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2169 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2170 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2171 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2173 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2174 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2175 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2178 add_insns (buf, sizeof buf);
2185 /* The "emit_ops" structure for s390. Named _impl to avoid name
2186 collision with s390_emit_ops function. */
2188 static struct emit_ops s390_emit_ops_impl =
2196 s390_emit_rsh_signed,
2197 s390_emit_rsh_unsigned,
2205 s390_emit_less_signed,
2206 s390_emit_less_unsigned,
2210 s390_write_goto_address,
2215 s390_emit_stack_flush,
2218 s390_emit_stack_adjust,
2219 s390_emit_int_call_1,
2220 s390_emit_void_call_2,
2231 /* The "emit_prologue" emit_ops method for s390x. */
2234 s390x_emit_prologue (void)
2236 static const unsigned char buf[] = {
2237 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2238 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2239 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2240 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2242 add_insns (buf, sizeof buf);
2245 /* The "emit_epilogue" emit_ops method for s390x. */
2248 s390x_emit_epilogue (void)
2250 static const unsigned char buf[] = {
2251 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2252 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2253 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2254 0x07, 0xfe, /* br %r14 */
2256 add_insns (buf, sizeof buf);
2259 /* The "emit_add" emit_ops method for s390x. */
2262 s390x_emit_add (void)
2264 static const unsigned char buf[] = {
2265 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2266 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2268 add_insns (buf, sizeof buf);
2271 /* The "emit_sub" emit_ops method for s390x. */
2274 s390x_emit_sub (void)
2276 static const unsigned char buf[] = {
2277 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2278 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2279 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2280 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2282 add_insns (buf, sizeof buf);
2285 /* The "emit_mul" emit_ops method for s390x. */
2288 s390x_emit_mul (void)
2293 /* The "emit_lsh" emit_ops method for s390x. */
2296 s390x_emit_lsh (void)
2298 static const unsigned char buf[] = {
2299 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2300 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2301 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2303 add_insns (buf, sizeof buf);
2306 /* The "emit_rsh_signed" emit_ops method for s390x. */
2309 s390x_emit_rsh_signed (void)
2311 static const unsigned char buf[] = {
2312 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2313 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2314 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2316 add_insns (buf, sizeof buf);
2319 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2322 s390x_emit_rsh_unsigned (void)
2324 static const unsigned char buf[] = {
2325 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2326 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2327 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2329 add_insns (buf, sizeof buf);
2332 /* The "emit_ext" emit_ops method for s390x. */
2335 s390x_emit_ext (int arg)
2337 unsigned char buf[] = {
2338 0xeb, 0x22, 0x00, 64 - arg, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2339 0xeb, 0x22, 0x00, 64 - arg, 0x00, 0x0a, /* srag %r2, %r2, <64-arg> */
2341 add_insns (buf, sizeof buf);
2344 /* The "emit_log_not" emit_ops method for s390x. */
2347 s390x_emit_log_not (void)
2349 static const unsigned char buf[] = {
2350 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2351 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2352 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2354 add_insns (buf, sizeof buf);
2357 /* The "emit_bit_and" emit_ops method for s390x. */
2360 s390x_emit_bit_and (void)
2362 static const unsigned char buf[] = {
2363 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2364 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2366 add_insns (buf, sizeof buf);
2369 /* The "emit_bit_or" emit_ops method for s390x. */
2372 s390x_emit_bit_or (void)
2374 static const unsigned char buf[] = {
2375 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2376 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2378 add_insns (buf, sizeof buf);
2381 /* The "emit_bit_xor" emit_ops method for s390x. */
2384 s390x_emit_bit_xor (void)
2386 static const unsigned char buf[] = {
2387 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2388 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2390 add_insns (buf, sizeof buf);
2393 /* The "emit_bit_not" emit_ops method for s390x. */
2396 s390x_emit_bit_not (void)
2398 static const unsigned char buf[] = {
2399 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2400 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2402 add_insns (buf, sizeof buf);
2405 /* The "emit_equal" emit_ops method for s390x. */
2408 s390x_emit_equal (void)
2410 s390x_emit_bit_xor ();
2411 s390x_emit_log_not ();
2414 /* The "emit_less_signed" emit_ops method for s390x. */
2417 s390x_emit_less_signed (void)
2419 static const unsigned char buf[] = {
2420 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2421 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2422 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2423 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2425 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2427 add_insns (buf, sizeof buf);
2430 /* The "emit_less_unsigned" emit_ops method for s390x. */
2433 s390x_emit_less_unsigned (void)
2435 static const unsigned char buf[] = {
2436 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2437 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2438 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2439 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2441 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2443 add_insns (buf, sizeof buf);
2446 /* The "emit_ref" emit_ops method for s390x. */
2449 s390x_emit_ref (int size)
2451 static const unsigned char buf1[] = {
2452 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2454 static const unsigned char buf2[] = {
2455 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2457 static const unsigned char buf4[] = {
2458 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2460 static const unsigned char buf8[] = {
2461 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2466 add_insns (buf1, sizeof buf1);
2469 add_insns (buf2, sizeof buf2);
2472 add_insns (buf4, sizeof buf4);
2475 add_insns (buf8, sizeof buf8);
2482 /* The "emit_if_goto" emit_ops method for s390x. */
2485 s390x_emit_if_goto (int *offset_p, int *size_p)
2487 static const unsigned char buf[] = {
2488 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2489 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2490 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2491 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2493 add_insns (buf, sizeof buf);
2500 /* The "emit_const" emit_ops method for s390x. */
2503 s390x_emit_const (LONGEST num)
2505 unsigned long long n = num;
2506 unsigned char buf_s[] = {
2507 0xa7, 0x29, num >> 8, num, /* lghi %r2, <num> */
2509 static const unsigned char buf_l[] = {
2510 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2512 if (num < 0x8000 && num >= -0x8000)
2514 add_insns (buf_s, sizeof buf_s);
2518 s390_emit_litpool (8);
2519 add_insns ((unsigned char *) &n, sizeof n);
2520 add_insns (buf_l, sizeof buf_l);
2524 /* The "emit_call" emit_ops method for s390x. */
2527 s390x_emit_call (CORE_ADDR fn)
2529 unsigned long n = fn;
2530 static const unsigned char buf[] = {
2531 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2532 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2533 0x0d, 0xe1, /* basr %r14, %r1 */
2534 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2536 s390_emit_litpool (8);
2537 add_insns ((unsigned char *) &n, sizeof n);
2538 add_insns (buf, sizeof buf);
2541 /* The "emit_reg" emit_ops method for s390x. */
2544 s390x_emit_reg (int reg)
2546 unsigned char buf[] = {
2547 0xb9, 0x04, 0x00, 0x29, /* lgr %r2, %r9 */
2548 0xa7, 0x39, reg >> 8, reg, /* lghi %r3, <reg> */
2550 add_insns (buf, sizeof buf);
2551 s390x_emit_call (get_raw_reg_func_addr ());
2554 /* The "emit_pop" emit_ops method for s390x. */
2557 s390x_emit_pop (void)
2559 static const unsigned char buf[] = {
2560 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2561 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2563 add_insns (buf, sizeof buf);
2566 /* The "emit_stack_flush" emit_ops method for s390x. */
2569 s390x_emit_stack_flush (void)
2571 static const unsigned char buf[] = {
2572 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2573 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2575 add_insns (buf, sizeof buf);
2578 /* The "emit_zero_ext" emit_ops method for s390x. */
2581 s390x_emit_zero_ext (int arg)
2583 unsigned char buf[] = {
2584 0xeb, 0x22, 0x00, 64 - arg, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2585 0xeb, 0x22, 0x00, 64 - arg, 0x00, 0x0c, /* srlg %r2, %r2, <64-arg> */
2587 add_insns (buf, sizeof buf);
2590 /* The "emit_swap" emit_ops method for s390x. */
2593 s390x_emit_swap (void)
2595 static const unsigned char buf[] = {
2596 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2597 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2598 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2600 add_insns (buf, sizeof buf);
2603 /* The "emit_stack_adjust" emit_ops method for s390x. */
2606 s390x_emit_stack_adjust (int n)
2608 unsigned char buf[] = {
2609 0xa7, 0xfb, n * 8 >> 8, n * 8, /* aghi %r15, 8*n */
2611 add_insns (buf, sizeof buf);
2614 /* The "emit_int_call_1" emit_ops method for s390x. */
2617 s390x_emit_int_call_1 (CORE_ADDR fn, int arg1)
2619 /* FN's prototype is `LONGEST(*fn)(int)'. */
2620 s390x_emit_const (arg1);
2621 s390x_emit_call (fn);
2624 /* The "emit_void_call_2" emit_ops method for s390x. */
2627 s390x_emit_void_call_2 (CORE_ADDR fn, int arg1)
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 */
2634 static const unsigned char buf2[] = {
2635 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2637 add_insns (buf, sizeof buf);
2638 s390x_emit_const (arg1);
2639 s390x_emit_call (fn);
2640 add_insns (buf2, sizeof buf2);
2643 /* The "emit_eq_goto" emit_ops method for s390x. */
2646 s390x_emit_eq_goto (int *offset_p, int *size_p)
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> */
2654 add_insns (buf, sizeof buf);
2661 /* The "emit_ne_goto" emit_ops method for s390x. */
2664 s390x_emit_ne_goto (int *offset_p, int *size_p)
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> */
2672 add_insns (buf, sizeof buf);
2679 /* The "emit_lt_goto" emit_ops method for s390x. */
2682 s390x_emit_lt_goto (int *offset_p, int *size_p)
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> */
2690 add_insns (buf, sizeof buf);
2697 /* The "emit_le_goto" emit_ops method for s390x. */
2700 s390x_emit_le_goto (int *offset_p, int *size_p)
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> */
2708 add_insns (buf, sizeof buf);
2715 /* The "emit_gt_goto" emit_ops method for s390x. */
2718 s390x_emit_gt_goto (int *offset_p, int *size_p)
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> */
2726 add_insns (buf, sizeof buf);
2733 /* The "emit_ge_goto" emit_ops method for s390x. */
2736 s390x_emit_ge_goto (int *offset_p, int *size_p)
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> */
2744 add_insns (buf, sizeof buf);
2751 /* The "emit_ops" structure for s390x. */
2753 static struct emit_ops s390x_emit_ops =
2755 s390x_emit_prologue,
2756 s390x_emit_epilogue,
2761 s390x_emit_rsh_signed,
2762 s390x_emit_rsh_unsigned,
2770 s390x_emit_less_signed,
2771 s390x_emit_less_unsigned,
2775 s390_write_goto_address,
2780 s390x_emit_stack_flush,
2781 s390x_emit_zero_ext,
2783 s390x_emit_stack_adjust,
2784 s390x_emit_int_call_1,
2785 s390x_emit_void_call_2,
2795 /* The "emit_ops" linux_target_ops method. */
2797 static struct emit_ops *
2798 s390_emit_ops (void)
2801 struct regcache *regcache = get_thread_regcache (current_thread, 0);
2803 if (register_size (regcache->tdesc, 0) == 8)
2804 return &s390x_emit_ops;
2807 return &s390_emit_ops_impl;
2810 struct linux_target_ops the_low_target = {
2813 s390_cannot_fetch_register,
2814 s390_cannot_store_register,
2815 NULL, /* fetch_register */
2818 NULL, /* breakpoint_kind_from_pc */
2819 s390_sw_breakpoint_from_kind,
2821 s390_breakpoint_len,
2823 s390_supports_z_point_type,
2828 s390_collect_ptrace_register,
2829 s390_supply_ptrace_register,
2830 NULL, /* siginfo_fixup */
2831 NULL, /* new_process */
2832 NULL, /* delete_process */
2833 NULL, /* new_thread */
2834 NULL, /* delete_thread */
2835 NULL, /* new_fork */
2836 NULL, /* prepare_to_resume */
2837 NULL, /* process_qsupported */
2838 s390_supports_tracepoints,
2839 s390_get_thread_area,
2840 s390_install_fast_tracepoint_jump_pad,
2842 s390_get_min_fast_tracepoint_insn_len,
2843 NULL, /* supports_range_stepping */
2844 NULL, /* breakpoint_kind_from_current_state */
2845 s390_supports_hardware_single_step,
2846 NULL, /* get_syscall_trapinfo */
2847 s390_get_ipa_tdesc_idx,
2851 initialize_low_arch (void)
2853 /* Initialize the Linux target descriptions. */
2855 init_registers_s390_linux32 ();
2856 init_registers_s390_linux32v1 ();
2857 init_registers_s390_linux32v2 ();
2858 init_registers_s390_linux64 ();
2859 init_registers_s390_linux64v1 ();
2860 init_registers_s390_linux64v2 ();
2861 init_registers_s390_te_linux64 ();
2862 init_registers_s390_vx_linux64 ();
2863 init_registers_s390_tevx_linux64 ();
2864 init_registers_s390_gs_linux64 ();
2866 init_registers_s390x_linux64 ();
2867 init_registers_s390x_linux64v1 ();
2868 init_registers_s390x_linux64v2 ();
2869 init_registers_s390x_te_linux64 ();
2870 init_registers_s390x_vx_linux64 ();
2871 init_registers_s390x_tevx_linux64 ();
2872 init_registers_s390x_gs_linux64 ();
2875 initialize_regsets_info (&s390_regsets_info);
2876 initialize_regsets_info (&s390_regsets_info_3264);