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
60 const regs_info
*get_regs_info () override
;
64 void low_arch_setup () override
;
67 /* The singleton target ops object. */
69 static s390_target the_s390_target
;
71 static int s390_regmap
[] = {
72 PT_PSWMASK
, PT_PSWADDR
,
74 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
75 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
76 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
77 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
79 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
80 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
81 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
82 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
87 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
88 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
89 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
90 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
92 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
93 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
94 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
95 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
101 #define s390_num_regs_3264 68
104 static int s390_regmap_3264
[] = {
105 PT_PSWMASK
, PT_PSWADDR
,
107 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
108 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
109 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
110 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
111 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
112 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
113 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
114 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
116 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
117 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
118 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
119 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
123 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
124 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
125 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
126 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
131 static int s390_regmap_3264
[] = {
132 PT_PSWMASK
, PT_PSWADDR
,
134 -1, PT_GPR0
, -1, PT_GPR1
,
135 -1, PT_GPR2
, -1, PT_GPR3
,
136 -1, PT_GPR4
, -1, PT_GPR5
,
137 -1, PT_GPR6
, -1, PT_GPR7
,
138 -1, PT_GPR8
, -1, PT_GPR9
,
139 -1, PT_GPR10
, -1, PT_GPR11
,
140 -1, PT_GPR12
, -1, PT_GPR13
,
141 -1, PT_GPR14
, -1, PT_GPR15
,
143 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
144 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
145 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
146 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
150 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
151 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
152 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
153 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
161 s390_cannot_fetch_register (int regno
)
167 s390_cannot_store_register (int regno
)
173 s390_collect_ptrace_register (struct regcache
*regcache
, int regno
, char *buf
)
175 int size
= register_size (regcache
->tdesc
, regno
);
176 const struct regs_info
*regs_info
= the_linux_target
->get_regs_info ();
177 struct usrregs_info
*usr
= regs_info
->usrregs
;
178 int regaddr
= usr
->regmap
[regno
];
180 if (size
< sizeof (long))
182 memset (buf
, 0, sizeof (long));
184 if ((regno
^ 1) < usr
->num_regs
185 && usr
->regmap
[regno
^ 1] == regaddr
)
187 collect_register (regcache
, regno
& ~1, buf
);
188 collect_register (regcache
, (regno
& ~1) + 1,
189 buf
+ sizeof (long) - size
);
191 else if (regaddr
== PT_PSWMASK
)
193 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
194 the basic addressing mode bit from the PSW address. */
195 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
196 collect_register (regcache
, regno
, buf
);
197 collect_register (regcache
, regno
^ 1, addr
);
199 buf
[size
] |= (addr
[0] & 0x80);
201 else if (regaddr
== PT_PSWADDR
)
203 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
204 mode bit (which gets copied to the PSW mask instead). */
205 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
206 buf
[sizeof (long) - size
] &= ~0x80;
208 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
209 || regaddr
== PT_ORIGGPR2
)
210 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
212 collect_register (regcache
, regno
, buf
);
214 else if (regaddr
!= -1)
215 collect_register (regcache
, regno
, buf
);
219 s390_supply_ptrace_register (struct regcache
*regcache
,
220 int regno
, const char *buf
)
222 int size
= register_size (regcache
->tdesc
, regno
);
223 const struct regs_info
*regs_info
= the_linux_target
->get_regs_info ();
224 struct usrregs_info
*usr
= regs_info
->usrregs
;
225 int regaddr
= usr
->regmap
[regno
];
227 if (size
< sizeof (long))
229 if ((regno
^ 1) < usr
->num_regs
230 && usr
->regmap
[regno
^ 1] == regaddr
)
232 supply_register (regcache
, regno
& ~1, buf
);
233 supply_register (regcache
, (regno
& ~1) + 1,
234 buf
+ sizeof (long) - size
);
236 else if (regaddr
== PT_PSWMASK
)
238 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
239 the basic addressing mode into the PSW address. */
240 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
241 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
242 memcpy (mask
, buf
, size
);
244 supply_register (regcache
, regno
, mask
);
246 collect_register (regcache
, regno
^ 1, addr
);
248 addr
[0] |= (buf
[size
] & 0x80);
249 supply_register (regcache
, regno
^ 1, addr
);
251 else if (regaddr
== PT_PSWADDR
)
253 /* Convert 8-byte PSW address to 4 bytes by truncating, but
254 keeping the addressing mode bit (which was set from the mask). */
255 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
257 collect_register (regcache
, regno
, addr
);
258 amode
= addr
[0] & 0x80;
259 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
262 supply_register (regcache
, regno
, addr
);
264 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
265 || regaddr
== PT_ORIGGPR2
)
266 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
268 supply_register (regcache
, regno
, buf
);
270 else if (regaddr
!= -1)
271 supply_register (regcache
, regno
, buf
);
274 /* Provide only a fill function for the general register set. ps_lgetregs
275 will use this for NPTL support. */
278 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
281 const struct regs_info
*regs_info
= the_linux_target
->get_regs_info ();
282 struct usrregs_info
*usr
= regs_info
->usrregs
;
284 for (i
= 0; i
< usr
->num_regs
; i
++)
286 if (usr
->regmap
[i
] < PT_PSWMASK
287 || usr
->regmap
[i
] > PT_ACR15
)
290 s390_collect_ptrace_register (regcache
, i
,
291 (char *) buf
+ usr
->regmap
[i
]);
295 /* Fill and store functions for extended register sets. */
299 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
301 int r0h
= find_regno (regcache
->tdesc
, "r0h");
304 for (i
= 0; i
< 16; i
++)
305 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
309 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
311 int r0h
= find_regno (regcache
->tdesc
, "r0h");
314 for (i
= 0; i
< 16; i
++)
315 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
320 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
324 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
325 supply_register_by_name (regcache
, "last_break", p
);
329 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
331 collect_register_by_name (regcache
, "system_call", buf
);
335 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
337 supply_register_by_name (regcache
, "system_call", buf
);
341 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
343 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
344 int tr0
= find_regno (regcache
->tdesc
, "tr0");
347 for (i
= 0; i
< 4; i
++)
348 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
350 for (i
= 0; i
< 16; i
++)
351 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
355 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
357 int v0
= find_regno (regcache
->tdesc
, "v0l");
360 for (i
= 0; i
< 16; i
++)
361 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
365 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
367 int v0
= find_regno (regcache
->tdesc
, "v0l");
370 for (i
= 0; i
< 16; i
++)
371 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
375 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
377 int v16
= find_regno (regcache
->tdesc
, "v16");
380 for (i
= 0; i
< 16; i
++)
381 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
385 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
387 int v16
= find_regno (regcache
->tdesc
, "v16");
390 for (i
= 0; i
< 16; i
++)
391 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
395 s390_store_gs (struct regcache
*regcache
, const void *buf
)
397 int gsd
= find_regno (regcache
->tdesc
, "gsd");
400 for (i
= 0; i
< 3; i
++)
401 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
405 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
407 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
410 for (i
= 0; i
< 3; i
++)
411 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
414 static struct regset_info s390_regsets
[] = {
415 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
417 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
418 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
420 /* Last break address is read-only; no fill function. */
421 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
422 NULL
, s390_store_last_break
},
423 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
424 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
425 /* TDB is read-only. */
426 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
427 NULL
, s390_store_tdb
},
428 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
429 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
430 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
431 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
432 /* Guarded storage registers are read-only. */
433 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
434 NULL
, s390_store_gs
},
435 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
436 NULL
, s390_store_gsbc
},
441 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
442 #define s390_breakpoint_len 2
444 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
446 static const gdb_byte
*
447 s390_sw_breakpoint_from_kind (int kind
, int *size
)
449 *size
= s390_breakpoint_len
;
450 return s390_breakpoint
;
454 s390_get_pc (struct regcache
*regcache
)
456 if (register_size (regcache
->tdesc
, 0) == 4)
459 collect_register_by_name (regcache
, "pswa", &pswa
);
460 return pswa
& 0x7fffffff;
465 collect_register_by_name (regcache
, "pswa", &pc
);
471 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
473 if (register_size (regcache
->tdesc
, 0) == 4)
476 collect_register_by_name (regcache
, "pswa", &pswa
);
477 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
478 supply_register_by_name (regcache
, "pswa", &pswa
);
482 unsigned long pc
= newpc
;
483 supply_register_by_name (regcache
, "pswa", &pc
);
487 /* Determine the word size for the given PID, in bytes. */
491 s390_get_wordsize (int pid
)
494 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
495 (PTRACE_TYPE_ARG3
) 0,
496 (PTRACE_TYPE_ARG4
) 0);
499 warning (_("Couldn't determine word size, assuming 64-bit."));
502 /* Derive word size from extended addressing mode (PSW bit 31). */
503 return pswm
& (1L << 32) ? 8 : 4;
506 #define s390_get_wordsize(pid) 4
510 s390_check_regset (int pid
, int regset
, int regsize
)
512 void *buf
= alloca (regsize
);
516 iov
.iov_len
= regsize
;
518 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
524 /* For a 31-bit inferior, whether the kernel supports using the full
526 static int have_hwcap_s390_high_gprs
= 0;
527 static int have_hwcap_s390_vx
= 0;
530 s390_target::low_arch_setup ()
532 const struct target_desc
*tdesc
;
533 struct regset_info
*regset
;
535 /* Determine word size and HWCAP. */
536 int pid
= pid_of (current_thread
);
537 int wordsize
= s390_get_wordsize (pid
);
538 unsigned long hwcap
= linux_get_hwcap (wordsize
);
540 /* Check whether the kernel supports extra register sets. */
541 int have_regset_last_break
542 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
543 int have_regset_system_call
544 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
546 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
547 && (hwcap
& HWCAP_S390_TE
) != 0);
549 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
550 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
551 && (hwcap
& HWCAP_S390_VX
) != 0);
553 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
554 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
555 && (hwcap
& HWCAP_S390_GS
) != 0);
562 tdesc
= tdesc_s390x_gs_linux64
;
563 else if (have_regset_vxrs
)
564 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
565 tdesc_s390x_vx_linux64
);
566 else if (have_regset_tdb
)
567 tdesc
= tdesc_s390x_te_linux64
;
568 else if (have_regset_system_call
)
569 tdesc
= tdesc_s390x_linux64v2
;
570 else if (have_regset_last_break
)
571 tdesc
= tdesc_s390x_linux64v1
;
573 tdesc
= tdesc_s390x_linux64
;
576 /* For a 31-bit inferior, check whether the kernel supports
577 using the full 64-bit GPRs. */
580 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
582 have_hwcap_s390_high_gprs
= 1;
584 tdesc
= tdesc_s390_gs_linux64
;
585 else if (have_regset_vxrs
)
586 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
587 tdesc_s390_vx_linux64
);
588 else if (have_regset_tdb
)
589 tdesc
= tdesc_s390_te_linux64
;
590 else if (have_regset_system_call
)
591 tdesc
= tdesc_s390_linux64v2
;
592 else if (have_regset_last_break
)
593 tdesc
= tdesc_s390_linux64v1
;
595 tdesc
= tdesc_s390_linux64
;
599 /* Assume 31-bit inferior process. */
600 if (have_regset_system_call
)
601 tdesc
= tdesc_s390_linux32v2
;
602 else if (have_regset_last_break
)
603 tdesc
= tdesc_s390_linux32v1
;
605 tdesc
= tdesc_s390_linux32
;
608 have_hwcap_s390_vx
= have_regset_vxrs
;
611 /* Update target_regsets according to available register sets. */
612 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
613 if (regset
->get_request
== PTRACE_GETREGSET
)
614 switch (regset
->nt_type
)
617 case NT_S390_HIGH_GPRS
:
618 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
621 case NT_S390_LAST_BREAK
:
622 regset
->size
= have_regset_last_break
? 8 : 0;
624 case NT_S390_SYSTEM_CALL
:
625 regset
->size
= have_regset_system_call
? 4 : 0;
628 regset
->size
= have_regset_tdb
? 256 : 0;
630 case NT_S390_VXRS_LOW
:
631 regset
->size
= have_regset_vxrs
? 128 : 0;
633 case NT_S390_VXRS_HIGH
:
634 regset
->size
= have_regset_vxrs
? 256 : 0;
638 regset
->size
= have_regset_gs
? 32 : 0;
643 current_process ()->tdesc
= tdesc
;
648 s390_breakpoint_at (CORE_ADDR pc
)
650 unsigned char c
[s390_breakpoint_len
];
651 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
652 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
655 /* Breakpoint/Watchpoint support. */
657 /* The "supports_z_point_type" linux_target_ops method. */
660 s390_supports_z_point_type (char z_type
)
671 /* Support for hardware single step. */
674 s390_supports_hardware_single_step (void)
679 static struct usrregs_info s390_usrregs_info
=
685 static struct regsets_info s390_regsets_info
=
687 s390_regsets
, /* regsets */
689 NULL
, /* disabled_regsets */
692 static struct regs_info myregs_info
=
694 NULL
, /* regset_bitmap */
699 static struct usrregs_info s390_usrregs_info_3264
=
705 static struct regsets_info s390_regsets_info_3264
=
707 s390_regsets
, /* regsets */
709 NULL
, /* disabled_regsets */
712 static struct regs_info regs_info_3264
=
714 NULL
, /* regset_bitmap */
715 &s390_usrregs_info_3264
,
716 &s390_regsets_info_3264
720 s390_target::get_regs_info ()
722 if (have_hwcap_s390_high_gprs
)
725 const struct target_desc
*tdesc
= current_process ()->tdesc
;
727 if (register_size (tdesc
, 0) == 4)
728 return ®s_info_3264
;
730 return ®s_info_3264
;
736 /* The "supports_tracepoints" linux_target_ops method. */
739 s390_supports_tracepoints (void)
744 /* Implementation of linux_target_ops method "get_thread_area". */
747 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
749 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
751 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
753 if (register_size (regcache
->tdesc
, 0) == 4)
754 res
&= 0xffffffffull
;
761 /* Fast tracepoint support.
763 The register save area on stack is identical for all targets:
765 0x000+i*0x10: VR0-VR31
772 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
773 Likewise, if there's no VX support, we just store the FRs into the slots
774 of low VR halves. The agent code is responsible for rearranging that
777 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
778 one trick used at the very beginning: since there's no way to allocate
779 stack space without destroying CC (lay instruction can do it, but it's
780 only supported on later CPUs), we take 4 different execution paths for
781 every possible value of CC, allocate stack space, save %r0, stuff the
782 CC value in %r0 (shifted to match its position in PSWM high word),
783 then branch to common path. */
785 static const unsigned char s390_ft_entry_gpr_esa
[] = {
786 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
787 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
788 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
790 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
791 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
792 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
793 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
795 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
796 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
797 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
798 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
800 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
801 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
802 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
803 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
805 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
806 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
807 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
809 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
810 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
811 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
812 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
813 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
814 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
815 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
816 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
817 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
818 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
819 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
820 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
821 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
822 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
823 /* Compute original value of %r15 and store it. We use ahi instead
824 of la to preserve the whole value, and not just the low 31 bits.
825 This is not particularly important here, but essential in the
826 zarch case where someone might be using the high word of %r15
827 as an extra register. */
828 0x18, 0x1f, /* lr %r1, %r15 */
829 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
830 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
833 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
834 target. Same as above, except this time we can use load/store multiple,
835 since the 64-bit regs are tightly packed. */
837 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
838 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
839 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
840 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
842 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
843 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
844 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
845 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
847 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
848 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
849 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
850 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
852 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
853 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
854 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
855 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
857 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
858 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
859 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
861 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
862 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
863 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
866 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
867 current PSWM (read by epsw) and CC from entry (in %r0). */
869 static const unsigned char s390_ft_entry_misc
[] = {
870 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
871 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
872 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
873 0x14, 0x21, /* nr %r2, %r1 */
874 0x16, 0x20, /* or %r2, %r0 */
875 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
876 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
877 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
880 /* Code sequence saving FRs, used if VX not supported. */
882 static const unsigned char s390_ft_entry_fr
[] = {
883 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
884 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
885 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
886 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
887 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
888 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
889 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
890 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
891 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
892 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
893 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
894 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
895 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
896 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
897 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
898 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
901 /* Code sequence saving VRs, used if VX not supported. */
903 static const unsigned char s390_ft_entry_vr
[] = {
904 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
905 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
908 /* Code sequence doing the collection call for 31-bit target. %r1 contains
909 the address of the literal pool. */
911 static const unsigned char s390_ft_main_31
[] = {
912 /* Load the literals into registers. */
913 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
914 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
915 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
916 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
917 /* Save original PSWA (tracepoint address | 0x80000000). */
918 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
919 /* Construct a collecting_t object at %r15+0x2e0. */
920 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
921 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
922 /* Move its address to %r0. */
923 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
926 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
927 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
928 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
929 /* Address of the register save block to %r3. */
930 0x18, 0x3f, /* lr %r3, %r15 */
931 /* Make a stack frame, so that we can call the collector. */
932 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
934 0x0d, 0xe4, /* basr %r14, %r4 */
935 /* And get rid of the stack frame again. */
936 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
937 /* Leave the lock. */
938 0x07, 0xf0, /* br %r0 */
939 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
940 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
943 /* Code sequence doing the collection call for 64-bit target. %r1 contains
944 the address of the literal pool. */
946 static const unsigned char s390_ft_main_64
[] = {
947 /* Load the literals into registers. */
948 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
949 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
950 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
951 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
952 /* Save original PSWA (tracepoint address). */
953 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
954 /* Construct a collecting_t object at %r15+0x2e0. */
955 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
956 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
957 /* Move its address to %r0. */
958 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
961 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
962 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
963 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
964 /* Address of the register save block to %r3. */
965 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
966 /* Make a stack frame, so that we can call the collector. */
967 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
969 0x0d, 0xe4, /* basr %r14, %r4 */
970 /* And get rid of the stack frame again. */
971 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
972 /* Leave the lock. */
973 0x07, 0xf0, /* br %r0 */
974 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
975 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
978 /* Code sequence restoring FRs, for targets with no VX support. */
980 static const unsigned char s390_ft_exit_fr
[] = {
981 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
982 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
983 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
984 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
985 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
986 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
987 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
988 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
989 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
990 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
991 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
992 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
993 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
994 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
995 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
996 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
999 /* Code sequence restoring VRs. */
1001 static const unsigned char s390_ft_exit_vr
[] = {
1002 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1003 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1006 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1007 modified by C code, so we use the alr instruction to restore it by
1008 manufacturing an operand that'll result in the original flags. */
1010 static const unsigned char s390_ft_exit_misc
[] = {
1011 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1012 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1013 /* Extract CC to high 2 bits of %r0. */
1014 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1015 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1016 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1017 will have carry iff CC bit 1 is set - resulting in the same flags
1019 0x1e, 0x00, /* alr %r0, %r0 */
1020 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1023 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1025 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1026 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1027 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1028 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1029 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1030 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1031 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1032 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1033 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1034 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1035 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1036 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1037 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1038 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1039 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1040 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1041 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1044 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1047 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1048 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1051 /* Writes instructions to target, updating the to pointer. */
1054 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1056 target_write_memory (*to
, buf
, len
);
1060 /* Relocates an instruction from oldloc to *to, updating to. */
1063 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1068 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1071 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1074 else if (buf
[0] < 0xc0)
1080 case 0x05: /* BALR */
1081 case 0x0c: /* BASSM */
1082 case 0x0d: /* BASR */
1083 case 0x45: /* BAL */
1084 case 0x4d: /* BAS */
1085 /* These save a return address and mess around with registers.
1086 We can't relocate them. */
1088 case 0x84: /* BRXH */
1089 case 0x85: /* BRXLE */
1094 /* BRC, BRAS, BRCT, BRCTG */
1095 if (op2
>= 4 && op2
<= 7)
1103 /* LARL, BRCL, BRASL */
1104 if (op2
== 0 || op2
== 4 || op2
== 5)
1112 /* PC-relative addressing instructions. */
1115 case 0xc5: /* BPRP */
1116 case 0xc7: /* BPP */
1117 /* Branch prediction - just skip it. */
1129 case 0x44: /* BRXHG */
1130 case 0x45: /* BRXLG */
1131 case 0x64: /* CGRJ */
1132 case 0x65: /* CLGRJ */
1133 case 0x76: /* CRJ */
1134 case 0x77: /* CLRJ */
1143 /* We'll have to relocate an instruction with a PC-relative field.
1144 First, compute the target. */
1145 int64_t loffset
= 0;
1149 int16_t soffset
= 0;
1150 memcpy (&soffset
, buf
+ 2, 2);
1155 int32_t soffset
= 0;
1156 memcpy (&soffset
, buf
+ 2, 4);
1159 target
= oldloc
+ loffset
* 2;
1161 target
&= 0x7fffffff;
1165 /* BRAS or BRASL was used. We cannot just relocate those, since
1166 they save the return address in a register. We can, however,
1167 replace them with a LARL+JG sequence. */
1169 /* Make the LARL. */
1173 loffset
= oldloc
+ ilen
- *to
;
1176 if (soffset
!= loffset
&& is_64
)
1178 memcpy (buf
+ 2, &soffset
, 4);
1179 append_insns (to
, 6, buf
);
1181 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1182 an address with the top bit 0, while BRAS/BRASL will write it
1183 with top bit 1. It should not matter much, since linux compilers
1184 use BR and not BSM to return from functions, but it could confuse
1185 some poor stack unwinder. */
1187 /* We'll now be writing a JG. */
1194 /* Compute the new offset and write it to the buffer. */
1195 loffset
= target
- *to
;
1200 int16_t soffset
= loffset
;
1201 if (soffset
!= loffset
)
1203 memcpy (buf
+ 2, &soffset
, 2);
1207 int32_t soffset
= loffset
;
1208 if (soffset
!= loffset
&& is_64
)
1210 memcpy (buf
+ 2, &soffset
, 4);
1213 append_insns (to
, ilen
, buf
);
1217 /* Implementation of linux_target_ops method
1218 "install_fast_tracepoint_jump_pad". */
1221 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1223 CORE_ADDR collector
,
1226 CORE_ADDR
*jump_entry
,
1227 CORE_ADDR
*trampoline
,
1228 ULONGEST
*trampoline_size
,
1229 unsigned char *jjump_pad_insn
,
1230 ULONGEST
*jjump_pad_insn_size
,
1231 CORE_ADDR
*adjusted_insn_addr
,
1232 CORE_ADDR
*adjusted_insn_addr_end
,
1238 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1239 CORE_ADDR buildaddr
= *jump_entry
;
1241 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1242 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1243 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1244 int has_vx
= have_hwcap_s390_vx
;
1246 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1248 CORE_ADDR literals
[4] = {
1255 /* First, store the GPRs. */
1257 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1258 s390_ft_entry_gpr_zarch
);
1260 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1261 s390_ft_entry_gpr_esa
);
1263 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1264 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1266 /* Third, FRs or VRs. */
1268 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1270 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1272 /* Now, the main part of code - store PSWA, take lock, call collector,
1273 leave lock. First, we'll need to fetch 4 literals. */
1275 unsigned char buf
[] = {
1276 0x07, 0x07, /* nopr %r7 */
1277 0x07, 0x07, /* nopr %r7 */
1278 0x07, 0x07, /* nopr %r7 */
1279 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1280 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1281 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1282 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1283 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1286 /* Find the proper start place in buf, so that literals will be
1288 int bufpos
= (buildaddr
+ 2) & 7;
1289 /* Stuff the literals into the buffer. */
1290 for (i
= 0; i
< 4; i
++) {
1291 uint64_t lit
= literals
[i
];
1292 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1294 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1295 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1297 unsigned char buf
[] = {
1298 0x07, 0x07, /* nopr %r7 */
1299 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1300 0, 0, 0, 0, /* tpaddr */
1301 0, 0, 0, 0, /* tpoint */
1302 0, 0, 0, 0, /* collector */
1303 0, 0, 0, 0, /* lockaddr */
1306 /* Find the proper start place in buf, so that literals will be
1308 int bufpos
= (buildaddr
+ 2) & 3;
1309 /* First literal will be saved as the PSWA, make sure it has the high bit
1311 literals
[0] |= 0x80000000;
1312 /* Stuff the literals into the buffer. */
1313 for (i
= 0; i
< 4; i
++) {
1314 uint32_t lit
= literals
[i
];
1315 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1317 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1318 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1321 /* Restore FRs or VRs. */
1323 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1325 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1327 /* Restore misc registers. */
1328 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1330 /* Restore the GPRs. */
1332 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1333 s390_ft_exit_gpr_zarch
);
1335 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1336 s390_ft_exit_gpr_esa
);
1338 /* Now, adjust the original instruction to execute in the jump
1340 *adjusted_insn_addr
= buildaddr
;
1341 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1343 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1346 *adjusted_insn_addr_end
= buildaddr
;
1348 /* Finally, write a jump back to the program. */
1350 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
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 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1363 /* The jump pad is now built. Wire in a jump to our jump pad. This
1364 is always done last (by our caller actually), so that we can
1365 install fast tracepoints with threads running. This relies on
1366 the agent's atomic write support. */
1367 loffset
= *jump_entry
- tpaddr
;
1370 if (is_64
&& offset
!= loffset
)
1373 "E.Jump back from jump pad too far from tracepoint "
1374 "(offset 0x%" PRIx64
" > int33).", loffset
);
1377 memcpy (jbuf
+ 2, &offset
, 4);
1378 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1379 *jjump_pad_insn_size
= sizeof jbuf
;
1381 /* Return the end address of our pad. */
1382 *jump_entry
= buildaddr
;
1387 /* Implementation of linux_target_ops method
1388 "get_min_fast_tracepoint_insn_len". */
1391 s390_get_min_fast_tracepoint_insn_len (void)
1393 /* We only support using 6-byte jumps to reach the tracepoint code.
1394 If the tracepoint buffer were allocated sufficiently close (64kiB)
1395 to the executable code, and the traced instruction itself was close
1396 enough to the beginning, we could use 4-byte jumps, but this doesn't
1397 seem to be worth the effort. */
1401 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1404 s390_get_ipa_tdesc_idx (void)
1406 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1407 const struct target_desc
*tdesc
= regcache
->tdesc
;
1410 if (tdesc
== tdesc_s390x_linux64
)
1411 return S390_TDESC_64
;
1412 if (tdesc
== tdesc_s390x_linux64v1
)
1413 return S390_TDESC_64V1
;
1414 if (tdesc
== tdesc_s390x_linux64v2
)
1415 return S390_TDESC_64V2
;
1416 if (tdesc
== tdesc_s390x_te_linux64
)
1417 return S390_TDESC_TE
;
1418 if (tdesc
== tdesc_s390x_vx_linux64
)
1419 return S390_TDESC_VX
;
1420 if (tdesc
== tdesc_s390x_tevx_linux64
)
1421 return S390_TDESC_TEVX
;
1422 if (tdesc
== tdesc_s390x_gs_linux64
)
1423 return S390_TDESC_GS
;
1426 if (tdesc
== tdesc_s390_linux32
)
1427 return S390_TDESC_32
;
1428 if (tdesc
== tdesc_s390_linux32v1
)
1429 return S390_TDESC_32V1
;
1430 if (tdesc
== tdesc_s390_linux32v2
)
1431 return S390_TDESC_32V2
;
1432 if (tdesc
== tdesc_s390_linux64
)
1433 return S390_TDESC_64
;
1434 if (tdesc
== tdesc_s390_linux64v1
)
1435 return S390_TDESC_64V1
;
1436 if (tdesc
== tdesc_s390_linux64v2
)
1437 return S390_TDESC_64V2
;
1438 if (tdesc
== tdesc_s390_te_linux64
)
1439 return S390_TDESC_TE
;
1440 if (tdesc
== tdesc_s390_vx_linux64
)
1441 return S390_TDESC_VX
;
1442 if (tdesc
== tdesc_s390_tevx_linux64
)
1443 return S390_TDESC_TEVX
;
1444 if (tdesc
== tdesc_s390_gs_linux64
)
1445 return S390_TDESC_GS
;
1450 /* Appends given buffer to current_insn_ptr in the target. */
1453 add_insns (const unsigned char *start
, int len
)
1455 CORE_ADDR buildaddr
= current_insn_ptr
;
1458 debug_printf ("Adding %d bytes of insn at %s\n",
1459 len
, paddress (buildaddr
));
1461 append_insns (&buildaddr
, len
, start
);
1462 current_insn_ptr
= buildaddr
;
1465 /* Register usage in emit:
1468 - %r2: top of stack (high word for 31-bit)
1469 - %r3: low word of top of stack (for 31-bit)
1471 - %r6, %r7, %r8: don't use
1474 - %r11: frame pointer
1475 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1476 - %r13: low word of saved top of stack (for 31-bit)
1477 - %r14: return address for calls
1478 - %r15: stack pointer
1482 /* The "emit_prologue" emit_ops method for s390. */
1485 s390_emit_prologue (void)
1487 static const unsigned char buf
[] = {
1488 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1489 0x18, 0x92, /* lr %r9, %r2 */
1490 0x18, 0xa3, /* lr %r10, %r3 */
1491 0x18, 0xbf, /* lr %r11, %r15 */
1493 add_insns (buf
, sizeof buf
);
1496 /* The "emit_epilogue" emit_ops method for s390. */
1499 s390_emit_epilogue (void)
1501 static const unsigned char buf
[] = {
1502 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1503 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1504 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1505 0x07, 0xfe, /* br %r14 */
1507 add_insns (buf
, sizeof buf
);
1510 /* The "emit_add" emit_ops method for s390. */
1513 s390_emit_add (void)
1515 static const unsigned char buf
[] = {
1516 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1517 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1518 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1520 add_insns (buf
, sizeof buf
);
1523 /* The "emit_sub" emit_ops method for s390. */
1526 s390_emit_sub (void)
1528 static const unsigned char buf
[] = {
1529 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1530 0x1f, 0x53, /* slr %r5, %r3 */
1531 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1532 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1533 0x18, 0x35, /* lr %r3, %r5 */
1534 0x18, 0x24, /* lr %r2, %r4 */
1536 add_insns (buf
, sizeof buf
);
1539 /* The "emit_mul" emit_ops method for s390. */
1542 s390_emit_mul (void)
1547 /* The "emit_lsh" emit_ops method for s390. */
1550 s390_emit_lsh (void)
1552 static const unsigned char buf
[] = {
1553 0x18, 0x43, /* lr %r4, %r3 */
1554 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1555 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1556 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1558 add_insns (buf
, sizeof buf
);
1561 /* The "emit_rsh_signed" emit_ops method for s390. */
1564 s390_emit_rsh_signed (void)
1566 static const unsigned char buf
[] = {
1567 0x18, 0x43, /* lr %r4, %r3 */
1568 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1569 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1570 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1572 add_insns (buf
, sizeof buf
);
1575 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1578 s390_emit_rsh_unsigned (void)
1580 static const unsigned char buf
[] = {
1581 0x18, 0x43, /* lr %r4, %r3 */
1582 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1583 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1584 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1586 add_insns (buf
, sizeof buf
);
1589 /* The "emit_ext" emit_ops method for s390. */
1592 s390_emit_ext (int arg
)
1594 unsigned char buf
[] = {
1595 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1596 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1598 add_insns (buf
, sizeof buf
);
1601 /* The "emit_log_not" emit_ops method for s390. */
1604 s390_emit_log_not (void)
1606 static const unsigned char buf
[] = {
1607 0x16, 0x23, /* or %r2, %r3 */
1608 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1609 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1610 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1611 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1614 add_insns (buf
, sizeof buf
);
1617 /* The "emit_bit_and" emit_ops method for s390. */
1620 s390_emit_bit_and (void)
1622 static const unsigned char buf
[] = {
1623 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1624 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1625 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1627 add_insns (buf
, sizeof buf
);
1630 /* The "emit_bit_or" emit_ops method for s390. */
1633 s390_emit_bit_or (void)
1635 static const unsigned char buf
[] = {
1636 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1637 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1638 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1640 add_insns (buf
, sizeof buf
);
1643 /* The "emit_bit_xor" emit_ops method for s390. */
1646 s390_emit_bit_xor (void)
1648 static const unsigned char buf
[] = {
1649 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1650 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1651 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1653 add_insns (buf
, sizeof buf
);
1656 /* The "emit_bit_not" emit_ops method for s390. */
1659 s390_emit_bit_not (void)
1661 static const unsigned char buf
[] = {
1662 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1663 0x17, 0x24, /* xr %r2, %r4 */
1664 0x17, 0x34, /* xr %r3, %r4 */
1666 add_insns (buf
, sizeof buf
);
1669 /* The "emit_equal" emit_ops method for s390. */
1672 s390_emit_equal (void)
1674 s390_emit_bit_xor ();
1675 s390_emit_log_not ();
1678 /* The "emit_less_signed" emit_ops method for s390. */
1681 s390_emit_less_signed (void)
1683 static const unsigned char buf
[] = {
1684 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1685 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1686 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1687 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1688 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1690 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1691 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1693 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1695 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1696 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1698 add_insns (buf
, sizeof buf
);
1701 /* The "emit_less_unsigned" emit_ops method for s390. */
1704 s390_emit_less_unsigned (void)
1706 static const unsigned char buf
[] = {
1707 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1708 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1709 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1710 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1711 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1713 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1714 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1716 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1718 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1719 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1721 add_insns (buf
, sizeof buf
);
1724 /* The "emit_ref" emit_ops method for s390. */
1727 s390_emit_ref (int size
)
1729 static const unsigned char buf1
[] = {
1730 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1731 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1733 static const unsigned char buf2
[] = {
1734 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1735 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1737 static const unsigned char buf4
[] = {
1738 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1739 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1741 static const unsigned char buf8
[] = {
1742 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1747 add_insns (buf1
, sizeof buf1
);
1750 add_insns (buf2
, sizeof buf2
);
1753 add_insns (buf4
, sizeof buf4
);
1756 add_insns (buf8
, sizeof buf8
);
1763 /* The "emit_if_goto" emit_ops method for s390. */
1766 s390_emit_if_goto (int *offset_p
, int *size_p
)
1768 static const unsigned char buf
[] = {
1769 0x16, 0x23, /* or %r2, %r3 */
1770 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1771 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1772 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1774 add_insns (buf
, sizeof buf
);
1781 /* The "emit_goto" emit_ops method for s390 and s390x. */
1784 s390_emit_goto (int *offset_p
, int *size_p
)
1786 static const unsigned char buf
[] = {
1787 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1789 add_insns (buf
, sizeof buf
);
1796 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1799 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1801 long diff
= ((long) (to
- (from
- 2))) / 2;
1803 unsigned char buf
[sizeof sdiff
];
1805 /* We're only doing 4-byte sizes at the moment. */
1806 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1812 memcpy (buf
, &sdiff
, sizeof sdiff
);
1813 target_write_memory (from
, buf
, sizeof sdiff
);
1816 /* Preparation for emitting a literal pool of given size. Loads the address
1817 of the pool into %r1, and jumps over it. Called should emit the pool data
1818 immediately afterwards. Used for both s390 and s390x. */
1821 s390_emit_litpool (int size
)
1823 static const unsigned char nop
[] = {
1826 unsigned char buf
[] = {
1828 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1833 /* buf needs to start at even halfword for litpool to be aligned */
1834 if (current_insn_ptr
& 2)
1835 add_insns (nop
, sizeof nop
);
1839 while ((current_insn_ptr
& 6) != 4)
1840 add_insns (nop
, sizeof nop
);
1842 add_insns (buf
, sizeof buf
);
1845 /* The "emit_const" emit_ops method for s390. */
1848 s390_emit_const (LONGEST num
)
1850 unsigned long long n
= num
;
1851 unsigned char buf_s
[] = {
1852 /* lhi %r3, <num> */
1854 (unsigned char) (num
>> 8), (unsigned char) num
,
1858 static const unsigned char buf_l
[] = {
1859 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1861 if (num
< 0x8000 && num
>= 0)
1863 add_insns (buf_s
, sizeof buf_s
);
1867 s390_emit_litpool (8);
1868 add_insns ((unsigned char *) &n
, sizeof n
);
1869 add_insns (buf_l
, sizeof buf_l
);
1873 /* The "emit_call" emit_ops method for s390. */
1876 s390_emit_call (CORE_ADDR fn
)
1878 unsigned int n
= fn
;
1879 static const unsigned char buf
[] = {
1880 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1881 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1882 0x0d, 0xe1, /* basr %r14, %r1 */
1883 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1885 s390_emit_litpool (4);
1886 add_insns ((unsigned char *) &n
, sizeof n
);
1887 add_insns (buf
, sizeof buf
);
1890 /* The "emit_reg" emit_ops method for s390. */
1893 s390_emit_reg (int reg
)
1895 unsigned char bufpre
[] = {
1898 /* lhi %r3, <reg> */
1899 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1901 add_insns (bufpre
, sizeof bufpre
);
1902 s390_emit_call (get_raw_reg_func_addr ());
1905 /* The "emit_pop" emit_ops method for s390. */
1908 s390_emit_pop (void)
1910 static const unsigned char buf
[] = {
1911 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1912 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1914 add_insns (buf
, sizeof buf
);
1917 /* The "emit_stack_flush" emit_ops method for s390. */
1920 s390_emit_stack_flush (void)
1922 static const unsigned char buf
[] = {
1923 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1924 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1926 add_insns (buf
, sizeof buf
);
1929 /* The "emit_zero_ext" emit_ops method for s390. */
1932 s390_emit_zero_ext (int arg
)
1934 unsigned char buf
[] = {
1935 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1936 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1938 add_insns (buf
, sizeof buf
);
1941 /* The "emit_swap" emit_ops method for s390. */
1944 s390_emit_swap (void)
1946 static const unsigned char buf
[] = {
1947 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1948 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1949 0x18, 0x24, /* lr %r2, %r4 */
1950 0x18, 0x35, /* lr %r3, %r5 */
1952 add_insns (buf
, sizeof buf
);
1955 /* The "emit_stack_adjust" emit_ops method for s390. */
1958 s390_emit_stack_adjust (int n
)
1960 unsigned char buf
[] = {
1963 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
1965 add_insns (buf
, sizeof buf
);
1968 /* Sets %r2 to a 32-bit constant. */
1971 s390_emit_set_r2 (int arg1
)
1973 unsigned char buf_s
[] = {
1974 /* lhi %r2, <arg1> */
1975 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
1977 static const unsigned char buf_l
[] = {
1978 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1980 if (arg1
< 0x8000 && arg1
>= -0x8000)
1982 add_insns (buf_s
, sizeof buf_s
);
1986 s390_emit_litpool (4);
1987 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
1988 add_insns (buf_l
, sizeof buf_l
);
1992 /* The "emit_int_call_1" emit_ops method for s390. */
1995 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
1997 /* FN's prototype is `LONGEST(*fn)(int)'. */
1998 s390_emit_set_r2 (arg1
);
1999 s390_emit_call (fn
);
2002 /* The "emit_void_call_2" emit_ops method for s390. */
2005 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2007 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2008 static const unsigned char buf
[] = {
2009 0x18, 0xc2, /* lr %r12, %r2 */
2010 0x18, 0xd3, /* lr %r13, %r3 */
2011 0x18, 0x43, /* lr %r4, %r3 */
2012 0x18, 0x32, /* lr %r3, %r2 */
2014 static const unsigned char buf2
[] = {
2015 0x18, 0x2c, /* lr %r2, %r12 */
2016 0x18, 0x3d, /* lr %r3, %r13 */
2018 add_insns (buf
, sizeof buf
);
2019 s390_emit_set_r2 (arg1
);
2020 s390_emit_call (fn
);
2021 add_insns (buf2
, sizeof buf2
);
2024 /* The "emit_eq_goto" emit_ops method for s390. */
2027 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2029 static const unsigned char buf
[] = {
2030 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2031 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2032 0x16, 0x23, /* or %r2, %r3 */
2033 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2034 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2035 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2037 add_insns (buf
, sizeof buf
);
2044 /* The "emit_ne_goto" emit_ops method for s390. */
2047 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2049 static const unsigned char buf
[] = {
2050 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2051 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2052 0x16, 0x23, /* or %r2, %r3 */
2053 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2054 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2055 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2057 add_insns (buf
, sizeof buf
);
2064 /* The "emit_lt_goto" emit_ops method for s390. */
2067 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2069 static const unsigned char buf
[] = {
2070 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2071 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2072 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2073 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2074 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2076 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2077 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2078 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2080 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2081 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2082 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2085 add_insns (buf
, sizeof buf
);
2092 /* The "emit_le_goto" emit_ops method for s390. */
2095 s390_emit_le_goto (int *offset_p
, int *size_p
)
2097 static const unsigned char buf
[] = {
2098 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2099 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2100 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2101 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2102 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2104 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2105 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2106 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2108 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2109 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2110 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2113 add_insns (buf
, sizeof buf
);
2120 /* The "emit_gt_goto" emit_ops method for s390. */
2123 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2125 static const unsigned char buf
[] = {
2126 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2127 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2128 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2129 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2130 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2132 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2133 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2134 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2136 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2137 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2138 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2141 add_insns (buf
, sizeof buf
);
2148 /* The "emit_ge_goto" emit_ops method for s390. */
2151 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2153 static const unsigned char buf
[] = {
2154 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2155 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2156 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2157 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2158 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2160 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2161 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2162 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2164 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2165 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2166 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2169 add_insns (buf
, sizeof buf
);
2176 /* The "emit_ops" structure for s390. Named _impl to avoid name
2177 collision with s390_emit_ops function. */
2179 static struct emit_ops s390_emit_ops_impl
=
2187 s390_emit_rsh_signed
,
2188 s390_emit_rsh_unsigned
,
2196 s390_emit_less_signed
,
2197 s390_emit_less_unsigned
,
2201 s390_write_goto_address
,
2206 s390_emit_stack_flush
,
2209 s390_emit_stack_adjust
,
2210 s390_emit_int_call_1
,
2211 s390_emit_void_call_2
,
2222 /* The "emit_prologue" emit_ops method for s390x. */
2225 s390x_emit_prologue (void)
2227 static const unsigned char buf
[] = {
2228 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2229 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2230 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2231 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2233 add_insns (buf
, sizeof buf
);
2236 /* The "emit_epilogue" emit_ops method for s390x. */
2239 s390x_emit_epilogue (void)
2241 static const unsigned char buf
[] = {
2242 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2243 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2244 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2245 0x07, 0xfe, /* br %r14 */
2247 add_insns (buf
, sizeof buf
);
2250 /* The "emit_add" emit_ops method for s390x. */
2253 s390x_emit_add (void)
2255 static const unsigned char buf
[] = {
2256 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2257 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2259 add_insns (buf
, sizeof buf
);
2262 /* The "emit_sub" emit_ops method for s390x. */
2265 s390x_emit_sub (void)
2267 static const unsigned char buf
[] = {
2268 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2269 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2270 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2271 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2273 add_insns (buf
, sizeof buf
);
2276 /* The "emit_mul" emit_ops method for s390x. */
2279 s390x_emit_mul (void)
2284 /* The "emit_lsh" emit_ops method for s390x. */
2287 s390x_emit_lsh (void)
2289 static const unsigned char buf
[] = {
2290 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2291 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2292 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2294 add_insns (buf
, sizeof buf
);
2297 /* The "emit_rsh_signed" emit_ops method for s390x. */
2300 s390x_emit_rsh_signed (void)
2302 static const unsigned char buf
[] = {
2303 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2304 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2305 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2307 add_insns (buf
, sizeof buf
);
2310 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2313 s390x_emit_rsh_unsigned (void)
2315 static const unsigned char buf
[] = {
2316 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2317 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2318 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2320 add_insns (buf
, sizeof buf
);
2323 /* The "emit_ext" emit_ops method for s390x. */
2326 s390x_emit_ext (int arg
)
2328 unsigned char buf
[] = {
2329 /* sllg %r2, %r2, <64-arg> */
2330 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2331 /* srag %r2, %r2, <64-arg> */
2332 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2334 add_insns (buf
, sizeof buf
);
2337 /* The "emit_log_not" emit_ops method for s390x. */
2340 s390x_emit_log_not (void)
2342 static const unsigned char buf
[] = {
2343 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2344 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2345 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2347 add_insns (buf
, sizeof buf
);
2350 /* The "emit_bit_and" emit_ops method for s390x. */
2353 s390x_emit_bit_and (void)
2355 static const unsigned char buf
[] = {
2356 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2357 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2359 add_insns (buf
, sizeof buf
);
2362 /* The "emit_bit_or" emit_ops method for s390x. */
2365 s390x_emit_bit_or (void)
2367 static const unsigned char buf
[] = {
2368 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2369 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2371 add_insns (buf
, sizeof buf
);
2374 /* The "emit_bit_xor" emit_ops method for s390x. */
2377 s390x_emit_bit_xor (void)
2379 static const unsigned char buf
[] = {
2380 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2381 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2383 add_insns (buf
, sizeof buf
);
2386 /* The "emit_bit_not" emit_ops method for s390x. */
2389 s390x_emit_bit_not (void)
2391 static const unsigned char buf
[] = {
2392 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2393 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2395 add_insns (buf
, sizeof buf
);
2398 /* The "emit_equal" emit_ops method for s390x. */
2401 s390x_emit_equal (void)
2403 s390x_emit_bit_xor ();
2404 s390x_emit_log_not ();
2407 /* The "emit_less_signed" emit_ops method for s390x. */
2410 s390x_emit_less_signed (void)
2412 static const unsigned char buf
[] = {
2413 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2414 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2415 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2416 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2418 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2420 add_insns (buf
, sizeof buf
);
2423 /* The "emit_less_unsigned" emit_ops method for s390x. */
2426 s390x_emit_less_unsigned (void)
2428 static const unsigned char buf
[] = {
2429 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2430 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2431 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2432 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2434 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2436 add_insns (buf
, sizeof buf
);
2439 /* The "emit_ref" emit_ops method for s390x. */
2442 s390x_emit_ref (int size
)
2444 static const unsigned char buf1
[] = {
2445 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2447 static const unsigned char buf2
[] = {
2448 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2450 static const unsigned char buf4
[] = {
2451 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2453 static const unsigned char buf8
[] = {
2454 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2459 add_insns (buf1
, sizeof buf1
);
2462 add_insns (buf2
, sizeof buf2
);
2465 add_insns (buf4
, sizeof buf4
);
2468 add_insns (buf8
, sizeof buf8
);
2475 /* The "emit_if_goto" emit_ops method for s390x. */
2478 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2480 static const unsigned char buf
[] = {
2481 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2482 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2483 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2484 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2486 add_insns (buf
, sizeof buf
);
2493 /* The "emit_const" emit_ops method for s390x. */
2496 s390x_emit_const (LONGEST num
)
2498 unsigned long long n
= num
;
2499 unsigned char buf_s
[] = {
2500 /* lghi %r2, <num> */
2501 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2503 static const unsigned char buf_l
[] = {
2504 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2506 if (num
< 0x8000 && num
>= -0x8000)
2508 add_insns (buf_s
, sizeof buf_s
);
2512 s390_emit_litpool (8);
2513 add_insns ((unsigned char *) &n
, sizeof n
);
2514 add_insns (buf_l
, sizeof buf_l
);
2518 /* The "emit_call" emit_ops method for s390x. */
2521 s390x_emit_call (CORE_ADDR fn
)
2523 unsigned long n
= fn
;
2524 static const unsigned char buf
[] = {
2525 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2526 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2527 0x0d, 0xe1, /* basr %r14, %r1 */
2528 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2530 s390_emit_litpool (8);
2531 add_insns ((unsigned char *) &n
, sizeof n
);
2532 add_insns (buf
, sizeof buf
);
2535 /* The "emit_reg" emit_ops method for s390x. */
2538 s390x_emit_reg (int reg
)
2540 unsigned char buf
[] = {
2542 0xb9, 0x04, 0x00, 0x29,
2543 /* lghi %r3, <reg> */
2544 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2546 add_insns (buf
, sizeof buf
);
2547 s390x_emit_call (get_raw_reg_func_addr ());
2550 /* The "emit_pop" emit_ops method for s390x. */
2553 s390x_emit_pop (void)
2555 static const unsigned char buf
[] = {
2556 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2557 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2559 add_insns (buf
, sizeof buf
);
2562 /* The "emit_stack_flush" emit_ops method for s390x. */
2565 s390x_emit_stack_flush (void)
2567 static const unsigned char buf
[] = {
2568 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2569 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2571 add_insns (buf
, sizeof buf
);
2574 /* The "emit_zero_ext" emit_ops method for s390x. */
2577 s390x_emit_zero_ext (int arg
)
2579 unsigned char buf
[] = {
2580 /* sllg %r2, %r2, <64-arg> */
2581 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2582 /* srlg %r2, %r2, <64-arg> */
2583 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2585 add_insns (buf
, sizeof buf
);
2588 /* The "emit_swap" emit_ops method for s390x. */
2591 s390x_emit_swap (void)
2593 static const unsigned char buf
[] = {
2594 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2595 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2596 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2598 add_insns (buf
, sizeof buf
);
2601 /* The "emit_stack_adjust" emit_ops method for s390x. */
2604 s390x_emit_stack_adjust (int n
)
2606 unsigned char buf
[] = {
2607 /* aghi %r15, 8*n */
2609 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2611 add_insns (buf
, sizeof buf
);
2614 /* The "emit_int_call_1" emit_ops method for s390x. */
2617 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2619 /* FN's prototype is `LONGEST(*fn)(int)'. */
2620 s390x_emit_const (arg1
);
2621 s390x_emit_call (fn
);
2624 /* The "emit_void_call_2" emit_ops method for s390x. */
2627 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2629 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2630 static const unsigned char buf
[] = {
2631 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2632 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2634 static const unsigned char buf2
[] = {
2635 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2637 add_insns (buf
, sizeof buf
);
2638 s390x_emit_const (arg1
);
2639 s390x_emit_call (fn
);
2640 add_insns (buf2
, sizeof buf2
);
2643 /* The "emit_eq_goto" emit_ops method for s390x. */
2646 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2648 static const unsigned char buf
[] = {
2649 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2650 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2651 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2652 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2654 add_insns (buf
, sizeof buf
);
2661 /* The "emit_ne_goto" emit_ops method for s390x. */
2664 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2666 static const unsigned char buf
[] = {
2667 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2668 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2669 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2670 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2672 add_insns (buf
, sizeof buf
);
2679 /* The "emit_lt_goto" emit_ops method for s390x. */
2682 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2684 static const unsigned char buf
[] = {
2685 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2686 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2687 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2688 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2690 add_insns (buf
, sizeof buf
);
2697 /* The "emit_le_goto" emit_ops method for s390x. */
2700 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2702 static const unsigned char buf
[] = {
2703 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2704 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2705 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2706 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2708 add_insns (buf
, sizeof buf
);
2715 /* The "emit_gt_goto" emit_ops method for s390x. */
2718 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2720 static const unsigned char buf
[] = {
2721 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2722 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2723 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2724 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2726 add_insns (buf
, sizeof buf
);
2733 /* The "emit_ge_goto" emit_ops method for s390x. */
2736 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2738 static const unsigned char buf
[] = {
2739 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2740 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2741 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2742 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2744 add_insns (buf
, sizeof buf
);
2751 /* The "emit_ops" structure for s390x. */
2753 static struct emit_ops s390x_emit_ops
=
2755 s390x_emit_prologue
,
2756 s390x_emit_epilogue
,
2761 s390x_emit_rsh_signed
,
2762 s390x_emit_rsh_unsigned
,
2770 s390x_emit_less_signed
,
2771 s390x_emit_less_unsigned
,
2775 s390_write_goto_address
,
2780 s390x_emit_stack_flush
,
2781 s390x_emit_zero_ext
,
2783 s390x_emit_stack_adjust
,
2784 s390x_emit_int_call_1
,
2785 s390x_emit_void_call_2
,
2795 /* The "emit_ops" linux_target_ops method. */
2797 static struct emit_ops
*
2798 s390_emit_ops (void)
2801 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2803 if (register_size (regcache
->tdesc
, 0) == 8)
2804 return &s390x_emit_ops
;
2807 return &s390_emit_ops_impl
;
2810 struct linux_target_ops the_low_target
= {
2811 s390_cannot_fetch_register
,
2812 s390_cannot_store_register
,
2813 NULL
, /* fetch_register */
2816 NULL
, /* breakpoint_kind_from_pc */
2817 s390_sw_breakpoint_from_kind
,
2819 s390_breakpoint_len
,
2821 s390_supports_z_point_type
,
2826 s390_collect_ptrace_register
,
2827 s390_supply_ptrace_register
,
2828 NULL
, /* siginfo_fixup */
2829 NULL
, /* new_process */
2830 NULL
, /* delete_process */
2831 NULL
, /* new_thread */
2832 NULL
, /* delete_thread */
2833 NULL
, /* new_fork */
2834 NULL
, /* prepare_to_resume */
2835 NULL
, /* process_qsupported */
2836 s390_supports_tracepoints
,
2837 s390_get_thread_area
,
2838 s390_install_fast_tracepoint_jump_pad
,
2840 s390_get_min_fast_tracepoint_insn_len
,
2841 NULL
, /* supports_range_stepping */
2842 NULL
, /* breakpoint_kind_from_current_state */
2843 s390_supports_hardware_single_step
,
2844 NULL
, /* get_syscall_trapinfo */
2845 s390_get_ipa_tdesc_idx
,
2848 /* The linux target ops object. */
2850 linux_process_target
*the_linux_target
= &the_s390_target
;
2853 initialize_low_arch (void)
2855 /* Initialize the Linux target descriptions. */
2857 init_registers_s390_linux32 ();
2858 init_registers_s390_linux32v1 ();
2859 init_registers_s390_linux32v2 ();
2860 init_registers_s390_linux64 ();
2861 init_registers_s390_linux64v1 ();
2862 init_registers_s390_linux64v2 ();
2863 init_registers_s390_te_linux64 ();
2864 init_registers_s390_vx_linux64 ();
2865 init_registers_s390_tevx_linux64 ();
2866 init_registers_s390_gs_linux64 ();
2868 init_registers_s390x_linux64 ();
2869 init_registers_s390x_linux64v1 ();
2870 init_registers_s390x_linux64v2 ();
2871 init_registers_s390x_te_linux64 ();
2872 init_registers_s390x_vx_linux64 ();
2873 init_registers_s390x_tevx_linux64 ();
2874 init_registers_s390x_gs_linux64 ();
2877 initialize_regsets_info (&s390_regsets_info
);
2878 initialize_regsets_info (&s390_regsets_info_3264
);