1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2019 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_store_gs (struct regcache
*regcache
, const void *buf
)
380 int gsd
= find_regno (regcache
->tdesc
, "gsd");
383 for (i
= 0; i
< 3; i
++)
384 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
388 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
390 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
393 for (i
= 0; i
< 3; i
++)
394 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
397 static struct regset_info s390_regsets
[] = {
398 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
400 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
401 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
403 /* Last break address is read-only; no fill function. */
404 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
405 NULL
, s390_store_last_break
},
406 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
407 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
408 /* TDB is read-only. */
409 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
410 NULL
, s390_store_tdb
},
411 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
412 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
413 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
414 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
415 /* Guarded storage registers are read-only. */
416 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
417 NULL
, s390_store_gs
},
418 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
419 NULL
, s390_store_gsbc
},
424 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
425 #define s390_breakpoint_len 2
427 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
429 static const gdb_byte
*
430 s390_sw_breakpoint_from_kind (int kind
, int *size
)
432 *size
= s390_breakpoint_len
;
433 return s390_breakpoint
;
437 s390_get_pc (struct regcache
*regcache
)
439 if (register_size (regcache
->tdesc
, 0) == 4)
442 collect_register_by_name (regcache
, "pswa", &pswa
);
443 return pswa
& 0x7fffffff;
448 collect_register_by_name (regcache
, "pswa", &pc
);
454 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
456 if (register_size (regcache
->tdesc
, 0) == 4)
459 collect_register_by_name (regcache
, "pswa", &pswa
);
460 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
461 supply_register_by_name (regcache
, "pswa", &pswa
);
465 unsigned long pc
= newpc
;
466 supply_register_by_name (regcache
, "pswa", &pc
);
470 /* Determine the word size for the given PID, in bytes. */
474 s390_get_wordsize (int pid
)
477 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
478 (PTRACE_TYPE_ARG3
) 0,
479 (PTRACE_TYPE_ARG4
) 0);
482 warning (_("Couldn't determine word size, assuming 64-bit.\n"));
485 /* Derive word size from extended addressing mode (PSW bit 31). */
486 return pswm
& (1L << 32) ? 8 : 4;
489 #define s390_get_wordsize(pid) 4
493 s390_check_regset (int pid
, int regset
, int regsize
)
495 void *buf
= alloca (regsize
);
499 iov
.iov_len
= regsize
;
501 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
507 /* For a 31-bit inferior, whether the kernel supports using the full
509 static int have_hwcap_s390_high_gprs
= 0;
510 static int have_hwcap_s390_vx
= 0;
513 s390_arch_setup (void)
515 const struct target_desc
*tdesc
;
516 struct regset_info
*regset
;
518 /* Determine word size and HWCAP. */
519 int pid
= pid_of (current_thread
);
520 int wordsize
= s390_get_wordsize (pid
);
521 unsigned long hwcap
= linux_get_hwcap (wordsize
);
523 /* Check whether the kernel supports extra register sets. */
524 int have_regset_last_break
525 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
526 int have_regset_system_call
527 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
529 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
530 && (hwcap
& HWCAP_S390_TE
) != 0);
532 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
533 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
534 && (hwcap
& HWCAP_S390_VX
) != 0);
536 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
537 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
538 && (hwcap
& HWCAP_S390_GS
) != 0);
545 tdesc
= tdesc_s390x_gs_linux64
;
546 else if (have_regset_vxrs
)
547 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
548 tdesc_s390x_vx_linux64
);
549 else if (have_regset_tdb
)
550 tdesc
= tdesc_s390x_te_linux64
;
551 else if (have_regset_system_call
)
552 tdesc
= tdesc_s390x_linux64v2
;
553 else if (have_regset_last_break
)
554 tdesc
= tdesc_s390x_linux64v1
;
556 tdesc
= tdesc_s390x_linux64
;
559 /* For a 31-bit inferior, check whether the kernel supports
560 using the full 64-bit GPRs. */
563 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
565 have_hwcap_s390_high_gprs
= 1;
567 tdesc
= tdesc_s390_gs_linux64
;
568 else if (have_regset_vxrs
)
569 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
570 tdesc_s390_vx_linux64
);
571 else if (have_regset_tdb
)
572 tdesc
= tdesc_s390_te_linux64
;
573 else if (have_regset_system_call
)
574 tdesc
= tdesc_s390_linux64v2
;
575 else if (have_regset_last_break
)
576 tdesc
= tdesc_s390_linux64v1
;
578 tdesc
= tdesc_s390_linux64
;
582 /* Assume 31-bit inferior process. */
583 if (have_regset_system_call
)
584 tdesc
= tdesc_s390_linux32v2
;
585 else if (have_regset_last_break
)
586 tdesc
= tdesc_s390_linux32v1
;
588 tdesc
= tdesc_s390_linux32
;
591 have_hwcap_s390_vx
= have_regset_vxrs
;
594 /* Update target_regsets according to available register sets. */
595 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
596 if (regset
->get_request
== PTRACE_GETREGSET
)
597 switch (regset
->nt_type
)
600 case NT_S390_HIGH_GPRS
:
601 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
604 case NT_S390_LAST_BREAK
:
605 regset
->size
= have_regset_last_break
? 8 : 0;
607 case NT_S390_SYSTEM_CALL
:
608 regset
->size
= have_regset_system_call
? 4 : 0;
611 regset
->size
= have_regset_tdb
? 256 : 0;
613 case NT_S390_VXRS_LOW
:
614 regset
->size
= have_regset_vxrs
? 128 : 0;
616 case NT_S390_VXRS_HIGH
:
617 regset
->size
= have_regset_vxrs
? 256 : 0;
621 regset
->size
= have_regset_gs
? 32 : 0;
626 current_process ()->tdesc
= tdesc
;
631 s390_breakpoint_at (CORE_ADDR pc
)
633 unsigned char c
[s390_breakpoint_len
];
634 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
635 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
638 /* Breakpoint/Watchpoint support. */
640 /* The "supports_z_point_type" linux_target_ops method. */
643 s390_supports_z_point_type (char z_type
)
654 /* Support for hardware single step. */
657 s390_supports_hardware_single_step (void)
662 static struct usrregs_info s390_usrregs_info
=
668 static struct regsets_info s390_regsets_info
=
670 s390_regsets
, /* regsets */
672 NULL
, /* disabled_regsets */
675 static struct regs_info regs_info
=
677 NULL
, /* regset_bitmap */
682 static struct usrregs_info s390_usrregs_info_3264
=
688 static struct regsets_info s390_regsets_info_3264
=
690 s390_regsets
, /* regsets */
692 NULL
, /* disabled_regsets */
695 static struct regs_info regs_info_3264
=
697 NULL
, /* regset_bitmap */
698 &s390_usrregs_info_3264
,
699 &s390_regsets_info_3264
702 static const struct regs_info
*
703 s390_regs_info (void)
705 if (have_hwcap_s390_high_gprs
)
708 const struct target_desc
*tdesc
= current_process ()->tdesc
;
710 if (register_size (tdesc
, 0) == 4)
711 return ®s_info_3264
;
713 return ®s_info_3264
;
719 /* The "supports_tracepoints" linux_target_ops method. */
722 s390_supports_tracepoints (void)
727 /* Implementation of linux_target_ops method "get_thread_area". */
730 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
732 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
734 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
736 if (register_size (regcache
->tdesc
, 0) == 4)
737 res
&= 0xffffffffull
;
744 /* Fast tracepoint support.
746 The register save area on stack is identical for all targets:
748 0x000+i*0x10: VR0-VR31
755 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
756 Likewise, if there's no VX support, we just store the FRs into the slots
757 of low VR halves. The agent code is responsible for rearranging that
760 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
761 one trick used at the very beginning: since there's no way to allocate
762 stack space without destroying CC (lay instruction can do it, but it's
763 only supported on later CPUs), we take 4 different execution paths for
764 every possible value of CC, allocate stack space, save %r0, stuff the
765 CC value in %r0 (shifted to match its position in PSWM high word),
766 then branch to common path. */
768 static const unsigned char s390_ft_entry_gpr_esa
[] = {
769 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
770 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
771 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
773 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
774 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
775 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
776 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
778 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
779 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
780 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
781 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
783 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
784 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
785 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
786 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
788 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
789 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
790 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
792 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
793 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
794 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
795 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
796 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
797 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
798 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
799 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
800 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
801 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
802 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
803 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
804 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
805 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
806 /* Compute original value of %r15 and store it. We use ahi instead
807 of la to preserve the whole value, and not just the low 31 bits.
808 This is not particularly important here, but essential in the
809 zarch case where someone might be using the high word of %r15
810 as an extra register. */
811 0x18, 0x1f, /* lr %r1, %r15 */
812 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
813 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
816 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
817 target. Same as above, except this time we can use load/store multiple,
818 since the 64-bit regs are tightly packed. */
820 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
821 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
822 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
823 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
825 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
826 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
827 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
828 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
830 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
831 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
832 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
833 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
835 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
836 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
837 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
838 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
840 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
841 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
842 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
844 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
845 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
846 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
849 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
850 current PSWM (read by epsw) and CC from entry (in %r0). */
852 static const unsigned char s390_ft_entry_misc
[] = {
853 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
854 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
855 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
856 0x14, 0x21, /* nr %r2, %r1 */
857 0x16, 0x20, /* or %r2, %r0 */
858 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
859 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
860 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
863 /* Code sequence saving FRs, used if VX not supported. */
865 static const unsigned char s390_ft_entry_fr
[] = {
866 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
867 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
868 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
869 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
870 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
871 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
872 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
873 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
874 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
875 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
876 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
877 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
878 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
879 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
880 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
881 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
884 /* Code sequence saving VRs, used if VX not supported. */
886 static const unsigned char s390_ft_entry_vr
[] = {
887 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
888 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
891 /* Code sequence doing the collection call for 31-bit target. %r1 contains
892 the address of the literal pool. */
894 static const unsigned char s390_ft_main_31
[] = {
895 /* Load the literals into registers. */
896 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
897 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
898 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
899 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
900 /* Save original PSWA (tracepoint address | 0x80000000). */
901 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
902 /* Construct a collecting_t object at %r15+0x2e0. */
903 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
904 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
905 /* Move its address to %r0. */
906 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
909 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
910 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
911 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
912 /* Address of the register save block to %r3. */
913 0x18, 0x3f, /* lr %r3, %r15 */
914 /* Make a stack frame, so that we can call the collector. */
915 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
917 0x0d, 0xe4, /* basr %r14, %r4 */
918 /* And get rid of the stack frame again. */
919 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
920 /* Leave the lock. */
921 0x07, 0xf0, /* br %r0 */
922 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
923 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
926 /* Code sequence doing the collection call for 64-bit target. %r1 contains
927 the address of the literal pool. */
929 static const unsigned char s390_ft_main_64
[] = {
930 /* Load the literals into registers. */
931 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
932 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
933 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
934 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
935 /* Save original PSWA (tracepoint address). */
936 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
937 /* Construct a collecting_t object at %r15+0x2e0. */
938 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
939 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
940 /* Move its address to %r0. */
941 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
944 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
945 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
946 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
947 /* Address of the register save block to %r3. */
948 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
949 /* Make a stack frame, so that we can call the collector. */
950 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
952 0x0d, 0xe4, /* basr %r14, %r4 */
953 /* And get rid of the stack frame again. */
954 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
955 /* Leave the lock. */
956 0x07, 0xf0, /* br %r0 */
957 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
958 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
961 /* Code sequence restoring FRs, for targets with no VX support. */
963 static const unsigned char s390_ft_exit_fr
[] = {
964 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
965 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
966 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
967 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
968 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
969 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
970 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
971 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
972 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
973 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
974 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
975 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
976 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
977 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
978 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
979 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
982 /* Code sequence restoring VRs. */
984 static const unsigned char s390_ft_exit_vr
[] = {
985 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
986 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
989 /* Code sequence restoring misc registers. As for PSWM, only CC should be
990 modified by C code, so we use the alr instruction to restore it by
991 manufacturing an operand that'll result in the original flags. */
993 static const unsigned char s390_ft_exit_misc
[] = {
994 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
995 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
996 /* Extract CC to high 2 bits of %r0. */
997 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
998 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
999 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1000 will have carry iff CC bit 1 is set - resulting in the same flags
1002 0x1e, 0x00, /* alr %r0, %r0 */
1003 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1006 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1008 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1009 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1010 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1011 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1012 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1013 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1014 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1015 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1016 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1017 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1018 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1019 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1020 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1021 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1022 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1023 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1024 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1027 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1030 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1031 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1034 /* Writes instructions to target, updating the to pointer. */
1037 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1039 write_inferior_memory (*to
, buf
, len
);
1043 /* Relocates an instruction from oldloc to *to, updating to. */
1046 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1051 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1054 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1057 else if (buf
[0] < 0xc0)
1063 case 0x05: /* BALR */
1064 case 0x0c: /* BASSM */
1065 case 0x0d: /* BASR */
1066 case 0x45: /* BAL */
1067 case 0x4d: /* BAS */
1068 /* These save a return address and mess around with registers.
1069 We can't relocate them. */
1071 case 0x84: /* BRXH */
1072 case 0x85: /* BRXLE */
1077 /* BRC, BRAS, BRCT, BRCTG */
1078 if (op2
>= 4 && op2
<= 7)
1086 /* LARL, BRCL, BRASL */
1087 if (op2
== 0 || op2
== 4 || op2
== 5)
1095 /* PC-relative addressing instructions. */
1098 case 0xc5: /* BPRP */
1099 case 0xc7: /* BPP */
1100 /* Branch prediction - just skip it. */
1112 case 0x44: /* BRXHG */
1113 case 0x45: /* BRXLG */
1114 case 0x64: /* CGRJ */
1115 case 0x65: /* CLGRJ */
1116 case 0x76: /* CRJ */
1117 case 0x77: /* CLRJ */
1126 /* We'll have to relocate an instruction with a PC-relative field.
1127 First, compute the target. */
1128 int64_t loffset
= 0;
1132 int16_t soffset
= 0;
1133 memcpy (&soffset
, buf
+ 2, 2);
1138 int32_t soffset
= 0;
1139 memcpy (&soffset
, buf
+ 2, 4);
1142 target
= oldloc
+ loffset
* 2;
1144 target
&= 0x7fffffff;
1148 /* BRAS or BRASL was used. We cannot just relocate those, since
1149 they save the return address in a register. We can, however,
1150 replace them with a LARL+JG sequence. */
1152 /* Make the LARL. */
1156 loffset
= oldloc
+ ilen
- *to
;
1159 if (soffset
!= loffset
&& is_64
)
1161 memcpy (buf
+ 2, &soffset
, 4);
1162 append_insns (to
, 6, buf
);
1164 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1165 an address with the top bit 0, while BRAS/BRASL will write it
1166 with top bit 1. It should not matter much, since linux compilers
1167 use BR and not BSM to return from functions, but it could confuse
1168 some poor stack unwinder. */
1170 /* We'll now be writing a JG. */
1177 /* Compute the new offset and write it to the buffer. */
1178 loffset
= target
- *to
;
1183 int16_t soffset
= loffset
;
1184 if (soffset
!= loffset
)
1186 memcpy (buf
+ 2, &soffset
, 2);
1190 int32_t soffset
= loffset
;
1191 if (soffset
!= loffset
&& is_64
)
1193 memcpy (buf
+ 2, &soffset
, 4);
1196 append_insns (to
, ilen
, buf
);
1200 /* Implementation of linux_target_ops method
1201 "install_fast_tracepoint_jump_pad". */
1204 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1206 CORE_ADDR collector
,
1209 CORE_ADDR
*jump_entry
,
1210 CORE_ADDR
*trampoline
,
1211 ULONGEST
*trampoline_size
,
1212 unsigned char *jjump_pad_insn
,
1213 ULONGEST
*jjump_pad_insn_size
,
1214 CORE_ADDR
*adjusted_insn_addr
,
1215 CORE_ADDR
*adjusted_insn_addr_end
,
1221 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1222 CORE_ADDR buildaddr
= *jump_entry
;
1224 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1225 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1226 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1227 int has_vx
= have_hwcap_s390_vx
;
1229 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1231 CORE_ADDR literals
[4] = {
1238 /* First, store the GPRs. */
1240 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1241 s390_ft_entry_gpr_zarch
);
1243 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1244 s390_ft_entry_gpr_esa
);
1246 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1247 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1249 /* Third, FRs or VRs. */
1251 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1253 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1255 /* Now, the main part of code - store PSWA, take lock, call collector,
1256 leave lock. First, we'll need to fetch 4 literals. */
1258 unsigned char buf
[] = {
1259 0x07, 0x07, /* nopr %r7 */
1260 0x07, 0x07, /* nopr %r7 */
1261 0x07, 0x07, /* nopr %r7 */
1262 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1263 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1264 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1265 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1266 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1269 /* Find the proper start place in buf, so that literals will be
1271 int bufpos
= (buildaddr
+ 2) & 7;
1272 /* Stuff the literals into the buffer. */
1273 for (i
= 0; i
< 4; i
++) {
1274 uint64_t lit
= literals
[i
];
1275 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1277 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1278 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1280 unsigned char buf
[] = {
1281 0x07, 0x07, /* nopr %r7 */
1282 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1283 0, 0, 0, 0, /* tpaddr */
1284 0, 0, 0, 0, /* tpoint */
1285 0, 0, 0, 0, /* collector */
1286 0, 0, 0, 0, /* lockaddr */
1289 /* Find the proper start place in buf, so that literals will be
1291 int bufpos
= (buildaddr
+ 2) & 3;
1292 /* First literal will be saved as the PSWA, make sure it has the high bit
1294 literals
[0] |= 0x80000000;
1295 /* Stuff the literals into the buffer. */
1296 for (i
= 0; i
< 4; i
++) {
1297 uint32_t lit
= literals
[i
];
1298 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1300 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1301 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1304 /* Restore FRs or VRs. */
1306 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1308 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1310 /* Restore misc registers. */
1311 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1313 /* Restore the GPRs. */
1315 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1316 s390_ft_exit_gpr_zarch
);
1318 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1319 s390_ft_exit_gpr_esa
);
1321 /* Now, adjust the original instruction to execute in the jump
1323 *adjusted_insn_addr
= buildaddr
;
1324 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1326 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1329 *adjusted_insn_addr_end
= buildaddr
;
1331 /* Finally, write a jump back to the program. */
1333 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1336 if (is_64
&& offset
!= loffset
)
1339 "E.Jump back from jump pad too far from tracepoint "
1340 "(offset 0x%" PRIx64
" > int33).", loffset
);
1343 memcpy (jbuf
+ 2, &offset
, 4);
1344 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1346 /* The jump pad is now built. Wire in a jump to our jump pad. This
1347 is always done last (by our caller actually), so that we can
1348 install fast tracepoints with threads running. This relies on
1349 the agent's atomic write support. */
1350 loffset
= *jump_entry
- tpaddr
;
1353 if (is_64
&& offset
!= loffset
)
1356 "E.Jump back from jump pad too far from tracepoint "
1357 "(offset 0x%" PRIx64
" > int33).", loffset
);
1360 memcpy (jbuf
+ 2, &offset
, 4);
1361 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1362 *jjump_pad_insn_size
= sizeof jbuf
;
1364 /* Return the end address of our pad. */
1365 *jump_entry
= buildaddr
;
1370 /* Implementation of linux_target_ops method
1371 "get_min_fast_tracepoint_insn_len". */
1374 s390_get_min_fast_tracepoint_insn_len (void)
1376 /* We only support using 6-byte jumps to reach the tracepoint code.
1377 If the tracepoint buffer were allocated sufficiently close (64kiB)
1378 to the executable code, and the traced instruction itself was close
1379 enough to the beginning, we could use 4-byte jumps, but this doesn't
1380 seem to be worth the effort. */
1384 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1387 s390_get_ipa_tdesc_idx (void)
1389 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1390 const struct target_desc
*tdesc
= regcache
->tdesc
;
1393 if (tdesc
== tdesc_s390x_linux64
)
1394 return S390_TDESC_64
;
1395 if (tdesc
== tdesc_s390x_linux64v1
)
1396 return S390_TDESC_64V1
;
1397 if (tdesc
== tdesc_s390x_linux64v2
)
1398 return S390_TDESC_64V2
;
1399 if (tdesc
== tdesc_s390x_te_linux64
)
1400 return S390_TDESC_TE
;
1401 if (tdesc
== tdesc_s390x_vx_linux64
)
1402 return S390_TDESC_VX
;
1403 if (tdesc
== tdesc_s390x_tevx_linux64
)
1404 return S390_TDESC_TEVX
;
1405 if (tdesc
== tdesc_s390x_gs_linux64
)
1406 return S390_TDESC_GS
;
1409 if (tdesc
== tdesc_s390_linux32
)
1410 return S390_TDESC_32
;
1411 if (tdesc
== tdesc_s390_linux32v1
)
1412 return S390_TDESC_32V1
;
1413 if (tdesc
== tdesc_s390_linux32v2
)
1414 return S390_TDESC_32V2
;
1415 if (tdesc
== tdesc_s390_linux64
)
1416 return S390_TDESC_64
;
1417 if (tdesc
== tdesc_s390_linux64v1
)
1418 return S390_TDESC_64V1
;
1419 if (tdesc
== tdesc_s390_linux64v2
)
1420 return S390_TDESC_64V2
;
1421 if (tdesc
== tdesc_s390_te_linux64
)
1422 return S390_TDESC_TE
;
1423 if (tdesc
== tdesc_s390_vx_linux64
)
1424 return S390_TDESC_VX
;
1425 if (tdesc
== tdesc_s390_tevx_linux64
)
1426 return S390_TDESC_TEVX
;
1427 if (tdesc
== tdesc_s390_gs_linux64
)
1428 return S390_TDESC_GS
;
1433 /* Appends given buffer to current_insn_ptr in the target. */
1436 add_insns (const unsigned char *start
, int len
)
1438 CORE_ADDR buildaddr
= current_insn_ptr
;
1441 debug_printf ("Adding %d bytes of insn at %s\n",
1442 len
, paddress (buildaddr
));
1444 append_insns (&buildaddr
, len
, start
);
1445 current_insn_ptr
= buildaddr
;
1448 /* Register usage in emit:
1451 - %r2: top of stack (high word for 31-bit)
1452 - %r3: low word of top of stack (for 31-bit)
1454 - %r6, %r7, %r8: don't use
1457 - %r11: frame pointer
1458 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1459 - %r13: low word of saved top of stack (for 31-bit)
1460 - %r14: return address for calls
1461 - %r15: stack pointer
1465 /* The "emit_prologue" emit_ops method for s390. */
1468 s390_emit_prologue (void)
1470 static const unsigned char buf
[] = {
1471 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1472 0x18, 0x92, /* lr %r9, %r2 */
1473 0x18, 0xa3, /* lr %r10, %r3 */
1474 0x18, 0xbf, /* lr %r11, %r15 */
1476 add_insns (buf
, sizeof buf
);
1479 /* The "emit_epilogue" emit_ops method for s390. */
1482 s390_emit_epilogue (void)
1484 static const unsigned char buf
[] = {
1485 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1486 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1487 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1488 0x07, 0xfe, /* br %r14 */
1490 add_insns (buf
, sizeof buf
);
1493 /* The "emit_add" emit_ops method for s390. */
1496 s390_emit_add (void)
1498 static const unsigned char buf
[] = {
1499 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1500 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1501 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1503 add_insns (buf
, sizeof buf
);
1506 /* The "emit_sub" emit_ops method for s390. */
1509 s390_emit_sub (void)
1511 static const unsigned char buf
[] = {
1512 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1513 0x1f, 0x53, /* slr %r5, %r3 */
1514 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1515 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1516 0x18, 0x35, /* lr %r3, %r5 */
1517 0x18, 0x24, /* lr %r2, %r4 */
1519 add_insns (buf
, sizeof buf
);
1522 /* The "emit_mul" emit_ops method for s390. */
1525 s390_emit_mul (void)
1530 /* The "emit_lsh" emit_ops method for s390. */
1533 s390_emit_lsh (void)
1535 static const unsigned char buf
[] = {
1536 0x18, 0x43, /* lr %r4, %r3 */
1537 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1538 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1539 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1541 add_insns (buf
, sizeof buf
);
1544 /* The "emit_rsh_signed" emit_ops method for s390. */
1547 s390_emit_rsh_signed (void)
1549 static const unsigned char buf
[] = {
1550 0x18, 0x43, /* lr %r4, %r3 */
1551 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1552 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1553 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1555 add_insns (buf
, sizeof buf
);
1558 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1561 s390_emit_rsh_unsigned (void)
1563 static const unsigned char buf
[] = {
1564 0x18, 0x43, /* lr %r4, %r3 */
1565 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1566 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1567 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1569 add_insns (buf
, sizeof buf
);
1572 /* The "emit_ext" emit_ops method for s390. */
1575 s390_emit_ext (int arg
)
1577 unsigned char buf
[] = {
1578 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1579 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1581 add_insns (buf
, sizeof buf
);
1584 /* The "emit_log_not" emit_ops method for s390. */
1587 s390_emit_log_not (void)
1589 static const unsigned char buf
[] = {
1590 0x16, 0x23, /* or %r2, %r3 */
1591 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1592 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1593 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1594 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1597 add_insns (buf
, sizeof buf
);
1600 /* The "emit_bit_and" emit_ops method for s390. */
1603 s390_emit_bit_and (void)
1605 static const unsigned char buf
[] = {
1606 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1607 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1608 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1610 add_insns (buf
, sizeof buf
);
1613 /* The "emit_bit_or" emit_ops method for s390. */
1616 s390_emit_bit_or (void)
1618 static const unsigned char buf
[] = {
1619 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1620 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1621 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1623 add_insns (buf
, sizeof buf
);
1626 /* The "emit_bit_xor" emit_ops method for s390. */
1629 s390_emit_bit_xor (void)
1631 static const unsigned char buf
[] = {
1632 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1633 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1634 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1636 add_insns (buf
, sizeof buf
);
1639 /* The "emit_bit_not" emit_ops method for s390. */
1642 s390_emit_bit_not (void)
1644 static const unsigned char buf
[] = {
1645 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1646 0x17, 0x24, /* xr %r2, %r4 */
1647 0x17, 0x34, /* xr %r3, %r4 */
1649 add_insns (buf
, sizeof buf
);
1652 /* The "emit_equal" emit_ops method for s390. */
1655 s390_emit_equal (void)
1657 s390_emit_bit_xor ();
1658 s390_emit_log_not ();
1661 /* The "emit_less_signed" emit_ops method for s390. */
1664 s390_emit_less_signed (void)
1666 static const unsigned char buf
[] = {
1667 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1668 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1669 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1670 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1671 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1673 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1674 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1676 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1678 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1679 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1681 add_insns (buf
, sizeof buf
);
1684 /* The "emit_less_unsigned" emit_ops method for s390. */
1687 s390_emit_less_unsigned (void)
1689 static const unsigned char buf
[] = {
1690 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1691 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1692 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1693 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1694 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1696 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1697 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1699 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1701 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1702 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1704 add_insns (buf
, sizeof buf
);
1707 /* The "emit_ref" emit_ops method for s390. */
1710 s390_emit_ref (int size
)
1712 static const unsigned char buf1
[] = {
1713 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1714 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1716 static const unsigned char buf2
[] = {
1717 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1718 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1720 static const unsigned char buf4
[] = {
1721 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1722 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1724 static const unsigned char buf8
[] = {
1725 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1730 add_insns (buf1
, sizeof buf1
);
1733 add_insns (buf2
, sizeof buf2
);
1736 add_insns (buf4
, sizeof buf4
);
1739 add_insns (buf8
, sizeof buf8
);
1746 /* The "emit_if_goto" emit_ops method for s390. */
1749 s390_emit_if_goto (int *offset_p
, int *size_p
)
1751 static const unsigned char buf
[] = {
1752 0x16, 0x23, /* or %r2, %r3 */
1753 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1754 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1755 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1757 add_insns (buf
, sizeof buf
);
1764 /* The "emit_goto" emit_ops method for s390 and s390x. */
1767 s390_emit_goto (int *offset_p
, int *size_p
)
1769 static const unsigned char buf
[] = {
1770 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1772 add_insns (buf
, sizeof buf
);
1779 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1782 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1784 long diff
= ((long) (to
- (from
- 2))) / 2;
1786 unsigned char buf
[sizeof sdiff
];
1788 /* We're only doing 4-byte sizes at the moment. */
1789 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1795 memcpy (buf
, &sdiff
, sizeof sdiff
);
1796 write_inferior_memory (from
, buf
, sizeof sdiff
);
1799 /* Preparation for emitting a literal pool of given size. Loads the address
1800 of the pool into %r1, and jumps over it. Called should emit the pool data
1801 immediately afterwards. Used for both s390 and s390x. */
1804 s390_emit_litpool (int size
)
1806 static const unsigned char nop
[] = {
1809 unsigned char buf
[] = {
1811 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1816 /* buf needs to start at even halfword for litpool to be aligned */
1817 if (current_insn_ptr
& 2)
1818 add_insns (nop
, sizeof nop
);
1822 while ((current_insn_ptr
& 6) != 4)
1823 add_insns (nop
, sizeof nop
);
1825 add_insns (buf
, sizeof buf
);
1828 /* The "emit_const" emit_ops method for s390. */
1831 s390_emit_const (LONGEST num
)
1833 unsigned long long n
= num
;
1834 unsigned char buf_s
[] = {
1835 /* lhi %r3, <num> */
1837 (unsigned char) (num
>> 8), (unsigned char) num
,
1841 static const unsigned char buf_l
[] = {
1842 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1844 if (num
< 0x8000 && num
>= 0)
1846 add_insns (buf_s
, sizeof buf_s
);
1850 s390_emit_litpool (8);
1851 add_insns ((unsigned char *) &n
, sizeof n
);
1852 add_insns (buf_l
, sizeof buf_l
);
1856 /* The "emit_call" emit_ops method for s390. */
1859 s390_emit_call (CORE_ADDR fn
)
1861 unsigned int n
= fn
;
1862 static const unsigned char buf
[] = {
1863 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1864 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1865 0x0d, 0xe1, /* basr %r14, %r1 */
1866 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1868 s390_emit_litpool (4);
1869 add_insns ((unsigned char *) &n
, sizeof n
);
1870 add_insns (buf
, sizeof buf
);
1873 /* The "emit_reg" emit_ops method for s390. */
1876 s390_emit_reg (int reg
)
1878 unsigned char bufpre
[] = {
1881 /* lhi %r3, <reg> */
1882 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1884 add_insns (bufpre
, sizeof bufpre
);
1885 s390_emit_call (get_raw_reg_func_addr ());
1888 /* The "emit_pop" emit_ops method for s390. */
1891 s390_emit_pop (void)
1893 static const unsigned char buf
[] = {
1894 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1895 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1897 add_insns (buf
, sizeof buf
);
1900 /* The "emit_stack_flush" emit_ops method for s390. */
1903 s390_emit_stack_flush (void)
1905 static const unsigned char buf
[] = {
1906 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1907 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1909 add_insns (buf
, sizeof buf
);
1912 /* The "emit_zero_ext" emit_ops method for s390. */
1915 s390_emit_zero_ext (int arg
)
1917 unsigned char buf
[] = {
1918 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1919 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1921 add_insns (buf
, sizeof buf
);
1924 /* The "emit_swap" emit_ops method for s390. */
1927 s390_emit_swap (void)
1929 static const unsigned char buf
[] = {
1930 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1931 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1932 0x18, 0x24, /* lr %r2, %r4 */
1933 0x18, 0x35, /* lr %r3, %r5 */
1935 add_insns (buf
, sizeof buf
);
1938 /* The "emit_stack_adjust" emit_ops method for s390. */
1941 s390_emit_stack_adjust (int n
)
1943 unsigned char buf
[] = {
1946 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
1948 add_insns (buf
, sizeof buf
);
1951 /* Sets %r2 to a 32-bit constant. */
1954 s390_emit_set_r2 (int arg1
)
1956 unsigned char buf_s
[] = {
1957 /* lhi %r2, <arg1> */
1958 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
1960 static const unsigned char buf_l
[] = {
1961 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1963 if (arg1
< 0x8000 && arg1
>= -0x8000)
1965 add_insns (buf_s
, sizeof buf_s
);
1969 s390_emit_litpool (4);
1970 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
1971 add_insns (buf_l
, sizeof buf_l
);
1975 /* The "emit_int_call_1" emit_ops method for s390. */
1978 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
1980 /* FN's prototype is `LONGEST(*fn)(int)'. */
1981 s390_emit_set_r2 (arg1
);
1982 s390_emit_call (fn
);
1985 /* The "emit_void_call_2" emit_ops method for s390. */
1988 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
1990 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
1991 static const unsigned char buf
[] = {
1992 0x18, 0xc2, /* lr %r12, %r2 */
1993 0x18, 0xd3, /* lr %r13, %r3 */
1994 0x18, 0x43, /* lr %r4, %r3 */
1995 0x18, 0x32, /* lr %r3, %r2 */
1997 static const unsigned char buf2
[] = {
1998 0x18, 0x2c, /* lr %r2, %r12 */
1999 0x18, 0x3d, /* lr %r3, %r13 */
2001 add_insns (buf
, sizeof buf
);
2002 s390_emit_set_r2 (arg1
);
2003 s390_emit_call (fn
);
2004 add_insns (buf2
, sizeof buf2
);
2007 /* The "emit_eq_goto" emit_ops method for s390. */
2010 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2012 static const unsigned char buf
[] = {
2013 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2014 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2015 0x16, 0x23, /* or %r2, %r3 */
2016 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2017 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2018 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2020 add_insns (buf
, sizeof buf
);
2027 /* The "emit_ne_goto" emit_ops method for s390. */
2030 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2032 static const unsigned char buf
[] = {
2033 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2034 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2035 0x16, 0x23, /* or %r2, %r3 */
2036 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2037 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2038 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2040 add_insns (buf
, sizeof buf
);
2047 /* The "emit_lt_goto" emit_ops method for s390. */
2050 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2052 static const unsigned char buf
[] = {
2053 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2054 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2055 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2056 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2057 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2059 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2060 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2061 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2063 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2064 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2065 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2068 add_insns (buf
, sizeof buf
);
2075 /* The "emit_le_goto" emit_ops method for s390. */
2078 s390_emit_le_goto (int *offset_p
, int *size_p
)
2080 static const unsigned char buf
[] = {
2081 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2082 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2083 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2084 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2085 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2087 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2088 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2089 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2091 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2092 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2093 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2096 add_insns (buf
, sizeof buf
);
2103 /* The "emit_gt_goto" emit_ops method for s390. */
2106 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2108 static const unsigned char buf
[] = {
2109 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2110 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2111 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2112 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2113 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
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 */
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> */
2124 add_insns (buf
, sizeof buf
);
2131 /* The "emit_ge_goto" emit_ops method for s390. */
2134 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2136 static const unsigned char buf
[] = {
2137 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2138 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2139 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2140 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2141 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
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 */
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> */
2152 add_insns (buf
, sizeof buf
);
2159 /* The "emit_ops" structure for s390. Named _impl to avoid name
2160 collision with s390_emit_ops function. */
2162 static struct emit_ops s390_emit_ops_impl
=
2170 s390_emit_rsh_signed
,
2171 s390_emit_rsh_unsigned
,
2179 s390_emit_less_signed
,
2180 s390_emit_less_unsigned
,
2184 s390_write_goto_address
,
2189 s390_emit_stack_flush
,
2192 s390_emit_stack_adjust
,
2193 s390_emit_int_call_1
,
2194 s390_emit_void_call_2
,
2205 /* The "emit_prologue" emit_ops method for s390x. */
2208 s390x_emit_prologue (void)
2210 static const unsigned char buf
[] = {
2211 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2212 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2213 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2214 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2216 add_insns (buf
, sizeof buf
);
2219 /* The "emit_epilogue" emit_ops method for s390x. */
2222 s390x_emit_epilogue (void)
2224 static const unsigned char buf
[] = {
2225 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2226 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2227 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2228 0x07, 0xfe, /* br %r14 */
2230 add_insns (buf
, sizeof buf
);
2233 /* The "emit_add" emit_ops method for s390x. */
2236 s390x_emit_add (void)
2238 static const unsigned char buf
[] = {
2239 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2240 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2242 add_insns (buf
, sizeof buf
);
2245 /* The "emit_sub" emit_ops method for s390x. */
2248 s390x_emit_sub (void)
2250 static const unsigned char buf
[] = {
2251 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2252 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2253 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2254 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2256 add_insns (buf
, sizeof buf
);
2259 /* The "emit_mul" emit_ops method for s390x. */
2262 s390x_emit_mul (void)
2267 /* The "emit_lsh" emit_ops method for s390x. */
2270 s390x_emit_lsh (void)
2272 static const unsigned char buf
[] = {
2273 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2274 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2275 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2277 add_insns (buf
, sizeof buf
);
2280 /* The "emit_rsh_signed" emit_ops method for s390x. */
2283 s390x_emit_rsh_signed (void)
2285 static const unsigned char buf
[] = {
2286 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2287 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2288 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2290 add_insns (buf
, sizeof buf
);
2293 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2296 s390x_emit_rsh_unsigned (void)
2298 static const unsigned char buf
[] = {
2299 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2300 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2301 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2303 add_insns (buf
, sizeof buf
);
2306 /* The "emit_ext" emit_ops method for s390x. */
2309 s390x_emit_ext (int arg
)
2311 unsigned char buf
[] = {
2312 /* sllg %r2, %r2, <64-arg> */
2313 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2314 /* srag %r2, %r2, <64-arg> */
2315 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2317 add_insns (buf
, sizeof buf
);
2320 /* The "emit_log_not" emit_ops method for s390x. */
2323 s390x_emit_log_not (void)
2325 static const unsigned char buf
[] = {
2326 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2327 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2328 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2330 add_insns (buf
, sizeof buf
);
2333 /* The "emit_bit_and" emit_ops method for s390x. */
2336 s390x_emit_bit_and (void)
2338 static const unsigned char buf
[] = {
2339 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2340 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2342 add_insns (buf
, sizeof buf
);
2345 /* The "emit_bit_or" emit_ops method for s390x. */
2348 s390x_emit_bit_or (void)
2350 static const unsigned char buf
[] = {
2351 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2352 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2354 add_insns (buf
, sizeof buf
);
2357 /* The "emit_bit_xor" emit_ops method for s390x. */
2360 s390x_emit_bit_xor (void)
2362 static const unsigned char buf
[] = {
2363 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2364 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2366 add_insns (buf
, sizeof buf
);
2369 /* The "emit_bit_not" emit_ops method for s390x. */
2372 s390x_emit_bit_not (void)
2374 static const unsigned char buf
[] = {
2375 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2376 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2378 add_insns (buf
, sizeof buf
);
2381 /* The "emit_equal" emit_ops method for s390x. */
2384 s390x_emit_equal (void)
2386 s390x_emit_bit_xor ();
2387 s390x_emit_log_not ();
2390 /* The "emit_less_signed" emit_ops method for s390x. */
2393 s390x_emit_less_signed (void)
2395 static const unsigned char buf
[] = {
2396 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2397 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2398 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2399 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2401 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2403 add_insns (buf
, sizeof buf
);
2406 /* The "emit_less_unsigned" emit_ops method for s390x. */
2409 s390x_emit_less_unsigned (void)
2411 static const unsigned char buf
[] = {
2412 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2413 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2414 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2415 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2417 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2419 add_insns (buf
, sizeof buf
);
2422 /* The "emit_ref" emit_ops method for s390x. */
2425 s390x_emit_ref (int size
)
2427 static const unsigned char buf1
[] = {
2428 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2430 static const unsigned char buf2
[] = {
2431 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2433 static const unsigned char buf4
[] = {
2434 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2436 static const unsigned char buf8
[] = {
2437 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2442 add_insns (buf1
, sizeof buf1
);
2445 add_insns (buf2
, sizeof buf2
);
2448 add_insns (buf4
, sizeof buf4
);
2451 add_insns (buf8
, sizeof buf8
);
2458 /* The "emit_if_goto" emit_ops method for s390x. */
2461 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2463 static const unsigned char buf
[] = {
2464 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2465 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2466 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2467 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2469 add_insns (buf
, sizeof buf
);
2476 /* The "emit_const" emit_ops method for s390x. */
2479 s390x_emit_const (LONGEST num
)
2481 unsigned long long n
= num
;
2482 unsigned char buf_s
[] = {
2483 /* lghi %r2, <num> */
2484 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2486 static const unsigned char buf_l
[] = {
2487 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2489 if (num
< 0x8000 && num
>= -0x8000)
2491 add_insns (buf_s
, sizeof buf_s
);
2495 s390_emit_litpool (8);
2496 add_insns ((unsigned char *) &n
, sizeof n
);
2497 add_insns (buf_l
, sizeof buf_l
);
2501 /* The "emit_call" emit_ops method for s390x. */
2504 s390x_emit_call (CORE_ADDR fn
)
2506 unsigned long n
= fn
;
2507 static const unsigned char buf
[] = {
2508 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2509 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2510 0x0d, 0xe1, /* basr %r14, %r1 */
2511 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2513 s390_emit_litpool (8);
2514 add_insns ((unsigned char *) &n
, sizeof n
);
2515 add_insns (buf
, sizeof buf
);
2518 /* The "emit_reg" emit_ops method for s390x. */
2521 s390x_emit_reg (int reg
)
2523 unsigned char buf
[] = {
2525 0xb9, 0x04, 0x00, 0x29,
2526 /* lghi %r3, <reg> */
2527 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2529 add_insns (buf
, sizeof buf
);
2530 s390x_emit_call (get_raw_reg_func_addr ());
2533 /* The "emit_pop" emit_ops method for s390x. */
2536 s390x_emit_pop (void)
2538 static const unsigned char buf
[] = {
2539 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2540 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2542 add_insns (buf
, sizeof buf
);
2545 /* The "emit_stack_flush" emit_ops method for s390x. */
2548 s390x_emit_stack_flush (void)
2550 static const unsigned char buf
[] = {
2551 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2552 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2554 add_insns (buf
, sizeof buf
);
2557 /* The "emit_zero_ext" emit_ops method for s390x. */
2560 s390x_emit_zero_ext (int arg
)
2562 unsigned char buf
[] = {
2563 /* sllg %r2, %r2, <64-arg> */
2564 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2565 /* srlg %r2, %r2, <64-arg> */
2566 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2568 add_insns (buf
, sizeof buf
);
2571 /* The "emit_swap" emit_ops method for s390x. */
2574 s390x_emit_swap (void)
2576 static const unsigned char buf
[] = {
2577 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2578 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2579 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2581 add_insns (buf
, sizeof buf
);
2584 /* The "emit_stack_adjust" emit_ops method for s390x. */
2587 s390x_emit_stack_adjust (int n
)
2589 unsigned char buf
[] = {
2590 /* aghi %r15, 8*n */
2592 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2594 add_insns (buf
, sizeof buf
);
2597 /* The "emit_int_call_1" emit_ops method for s390x. */
2600 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2602 /* FN's prototype is `LONGEST(*fn)(int)'. */
2603 s390x_emit_const (arg1
);
2604 s390x_emit_call (fn
);
2607 /* The "emit_void_call_2" emit_ops method for s390x. */
2610 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2612 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2613 static const unsigned char buf
[] = {
2614 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2615 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2617 static const unsigned char buf2
[] = {
2618 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2620 add_insns (buf
, sizeof buf
);
2621 s390x_emit_const (arg1
);
2622 s390x_emit_call (fn
);
2623 add_insns (buf2
, sizeof buf2
);
2626 /* The "emit_eq_goto" emit_ops method for s390x. */
2629 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2631 static const unsigned char buf
[] = {
2632 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2633 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2634 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2635 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2637 add_insns (buf
, sizeof buf
);
2644 /* The "emit_ne_goto" emit_ops method for s390x. */
2647 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2649 static const unsigned char buf
[] = {
2650 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2651 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2652 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2653 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2655 add_insns (buf
, sizeof buf
);
2662 /* The "emit_lt_goto" emit_ops method for s390x. */
2665 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2667 static const unsigned char buf
[] = {
2668 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2669 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2670 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2671 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2673 add_insns (buf
, sizeof buf
);
2680 /* The "emit_le_goto" emit_ops method for s390x. */
2683 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2685 static const unsigned char buf
[] = {
2686 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2687 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2688 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2689 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2691 add_insns (buf
, sizeof buf
);
2698 /* The "emit_gt_goto" emit_ops method for s390x. */
2701 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2703 static const unsigned char buf
[] = {
2704 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2705 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2706 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2707 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2709 add_insns (buf
, sizeof buf
);
2716 /* The "emit_ge_goto" emit_ops method for s390x. */
2719 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2721 static const unsigned char buf
[] = {
2722 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2723 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2724 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2725 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2727 add_insns (buf
, sizeof buf
);
2734 /* The "emit_ops" structure for s390x. */
2736 static struct emit_ops s390x_emit_ops
=
2738 s390x_emit_prologue
,
2739 s390x_emit_epilogue
,
2744 s390x_emit_rsh_signed
,
2745 s390x_emit_rsh_unsigned
,
2753 s390x_emit_less_signed
,
2754 s390x_emit_less_unsigned
,
2758 s390_write_goto_address
,
2763 s390x_emit_stack_flush
,
2764 s390x_emit_zero_ext
,
2766 s390x_emit_stack_adjust
,
2767 s390x_emit_int_call_1
,
2768 s390x_emit_void_call_2
,
2778 /* The "emit_ops" linux_target_ops method. */
2780 static struct emit_ops
*
2781 s390_emit_ops (void)
2784 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2786 if (register_size (regcache
->tdesc
, 0) == 8)
2787 return &s390x_emit_ops
;
2790 return &s390_emit_ops_impl
;
2793 struct linux_target_ops the_low_target
= {
2796 s390_cannot_fetch_register
,
2797 s390_cannot_store_register
,
2798 NULL
, /* fetch_register */
2801 NULL
, /* breakpoint_kind_from_pc */
2802 s390_sw_breakpoint_from_kind
,
2804 s390_breakpoint_len
,
2806 s390_supports_z_point_type
,
2811 s390_collect_ptrace_register
,
2812 s390_supply_ptrace_register
,
2813 NULL
, /* siginfo_fixup */
2814 NULL
, /* new_process */
2815 NULL
, /* delete_process */
2816 NULL
, /* new_thread */
2817 NULL
, /* delete_thread */
2818 NULL
, /* new_fork */
2819 NULL
, /* prepare_to_resume */
2820 NULL
, /* process_qsupported */
2821 s390_supports_tracepoints
,
2822 s390_get_thread_area
,
2823 s390_install_fast_tracepoint_jump_pad
,
2825 s390_get_min_fast_tracepoint_insn_len
,
2826 NULL
, /* supports_range_stepping */
2827 NULL
, /* breakpoint_kind_from_current_state */
2828 s390_supports_hardware_single_step
,
2829 NULL
, /* get_syscall_trapinfo */
2830 s390_get_ipa_tdesc_idx
,
2834 initialize_low_arch (void)
2836 /* Initialize the Linux target descriptions. */
2838 init_registers_s390_linux32 ();
2839 init_registers_s390_linux32v1 ();
2840 init_registers_s390_linux32v2 ();
2841 init_registers_s390_linux64 ();
2842 init_registers_s390_linux64v1 ();
2843 init_registers_s390_linux64v2 ();
2844 init_registers_s390_te_linux64 ();
2845 init_registers_s390_vx_linux64 ();
2846 init_registers_s390_tevx_linux64 ();
2847 init_registers_s390_gs_linux64 ();
2849 init_registers_s390x_linux64 ();
2850 init_registers_s390x_linux64v1 ();
2851 init_registers_s390x_linux64v2 ();
2852 init_registers_s390x_te_linux64 ();
2853 init_registers_s390x_vx_linux64 ();
2854 init_registers_s390x_tevx_linux64 ();
2855 init_registers_s390x_gs_linux64 ();
2858 initialize_regsets_info (&s390_regsets_info
);
2859 initialize_regsets_info (&s390_regsets_info_3264
);