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 void low_arch_setup () override
;
65 /* The singleton target ops object. */
67 static s390_target the_s390_target
;
69 static int s390_regmap
[] = {
70 PT_PSWMASK
, PT_PSWADDR
,
72 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
73 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
74 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
75 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
77 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
78 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
79 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
80 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
85 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
86 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
87 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
88 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
90 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
91 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
92 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
93 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
99 #define s390_num_regs_3264 68
102 static int s390_regmap_3264
[] = {
103 PT_PSWMASK
, PT_PSWADDR
,
105 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
106 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
107 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
108 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
109 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
110 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
111 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
112 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
114 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
115 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
116 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
117 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
121 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
122 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
123 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
124 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
129 static int s390_regmap_3264
[] = {
130 PT_PSWMASK
, PT_PSWADDR
,
132 -1, PT_GPR0
, -1, PT_GPR1
,
133 -1, PT_GPR2
, -1, PT_GPR3
,
134 -1, PT_GPR4
, -1, PT_GPR5
,
135 -1, PT_GPR6
, -1, PT_GPR7
,
136 -1, PT_GPR8
, -1, PT_GPR9
,
137 -1, PT_GPR10
, -1, PT_GPR11
,
138 -1, PT_GPR12
, -1, PT_GPR13
,
139 -1, PT_GPR14
, -1, PT_GPR15
,
141 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
142 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
143 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
144 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
148 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
149 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
150 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
151 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
159 s390_cannot_fetch_register (int regno
)
165 s390_cannot_store_register (int regno
)
171 s390_collect_ptrace_register (struct regcache
*regcache
, int regno
, char *buf
)
173 int size
= register_size (regcache
->tdesc
, regno
);
174 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
175 struct usrregs_info
*usr
= regs_info
->usrregs
;
176 int regaddr
= usr
->regmap
[regno
];
178 if (size
< sizeof (long))
180 memset (buf
, 0, sizeof (long));
182 if ((regno
^ 1) < usr
->num_regs
183 && usr
->regmap
[regno
^ 1] == regaddr
)
185 collect_register (regcache
, regno
& ~1, buf
);
186 collect_register (regcache
, (regno
& ~1) + 1,
187 buf
+ sizeof (long) - size
);
189 else if (regaddr
== PT_PSWMASK
)
191 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
192 the basic addressing mode bit from the PSW address. */
193 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
194 collect_register (regcache
, regno
, buf
);
195 collect_register (regcache
, regno
^ 1, addr
);
197 buf
[size
] |= (addr
[0] & 0x80);
199 else if (regaddr
== PT_PSWADDR
)
201 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
202 mode bit (which gets copied to the PSW mask instead). */
203 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
204 buf
[sizeof (long) - size
] &= ~0x80;
206 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
207 || regaddr
== PT_ORIGGPR2
)
208 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
210 collect_register (regcache
, regno
, buf
);
212 else if (regaddr
!= -1)
213 collect_register (regcache
, regno
, buf
);
217 s390_supply_ptrace_register (struct regcache
*regcache
,
218 int regno
, const char *buf
)
220 int size
= register_size (regcache
->tdesc
, regno
);
221 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
222 struct usrregs_info
*usr
= regs_info
->usrregs
;
223 int regaddr
= usr
->regmap
[regno
];
225 if (size
< sizeof (long))
227 if ((regno
^ 1) < usr
->num_regs
228 && usr
->regmap
[regno
^ 1] == regaddr
)
230 supply_register (regcache
, regno
& ~1, buf
);
231 supply_register (regcache
, (regno
& ~1) + 1,
232 buf
+ sizeof (long) - size
);
234 else if (regaddr
== PT_PSWMASK
)
236 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
237 the basic addressing mode into the PSW address. */
238 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
239 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
240 memcpy (mask
, buf
, size
);
242 supply_register (regcache
, regno
, mask
);
244 collect_register (regcache
, regno
^ 1, addr
);
246 addr
[0] |= (buf
[size
] & 0x80);
247 supply_register (regcache
, regno
^ 1, addr
);
249 else if (regaddr
== PT_PSWADDR
)
251 /* Convert 8-byte PSW address to 4 bytes by truncating, but
252 keeping the addressing mode bit (which was set from the mask). */
253 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
255 collect_register (regcache
, regno
, addr
);
256 amode
= addr
[0] & 0x80;
257 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
260 supply_register (regcache
, regno
, addr
);
262 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
263 || regaddr
== PT_ORIGGPR2
)
264 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
266 supply_register (regcache
, regno
, buf
);
268 else if (regaddr
!= -1)
269 supply_register (regcache
, regno
, buf
);
272 /* Provide only a fill function for the general register set. ps_lgetregs
273 will use this for NPTL support. */
276 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
279 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
280 struct usrregs_info
*usr
= regs_info
->usrregs
;
282 for (i
= 0; i
< usr
->num_regs
; i
++)
284 if (usr
->regmap
[i
] < PT_PSWMASK
285 || usr
->regmap
[i
] > PT_ACR15
)
288 s390_collect_ptrace_register (regcache
, i
,
289 (char *) buf
+ usr
->regmap
[i
]);
293 /* Fill and store functions for extended register sets. */
297 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
299 int r0h
= find_regno (regcache
->tdesc
, "r0h");
302 for (i
= 0; i
< 16; i
++)
303 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
307 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
309 int r0h
= find_regno (regcache
->tdesc
, "r0h");
312 for (i
= 0; i
< 16; i
++)
313 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
318 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
322 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
323 supply_register_by_name (regcache
, "last_break", p
);
327 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
329 collect_register_by_name (regcache
, "system_call", buf
);
333 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
335 supply_register_by_name (regcache
, "system_call", buf
);
339 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
341 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
342 int tr0
= find_regno (regcache
->tdesc
, "tr0");
345 for (i
= 0; i
< 4; i
++)
346 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
348 for (i
= 0; i
< 16; i
++)
349 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
353 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
355 int v0
= find_regno (regcache
->tdesc
, "v0l");
358 for (i
= 0; i
< 16; i
++)
359 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
363 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
365 int v0
= find_regno (regcache
->tdesc
, "v0l");
368 for (i
= 0; i
< 16; i
++)
369 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
373 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
375 int v16
= find_regno (regcache
->tdesc
, "v16");
378 for (i
= 0; i
< 16; i
++)
379 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
383 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
385 int v16
= find_regno (regcache
->tdesc
, "v16");
388 for (i
= 0; i
< 16; i
++)
389 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
393 s390_store_gs (struct regcache
*regcache
, const void *buf
)
395 int gsd
= find_regno (regcache
->tdesc
, "gsd");
398 for (i
= 0; i
< 3; i
++)
399 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
403 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
405 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
408 for (i
= 0; i
< 3; i
++)
409 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
412 static struct regset_info s390_regsets
[] = {
413 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
415 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
416 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
418 /* Last break address is read-only; no fill function. */
419 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
420 NULL
, s390_store_last_break
},
421 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
422 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
423 /* TDB is read-only. */
424 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
425 NULL
, s390_store_tdb
},
426 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
427 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
428 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
429 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
430 /* Guarded storage registers are read-only. */
431 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
432 NULL
, s390_store_gs
},
433 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
434 NULL
, s390_store_gsbc
},
439 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
440 #define s390_breakpoint_len 2
442 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
444 static const gdb_byte
*
445 s390_sw_breakpoint_from_kind (int kind
, int *size
)
447 *size
= s390_breakpoint_len
;
448 return s390_breakpoint
;
452 s390_get_pc (struct regcache
*regcache
)
454 if (register_size (regcache
->tdesc
, 0) == 4)
457 collect_register_by_name (regcache
, "pswa", &pswa
);
458 return pswa
& 0x7fffffff;
463 collect_register_by_name (regcache
, "pswa", &pc
);
469 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
471 if (register_size (regcache
->tdesc
, 0) == 4)
474 collect_register_by_name (regcache
, "pswa", &pswa
);
475 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
476 supply_register_by_name (regcache
, "pswa", &pswa
);
480 unsigned long pc
= newpc
;
481 supply_register_by_name (regcache
, "pswa", &pc
);
485 /* Determine the word size for the given PID, in bytes. */
489 s390_get_wordsize (int pid
)
492 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
493 (PTRACE_TYPE_ARG3
) 0,
494 (PTRACE_TYPE_ARG4
) 0);
497 warning (_("Couldn't determine word size, assuming 64-bit."));
500 /* Derive word size from extended addressing mode (PSW bit 31). */
501 return pswm
& (1L << 32) ? 8 : 4;
504 #define s390_get_wordsize(pid) 4
508 s390_check_regset (int pid
, int regset
, int regsize
)
510 void *buf
= alloca (regsize
);
514 iov
.iov_len
= regsize
;
516 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
522 /* For a 31-bit inferior, whether the kernel supports using the full
524 static int have_hwcap_s390_high_gprs
= 0;
525 static int have_hwcap_s390_vx
= 0;
528 s390_target::low_arch_setup ()
530 const struct target_desc
*tdesc
;
531 struct regset_info
*regset
;
533 /* Determine word size and HWCAP. */
534 int pid
= pid_of (current_thread
);
535 int wordsize
= s390_get_wordsize (pid
);
536 unsigned long hwcap
= linux_get_hwcap (wordsize
);
538 /* Check whether the kernel supports extra register sets. */
539 int have_regset_last_break
540 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
541 int have_regset_system_call
542 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
544 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
545 && (hwcap
& HWCAP_S390_TE
) != 0);
547 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
548 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
549 && (hwcap
& HWCAP_S390_VX
) != 0);
551 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
552 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
553 && (hwcap
& HWCAP_S390_GS
) != 0);
560 tdesc
= tdesc_s390x_gs_linux64
;
561 else if (have_regset_vxrs
)
562 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
563 tdesc_s390x_vx_linux64
);
564 else if (have_regset_tdb
)
565 tdesc
= tdesc_s390x_te_linux64
;
566 else if (have_regset_system_call
)
567 tdesc
= tdesc_s390x_linux64v2
;
568 else if (have_regset_last_break
)
569 tdesc
= tdesc_s390x_linux64v1
;
571 tdesc
= tdesc_s390x_linux64
;
574 /* For a 31-bit inferior, check whether the kernel supports
575 using the full 64-bit GPRs. */
578 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
580 have_hwcap_s390_high_gprs
= 1;
582 tdesc
= tdesc_s390_gs_linux64
;
583 else if (have_regset_vxrs
)
584 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
585 tdesc_s390_vx_linux64
);
586 else if (have_regset_tdb
)
587 tdesc
= tdesc_s390_te_linux64
;
588 else if (have_regset_system_call
)
589 tdesc
= tdesc_s390_linux64v2
;
590 else if (have_regset_last_break
)
591 tdesc
= tdesc_s390_linux64v1
;
593 tdesc
= tdesc_s390_linux64
;
597 /* Assume 31-bit inferior process. */
598 if (have_regset_system_call
)
599 tdesc
= tdesc_s390_linux32v2
;
600 else if (have_regset_last_break
)
601 tdesc
= tdesc_s390_linux32v1
;
603 tdesc
= tdesc_s390_linux32
;
606 have_hwcap_s390_vx
= have_regset_vxrs
;
609 /* Update target_regsets according to available register sets. */
610 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
611 if (regset
->get_request
== PTRACE_GETREGSET
)
612 switch (regset
->nt_type
)
615 case NT_S390_HIGH_GPRS
:
616 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
619 case NT_S390_LAST_BREAK
:
620 regset
->size
= have_regset_last_break
? 8 : 0;
622 case NT_S390_SYSTEM_CALL
:
623 regset
->size
= have_regset_system_call
? 4 : 0;
626 regset
->size
= have_regset_tdb
? 256 : 0;
628 case NT_S390_VXRS_LOW
:
629 regset
->size
= have_regset_vxrs
? 128 : 0;
631 case NT_S390_VXRS_HIGH
:
632 regset
->size
= have_regset_vxrs
? 256 : 0;
636 regset
->size
= have_regset_gs
? 32 : 0;
641 current_process ()->tdesc
= tdesc
;
646 s390_breakpoint_at (CORE_ADDR pc
)
648 unsigned char c
[s390_breakpoint_len
];
649 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
650 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
653 /* Breakpoint/Watchpoint support. */
655 /* The "supports_z_point_type" linux_target_ops method. */
658 s390_supports_z_point_type (char z_type
)
669 /* Support for hardware single step. */
672 s390_supports_hardware_single_step (void)
677 static struct usrregs_info s390_usrregs_info
=
683 static struct regsets_info s390_regsets_info
=
685 s390_regsets
, /* regsets */
687 NULL
, /* disabled_regsets */
690 static struct regs_info regs_info
=
692 NULL
, /* regset_bitmap */
697 static struct usrregs_info s390_usrregs_info_3264
=
703 static struct regsets_info s390_regsets_info_3264
=
705 s390_regsets
, /* regsets */
707 NULL
, /* disabled_regsets */
710 static struct regs_info regs_info_3264
=
712 NULL
, /* regset_bitmap */
713 &s390_usrregs_info_3264
,
714 &s390_regsets_info_3264
717 static const struct regs_info
*
718 s390_regs_info (void)
720 if (have_hwcap_s390_high_gprs
)
723 const struct target_desc
*tdesc
= current_process ()->tdesc
;
725 if (register_size (tdesc
, 0) == 4)
726 return ®s_info_3264
;
728 return ®s_info_3264
;
734 /* The "supports_tracepoints" linux_target_ops method. */
737 s390_supports_tracepoints (void)
742 /* Implementation of linux_target_ops method "get_thread_area". */
745 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
747 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
749 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
751 if (register_size (regcache
->tdesc
, 0) == 4)
752 res
&= 0xffffffffull
;
759 /* Fast tracepoint support.
761 The register save area on stack is identical for all targets:
763 0x000+i*0x10: VR0-VR31
770 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
771 Likewise, if there's no VX support, we just store the FRs into the slots
772 of low VR halves. The agent code is responsible for rearranging that
775 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
776 one trick used at the very beginning: since there's no way to allocate
777 stack space without destroying CC (lay instruction can do it, but it's
778 only supported on later CPUs), we take 4 different execution paths for
779 every possible value of CC, allocate stack space, save %r0, stuff the
780 CC value in %r0 (shifted to match its position in PSWM high word),
781 then branch to common path. */
783 static const unsigned char s390_ft_entry_gpr_esa
[] = {
784 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
785 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
786 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
788 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
789 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
790 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
791 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
793 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
794 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
795 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
796 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
798 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
799 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
800 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
801 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
803 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
804 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
805 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
807 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
808 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
809 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
810 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
811 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
812 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
813 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
814 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
815 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
816 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
817 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
818 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
819 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
820 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
821 /* Compute original value of %r15 and store it. We use ahi instead
822 of la to preserve the whole value, and not just the low 31 bits.
823 This is not particularly important here, but essential in the
824 zarch case where someone might be using the high word of %r15
825 as an extra register. */
826 0x18, 0x1f, /* lr %r1, %r15 */
827 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
828 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
831 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
832 target. Same as above, except this time we can use load/store multiple,
833 since the 64-bit regs are tightly packed. */
835 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
836 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
837 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
838 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
840 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
841 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
842 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
843 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
845 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
846 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
847 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
848 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
850 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
851 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
852 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
853 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
855 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
856 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
857 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
859 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
860 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
861 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
864 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
865 current PSWM (read by epsw) and CC from entry (in %r0). */
867 static const unsigned char s390_ft_entry_misc
[] = {
868 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
869 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
870 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
871 0x14, 0x21, /* nr %r2, %r1 */
872 0x16, 0x20, /* or %r2, %r0 */
873 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
874 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
875 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
878 /* Code sequence saving FRs, used if VX not supported. */
880 static const unsigned char s390_ft_entry_fr
[] = {
881 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
882 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
883 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
884 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
885 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
886 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
887 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
888 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
889 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
890 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
891 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
892 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
893 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
894 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
895 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
896 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
899 /* Code sequence saving VRs, used if VX not supported. */
901 static const unsigned char s390_ft_entry_vr
[] = {
902 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
903 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
906 /* Code sequence doing the collection call for 31-bit target. %r1 contains
907 the address of the literal pool. */
909 static const unsigned char s390_ft_main_31
[] = {
910 /* Load the literals into registers. */
911 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
912 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
913 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
914 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
915 /* Save original PSWA (tracepoint address | 0x80000000). */
916 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
917 /* Construct a collecting_t object at %r15+0x2e0. */
918 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
919 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
920 /* Move its address to %r0. */
921 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
924 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
925 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
926 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
927 /* Address of the register save block to %r3. */
928 0x18, 0x3f, /* lr %r3, %r15 */
929 /* Make a stack frame, so that we can call the collector. */
930 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
932 0x0d, 0xe4, /* basr %r14, %r4 */
933 /* And get rid of the stack frame again. */
934 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
935 /* Leave the lock. */
936 0x07, 0xf0, /* br %r0 */
937 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
938 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
941 /* Code sequence doing the collection call for 64-bit target. %r1 contains
942 the address of the literal pool. */
944 static const unsigned char s390_ft_main_64
[] = {
945 /* Load the literals into registers. */
946 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
947 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
948 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
949 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
950 /* Save original PSWA (tracepoint address). */
951 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
952 /* Construct a collecting_t object at %r15+0x2e0. */
953 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
954 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
955 /* Move its address to %r0. */
956 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
959 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
960 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
961 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
962 /* Address of the register save block to %r3. */
963 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
964 /* Make a stack frame, so that we can call the collector. */
965 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
967 0x0d, 0xe4, /* basr %r14, %r4 */
968 /* And get rid of the stack frame again. */
969 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
970 /* Leave the lock. */
971 0x07, 0xf0, /* br %r0 */
972 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
973 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
976 /* Code sequence restoring FRs, for targets with no VX support. */
978 static const unsigned char s390_ft_exit_fr
[] = {
979 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
980 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
981 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
982 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
983 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
984 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
985 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
986 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
987 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
988 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
989 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
990 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
991 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
992 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
993 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
994 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
997 /* Code sequence restoring VRs. */
999 static const unsigned char s390_ft_exit_vr
[] = {
1000 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1001 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1004 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1005 modified by C code, so we use the alr instruction to restore it by
1006 manufacturing an operand that'll result in the original flags. */
1008 static const unsigned char s390_ft_exit_misc
[] = {
1009 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1010 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1011 /* Extract CC to high 2 bits of %r0. */
1012 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1013 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1014 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1015 will have carry iff CC bit 1 is set - resulting in the same flags
1017 0x1e, 0x00, /* alr %r0, %r0 */
1018 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1021 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1023 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1024 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1025 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1026 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1027 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1028 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1029 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1030 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1031 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1032 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1033 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1034 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1035 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1036 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1037 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1038 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1039 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1042 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1045 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1046 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1049 /* Writes instructions to target, updating the to pointer. */
1052 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1054 target_write_memory (*to
, buf
, len
);
1058 /* Relocates an instruction from oldloc to *to, updating to. */
1061 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1066 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1069 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1072 else if (buf
[0] < 0xc0)
1078 case 0x05: /* BALR */
1079 case 0x0c: /* BASSM */
1080 case 0x0d: /* BASR */
1081 case 0x45: /* BAL */
1082 case 0x4d: /* BAS */
1083 /* These save a return address and mess around with registers.
1084 We can't relocate them. */
1086 case 0x84: /* BRXH */
1087 case 0x85: /* BRXLE */
1092 /* BRC, BRAS, BRCT, BRCTG */
1093 if (op2
>= 4 && op2
<= 7)
1101 /* LARL, BRCL, BRASL */
1102 if (op2
== 0 || op2
== 4 || op2
== 5)
1110 /* PC-relative addressing instructions. */
1113 case 0xc5: /* BPRP */
1114 case 0xc7: /* BPP */
1115 /* Branch prediction - just skip it. */
1127 case 0x44: /* BRXHG */
1128 case 0x45: /* BRXLG */
1129 case 0x64: /* CGRJ */
1130 case 0x65: /* CLGRJ */
1131 case 0x76: /* CRJ */
1132 case 0x77: /* CLRJ */
1141 /* We'll have to relocate an instruction with a PC-relative field.
1142 First, compute the target. */
1143 int64_t loffset
= 0;
1147 int16_t soffset
= 0;
1148 memcpy (&soffset
, buf
+ 2, 2);
1153 int32_t soffset
= 0;
1154 memcpy (&soffset
, buf
+ 2, 4);
1157 target
= oldloc
+ loffset
* 2;
1159 target
&= 0x7fffffff;
1163 /* BRAS or BRASL was used. We cannot just relocate those, since
1164 they save the return address in a register. We can, however,
1165 replace them with a LARL+JG sequence. */
1167 /* Make the LARL. */
1171 loffset
= oldloc
+ ilen
- *to
;
1174 if (soffset
!= loffset
&& is_64
)
1176 memcpy (buf
+ 2, &soffset
, 4);
1177 append_insns (to
, 6, buf
);
1179 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1180 an address with the top bit 0, while BRAS/BRASL will write it
1181 with top bit 1. It should not matter much, since linux compilers
1182 use BR and not BSM to return from functions, but it could confuse
1183 some poor stack unwinder. */
1185 /* We'll now be writing a JG. */
1192 /* Compute the new offset and write it to the buffer. */
1193 loffset
= target
- *to
;
1198 int16_t soffset
= loffset
;
1199 if (soffset
!= loffset
)
1201 memcpy (buf
+ 2, &soffset
, 2);
1205 int32_t soffset
= loffset
;
1206 if (soffset
!= loffset
&& is_64
)
1208 memcpy (buf
+ 2, &soffset
, 4);
1211 append_insns (to
, ilen
, buf
);
1215 /* Implementation of linux_target_ops method
1216 "install_fast_tracepoint_jump_pad". */
1219 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1221 CORE_ADDR collector
,
1224 CORE_ADDR
*jump_entry
,
1225 CORE_ADDR
*trampoline
,
1226 ULONGEST
*trampoline_size
,
1227 unsigned char *jjump_pad_insn
,
1228 ULONGEST
*jjump_pad_insn_size
,
1229 CORE_ADDR
*adjusted_insn_addr
,
1230 CORE_ADDR
*adjusted_insn_addr_end
,
1236 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1237 CORE_ADDR buildaddr
= *jump_entry
;
1239 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1240 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1241 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1242 int has_vx
= have_hwcap_s390_vx
;
1244 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1246 CORE_ADDR literals
[4] = {
1253 /* First, store the GPRs. */
1255 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1256 s390_ft_entry_gpr_zarch
);
1258 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1259 s390_ft_entry_gpr_esa
);
1261 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1262 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1264 /* Third, FRs or VRs. */
1266 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1268 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1270 /* Now, the main part of code - store PSWA, take lock, call collector,
1271 leave lock. First, we'll need to fetch 4 literals. */
1273 unsigned char buf
[] = {
1274 0x07, 0x07, /* nopr %r7 */
1275 0x07, 0x07, /* nopr %r7 */
1276 0x07, 0x07, /* nopr %r7 */
1277 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1278 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1279 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1280 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1281 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1284 /* Find the proper start place in buf, so that literals will be
1286 int bufpos
= (buildaddr
+ 2) & 7;
1287 /* Stuff the literals into the buffer. */
1288 for (i
= 0; i
< 4; i
++) {
1289 uint64_t lit
= literals
[i
];
1290 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1292 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1293 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1295 unsigned char buf
[] = {
1296 0x07, 0x07, /* nopr %r7 */
1297 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1298 0, 0, 0, 0, /* tpaddr */
1299 0, 0, 0, 0, /* tpoint */
1300 0, 0, 0, 0, /* collector */
1301 0, 0, 0, 0, /* lockaddr */
1304 /* Find the proper start place in buf, so that literals will be
1306 int bufpos
= (buildaddr
+ 2) & 3;
1307 /* First literal will be saved as the PSWA, make sure it has the high bit
1309 literals
[0] |= 0x80000000;
1310 /* Stuff the literals into the buffer. */
1311 for (i
= 0; i
< 4; i
++) {
1312 uint32_t lit
= literals
[i
];
1313 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1315 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1316 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1319 /* Restore FRs or VRs. */
1321 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1323 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1325 /* Restore misc registers. */
1326 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1328 /* Restore the GPRs. */
1330 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1331 s390_ft_exit_gpr_zarch
);
1333 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1334 s390_ft_exit_gpr_esa
);
1336 /* Now, adjust the original instruction to execute in the jump
1338 *adjusted_insn_addr
= buildaddr
;
1339 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1341 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1344 *adjusted_insn_addr_end
= buildaddr
;
1346 /* Finally, write a jump back to the program. */
1348 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1351 if (is_64
&& offset
!= loffset
)
1354 "E.Jump back from jump pad too far from tracepoint "
1355 "(offset 0x%" PRIx64
" > int33).", loffset
);
1358 memcpy (jbuf
+ 2, &offset
, 4);
1359 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1361 /* The jump pad is now built. Wire in a jump to our jump pad. This
1362 is always done last (by our caller actually), so that we can
1363 install fast tracepoints with threads running. This relies on
1364 the agent's atomic write support. */
1365 loffset
= *jump_entry
- tpaddr
;
1368 if (is_64
&& offset
!= loffset
)
1371 "E.Jump back from jump pad too far from tracepoint "
1372 "(offset 0x%" PRIx64
" > int33).", loffset
);
1375 memcpy (jbuf
+ 2, &offset
, 4);
1376 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1377 *jjump_pad_insn_size
= sizeof jbuf
;
1379 /* Return the end address of our pad. */
1380 *jump_entry
= buildaddr
;
1385 /* Implementation of linux_target_ops method
1386 "get_min_fast_tracepoint_insn_len". */
1389 s390_get_min_fast_tracepoint_insn_len (void)
1391 /* We only support using 6-byte jumps to reach the tracepoint code.
1392 If the tracepoint buffer were allocated sufficiently close (64kiB)
1393 to the executable code, and the traced instruction itself was close
1394 enough to the beginning, we could use 4-byte jumps, but this doesn't
1395 seem to be worth the effort. */
1399 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1402 s390_get_ipa_tdesc_idx (void)
1404 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1405 const struct target_desc
*tdesc
= regcache
->tdesc
;
1408 if (tdesc
== tdesc_s390x_linux64
)
1409 return S390_TDESC_64
;
1410 if (tdesc
== tdesc_s390x_linux64v1
)
1411 return S390_TDESC_64V1
;
1412 if (tdesc
== tdesc_s390x_linux64v2
)
1413 return S390_TDESC_64V2
;
1414 if (tdesc
== tdesc_s390x_te_linux64
)
1415 return S390_TDESC_TE
;
1416 if (tdesc
== tdesc_s390x_vx_linux64
)
1417 return S390_TDESC_VX
;
1418 if (tdesc
== tdesc_s390x_tevx_linux64
)
1419 return S390_TDESC_TEVX
;
1420 if (tdesc
== tdesc_s390x_gs_linux64
)
1421 return S390_TDESC_GS
;
1424 if (tdesc
== tdesc_s390_linux32
)
1425 return S390_TDESC_32
;
1426 if (tdesc
== tdesc_s390_linux32v1
)
1427 return S390_TDESC_32V1
;
1428 if (tdesc
== tdesc_s390_linux32v2
)
1429 return S390_TDESC_32V2
;
1430 if (tdesc
== tdesc_s390_linux64
)
1431 return S390_TDESC_64
;
1432 if (tdesc
== tdesc_s390_linux64v1
)
1433 return S390_TDESC_64V1
;
1434 if (tdesc
== tdesc_s390_linux64v2
)
1435 return S390_TDESC_64V2
;
1436 if (tdesc
== tdesc_s390_te_linux64
)
1437 return S390_TDESC_TE
;
1438 if (tdesc
== tdesc_s390_vx_linux64
)
1439 return S390_TDESC_VX
;
1440 if (tdesc
== tdesc_s390_tevx_linux64
)
1441 return S390_TDESC_TEVX
;
1442 if (tdesc
== tdesc_s390_gs_linux64
)
1443 return S390_TDESC_GS
;
1448 /* Appends given buffer to current_insn_ptr in the target. */
1451 add_insns (const unsigned char *start
, int len
)
1453 CORE_ADDR buildaddr
= current_insn_ptr
;
1456 debug_printf ("Adding %d bytes of insn at %s\n",
1457 len
, paddress (buildaddr
));
1459 append_insns (&buildaddr
, len
, start
);
1460 current_insn_ptr
= buildaddr
;
1463 /* Register usage in emit:
1466 - %r2: top of stack (high word for 31-bit)
1467 - %r3: low word of top of stack (for 31-bit)
1469 - %r6, %r7, %r8: don't use
1472 - %r11: frame pointer
1473 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1474 - %r13: low word of saved top of stack (for 31-bit)
1475 - %r14: return address for calls
1476 - %r15: stack pointer
1480 /* The "emit_prologue" emit_ops method for s390. */
1483 s390_emit_prologue (void)
1485 static const unsigned char buf
[] = {
1486 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1487 0x18, 0x92, /* lr %r9, %r2 */
1488 0x18, 0xa3, /* lr %r10, %r3 */
1489 0x18, 0xbf, /* lr %r11, %r15 */
1491 add_insns (buf
, sizeof buf
);
1494 /* The "emit_epilogue" emit_ops method for s390. */
1497 s390_emit_epilogue (void)
1499 static const unsigned char buf
[] = {
1500 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1501 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1502 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1503 0x07, 0xfe, /* br %r14 */
1505 add_insns (buf
, sizeof buf
);
1508 /* The "emit_add" emit_ops method for s390. */
1511 s390_emit_add (void)
1513 static const unsigned char buf
[] = {
1514 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1515 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1516 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1518 add_insns (buf
, sizeof buf
);
1521 /* The "emit_sub" emit_ops method for s390. */
1524 s390_emit_sub (void)
1526 static const unsigned char buf
[] = {
1527 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1528 0x1f, 0x53, /* slr %r5, %r3 */
1529 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1530 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1531 0x18, 0x35, /* lr %r3, %r5 */
1532 0x18, 0x24, /* lr %r2, %r4 */
1534 add_insns (buf
, sizeof buf
);
1537 /* The "emit_mul" emit_ops method for s390. */
1540 s390_emit_mul (void)
1545 /* The "emit_lsh" emit_ops method for s390. */
1548 s390_emit_lsh (void)
1550 static const unsigned char buf
[] = {
1551 0x18, 0x43, /* lr %r4, %r3 */
1552 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1553 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1554 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1556 add_insns (buf
, sizeof buf
);
1559 /* The "emit_rsh_signed" emit_ops method for s390. */
1562 s390_emit_rsh_signed (void)
1564 static const unsigned char buf
[] = {
1565 0x18, 0x43, /* lr %r4, %r3 */
1566 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1567 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1568 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1570 add_insns (buf
, sizeof buf
);
1573 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1576 s390_emit_rsh_unsigned (void)
1578 static const unsigned char buf
[] = {
1579 0x18, 0x43, /* lr %r4, %r3 */
1580 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1581 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1582 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1584 add_insns (buf
, sizeof buf
);
1587 /* The "emit_ext" emit_ops method for s390. */
1590 s390_emit_ext (int arg
)
1592 unsigned char buf
[] = {
1593 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1594 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1596 add_insns (buf
, sizeof buf
);
1599 /* The "emit_log_not" emit_ops method for s390. */
1602 s390_emit_log_not (void)
1604 static const unsigned char buf
[] = {
1605 0x16, 0x23, /* or %r2, %r3 */
1606 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1607 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1608 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1609 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1612 add_insns (buf
, sizeof buf
);
1615 /* The "emit_bit_and" emit_ops method for s390. */
1618 s390_emit_bit_and (void)
1620 static const unsigned char buf
[] = {
1621 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1622 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1623 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1625 add_insns (buf
, sizeof buf
);
1628 /* The "emit_bit_or" emit_ops method for s390. */
1631 s390_emit_bit_or (void)
1633 static const unsigned char buf
[] = {
1634 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1635 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1636 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1638 add_insns (buf
, sizeof buf
);
1641 /* The "emit_bit_xor" emit_ops method for s390. */
1644 s390_emit_bit_xor (void)
1646 static const unsigned char buf
[] = {
1647 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1648 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1649 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1651 add_insns (buf
, sizeof buf
);
1654 /* The "emit_bit_not" emit_ops method for s390. */
1657 s390_emit_bit_not (void)
1659 static const unsigned char buf
[] = {
1660 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1661 0x17, 0x24, /* xr %r2, %r4 */
1662 0x17, 0x34, /* xr %r3, %r4 */
1664 add_insns (buf
, sizeof buf
);
1667 /* The "emit_equal" emit_ops method for s390. */
1670 s390_emit_equal (void)
1672 s390_emit_bit_xor ();
1673 s390_emit_log_not ();
1676 /* The "emit_less_signed" emit_ops method for s390. */
1679 s390_emit_less_signed (void)
1681 static const unsigned char buf
[] = {
1682 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1683 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1684 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1685 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1686 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1688 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1689 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1691 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1693 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1694 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1696 add_insns (buf
, sizeof buf
);
1699 /* The "emit_less_unsigned" emit_ops method for s390. */
1702 s390_emit_less_unsigned (void)
1704 static const unsigned char buf
[] = {
1705 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1706 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1707 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1708 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1709 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1711 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1712 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1714 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1716 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1717 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1719 add_insns (buf
, sizeof buf
);
1722 /* The "emit_ref" emit_ops method for s390. */
1725 s390_emit_ref (int size
)
1727 static const unsigned char buf1
[] = {
1728 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1729 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1731 static const unsigned char buf2
[] = {
1732 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1733 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1735 static const unsigned char buf4
[] = {
1736 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1737 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1739 static const unsigned char buf8
[] = {
1740 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1745 add_insns (buf1
, sizeof buf1
);
1748 add_insns (buf2
, sizeof buf2
);
1751 add_insns (buf4
, sizeof buf4
);
1754 add_insns (buf8
, sizeof buf8
);
1761 /* The "emit_if_goto" emit_ops method for s390. */
1764 s390_emit_if_goto (int *offset_p
, int *size_p
)
1766 static const unsigned char buf
[] = {
1767 0x16, 0x23, /* or %r2, %r3 */
1768 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1769 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1770 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1772 add_insns (buf
, sizeof buf
);
1779 /* The "emit_goto" emit_ops method for s390 and s390x. */
1782 s390_emit_goto (int *offset_p
, int *size_p
)
1784 static const unsigned char buf
[] = {
1785 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1787 add_insns (buf
, sizeof buf
);
1794 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1797 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1799 long diff
= ((long) (to
- (from
- 2))) / 2;
1801 unsigned char buf
[sizeof sdiff
];
1803 /* We're only doing 4-byte sizes at the moment. */
1804 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1810 memcpy (buf
, &sdiff
, sizeof sdiff
);
1811 target_write_memory (from
, buf
, sizeof sdiff
);
1814 /* Preparation for emitting a literal pool of given size. Loads the address
1815 of the pool into %r1, and jumps over it. Called should emit the pool data
1816 immediately afterwards. Used for both s390 and s390x. */
1819 s390_emit_litpool (int size
)
1821 static const unsigned char nop
[] = {
1824 unsigned char buf
[] = {
1826 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1831 /* buf needs to start at even halfword for litpool to be aligned */
1832 if (current_insn_ptr
& 2)
1833 add_insns (nop
, sizeof nop
);
1837 while ((current_insn_ptr
& 6) != 4)
1838 add_insns (nop
, sizeof nop
);
1840 add_insns (buf
, sizeof buf
);
1843 /* The "emit_const" emit_ops method for s390. */
1846 s390_emit_const (LONGEST num
)
1848 unsigned long long n
= num
;
1849 unsigned char buf_s
[] = {
1850 /* lhi %r3, <num> */
1852 (unsigned char) (num
>> 8), (unsigned char) num
,
1856 static const unsigned char buf_l
[] = {
1857 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1859 if (num
< 0x8000 && num
>= 0)
1861 add_insns (buf_s
, sizeof buf_s
);
1865 s390_emit_litpool (8);
1866 add_insns ((unsigned char *) &n
, sizeof n
);
1867 add_insns (buf_l
, sizeof buf_l
);
1871 /* The "emit_call" emit_ops method for s390. */
1874 s390_emit_call (CORE_ADDR fn
)
1876 unsigned int n
= fn
;
1877 static const unsigned char buf
[] = {
1878 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1879 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1880 0x0d, 0xe1, /* basr %r14, %r1 */
1881 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1883 s390_emit_litpool (4);
1884 add_insns ((unsigned char *) &n
, sizeof n
);
1885 add_insns (buf
, sizeof buf
);
1888 /* The "emit_reg" emit_ops method for s390. */
1891 s390_emit_reg (int reg
)
1893 unsigned char bufpre
[] = {
1896 /* lhi %r3, <reg> */
1897 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1899 add_insns (bufpre
, sizeof bufpre
);
1900 s390_emit_call (get_raw_reg_func_addr ());
1903 /* The "emit_pop" emit_ops method for s390. */
1906 s390_emit_pop (void)
1908 static const unsigned char buf
[] = {
1909 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1910 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1912 add_insns (buf
, sizeof buf
);
1915 /* The "emit_stack_flush" emit_ops method for s390. */
1918 s390_emit_stack_flush (void)
1920 static const unsigned char buf
[] = {
1921 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1922 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1924 add_insns (buf
, sizeof buf
);
1927 /* The "emit_zero_ext" emit_ops method for s390. */
1930 s390_emit_zero_ext (int arg
)
1932 unsigned char buf
[] = {
1933 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1934 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1936 add_insns (buf
, sizeof buf
);
1939 /* The "emit_swap" emit_ops method for s390. */
1942 s390_emit_swap (void)
1944 static const unsigned char buf
[] = {
1945 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1946 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1947 0x18, 0x24, /* lr %r2, %r4 */
1948 0x18, 0x35, /* lr %r3, %r5 */
1950 add_insns (buf
, sizeof buf
);
1953 /* The "emit_stack_adjust" emit_ops method for s390. */
1956 s390_emit_stack_adjust (int n
)
1958 unsigned char buf
[] = {
1961 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
1963 add_insns (buf
, sizeof buf
);
1966 /* Sets %r2 to a 32-bit constant. */
1969 s390_emit_set_r2 (int arg1
)
1971 unsigned char buf_s
[] = {
1972 /* lhi %r2, <arg1> */
1973 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
1975 static const unsigned char buf_l
[] = {
1976 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1978 if (arg1
< 0x8000 && arg1
>= -0x8000)
1980 add_insns (buf_s
, sizeof buf_s
);
1984 s390_emit_litpool (4);
1985 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
1986 add_insns (buf_l
, sizeof buf_l
);
1990 /* The "emit_int_call_1" emit_ops method for s390. */
1993 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
1995 /* FN's prototype is `LONGEST(*fn)(int)'. */
1996 s390_emit_set_r2 (arg1
);
1997 s390_emit_call (fn
);
2000 /* The "emit_void_call_2" emit_ops method for s390. */
2003 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2005 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2006 static const unsigned char buf
[] = {
2007 0x18, 0xc2, /* lr %r12, %r2 */
2008 0x18, 0xd3, /* lr %r13, %r3 */
2009 0x18, 0x43, /* lr %r4, %r3 */
2010 0x18, 0x32, /* lr %r3, %r2 */
2012 static const unsigned char buf2
[] = {
2013 0x18, 0x2c, /* lr %r2, %r12 */
2014 0x18, 0x3d, /* lr %r3, %r13 */
2016 add_insns (buf
, sizeof buf
);
2017 s390_emit_set_r2 (arg1
);
2018 s390_emit_call (fn
);
2019 add_insns (buf2
, sizeof buf2
);
2022 /* The "emit_eq_goto" emit_ops method for s390. */
2025 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2027 static const unsigned char buf
[] = {
2028 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2029 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2030 0x16, 0x23, /* or %r2, %r3 */
2031 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2032 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2033 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2035 add_insns (buf
, sizeof buf
);
2042 /* The "emit_ne_goto" emit_ops method for s390. */
2045 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2047 static const unsigned char buf
[] = {
2048 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2049 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2050 0x16, 0x23, /* or %r2, %r3 */
2051 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2052 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2053 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2055 add_insns (buf
, sizeof buf
);
2062 /* The "emit_lt_goto" emit_ops method for s390. */
2065 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2067 static const unsigned char buf
[] = {
2068 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2069 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2070 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2071 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2072 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2074 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2075 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2076 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2078 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2079 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2080 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2083 add_insns (buf
, sizeof buf
);
2090 /* The "emit_le_goto" emit_ops method for s390. */
2093 s390_emit_le_goto (int *offset_p
, int *size_p
)
2095 static const unsigned char buf
[] = {
2096 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2097 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2098 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2099 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2100 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2102 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2103 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2104 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2106 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2107 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2108 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2111 add_insns (buf
, sizeof buf
);
2118 /* The "emit_gt_goto" emit_ops method for s390. */
2121 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2123 static const unsigned char buf
[] = {
2124 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2125 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2126 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2127 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2128 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2130 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2131 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2132 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2134 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2135 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2136 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2139 add_insns (buf
, sizeof buf
);
2146 /* The "emit_ge_goto" emit_ops method for s390. */
2149 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2151 static const unsigned char buf
[] = {
2152 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2153 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2154 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2155 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2156 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2158 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2159 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2160 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2162 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2163 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2164 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2167 add_insns (buf
, sizeof buf
);
2174 /* The "emit_ops" structure for s390. Named _impl to avoid name
2175 collision with s390_emit_ops function. */
2177 static struct emit_ops s390_emit_ops_impl
=
2185 s390_emit_rsh_signed
,
2186 s390_emit_rsh_unsigned
,
2194 s390_emit_less_signed
,
2195 s390_emit_less_unsigned
,
2199 s390_write_goto_address
,
2204 s390_emit_stack_flush
,
2207 s390_emit_stack_adjust
,
2208 s390_emit_int_call_1
,
2209 s390_emit_void_call_2
,
2220 /* The "emit_prologue" emit_ops method for s390x. */
2223 s390x_emit_prologue (void)
2225 static const unsigned char buf
[] = {
2226 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2227 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2228 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2229 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2231 add_insns (buf
, sizeof buf
);
2234 /* The "emit_epilogue" emit_ops method for s390x. */
2237 s390x_emit_epilogue (void)
2239 static const unsigned char buf
[] = {
2240 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2241 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2242 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2243 0x07, 0xfe, /* br %r14 */
2245 add_insns (buf
, sizeof buf
);
2248 /* The "emit_add" emit_ops method for s390x. */
2251 s390x_emit_add (void)
2253 static const unsigned char buf
[] = {
2254 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2255 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2257 add_insns (buf
, sizeof buf
);
2260 /* The "emit_sub" emit_ops method for s390x. */
2263 s390x_emit_sub (void)
2265 static const unsigned char buf
[] = {
2266 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2267 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2268 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2269 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2271 add_insns (buf
, sizeof buf
);
2274 /* The "emit_mul" emit_ops method for s390x. */
2277 s390x_emit_mul (void)
2282 /* The "emit_lsh" emit_ops method for s390x. */
2285 s390x_emit_lsh (void)
2287 static const unsigned char buf
[] = {
2288 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2289 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2290 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2292 add_insns (buf
, sizeof buf
);
2295 /* The "emit_rsh_signed" emit_ops method for s390x. */
2298 s390x_emit_rsh_signed (void)
2300 static const unsigned char buf
[] = {
2301 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2302 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2303 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2305 add_insns (buf
, sizeof buf
);
2308 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2311 s390x_emit_rsh_unsigned (void)
2313 static const unsigned char buf
[] = {
2314 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2315 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2316 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2318 add_insns (buf
, sizeof buf
);
2321 /* The "emit_ext" emit_ops method for s390x. */
2324 s390x_emit_ext (int arg
)
2326 unsigned char buf
[] = {
2327 /* sllg %r2, %r2, <64-arg> */
2328 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2329 /* srag %r2, %r2, <64-arg> */
2330 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2332 add_insns (buf
, sizeof buf
);
2335 /* The "emit_log_not" emit_ops method for s390x. */
2338 s390x_emit_log_not (void)
2340 static const unsigned char buf
[] = {
2341 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2342 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2343 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2345 add_insns (buf
, sizeof buf
);
2348 /* The "emit_bit_and" emit_ops method for s390x. */
2351 s390x_emit_bit_and (void)
2353 static const unsigned char buf
[] = {
2354 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2355 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2357 add_insns (buf
, sizeof buf
);
2360 /* The "emit_bit_or" emit_ops method for s390x. */
2363 s390x_emit_bit_or (void)
2365 static const unsigned char buf
[] = {
2366 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2367 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2369 add_insns (buf
, sizeof buf
);
2372 /* The "emit_bit_xor" emit_ops method for s390x. */
2375 s390x_emit_bit_xor (void)
2377 static const unsigned char buf
[] = {
2378 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2379 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2381 add_insns (buf
, sizeof buf
);
2384 /* The "emit_bit_not" emit_ops method for s390x. */
2387 s390x_emit_bit_not (void)
2389 static const unsigned char buf
[] = {
2390 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2391 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2393 add_insns (buf
, sizeof buf
);
2396 /* The "emit_equal" emit_ops method for s390x. */
2399 s390x_emit_equal (void)
2401 s390x_emit_bit_xor ();
2402 s390x_emit_log_not ();
2405 /* The "emit_less_signed" emit_ops method for s390x. */
2408 s390x_emit_less_signed (void)
2410 static const unsigned char buf
[] = {
2411 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2412 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2413 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2414 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2416 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2418 add_insns (buf
, sizeof buf
);
2421 /* The "emit_less_unsigned" emit_ops method for s390x. */
2424 s390x_emit_less_unsigned (void)
2426 static const unsigned char buf
[] = {
2427 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2428 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2429 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2430 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2432 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2434 add_insns (buf
, sizeof buf
);
2437 /* The "emit_ref" emit_ops method for s390x. */
2440 s390x_emit_ref (int size
)
2442 static const unsigned char buf1
[] = {
2443 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2445 static const unsigned char buf2
[] = {
2446 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2448 static const unsigned char buf4
[] = {
2449 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2451 static const unsigned char buf8
[] = {
2452 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2457 add_insns (buf1
, sizeof buf1
);
2460 add_insns (buf2
, sizeof buf2
);
2463 add_insns (buf4
, sizeof buf4
);
2466 add_insns (buf8
, sizeof buf8
);
2473 /* The "emit_if_goto" emit_ops method for s390x. */
2476 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2478 static const unsigned char buf
[] = {
2479 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2480 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2481 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2482 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2484 add_insns (buf
, sizeof buf
);
2491 /* The "emit_const" emit_ops method for s390x. */
2494 s390x_emit_const (LONGEST num
)
2496 unsigned long long n
= num
;
2497 unsigned char buf_s
[] = {
2498 /* lghi %r2, <num> */
2499 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2501 static const unsigned char buf_l
[] = {
2502 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2504 if (num
< 0x8000 && num
>= -0x8000)
2506 add_insns (buf_s
, sizeof buf_s
);
2510 s390_emit_litpool (8);
2511 add_insns ((unsigned char *) &n
, sizeof n
);
2512 add_insns (buf_l
, sizeof buf_l
);
2516 /* The "emit_call" emit_ops method for s390x. */
2519 s390x_emit_call (CORE_ADDR fn
)
2521 unsigned long n
= fn
;
2522 static const unsigned char buf
[] = {
2523 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2524 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2525 0x0d, 0xe1, /* basr %r14, %r1 */
2526 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2528 s390_emit_litpool (8);
2529 add_insns ((unsigned char *) &n
, sizeof n
);
2530 add_insns (buf
, sizeof buf
);
2533 /* The "emit_reg" emit_ops method for s390x. */
2536 s390x_emit_reg (int reg
)
2538 unsigned char buf
[] = {
2540 0xb9, 0x04, 0x00, 0x29,
2541 /* lghi %r3, <reg> */
2542 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2544 add_insns (buf
, sizeof buf
);
2545 s390x_emit_call (get_raw_reg_func_addr ());
2548 /* The "emit_pop" emit_ops method for s390x. */
2551 s390x_emit_pop (void)
2553 static const unsigned char buf
[] = {
2554 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2555 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2557 add_insns (buf
, sizeof buf
);
2560 /* The "emit_stack_flush" emit_ops method for s390x. */
2563 s390x_emit_stack_flush (void)
2565 static const unsigned char buf
[] = {
2566 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2567 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2569 add_insns (buf
, sizeof buf
);
2572 /* The "emit_zero_ext" emit_ops method for s390x. */
2575 s390x_emit_zero_ext (int arg
)
2577 unsigned char buf
[] = {
2578 /* sllg %r2, %r2, <64-arg> */
2579 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2580 /* srlg %r2, %r2, <64-arg> */
2581 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2583 add_insns (buf
, sizeof buf
);
2586 /* The "emit_swap" emit_ops method for s390x. */
2589 s390x_emit_swap (void)
2591 static const unsigned char buf
[] = {
2592 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2593 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2594 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2596 add_insns (buf
, sizeof buf
);
2599 /* The "emit_stack_adjust" emit_ops method for s390x. */
2602 s390x_emit_stack_adjust (int n
)
2604 unsigned char buf
[] = {
2605 /* aghi %r15, 8*n */
2607 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2609 add_insns (buf
, sizeof buf
);
2612 /* The "emit_int_call_1" emit_ops method for s390x. */
2615 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2617 /* FN's prototype is `LONGEST(*fn)(int)'. */
2618 s390x_emit_const (arg1
);
2619 s390x_emit_call (fn
);
2622 /* The "emit_void_call_2" emit_ops method for s390x. */
2625 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2627 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2628 static const unsigned char buf
[] = {
2629 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2630 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2632 static const unsigned char buf2
[] = {
2633 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2635 add_insns (buf
, sizeof buf
);
2636 s390x_emit_const (arg1
);
2637 s390x_emit_call (fn
);
2638 add_insns (buf2
, sizeof buf2
);
2641 /* The "emit_eq_goto" emit_ops method for s390x. */
2644 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2646 static const unsigned char buf
[] = {
2647 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2648 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2649 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2650 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2652 add_insns (buf
, sizeof buf
);
2659 /* The "emit_ne_goto" emit_ops method for s390x. */
2662 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2664 static const unsigned char buf
[] = {
2665 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2666 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2667 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2668 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2670 add_insns (buf
, sizeof buf
);
2677 /* The "emit_lt_goto" emit_ops method for s390x. */
2680 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2682 static const unsigned char buf
[] = {
2683 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2684 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2685 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2686 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2688 add_insns (buf
, sizeof buf
);
2695 /* The "emit_le_goto" emit_ops method for s390x. */
2698 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2700 static const unsigned char buf
[] = {
2701 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2702 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2703 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2704 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2706 add_insns (buf
, sizeof buf
);
2713 /* The "emit_gt_goto" emit_ops method for s390x. */
2716 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2718 static const unsigned char buf
[] = {
2719 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2720 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2721 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2722 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2724 add_insns (buf
, sizeof buf
);
2731 /* The "emit_ge_goto" emit_ops method for s390x. */
2734 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2736 static const unsigned char buf
[] = {
2737 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2738 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2739 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2740 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2742 add_insns (buf
, sizeof buf
);
2749 /* The "emit_ops" structure for s390x. */
2751 static struct emit_ops s390x_emit_ops
=
2753 s390x_emit_prologue
,
2754 s390x_emit_epilogue
,
2759 s390x_emit_rsh_signed
,
2760 s390x_emit_rsh_unsigned
,
2768 s390x_emit_less_signed
,
2769 s390x_emit_less_unsigned
,
2773 s390_write_goto_address
,
2778 s390x_emit_stack_flush
,
2779 s390x_emit_zero_ext
,
2781 s390x_emit_stack_adjust
,
2782 s390x_emit_int_call_1
,
2783 s390x_emit_void_call_2
,
2793 /* The "emit_ops" linux_target_ops method. */
2795 static struct emit_ops
*
2796 s390_emit_ops (void)
2799 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2801 if (register_size (regcache
->tdesc
, 0) == 8)
2802 return &s390x_emit_ops
;
2805 return &s390_emit_ops_impl
;
2808 struct linux_target_ops the_low_target
= {
2810 s390_cannot_fetch_register
,
2811 s390_cannot_store_register
,
2812 NULL
, /* fetch_register */
2815 NULL
, /* breakpoint_kind_from_pc */
2816 s390_sw_breakpoint_from_kind
,
2818 s390_breakpoint_len
,
2820 s390_supports_z_point_type
,
2825 s390_collect_ptrace_register
,
2826 s390_supply_ptrace_register
,
2827 NULL
, /* siginfo_fixup */
2828 NULL
, /* new_process */
2829 NULL
, /* delete_process */
2830 NULL
, /* new_thread */
2831 NULL
, /* delete_thread */
2832 NULL
, /* new_fork */
2833 NULL
, /* prepare_to_resume */
2834 NULL
, /* process_qsupported */
2835 s390_supports_tracepoints
,
2836 s390_get_thread_area
,
2837 s390_install_fast_tracepoint_jump_pad
,
2839 s390_get_min_fast_tracepoint_insn_len
,
2840 NULL
, /* supports_range_stepping */
2841 NULL
, /* breakpoint_kind_from_current_state */
2842 s390_supports_hardware_single_step
,
2843 NULL
, /* get_syscall_trapinfo */
2844 s390_get_ipa_tdesc_idx
,
2847 /* The linux target ops object. */
2849 linux_process_target
*the_linux_target
= &the_s390_target
;
2852 initialize_low_arch (void)
2854 /* Initialize the Linux target descriptions. */
2856 init_registers_s390_linux32 ();
2857 init_registers_s390_linux32v1 ();
2858 init_registers_s390_linux32v2 ();
2859 init_registers_s390_linux64 ();
2860 init_registers_s390_linux64v1 ();
2861 init_registers_s390_linux64v2 ();
2862 init_registers_s390_te_linux64 ();
2863 init_registers_s390_vx_linux64 ();
2864 init_registers_s390_tevx_linux64 ();
2865 init_registers_s390_gs_linux64 ();
2867 init_registers_s390x_linux64 ();
2868 init_registers_s390x_linux64v1 ();
2869 init_registers_s390x_linux64v2 ();
2870 init_registers_s390x_te_linux64 ();
2871 init_registers_s390x_vx_linux64 ();
2872 init_registers_s390x_tevx_linux64 ();
2873 init_registers_s390x_gs_linux64 ();
2876 initialize_regsets_info (&s390_regsets_info
);
2877 initialize_regsets_info (&s390_regsets_info_3264
);