1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2020 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 /* Linux target op definitions for the S/390 architecture. */
56 class s390_target
: public linux_process_target
62 /* The singleton target ops object. */
64 static s390_target the_s390_target
;
66 static int s390_regmap
[] = {
67 PT_PSWMASK
, PT_PSWADDR
,
69 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
70 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
71 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
72 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
74 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
75 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
76 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
77 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
82 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
83 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
84 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
85 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
87 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
88 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
89 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
90 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
96 #define s390_num_regs_3264 68
99 static int s390_regmap_3264
[] = {
100 PT_PSWMASK
, PT_PSWADDR
,
102 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
103 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
104 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
105 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
106 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
107 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
108 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
109 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
111 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
112 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
113 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
114 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
118 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
119 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
120 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
121 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
126 static int s390_regmap_3264
[] = {
127 PT_PSWMASK
, PT_PSWADDR
,
129 -1, PT_GPR0
, -1, PT_GPR1
,
130 -1, PT_GPR2
, -1, PT_GPR3
,
131 -1, PT_GPR4
, -1, PT_GPR5
,
132 -1, PT_GPR6
, -1, PT_GPR7
,
133 -1, PT_GPR8
, -1, PT_GPR9
,
134 -1, PT_GPR10
, -1, PT_GPR11
,
135 -1, PT_GPR12
, -1, PT_GPR13
,
136 -1, PT_GPR14
, -1, PT_GPR15
,
138 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
139 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
140 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
141 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
145 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
146 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
147 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
148 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
156 s390_cannot_fetch_register (int regno
)
162 s390_cannot_store_register (int regno
)
168 s390_collect_ptrace_register (struct regcache
*regcache
, int regno
, char *buf
)
170 int size
= register_size (regcache
->tdesc
, regno
);
171 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
172 struct usrregs_info
*usr
= regs_info
->usrregs
;
173 int regaddr
= usr
->regmap
[regno
];
175 if (size
< sizeof (long))
177 memset (buf
, 0, sizeof (long));
179 if ((regno
^ 1) < usr
->num_regs
180 && usr
->regmap
[regno
^ 1] == regaddr
)
182 collect_register (regcache
, regno
& ~1, buf
);
183 collect_register (regcache
, (regno
& ~1) + 1,
184 buf
+ sizeof (long) - size
);
186 else if (regaddr
== PT_PSWMASK
)
188 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
189 the basic addressing mode bit from the PSW address. */
190 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
191 collect_register (regcache
, regno
, buf
);
192 collect_register (regcache
, regno
^ 1, addr
);
194 buf
[size
] |= (addr
[0] & 0x80);
196 else if (regaddr
== PT_PSWADDR
)
198 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
199 mode bit (which gets copied to the PSW mask instead). */
200 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
201 buf
[sizeof (long) - size
] &= ~0x80;
203 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
204 || regaddr
== PT_ORIGGPR2
)
205 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
207 collect_register (regcache
, regno
, buf
);
209 else if (regaddr
!= -1)
210 collect_register (regcache
, regno
, buf
);
214 s390_supply_ptrace_register (struct regcache
*regcache
,
215 int regno
, const char *buf
)
217 int size
= register_size (regcache
->tdesc
, regno
);
218 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
219 struct usrregs_info
*usr
= regs_info
->usrregs
;
220 int regaddr
= usr
->regmap
[regno
];
222 if (size
< sizeof (long))
224 if ((regno
^ 1) < usr
->num_regs
225 && usr
->regmap
[regno
^ 1] == regaddr
)
227 supply_register (regcache
, regno
& ~1, buf
);
228 supply_register (regcache
, (regno
& ~1) + 1,
229 buf
+ sizeof (long) - size
);
231 else if (regaddr
== PT_PSWMASK
)
233 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
234 the basic addressing mode into the PSW address. */
235 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
236 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
237 memcpy (mask
, buf
, size
);
239 supply_register (regcache
, regno
, mask
);
241 collect_register (regcache
, regno
^ 1, addr
);
243 addr
[0] |= (buf
[size
] & 0x80);
244 supply_register (regcache
, regno
^ 1, addr
);
246 else if (regaddr
== PT_PSWADDR
)
248 /* Convert 8-byte PSW address to 4 bytes by truncating, but
249 keeping the addressing mode bit (which was set from the mask). */
250 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
252 collect_register (regcache
, regno
, addr
);
253 amode
= addr
[0] & 0x80;
254 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
257 supply_register (regcache
, regno
, addr
);
259 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
260 || regaddr
== PT_ORIGGPR2
)
261 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
263 supply_register (regcache
, regno
, buf
);
265 else if (regaddr
!= -1)
266 supply_register (regcache
, regno
, buf
);
269 /* Provide only a fill function for the general register set. ps_lgetregs
270 will use this for NPTL support. */
273 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
276 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
277 struct usrregs_info
*usr
= regs_info
->usrregs
;
279 for (i
= 0; i
< usr
->num_regs
; i
++)
281 if (usr
->regmap
[i
] < PT_PSWMASK
282 || usr
->regmap
[i
] > PT_ACR15
)
285 s390_collect_ptrace_register (regcache
, i
,
286 (char *) buf
+ usr
->regmap
[i
]);
290 /* Fill and store functions for extended register sets. */
294 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
296 int r0h
= find_regno (regcache
->tdesc
, "r0h");
299 for (i
= 0; i
< 16; i
++)
300 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
304 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
306 int r0h
= find_regno (regcache
->tdesc
, "r0h");
309 for (i
= 0; i
< 16; i
++)
310 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
315 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
319 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
320 supply_register_by_name (regcache
, "last_break", p
);
324 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
326 collect_register_by_name (regcache
, "system_call", buf
);
330 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
332 supply_register_by_name (regcache
, "system_call", buf
);
336 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
338 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
339 int tr0
= find_regno (regcache
->tdesc
, "tr0");
342 for (i
= 0; i
< 4; i
++)
343 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
345 for (i
= 0; i
< 16; i
++)
346 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
350 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
352 int v0
= find_regno (regcache
->tdesc
, "v0l");
355 for (i
= 0; i
< 16; i
++)
356 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
360 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
362 int v0
= find_regno (regcache
->tdesc
, "v0l");
365 for (i
= 0; i
< 16; i
++)
366 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
370 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
372 int v16
= find_regno (regcache
->tdesc
, "v16");
375 for (i
= 0; i
< 16; i
++)
376 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
380 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
382 int v16
= find_regno (regcache
->tdesc
, "v16");
385 for (i
= 0; i
< 16; i
++)
386 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
390 s390_store_gs (struct regcache
*regcache
, const void *buf
)
392 int gsd
= find_regno (regcache
->tdesc
, "gsd");
395 for (i
= 0; i
< 3; i
++)
396 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
400 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
402 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
405 for (i
= 0; i
< 3; i
++)
406 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
409 static struct regset_info s390_regsets
[] = {
410 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
412 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
413 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
415 /* Last break address is read-only; no fill function. */
416 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
417 NULL
, s390_store_last_break
},
418 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
419 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
420 /* TDB is read-only. */
421 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
422 NULL
, s390_store_tdb
},
423 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
424 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
425 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
426 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
427 /* Guarded storage registers are read-only. */
428 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
429 NULL
, s390_store_gs
},
430 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
431 NULL
, s390_store_gsbc
},
436 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
437 #define s390_breakpoint_len 2
439 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
441 static const gdb_byte
*
442 s390_sw_breakpoint_from_kind (int kind
, int *size
)
444 *size
= s390_breakpoint_len
;
445 return s390_breakpoint
;
449 s390_get_pc (struct regcache
*regcache
)
451 if (register_size (regcache
->tdesc
, 0) == 4)
454 collect_register_by_name (regcache
, "pswa", &pswa
);
455 return pswa
& 0x7fffffff;
460 collect_register_by_name (regcache
, "pswa", &pc
);
466 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
468 if (register_size (regcache
->tdesc
, 0) == 4)
471 collect_register_by_name (regcache
, "pswa", &pswa
);
472 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
473 supply_register_by_name (regcache
, "pswa", &pswa
);
477 unsigned long pc
= newpc
;
478 supply_register_by_name (regcache
, "pswa", &pc
);
482 /* Determine the word size for the given PID, in bytes. */
486 s390_get_wordsize (int pid
)
489 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
490 (PTRACE_TYPE_ARG3
) 0,
491 (PTRACE_TYPE_ARG4
) 0);
494 warning (_("Couldn't determine word size, assuming 64-bit."));
497 /* Derive word size from extended addressing mode (PSW bit 31). */
498 return pswm
& (1L << 32) ? 8 : 4;
501 #define s390_get_wordsize(pid) 4
505 s390_check_regset (int pid
, int regset
, int regsize
)
507 void *buf
= alloca (regsize
);
511 iov
.iov_len
= regsize
;
513 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
519 /* For a 31-bit inferior, whether the kernel supports using the full
521 static int have_hwcap_s390_high_gprs
= 0;
522 static int have_hwcap_s390_vx
= 0;
525 s390_arch_setup (void)
527 const struct target_desc
*tdesc
;
528 struct regset_info
*regset
;
530 /* Determine word size and HWCAP. */
531 int pid
= pid_of (current_thread
);
532 int wordsize
= s390_get_wordsize (pid
);
533 unsigned long hwcap
= linux_get_hwcap (wordsize
);
535 /* Check whether the kernel supports extra register sets. */
536 int have_regset_last_break
537 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
538 int have_regset_system_call
539 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
541 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
542 && (hwcap
& HWCAP_S390_TE
) != 0);
544 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
545 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
546 && (hwcap
& HWCAP_S390_VX
) != 0);
548 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
549 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
550 && (hwcap
& HWCAP_S390_GS
) != 0);
557 tdesc
= tdesc_s390x_gs_linux64
;
558 else if (have_regset_vxrs
)
559 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
560 tdesc_s390x_vx_linux64
);
561 else if (have_regset_tdb
)
562 tdesc
= tdesc_s390x_te_linux64
;
563 else if (have_regset_system_call
)
564 tdesc
= tdesc_s390x_linux64v2
;
565 else if (have_regset_last_break
)
566 tdesc
= tdesc_s390x_linux64v1
;
568 tdesc
= tdesc_s390x_linux64
;
571 /* For a 31-bit inferior, check whether the kernel supports
572 using the full 64-bit GPRs. */
575 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
577 have_hwcap_s390_high_gprs
= 1;
579 tdesc
= tdesc_s390_gs_linux64
;
580 else if (have_regset_vxrs
)
581 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
582 tdesc_s390_vx_linux64
);
583 else if (have_regset_tdb
)
584 tdesc
= tdesc_s390_te_linux64
;
585 else if (have_regset_system_call
)
586 tdesc
= tdesc_s390_linux64v2
;
587 else if (have_regset_last_break
)
588 tdesc
= tdesc_s390_linux64v1
;
590 tdesc
= tdesc_s390_linux64
;
594 /* Assume 31-bit inferior process. */
595 if (have_regset_system_call
)
596 tdesc
= tdesc_s390_linux32v2
;
597 else if (have_regset_last_break
)
598 tdesc
= tdesc_s390_linux32v1
;
600 tdesc
= tdesc_s390_linux32
;
603 have_hwcap_s390_vx
= have_regset_vxrs
;
606 /* Update target_regsets according to available register sets. */
607 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
608 if (regset
->get_request
== PTRACE_GETREGSET
)
609 switch (regset
->nt_type
)
612 case NT_S390_HIGH_GPRS
:
613 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
616 case NT_S390_LAST_BREAK
:
617 regset
->size
= have_regset_last_break
? 8 : 0;
619 case NT_S390_SYSTEM_CALL
:
620 regset
->size
= have_regset_system_call
? 4 : 0;
623 regset
->size
= have_regset_tdb
? 256 : 0;
625 case NT_S390_VXRS_LOW
:
626 regset
->size
= have_regset_vxrs
? 128 : 0;
628 case NT_S390_VXRS_HIGH
:
629 regset
->size
= have_regset_vxrs
? 256 : 0;
633 regset
->size
= have_regset_gs
? 32 : 0;
638 current_process ()->tdesc
= tdesc
;
643 s390_breakpoint_at (CORE_ADDR pc
)
645 unsigned char c
[s390_breakpoint_len
];
646 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
647 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
650 /* Breakpoint/Watchpoint support. */
652 /* The "supports_z_point_type" linux_target_ops method. */
655 s390_supports_z_point_type (char z_type
)
666 /* Support for hardware single step. */
669 s390_supports_hardware_single_step (void)
674 static struct usrregs_info s390_usrregs_info
=
680 static struct regsets_info s390_regsets_info
=
682 s390_regsets
, /* regsets */
684 NULL
, /* disabled_regsets */
687 static struct regs_info regs_info
=
689 NULL
, /* regset_bitmap */
694 static struct usrregs_info s390_usrregs_info_3264
=
700 static struct regsets_info s390_regsets_info_3264
=
702 s390_regsets
, /* regsets */
704 NULL
, /* disabled_regsets */
707 static struct regs_info regs_info_3264
=
709 NULL
, /* regset_bitmap */
710 &s390_usrregs_info_3264
,
711 &s390_regsets_info_3264
714 static const struct regs_info
*
715 s390_regs_info (void)
717 if (have_hwcap_s390_high_gprs
)
720 const struct target_desc
*tdesc
= current_process ()->tdesc
;
722 if (register_size (tdesc
, 0) == 4)
723 return ®s_info_3264
;
725 return ®s_info_3264
;
731 /* The "supports_tracepoints" linux_target_ops method. */
734 s390_supports_tracepoints (void)
739 /* Implementation of linux_target_ops method "get_thread_area". */
742 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
744 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
746 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
748 if (register_size (regcache
->tdesc
, 0) == 4)
749 res
&= 0xffffffffull
;
756 /* Fast tracepoint support.
758 The register save area on stack is identical for all targets:
760 0x000+i*0x10: VR0-VR31
767 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
768 Likewise, if there's no VX support, we just store the FRs into the slots
769 of low VR halves. The agent code is responsible for rearranging that
772 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
773 one trick used at the very beginning: since there's no way to allocate
774 stack space without destroying CC (lay instruction can do it, but it's
775 only supported on later CPUs), we take 4 different execution paths for
776 every possible value of CC, allocate stack space, save %r0, stuff the
777 CC value in %r0 (shifted to match its position in PSWM high word),
778 then branch to common path. */
780 static const unsigned char s390_ft_entry_gpr_esa
[] = {
781 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
782 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
783 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
785 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
786 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
787 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
788 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
790 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
791 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
792 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
793 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
795 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
796 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
797 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
798 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
800 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
801 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
802 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
804 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
805 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
806 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
807 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
808 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
809 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
810 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
811 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
812 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
813 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
814 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
815 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
816 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
817 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
818 /* Compute original value of %r15 and store it. We use ahi instead
819 of la to preserve the whole value, and not just the low 31 bits.
820 This is not particularly important here, but essential in the
821 zarch case where someone might be using the high word of %r15
822 as an extra register. */
823 0x18, 0x1f, /* lr %r1, %r15 */
824 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
825 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
828 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
829 target. Same as above, except this time we can use load/store multiple,
830 since the 64-bit regs are tightly packed. */
832 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
833 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
834 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
835 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
837 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
838 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
839 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
840 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
842 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
843 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
844 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
845 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
847 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
848 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
849 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
850 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
852 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
853 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
854 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
856 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
857 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
858 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
861 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
862 current PSWM (read by epsw) and CC from entry (in %r0). */
864 static const unsigned char s390_ft_entry_misc
[] = {
865 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
866 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
867 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
868 0x14, 0x21, /* nr %r2, %r1 */
869 0x16, 0x20, /* or %r2, %r0 */
870 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
871 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
872 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
875 /* Code sequence saving FRs, used if VX not supported. */
877 static const unsigned char s390_ft_entry_fr
[] = {
878 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
879 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
880 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
881 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
882 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
883 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
884 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
885 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
886 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
887 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
888 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
889 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
890 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
891 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
892 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
893 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
896 /* Code sequence saving VRs, used if VX not supported. */
898 static const unsigned char s390_ft_entry_vr
[] = {
899 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
900 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
903 /* Code sequence doing the collection call for 31-bit target. %r1 contains
904 the address of the literal pool. */
906 static const unsigned char s390_ft_main_31
[] = {
907 /* Load the literals into registers. */
908 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
909 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
910 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
911 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
912 /* Save original PSWA (tracepoint address | 0x80000000). */
913 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
914 /* Construct a collecting_t object at %r15+0x2e0. */
915 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
916 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
917 /* Move its address to %r0. */
918 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
921 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
922 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
923 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
924 /* Address of the register save block to %r3. */
925 0x18, 0x3f, /* lr %r3, %r15 */
926 /* Make a stack frame, so that we can call the collector. */
927 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
929 0x0d, 0xe4, /* basr %r14, %r4 */
930 /* And get rid of the stack frame again. */
931 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
932 /* Leave the lock. */
933 0x07, 0xf0, /* br %r0 */
934 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
935 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
938 /* Code sequence doing the collection call for 64-bit target. %r1 contains
939 the address of the literal pool. */
941 static const unsigned char s390_ft_main_64
[] = {
942 /* Load the literals into registers. */
943 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
944 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
945 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
946 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
947 /* Save original PSWA (tracepoint address). */
948 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
949 /* Construct a collecting_t object at %r15+0x2e0. */
950 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
951 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
952 /* Move its address to %r0. */
953 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
956 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
957 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
958 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
959 /* Address of the register save block to %r3. */
960 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
961 /* Make a stack frame, so that we can call the collector. */
962 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
964 0x0d, 0xe4, /* basr %r14, %r4 */
965 /* And get rid of the stack frame again. */
966 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
967 /* Leave the lock. */
968 0x07, 0xf0, /* br %r0 */
969 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
970 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
973 /* Code sequence restoring FRs, for targets with no VX support. */
975 static const unsigned char s390_ft_exit_fr
[] = {
976 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
977 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
978 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
979 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
980 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
981 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
982 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
983 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
984 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
985 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
986 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
987 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
988 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
989 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
990 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
991 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
994 /* Code sequence restoring VRs. */
996 static const unsigned char s390_ft_exit_vr
[] = {
997 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
998 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1001 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1002 modified by C code, so we use the alr instruction to restore it by
1003 manufacturing an operand that'll result in the original flags. */
1005 static const unsigned char s390_ft_exit_misc
[] = {
1006 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1007 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1008 /* Extract CC to high 2 bits of %r0. */
1009 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1010 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1011 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1012 will have carry iff CC bit 1 is set - resulting in the same flags
1014 0x1e, 0x00, /* alr %r0, %r0 */
1015 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1018 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1020 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1021 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1022 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1023 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1024 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1025 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1026 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1027 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1028 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1029 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1030 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1031 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1032 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1033 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1034 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1035 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1036 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1039 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1042 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1043 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1046 /* Writes instructions to target, updating the to pointer. */
1049 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1051 target_write_memory (*to
, buf
, len
);
1055 /* Relocates an instruction from oldloc to *to, updating to. */
1058 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1063 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1066 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1069 else if (buf
[0] < 0xc0)
1075 case 0x05: /* BALR */
1076 case 0x0c: /* BASSM */
1077 case 0x0d: /* BASR */
1078 case 0x45: /* BAL */
1079 case 0x4d: /* BAS */
1080 /* These save a return address and mess around with registers.
1081 We can't relocate them. */
1083 case 0x84: /* BRXH */
1084 case 0x85: /* BRXLE */
1089 /* BRC, BRAS, BRCT, BRCTG */
1090 if (op2
>= 4 && op2
<= 7)
1098 /* LARL, BRCL, BRASL */
1099 if (op2
== 0 || op2
== 4 || op2
== 5)
1107 /* PC-relative addressing instructions. */
1110 case 0xc5: /* BPRP */
1111 case 0xc7: /* BPP */
1112 /* Branch prediction - just skip it. */
1124 case 0x44: /* BRXHG */
1125 case 0x45: /* BRXLG */
1126 case 0x64: /* CGRJ */
1127 case 0x65: /* CLGRJ */
1128 case 0x76: /* CRJ */
1129 case 0x77: /* CLRJ */
1138 /* We'll have to relocate an instruction with a PC-relative field.
1139 First, compute the target. */
1140 int64_t loffset
= 0;
1144 int16_t soffset
= 0;
1145 memcpy (&soffset
, buf
+ 2, 2);
1150 int32_t soffset
= 0;
1151 memcpy (&soffset
, buf
+ 2, 4);
1154 target
= oldloc
+ loffset
* 2;
1156 target
&= 0x7fffffff;
1160 /* BRAS or BRASL was used. We cannot just relocate those, since
1161 they save the return address in a register. We can, however,
1162 replace them with a LARL+JG sequence. */
1164 /* Make the LARL. */
1168 loffset
= oldloc
+ ilen
- *to
;
1171 if (soffset
!= loffset
&& is_64
)
1173 memcpy (buf
+ 2, &soffset
, 4);
1174 append_insns (to
, 6, buf
);
1176 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1177 an address with the top bit 0, while BRAS/BRASL will write it
1178 with top bit 1. It should not matter much, since linux compilers
1179 use BR and not BSM to return from functions, but it could confuse
1180 some poor stack unwinder. */
1182 /* We'll now be writing a JG. */
1189 /* Compute the new offset and write it to the buffer. */
1190 loffset
= target
- *to
;
1195 int16_t soffset
= loffset
;
1196 if (soffset
!= loffset
)
1198 memcpy (buf
+ 2, &soffset
, 2);
1202 int32_t soffset
= loffset
;
1203 if (soffset
!= loffset
&& is_64
)
1205 memcpy (buf
+ 2, &soffset
, 4);
1208 append_insns (to
, ilen
, buf
);
1212 /* Implementation of linux_target_ops method
1213 "install_fast_tracepoint_jump_pad". */
1216 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1218 CORE_ADDR collector
,
1221 CORE_ADDR
*jump_entry
,
1222 CORE_ADDR
*trampoline
,
1223 ULONGEST
*trampoline_size
,
1224 unsigned char *jjump_pad_insn
,
1225 ULONGEST
*jjump_pad_insn_size
,
1226 CORE_ADDR
*adjusted_insn_addr
,
1227 CORE_ADDR
*adjusted_insn_addr_end
,
1233 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1234 CORE_ADDR buildaddr
= *jump_entry
;
1236 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1237 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1238 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1239 int has_vx
= have_hwcap_s390_vx
;
1241 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1243 CORE_ADDR literals
[4] = {
1250 /* First, store the GPRs. */
1252 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1253 s390_ft_entry_gpr_zarch
);
1255 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1256 s390_ft_entry_gpr_esa
);
1258 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1259 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1261 /* Third, FRs or VRs. */
1263 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1265 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1267 /* Now, the main part of code - store PSWA, take lock, call collector,
1268 leave lock. First, we'll need to fetch 4 literals. */
1270 unsigned char buf
[] = {
1271 0x07, 0x07, /* nopr %r7 */
1272 0x07, 0x07, /* nopr %r7 */
1273 0x07, 0x07, /* nopr %r7 */
1274 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1275 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1276 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1277 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1278 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1281 /* Find the proper start place in buf, so that literals will be
1283 int bufpos
= (buildaddr
+ 2) & 7;
1284 /* Stuff the literals into the buffer. */
1285 for (i
= 0; i
< 4; i
++) {
1286 uint64_t lit
= literals
[i
];
1287 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1289 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1290 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1292 unsigned char buf
[] = {
1293 0x07, 0x07, /* nopr %r7 */
1294 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1295 0, 0, 0, 0, /* tpaddr */
1296 0, 0, 0, 0, /* tpoint */
1297 0, 0, 0, 0, /* collector */
1298 0, 0, 0, 0, /* lockaddr */
1301 /* Find the proper start place in buf, so that literals will be
1303 int bufpos
= (buildaddr
+ 2) & 3;
1304 /* First literal will be saved as the PSWA, make sure it has the high bit
1306 literals
[0] |= 0x80000000;
1307 /* Stuff the literals into the buffer. */
1308 for (i
= 0; i
< 4; i
++) {
1309 uint32_t lit
= literals
[i
];
1310 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1312 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1313 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1316 /* Restore FRs or VRs. */
1318 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1320 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1322 /* Restore misc registers. */
1323 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1325 /* Restore the GPRs. */
1327 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1328 s390_ft_exit_gpr_zarch
);
1330 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1331 s390_ft_exit_gpr_esa
);
1333 /* Now, adjust the original instruction to execute in the jump
1335 *adjusted_insn_addr
= buildaddr
;
1336 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1338 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1341 *adjusted_insn_addr_end
= buildaddr
;
1343 /* Finally, write a jump back to the program. */
1345 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1348 if (is_64
&& offset
!= loffset
)
1351 "E.Jump back from jump pad too far from tracepoint "
1352 "(offset 0x%" PRIx64
" > int33).", loffset
);
1355 memcpy (jbuf
+ 2, &offset
, 4);
1356 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1358 /* The jump pad is now built. Wire in a jump to our jump pad. This
1359 is always done last (by our caller actually), so that we can
1360 install fast tracepoints with threads running. This relies on
1361 the agent's atomic write support. */
1362 loffset
= *jump_entry
- tpaddr
;
1365 if (is_64
&& offset
!= loffset
)
1368 "E.Jump back from jump pad too far from tracepoint "
1369 "(offset 0x%" PRIx64
" > int33).", loffset
);
1372 memcpy (jbuf
+ 2, &offset
, 4);
1373 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1374 *jjump_pad_insn_size
= sizeof jbuf
;
1376 /* Return the end address of our pad. */
1377 *jump_entry
= buildaddr
;
1382 /* Implementation of linux_target_ops method
1383 "get_min_fast_tracepoint_insn_len". */
1386 s390_get_min_fast_tracepoint_insn_len (void)
1388 /* We only support using 6-byte jumps to reach the tracepoint code.
1389 If the tracepoint buffer were allocated sufficiently close (64kiB)
1390 to the executable code, and the traced instruction itself was close
1391 enough to the beginning, we could use 4-byte jumps, but this doesn't
1392 seem to be worth the effort. */
1396 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1399 s390_get_ipa_tdesc_idx (void)
1401 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1402 const struct target_desc
*tdesc
= regcache
->tdesc
;
1405 if (tdesc
== tdesc_s390x_linux64
)
1406 return S390_TDESC_64
;
1407 if (tdesc
== tdesc_s390x_linux64v1
)
1408 return S390_TDESC_64V1
;
1409 if (tdesc
== tdesc_s390x_linux64v2
)
1410 return S390_TDESC_64V2
;
1411 if (tdesc
== tdesc_s390x_te_linux64
)
1412 return S390_TDESC_TE
;
1413 if (tdesc
== tdesc_s390x_vx_linux64
)
1414 return S390_TDESC_VX
;
1415 if (tdesc
== tdesc_s390x_tevx_linux64
)
1416 return S390_TDESC_TEVX
;
1417 if (tdesc
== tdesc_s390x_gs_linux64
)
1418 return S390_TDESC_GS
;
1421 if (tdesc
== tdesc_s390_linux32
)
1422 return S390_TDESC_32
;
1423 if (tdesc
== tdesc_s390_linux32v1
)
1424 return S390_TDESC_32V1
;
1425 if (tdesc
== tdesc_s390_linux32v2
)
1426 return S390_TDESC_32V2
;
1427 if (tdesc
== tdesc_s390_linux64
)
1428 return S390_TDESC_64
;
1429 if (tdesc
== tdesc_s390_linux64v1
)
1430 return S390_TDESC_64V1
;
1431 if (tdesc
== tdesc_s390_linux64v2
)
1432 return S390_TDESC_64V2
;
1433 if (tdesc
== tdesc_s390_te_linux64
)
1434 return S390_TDESC_TE
;
1435 if (tdesc
== tdesc_s390_vx_linux64
)
1436 return S390_TDESC_VX
;
1437 if (tdesc
== tdesc_s390_tevx_linux64
)
1438 return S390_TDESC_TEVX
;
1439 if (tdesc
== tdesc_s390_gs_linux64
)
1440 return S390_TDESC_GS
;
1445 /* Appends given buffer to current_insn_ptr in the target. */
1448 add_insns (const unsigned char *start
, int len
)
1450 CORE_ADDR buildaddr
= current_insn_ptr
;
1453 debug_printf ("Adding %d bytes of insn at %s\n",
1454 len
, paddress (buildaddr
));
1456 append_insns (&buildaddr
, len
, start
);
1457 current_insn_ptr
= buildaddr
;
1460 /* Register usage in emit:
1463 - %r2: top of stack (high word for 31-bit)
1464 - %r3: low word of top of stack (for 31-bit)
1466 - %r6, %r7, %r8: don't use
1469 - %r11: frame pointer
1470 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1471 - %r13: low word of saved top of stack (for 31-bit)
1472 - %r14: return address for calls
1473 - %r15: stack pointer
1477 /* The "emit_prologue" emit_ops method for s390. */
1480 s390_emit_prologue (void)
1482 static const unsigned char buf
[] = {
1483 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1484 0x18, 0x92, /* lr %r9, %r2 */
1485 0x18, 0xa3, /* lr %r10, %r3 */
1486 0x18, 0xbf, /* lr %r11, %r15 */
1488 add_insns (buf
, sizeof buf
);
1491 /* The "emit_epilogue" emit_ops method for s390. */
1494 s390_emit_epilogue (void)
1496 static const unsigned char buf
[] = {
1497 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1498 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1499 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1500 0x07, 0xfe, /* br %r14 */
1502 add_insns (buf
, sizeof buf
);
1505 /* The "emit_add" emit_ops method for s390. */
1508 s390_emit_add (void)
1510 static const unsigned char buf
[] = {
1511 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1512 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1513 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1515 add_insns (buf
, sizeof buf
);
1518 /* The "emit_sub" emit_ops method for s390. */
1521 s390_emit_sub (void)
1523 static const unsigned char buf
[] = {
1524 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1525 0x1f, 0x53, /* slr %r5, %r3 */
1526 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1527 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1528 0x18, 0x35, /* lr %r3, %r5 */
1529 0x18, 0x24, /* lr %r2, %r4 */
1531 add_insns (buf
, sizeof buf
);
1534 /* The "emit_mul" emit_ops method for s390. */
1537 s390_emit_mul (void)
1542 /* The "emit_lsh" emit_ops method for s390. */
1545 s390_emit_lsh (void)
1547 static const unsigned char buf
[] = {
1548 0x18, 0x43, /* lr %r4, %r3 */
1549 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1550 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1551 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1553 add_insns (buf
, sizeof buf
);
1556 /* The "emit_rsh_signed" emit_ops method for s390. */
1559 s390_emit_rsh_signed (void)
1561 static const unsigned char buf
[] = {
1562 0x18, 0x43, /* lr %r4, %r3 */
1563 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1564 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1565 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1567 add_insns (buf
, sizeof buf
);
1570 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1573 s390_emit_rsh_unsigned (void)
1575 static const unsigned char buf
[] = {
1576 0x18, 0x43, /* lr %r4, %r3 */
1577 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1578 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1579 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1581 add_insns (buf
, sizeof buf
);
1584 /* The "emit_ext" emit_ops method for s390. */
1587 s390_emit_ext (int arg
)
1589 unsigned char buf
[] = {
1590 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1591 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1593 add_insns (buf
, sizeof buf
);
1596 /* The "emit_log_not" emit_ops method for s390. */
1599 s390_emit_log_not (void)
1601 static const unsigned char buf
[] = {
1602 0x16, 0x23, /* or %r2, %r3 */
1603 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1604 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1605 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1606 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1609 add_insns (buf
, sizeof buf
);
1612 /* The "emit_bit_and" emit_ops method for s390. */
1615 s390_emit_bit_and (void)
1617 static const unsigned char buf
[] = {
1618 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1619 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1620 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1622 add_insns (buf
, sizeof buf
);
1625 /* The "emit_bit_or" emit_ops method for s390. */
1628 s390_emit_bit_or (void)
1630 static const unsigned char buf
[] = {
1631 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1632 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1633 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1635 add_insns (buf
, sizeof buf
);
1638 /* The "emit_bit_xor" emit_ops method for s390. */
1641 s390_emit_bit_xor (void)
1643 static const unsigned char buf
[] = {
1644 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1645 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1646 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1648 add_insns (buf
, sizeof buf
);
1651 /* The "emit_bit_not" emit_ops method for s390. */
1654 s390_emit_bit_not (void)
1656 static const unsigned char buf
[] = {
1657 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1658 0x17, 0x24, /* xr %r2, %r4 */
1659 0x17, 0x34, /* xr %r3, %r4 */
1661 add_insns (buf
, sizeof buf
);
1664 /* The "emit_equal" emit_ops method for s390. */
1667 s390_emit_equal (void)
1669 s390_emit_bit_xor ();
1670 s390_emit_log_not ();
1673 /* The "emit_less_signed" emit_ops method for s390. */
1676 s390_emit_less_signed (void)
1678 static const unsigned char buf
[] = {
1679 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1680 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1681 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1682 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1683 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1685 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1686 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1688 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1690 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1691 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1693 add_insns (buf
, sizeof buf
);
1696 /* The "emit_less_unsigned" emit_ops method for s390. */
1699 s390_emit_less_unsigned (void)
1701 static const unsigned char buf
[] = {
1702 0x55, 0x20, 0xf0, 0x00, /* cl %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_ref" emit_ops method for s390. */
1722 s390_emit_ref (int size
)
1724 static const unsigned char buf1
[] = {
1725 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1726 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1728 static const unsigned char buf2
[] = {
1729 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1730 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1732 static const unsigned char buf4
[] = {
1733 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1734 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1736 static const unsigned char buf8
[] = {
1737 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1742 add_insns (buf1
, sizeof buf1
);
1745 add_insns (buf2
, sizeof buf2
);
1748 add_insns (buf4
, sizeof buf4
);
1751 add_insns (buf8
, sizeof buf8
);
1758 /* The "emit_if_goto" emit_ops method for s390. */
1761 s390_emit_if_goto (int *offset_p
, int *size_p
)
1763 static const unsigned char buf
[] = {
1764 0x16, 0x23, /* or %r2, %r3 */
1765 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1766 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1767 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1769 add_insns (buf
, sizeof buf
);
1776 /* The "emit_goto" emit_ops method for s390 and s390x. */
1779 s390_emit_goto (int *offset_p
, int *size_p
)
1781 static const unsigned char buf
[] = {
1782 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1784 add_insns (buf
, sizeof buf
);
1791 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1794 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1796 long diff
= ((long) (to
- (from
- 2))) / 2;
1798 unsigned char buf
[sizeof sdiff
];
1800 /* We're only doing 4-byte sizes at the moment. */
1801 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1807 memcpy (buf
, &sdiff
, sizeof sdiff
);
1808 target_write_memory (from
, buf
, sizeof sdiff
);
1811 /* Preparation for emitting a literal pool of given size. Loads the address
1812 of the pool into %r1, and jumps over it. Called should emit the pool data
1813 immediately afterwards. Used for both s390 and s390x. */
1816 s390_emit_litpool (int size
)
1818 static const unsigned char nop
[] = {
1821 unsigned char buf
[] = {
1823 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1828 /* buf needs to start at even halfword for litpool to be aligned */
1829 if (current_insn_ptr
& 2)
1830 add_insns (nop
, sizeof nop
);
1834 while ((current_insn_ptr
& 6) != 4)
1835 add_insns (nop
, sizeof nop
);
1837 add_insns (buf
, sizeof buf
);
1840 /* The "emit_const" emit_ops method for s390. */
1843 s390_emit_const (LONGEST num
)
1845 unsigned long long n
= num
;
1846 unsigned char buf_s
[] = {
1847 /* lhi %r3, <num> */
1849 (unsigned char) (num
>> 8), (unsigned char) num
,
1853 static const unsigned char buf_l
[] = {
1854 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1856 if (num
< 0x8000 && num
>= 0)
1858 add_insns (buf_s
, sizeof buf_s
);
1862 s390_emit_litpool (8);
1863 add_insns ((unsigned char *) &n
, sizeof n
);
1864 add_insns (buf_l
, sizeof buf_l
);
1868 /* The "emit_call" emit_ops method for s390. */
1871 s390_emit_call (CORE_ADDR fn
)
1873 unsigned int n
= fn
;
1874 static const unsigned char buf
[] = {
1875 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1876 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1877 0x0d, 0xe1, /* basr %r14, %r1 */
1878 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1880 s390_emit_litpool (4);
1881 add_insns ((unsigned char *) &n
, sizeof n
);
1882 add_insns (buf
, sizeof buf
);
1885 /* The "emit_reg" emit_ops method for s390. */
1888 s390_emit_reg (int reg
)
1890 unsigned char bufpre
[] = {
1893 /* lhi %r3, <reg> */
1894 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1896 add_insns (bufpre
, sizeof bufpre
);
1897 s390_emit_call (get_raw_reg_func_addr ());
1900 /* The "emit_pop" emit_ops method for s390. */
1903 s390_emit_pop (void)
1905 static const unsigned char buf
[] = {
1906 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1907 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1909 add_insns (buf
, sizeof buf
);
1912 /* The "emit_stack_flush" emit_ops method for s390. */
1915 s390_emit_stack_flush (void)
1917 static const unsigned char buf
[] = {
1918 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1919 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1921 add_insns (buf
, sizeof buf
);
1924 /* The "emit_zero_ext" emit_ops method for s390. */
1927 s390_emit_zero_ext (int arg
)
1929 unsigned char buf
[] = {
1930 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1931 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1933 add_insns (buf
, sizeof buf
);
1936 /* The "emit_swap" emit_ops method for s390. */
1939 s390_emit_swap (void)
1941 static const unsigned char buf
[] = {
1942 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1943 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1944 0x18, 0x24, /* lr %r2, %r4 */
1945 0x18, 0x35, /* lr %r3, %r5 */
1947 add_insns (buf
, sizeof buf
);
1950 /* The "emit_stack_adjust" emit_ops method for s390. */
1953 s390_emit_stack_adjust (int n
)
1955 unsigned char buf
[] = {
1958 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
1960 add_insns (buf
, sizeof buf
);
1963 /* Sets %r2 to a 32-bit constant. */
1966 s390_emit_set_r2 (int arg1
)
1968 unsigned char buf_s
[] = {
1969 /* lhi %r2, <arg1> */
1970 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
1972 static const unsigned char buf_l
[] = {
1973 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1975 if (arg1
< 0x8000 && arg1
>= -0x8000)
1977 add_insns (buf_s
, sizeof buf_s
);
1981 s390_emit_litpool (4);
1982 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
1983 add_insns (buf_l
, sizeof buf_l
);
1987 /* The "emit_int_call_1" emit_ops method for s390. */
1990 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
1992 /* FN's prototype is `LONGEST(*fn)(int)'. */
1993 s390_emit_set_r2 (arg1
);
1994 s390_emit_call (fn
);
1997 /* The "emit_void_call_2" emit_ops method for s390. */
2000 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2002 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2003 static const unsigned char buf
[] = {
2004 0x18, 0xc2, /* lr %r12, %r2 */
2005 0x18, 0xd3, /* lr %r13, %r3 */
2006 0x18, 0x43, /* lr %r4, %r3 */
2007 0x18, 0x32, /* lr %r3, %r2 */
2009 static const unsigned char buf2
[] = {
2010 0x18, 0x2c, /* lr %r2, %r12 */
2011 0x18, 0x3d, /* lr %r3, %r13 */
2013 add_insns (buf
, sizeof buf
);
2014 s390_emit_set_r2 (arg1
);
2015 s390_emit_call (fn
);
2016 add_insns (buf2
, sizeof buf2
);
2019 /* The "emit_eq_goto" emit_ops method for s390. */
2022 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2024 static const unsigned char buf
[] = {
2025 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2026 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2027 0x16, 0x23, /* or %r2, %r3 */
2028 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2029 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2030 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2032 add_insns (buf
, sizeof buf
);
2039 /* The "emit_ne_goto" emit_ops method for s390. */
2042 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2044 static const unsigned char buf
[] = {
2045 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2046 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2047 0x16, 0x23, /* or %r2, %r3 */
2048 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2049 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2050 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2052 add_insns (buf
, sizeof buf
);
2059 /* The "emit_lt_goto" emit_ops method for s390. */
2062 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2064 static const unsigned char buf
[] = {
2065 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2066 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2067 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2068 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2069 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2071 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2072 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2073 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2075 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2076 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2077 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2080 add_insns (buf
, sizeof buf
);
2087 /* The "emit_le_goto" emit_ops method for s390. */
2090 s390_emit_le_goto (int *offset_p
, int *size_p
)
2092 static const unsigned char buf
[] = {
2093 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2094 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2095 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2096 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2097 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2099 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2100 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2101 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2103 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2104 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2105 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2108 add_insns (buf
, sizeof buf
);
2115 /* The "emit_gt_goto" emit_ops method for s390. */
2118 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2120 static const unsigned char buf
[] = {
2121 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2122 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2123 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2124 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2125 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2127 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2128 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2129 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2131 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2132 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2133 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2136 add_insns (buf
, sizeof buf
);
2143 /* The "emit_ge_goto" emit_ops method for s390. */
2146 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2148 static const unsigned char buf
[] = {
2149 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2150 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2151 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2152 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2153 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2155 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2156 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2157 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2159 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2160 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2161 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2164 add_insns (buf
, sizeof buf
);
2171 /* The "emit_ops" structure for s390. Named _impl to avoid name
2172 collision with s390_emit_ops function. */
2174 static struct emit_ops s390_emit_ops_impl
=
2182 s390_emit_rsh_signed
,
2183 s390_emit_rsh_unsigned
,
2191 s390_emit_less_signed
,
2192 s390_emit_less_unsigned
,
2196 s390_write_goto_address
,
2201 s390_emit_stack_flush
,
2204 s390_emit_stack_adjust
,
2205 s390_emit_int_call_1
,
2206 s390_emit_void_call_2
,
2217 /* The "emit_prologue" emit_ops method for s390x. */
2220 s390x_emit_prologue (void)
2222 static const unsigned char buf
[] = {
2223 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2224 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2225 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2226 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2228 add_insns (buf
, sizeof buf
);
2231 /* The "emit_epilogue" emit_ops method for s390x. */
2234 s390x_emit_epilogue (void)
2236 static const unsigned char buf
[] = {
2237 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2238 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2239 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2240 0x07, 0xfe, /* br %r14 */
2242 add_insns (buf
, sizeof buf
);
2245 /* The "emit_add" emit_ops method for s390x. */
2248 s390x_emit_add (void)
2250 static const unsigned char buf
[] = {
2251 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2252 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2254 add_insns (buf
, sizeof buf
);
2257 /* The "emit_sub" emit_ops method for s390x. */
2260 s390x_emit_sub (void)
2262 static const unsigned char buf
[] = {
2263 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2264 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2265 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2266 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2268 add_insns (buf
, sizeof buf
);
2271 /* The "emit_mul" emit_ops method for s390x. */
2274 s390x_emit_mul (void)
2279 /* The "emit_lsh" emit_ops method for s390x. */
2282 s390x_emit_lsh (void)
2284 static const unsigned char buf
[] = {
2285 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2286 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2287 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2289 add_insns (buf
, sizeof buf
);
2292 /* The "emit_rsh_signed" emit_ops method for s390x. */
2295 s390x_emit_rsh_signed (void)
2297 static const unsigned char buf
[] = {
2298 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2299 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2300 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2302 add_insns (buf
, sizeof buf
);
2305 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2308 s390x_emit_rsh_unsigned (void)
2310 static const unsigned char buf
[] = {
2311 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2312 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2313 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2315 add_insns (buf
, sizeof buf
);
2318 /* The "emit_ext" emit_ops method for s390x. */
2321 s390x_emit_ext (int arg
)
2323 unsigned char buf
[] = {
2324 /* sllg %r2, %r2, <64-arg> */
2325 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2326 /* srag %r2, %r2, <64-arg> */
2327 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2329 add_insns (buf
, sizeof buf
);
2332 /* The "emit_log_not" emit_ops method for s390x. */
2335 s390x_emit_log_not (void)
2337 static const unsigned char buf
[] = {
2338 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2339 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2340 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2342 add_insns (buf
, sizeof buf
);
2345 /* The "emit_bit_and" emit_ops method for s390x. */
2348 s390x_emit_bit_and (void)
2350 static const unsigned char buf
[] = {
2351 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2352 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2354 add_insns (buf
, sizeof buf
);
2357 /* The "emit_bit_or" emit_ops method for s390x. */
2360 s390x_emit_bit_or (void)
2362 static const unsigned char buf
[] = {
2363 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2364 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2366 add_insns (buf
, sizeof buf
);
2369 /* The "emit_bit_xor" emit_ops method for s390x. */
2372 s390x_emit_bit_xor (void)
2374 static const unsigned char buf
[] = {
2375 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2376 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2378 add_insns (buf
, sizeof buf
);
2381 /* The "emit_bit_not" emit_ops method for s390x. */
2384 s390x_emit_bit_not (void)
2386 static const unsigned char buf
[] = {
2387 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2388 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2390 add_insns (buf
, sizeof buf
);
2393 /* The "emit_equal" emit_ops method for s390x. */
2396 s390x_emit_equal (void)
2398 s390x_emit_bit_xor ();
2399 s390x_emit_log_not ();
2402 /* The "emit_less_signed" emit_ops method for s390x. */
2405 s390x_emit_less_signed (void)
2407 static const unsigned char buf
[] = {
2408 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2409 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2410 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2411 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2413 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2415 add_insns (buf
, sizeof buf
);
2418 /* The "emit_less_unsigned" emit_ops method for s390x. */
2421 s390x_emit_less_unsigned (void)
2423 static const unsigned char buf
[] = {
2424 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2425 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2426 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2427 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2429 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2431 add_insns (buf
, sizeof buf
);
2434 /* The "emit_ref" emit_ops method for s390x. */
2437 s390x_emit_ref (int size
)
2439 static const unsigned char buf1
[] = {
2440 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2442 static const unsigned char buf2
[] = {
2443 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2445 static const unsigned char buf4
[] = {
2446 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2448 static const unsigned char buf8
[] = {
2449 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2454 add_insns (buf1
, sizeof buf1
);
2457 add_insns (buf2
, sizeof buf2
);
2460 add_insns (buf4
, sizeof buf4
);
2463 add_insns (buf8
, sizeof buf8
);
2470 /* The "emit_if_goto" emit_ops method for s390x. */
2473 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2475 static const unsigned char buf
[] = {
2476 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2477 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2478 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2479 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2481 add_insns (buf
, sizeof buf
);
2488 /* The "emit_const" emit_ops method for s390x. */
2491 s390x_emit_const (LONGEST num
)
2493 unsigned long long n
= num
;
2494 unsigned char buf_s
[] = {
2495 /* lghi %r2, <num> */
2496 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2498 static const unsigned char buf_l
[] = {
2499 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2501 if (num
< 0x8000 && num
>= -0x8000)
2503 add_insns (buf_s
, sizeof buf_s
);
2507 s390_emit_litpool (8);
2508 add_insns ((unsigned char *) &n
, sizeof n
);
2509 add_insns (buf_l
, sizeof buf_l
);
2513 /* The "emit_call" emit_ops method for s390x. */
2516 s390x_emit_call (CORE_ADDR fn
)
2518 unsigned long n
= fn
;
2519 static const unsigned char buf
[] = {
2520 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2521 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2522 0x0d, 0xe1, /* basr %r14, %r1 */
2523 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2525 s390_emit_litpool (8);
2526 add_insns ((unsigned char *) &n
, sizeof n
);
2527 add_insns (buf
, sizeof buf
);
2530 /* The "emit_reg" emit_ops method for s390x. */
2533 s390x_emit_reg (int reg
)
2535 unsigned char buf
[] = {
2537 0xb9, 0x04, 0x00, 0x29,
2538 /* lghi %r3, <reg> */
2539 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2541 add_insns (buf
, sizeof buf
);
2542 s390x_emit_call (get_raw_reg_func_addr ());
2545 /* The "emit_pop" emit_ops method for s390x. */
2548 s390x_emit_pop (void)
2550 static const unsigned char buf
[] = {
2551 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2552 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2554 add_insns (buf
, sizeof buf
);
2557 /* The "emit_stack_flush" emit_ops method for s390x. */
2560 s390x_emit_stack_flush (void)
2562 static const unsigned char buf
[] = {
2563 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2564 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2566 add_insns (buf
, sizeof buf
);
2569 /* The "emit_zero_ext" emit_ops method for s390x. */
2572 s390x_emit_zero_ext (int arg
)
2574 unsigned char buf
[] = {
2575 /* sllg %r2, %r2, <64-arg> */
2576 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2577 /* srlg %r2, %r2, <64-arg> */
2578 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2580 add_insns (buf
, sizeof buf
);
2583 /* The "emit_swap" emit_ops method for s390x. */
2586 s390x_emit_swap (void)
2588 static const unsigned char buf
[] = {
2589 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2590 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2591 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2593 add_insns (buf
, sizeof buf
);
2596 /* The "emit_stack_adjust" emit_ops method for s390x. */
2599 s390x_emit_stack_adjust (int n
)
2601 unsigned char buf
[] = {
2602 /* aghi %r15, 8*n */
2604 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2606 add_insns (buf
, sizeof buf
);
2609 /* The "emit_int_call_1" emit_ops method for s390x. */
2612 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2614 /* FN's prototype is `LONGEST(*fn)(int)'. */
2615 s390x_emit_const (arg1
);
2616 s390x_emit_call (fn
);
2619 /* The "emit_void_call_2" emit_ops method for s390x. */
2622 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2624 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2625 static const unsigned char buf
[] = {
2626 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2627 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2629 static const unsigned char buf2
[] = {
2630 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2632 add_insns (buf
, sizeof buf
);
2633 s390x_emit_const (arg1
);
2634 s390x_emit_call (fn
);
2635 add_insns (buf2
, sizeof buf2
);
2638 /* The "emit_eq_goto" emit_ops method for s390x. */
2641 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2643 static const unsigned char buf
[] = {
2644 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2645 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2646 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2647 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2649 add_insns (buf
, sizeof buf
);
2656 /* The "emit_ne_goto" emit_ops method for s390x. */
2659 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2661 static const unsigned char buf
[] = {
2662 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2663 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2664 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2665 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2667 add_insns (buf
, sizeof buf
);
2674 /* The "emit_lt_goto" emit_ops method for s390x. */
2677 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2679 static const unsigned char buf
[] = {
2680 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2681 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2682 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2683 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2685 add_insns (buf
, sizeof buf
);
2692 /* The "emit_le_goto" emit_ops method for s390x. */
2695 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2697 static const unsigned char buf
[] = {
2698 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2699 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2700 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2701 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2703 add_insns (buf
, sizeof buf
);
2710 /* The "emit_gt_goto" emit_ops method for s390x. */
2713 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2715 static const unsigned char buf
[] = {
2716 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2717 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2718 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2719 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2721 add_insns (buf
, sizeof buf
);
2728 /* The "emit_ge_goto" emit_ops method for s390x. */
2731 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2733 static const unsigned char buf
[] = {
2734 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2735 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2736 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2737 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2739 add_insns (buf
, sizeof buf
);
2746 /* The "emit_ops" structure for s390x. */
2748 static struct emit_ops s390x_emit_ops
=
2750 s390x_emit_prologue
,
2751 s390x_emit_epilogue
,
2756 s390x_emit_rsh_signed
,
2757 s390x_emit_rsh_unsigned
,
2765 s390x_emit_less_signed
,
2766 s390x_emit_less_unsigned
,
2770 s390_write_goto_address
,
2775 s390x_emit_stack_flush
,
2776 s390x_emit_zero_ext
,
2778 s390x_emit_stack_adjust
,
2779 s390x_emit_int_call_1
,
2780 s390x_emit_void_call_2
,
2790 /* The "emit_ops" linux_target_ops method. */
2792 static struct emit_ops
*
2793 s390_emit_ops (void)
2796 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2798 if (register_size (regcache
->tdesc
, 0) == 8)
2799 return &s390x_emit_ops
;
2802 return &s390_emit_ops_impl
;
2805 struct linux_target_ops the_low_target
= {
2808 s390_cannot_fetch_register
,
2809 s390_cannot_store_register
,
2810 NULL
, /* fetch_register */
2813 NULL
, /* breakpoint_kind_from_pc */
2814 s390_sw_breakpoint_from_kind
,
2816 s390_breakpoint_len
,
2818 s390_supports_z_point_type
,
2823 s390_collect_ptrace_register
,
2824 s390_supply_ptrace_register
,
2825 NULL
, /* siginfo_fixup */
2826 NULL
, /* new_process */
2827 NULL
, /* delete_process */
2828 NULL
, /* new_thread */
2829 NULL
, /* delete_thread */
2830 NULL
, /* new_fork */
2831 NULL
, /* prepare_to_resume */
2832 NULL
, /* process_qsupported */
2833 s390_supports_tracepoints
,
2834 s390_get_thread_area
,
2835 s390_install_fast_tracepoint_jump_pad
,
2837 s390_get_min_fast_tracepoint_insn_len
,
2838 NULL
, /* supports_range_stepping */
2839 NULL
, /* breakpoint_kind_from_current_state */
2840 s390_supports_hardware_single_step
,
2841 NULL
, /* get_syscall_trapinfo */
2842 s390_get_ipa_tdesc_idx
,
2845 /* The linux target ops object. */
2847 linux_process_target
*the_linux_target
= &the_s390_target
;
2850 initialize_low_arch (void)
2852 /* Initialize the Linux target descriptions. */
2854 init_registers_s390_linux32 ();
2855 init_registers_s390_linux32v1 ();
2856 init_registers_s390_linux32v2 ();
2857 init_registers_s390_linux64 ();
2858 init_registers_s390_linux64v1 ();
2859 init_registers_s390_linux64v2 ();
2860 init_registers_s390_te_linux64 ();
2861 init_registers_s390_vx_linux64 ();
2862 init_registers_s390_tevx_linux64 ();
2863 init_registers_s390_gs_linux64 ();
2865 init_registers_s390x_linux64 ();
2866 init_registers_s390x_linux64v1 ();
2867 init_registers_s390x_linux64v2 ();
2868 init_registers_s390x_te_linux64 ();
2869 init_registers_s390x_vx_linux64 ();
2870 init_registers_s390x_tevx_linux64 ();
2871 init_registers_s390x_gs_linux64 ();
2874 initialize_regsets_info (&s390_regsets_info
);
2875 initialize_regsets_info (&s390_regsets_info_3264
);