1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2018 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* This file is used for both 31-bit and 64-bit S/390 systems. */
23 #include "linux-low.h"
24 #include "elf/common.h"
26 #include "tracepoint.h"
28 #include <asm/ptrace.h>
29 #include "nat/gdb_ptrace.h"
34 #include "linux-s390-tdesc.h"
36 #ifndef HWCAP_S390_HIGH_GPRS
37 #define HWCAP_S390_HIGH_GPRS 512
41 #define HWCAP_S390_TE 1024
45 #define HWCAP_S390_VX 2048
49 #define HWCAP_S390_GS 16384
52 #define s390_num_regs 52
54 static int s390_regmap
[] = {
55 PT_PSWMASK
, PT_PSWADDR
,
57 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
58 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
59 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
60 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
62 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
63 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
64 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
65 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
70 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
71 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
72 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
73 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
75 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
76 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
77 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
78 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
84 #define s390_num_regs_3264 68
87 static int s390_regmap_3264
[] = {
88 PT_PSWMASK
, PT_PSWADDR
,
90 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
91 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
92 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
93 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
94 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
95 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
96 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
97 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
99 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
100 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
101 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
102 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
106 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
107 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
108 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
109 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
114 static int s390_regmap_3264
[] = {
115 PT_PSWMASK
, PT_PSWADDR
,
117 -1, PT_GPR0
, -1, PT_GPR1
,
118 -1, PT_GPR2
, -1, PT_GPR3
,
119 -1, PT_GPR4
, -1, PT_GPR5
,
120 -1, PT_GPR6
, -1, PT_GPR7
,
121 -1, PT_GPR8
, -1, PT_GPR9
,
122 -1, PT_GPR10
, -1, PT_GPR11
,
123 -1, PT_GPR12
, -1, PT_GPR13
,
124 -1, PT_GPR14
, -1, PT_GPR15
,
126 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
127 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
128 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
129 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
133 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
134 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
135 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
136 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
144 s390_cannot_fetch_register (int regno
)
150 s390_cannot_store_register (int regno
)
156 s390_collect_ptrace_register (struct regcache
*regcache
, int regno
, char *buf
)
158 int size
= register_size (regcache
->tdesc
, regno
);
159 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
160 struct usrregs_info
*usr
= regs_info
->usrregs
;
161 int regaddr
= usr
->regmap
[regno
];
163 if (size
< sizeof (long))
165 memset (buf
, 0, sizeof (long));
167 if ((regno
^ 1) < usr
->num_regs
168 && usr
->regmap
[regno
^ 1] == regaddr
)
170 collect_register (regcache
, regno
& ~1, buf
);
171 collect_register (regcache
, (regno
& ~1) + 1,
172 buf
+ sizeof (long) - size
);
174 else if (regaddr
== PT_PSWMASK
)
176 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
177 the basic addressing mode bit from the PSW address. */
178 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
179 collect_register (regcache
, regno
, buf
);
180 collect_register (regcache
, regno
^ 1, addr
);
182 buf
[size
] |= (addr
[0] & 0x80);
184 else if (regaddr
== PT_PSWADDR
)
186 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
187 mode bit (which gets copied to the PSW mask instead). */
188 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
189 buf
[sizeof (long) - size
] &= ~0x80;
191 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
192 || regaddr
== PT_ORIGGPR2
)
193 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
195 collect_register (regcache
, regno
, buf
);
197 else if (regaddr
!= -1)
198 collect_register (regcache
, regno
, buf
);
202 s390_supply_ptrace_register (struct regcache
*regcache
,
203 int regno
, const char *buf
)
205 int size
= register_size (regcache
->tdesc
, regno
);
206 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
207 struct usrregs_info
*usr
= regs_info
->usrregs
;
208 int regaddr
= usr
->regmap
[regno
];
210 if (size
< sizeof (long))
212 if ((regno
^ 1) < usr
->num_regs
213 && usr
->regmap
[regno
^ 1] == regaddr
)
215 supply_register (regcache
, regno
& ~1, buf
);
216 supply_register (regcache
, (regno
& ~1) + 1,
217 buf
+ sizeof (long) - size
);
219 else if (regaddr
== PT_PSWMASK
)
221 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
222 the basic addressing mode into the PSW address. */
223 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
224 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
225 memcpy (mask
, buf
, size
);
227 supply_register (regcache
, regno
, mask
);
229 collect_register (regcache
, regno
^ 1, addr
);
231 addr
[0] |= (buf
[size
] & 0x80);
232 supply_register (regcache
, regno
^ 1, addr
);
234 else if (regaddr
== PT_PSWADDR
)
236 /* Convert 8-byte PSW address to 4 bytes by truncating, but
237 keeping the addressing mode bit (which was set from the mask). */
238 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
240 collect_register (regcache
, regno
, addr
);
241 amode
= addr
[0] & 0x80;
242 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
245 supply_register (regcache
, regno
, addr
);
247 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
248 || regaddr
== PT_ORIGGPR2
)
249 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
251 supply_register (regcache
, regno
, buf
);
253 else if (regaddr
!= -1)
254 supply_register (regcache
, regno
, buf
);
257 /* Provide only a fill function for the general register set. ps_lgetregs
258 will use this for NPTL support. */
261 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
264 const struct regs_info
*regs_info
= (*the_low_target
.regs_info
) ();
265 struct usrregs_info
*usr
= regs_info
->usrregs
;
267 for (i
= 0; i
< usr
->num_regs
; i
++)
269 if (usr
->regmap
[i
] < PT_PSWMASK
270 || usr
->regmap
[i
] > PT_ACR15
)
273 s390_collect_ptrace_register (regcache
, i
,
274 (char *) buf
+ usr
->regmap
[i
]);
278 /* Fill and store functions for extended register sets. */
282 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
284 int r0h
= find_regno (regcache
->tdesc
, "r0h");
287 for (i
= 0; i
< 16; i
++)
288 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
292 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
294 int r0h
= find_regno (regcache
->tdesc
, "r0h");
297 for (i
= 0; i
< 16; i
++)
298 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
303 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
307 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
308 supply_register_by_name (regcache
, "last_break", p
);
312 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
314 collect_register_by_name (regcache
, "system_call", buf
);
318 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
320 supply_register_by_name (regcache
, "system_call", buf
);
324 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
326 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
327 int tr0
= find_regno (regcache
->tdesc
, "tr0");
330 for (i
= 0; i
< 4; i
++)
331 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
333 for (i
= 0; i
< 16; i
++)
334 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
338 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
340 int v0
= find_regno (regcache
->tdesc
, "v0l");
343 for (i
= 0; i
< 16; i
++)
344 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
348 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
350 int v0
= find_regno (regcache
->tdesc
, "v0l");
353 for (i
= 0; i
< 16; i
++)
354 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
358 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
360 int v16
= find_regno (regcache
->tdesc
, "v16");
363 for (i
= 0; i
< 16; i
++)
364 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
368 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
370 int v16
= find_regno (regcache
->tdesc
, "v16");
373 for (i
= 0; i
< 16; i
++)
374 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
378 s390_store_gs (struct regcache
*regcache
, const void *buf
)
380 int gsd
= find_regno (regcache
->tdesc
, "gsd");
383 for (i
= 0; i
< 3; i
++)
384 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
388 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
390 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
393 for (i
= 0; i
< 3; i
++)
394 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
397 static struct regset_info s390_regsets
[] = {
398 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
400 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
401 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
403 /* Last break address is read-only; no fill function. */
404 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
405 NULL
, s390_store_last_break
},
406 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
407 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
408 /* TDB is read-only. */
409 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
410 NULL
, s390_store_tdb
},
411 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
412 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
413 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
414 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
415 /* Guarded storage registers are read-only. */
416 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
417 NULL
, s390_store_gs
},
418 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
419 NULL
, s390_store_gsbc
},
424 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
425 #define s390_breakpoint_len 2
427 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
429 static const gdb_byte
*
430 s390_sw_breakpoint_from_kind (int kind
, int *size
)
432 *size
= s390_breakpoint_len
;
433 return s390_breakpoint
;
437 s390_get_pc (struct regcache
*regcache
)
439 if (register_size (regcache
->tdesc
, 0) == 4)
442 collect_register_by_name (regcache
, "pswa", &pswa
);
443 return pswa
& 0x7fffffff;
448 collect_register_by_name (regcache
, "pswa", &pc
);
454 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
456 if (register_size (regcache
->tdesc
, 0) == 4)
459 collect_register_by_name (regcache
, "pswa", &pswa
);
460 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
461 supply_register_by_name (regcache
, "pswa", &pswa
);
465 unsigned long pc
= newpc
;
466 supply_register_by_name (regcache
, "pswa", &pc
);
470 /* Get HWCAP from AUXV, using the given WORDSIZE. Return the HWCAP, or
471 zero if not found. */
474 s390_get_hwcap (int wordsize
)
476 gdb_byte
*data
= (gdb_byte
*) alloca (2 * wordsize
);
479 while ((*the_target
->read_auxv
) (offset
, data
, 2 * wordsize
) == 2 * wordsize
)
483 unsigned int *data_p
= (unsigned int *)data
;
484 if (data_p
[0] == AT_HWCAP
)
489 unsigned long *data_p
= (unsigned long *)data
;
490 if (data_p
[0] == AT_HWCAP
)
494 offset
+= 2 * wordsize
;
500 /* Determine the word size for the given PID, in bytes. */
504 s390_get_wordsize (int pid
)
507 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
508 (PTRACE_TYPE_ARG3
) 0,
509 (PTRACE_TYPE_ARG4
) 0);
512 warning (_("Couldn't determine word size, assuming 64-bit.\n"));
515 /* Derive word size from extended addressing mode (PSW bit 31). */
516 return pswm
& (1L << 32) ? 8 : 4;
519 #define s390_get_wordsize(pid) 4
523 s390_check_regset (int pid
, int regset
, int regsize
)
525 void *buf
= alloca (regsize
);
529 iov
.iov_len
= regsize
;
531 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
537 /* For a 31-bit inferior, whether the kernel supports using the full
539 static int have_hwcap_s390_high_gprs
= 0;
540 static int have_hwcap_s390_vx
= 0;
543 s390_arch_setup (void)
545 const struct target_desc
*tdesc
;
546 struct regset_info
*regset
;
548 /* Determine word size and HWCAP. */
549 int pid
= pid_of (current_thread
);
550 int wordsize
= s390_get_wordsize (pid
);
551 unsigned long hwcap
= s390_get_hwcap (wordsize
);
553 /* Check whether the kernel supports extra register sets. */
554 int have_regset_last_break
555 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
556 int have_regset_system_call
557 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
559 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
560 && (hwcap
& HWCAP_S390_TE
) != 0);
562 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
563 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
564 && (hwcap
& HWCAP_S390_VX
) != 0);
566 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
567 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
568 && (hwcap
& HWCAP_S390_GS
) != 0);
575 tdesc
= tdesc_s390x_gs_linux64
;
576 else if (have_regset_vxrs
)
577 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
578 tdesc_s390x_vx_linux64
);
579 else if (have_regset_tdb
)
580 tdesc
= tdesc_s390x_te_linux64
;
581 else if (have_regset_system_call
)
582 tdesc
= tdesc_s390x_linux64v2
;
583 else if (have_regset_last_break
)
584 tdesc
= tdesc_s390x_linux64v1
;
586 tdesc
= tdesc_s390x_linux64
;
589 /* For a 31-bit inferior, check whether the kernel supports
590 using the full 64-bit GPRs. */
593 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
595 have_hwcap_s390_high_gprs
= 1;
597 tdesc
= tdesc_s390_gs_linux64
;
598 else if (have_regset_vxrs
)
599 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
600 tdesc_s390_vx_linux64
);
601 else if (have_regset_tdb
)
602 tdesc
= tdesc_s390_te_linux64
;
603 else if (have_regset_system_call
)
604 tdesc
= tdesc_s390_linux64v2
;
605 else if (have_regset_last_break
)
606 tdesc
= tdesc_s390_linux64v1
;
608 tdesc
= tdesc_s390_linux64
;
612 /* Assume 31-bit inferior process. */
613 if (have_regset_system_call
)
614 tdesc
= tdesc_s390_linux32v2
;
615 else if (have_regset_last_break
)
616 tdesc
= tdesc_s390_linux32v1
;
618 tdesc
= tdesc_s390_linux32
;
621 have_hwcap_s390_vx
= have_regset_vxrs
;
624 /* Update target_regsets according to available register sets. */
625 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
626 if (regset
->get_request
== PTRACE_GETREGSET
)
627 switch (regset
->nt_type
)
630 case NT_S390_HIGH_GPRS
:
631 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
634 case NT_S390_LAST_BREAK
:
635 regset
->size
= have_regset_last_break
? 8 : 0;
637 case NT_S390_SYSTEM_CALL
:
638 regset
->size
= have_regset_system_call
? 4 : 0;
641 regset
->size
= have_regset_tdb
? 256 : 0;
643 case NT_S390_VXRS_LOW
:
644 regset
->size
= have_regset_vxrs
? 128 : 0;
646 case NT_S390_VXRS_HIGH
:
647 regset
->size
= have_regset_vxrs
? 256 : 0;
651 regset
->size
= have_regset_gs
? 32 : 0;
656 current_process ()->tdesc
= tdesc
;
661 s390_breakpoint_at (CORE_ADDR pc
)
663 unsigned char c
[s390_breakpoint_len
];
664 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
665 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
668 /* Breakpoint/Watchpoint support. */
670 /* The "supports_z_point_type" linux_target_ops method. */
673 s390_supports_z_point_type (char z_type
)
684 /* Support for hardware single step. */
687 s390_supports_hardware_single_step (void)
692 static struct usrregs_info s390_usrregs_info
=
698 static struct regsets_info s390_regsets_info
=
700 s390_regsets
, /* regsets */
702 NULL
, /* disabled_regsets */
705 static struct regs_info regs_info
=
707 NULL
, /* regset_bitmap */
712 static struct usrregs_info s390_usrregs_info_3264
=
718 static struct regsets_info s390_regsets_info_3264
=
720 s390_regsets
, /* regsets */
722 NULL
, /* disabled_regsets */
725 static struct regs_info regs_info_3264
=
727 NULL
, /* regset_bitmap */
728 &s390_usrregs_info_3264
,
729 &s390_regsets_info_3264
732 static const struct regs_info
*
733 s390_regs_info (void)
735 if (have_hwcap_s390_high_gprs
)
738 const struct target_desc
*tdesc
= current_process ()->tdesc
;
740 if (register_size (tdesc
, 0) == 4)
741 return ®s_info_3264
;
743 return ®s_info_3264
;
749 /* The "supports_tracepoints" linux_target_ops method. */
752 s390_supports_tracepoints (void)
757 /* Implementation of linux_target_ops method "get_thread_area". */
760 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
762 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
764 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
766 if (register_size (regcache
->tdesc
, 0) == 4)
767 res
&= 0xffffffffull
;
774 /* Fast tracepoint support.
776 The register save area on stack is identical for all targets:
778 0x000+i*0x10: VR0-VR31
785 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
786 Likewise, if there's no VX support, we just store the FRs into the slots
787 of low VR halves. The agent code is responsible for rearranging that
790 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
791 one trick used at the very beginning: since there's no way to allocate
792 stack space without destroying CC (lay instruction can do it, but it's
793 only supported on later CPUs), we take 4 different execution paths for
794 every possible value of CC, allocate stack space, save %r0, stuff the
795 CC value in %r0 (shifted to match its position in PSWM high word),
796 then branch to common path. */
798 static const unsigned char s390_ft_entry_gpr_esa
[] = {
799 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
800 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
801 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
803 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
804 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
805 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
806 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
808 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
809 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
810 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
811 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
813 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
814 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
815 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
816 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
818 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
819 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
820 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
822 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
823 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
824 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
825 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
826 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
827 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
828 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
829 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
830 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
831 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
832 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
833 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
834 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
835 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
836 /* Compute original value of %r15 and store it. We use ahi instead
837 of la to preserve the whole value, and not just the low 31 bits.
838 This is not particularly important here, but essential in the
839 zarch case where someone might be using the high word of %r15
840 as an extra register. */
841 0x18, 0x1f, /* lr %r1, %r15 */
842 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
843 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
846 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
847 target. Same as above, except this time we can use load/store multiple,
848 since the 64-bit regs are tightly packed. */
850 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
851 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
852 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
853 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
855 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
856 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
857 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
858 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
860 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
861 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
862 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
863 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
865 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
866 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
867 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
868 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
870 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
871 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
872 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
874 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
875 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
876 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
879 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
880 current PSWM (read by epsw) and CC from entry (in %r0). */
882 static const unsigned char s390_ft_entry_misc
[] = {
883 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
884 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
885 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
886 0x14, 0x21, /* nr %r2, %r1 */
887 0x16, 0x20, /* or %r2, %r0 */
888 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
889 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
890 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
893 /* Code sequence saving FRs, used if VX not supported. */
895 static const unsigned char s390_ft_entry_fr
[] = {
896 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
897 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
898 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
899 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
900 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
901 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
902 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
903 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
904 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
905 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
906 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
907 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
908 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
909 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
910 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
911 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
914 /* Code sequence saving VRs, used if VX not supported. */
916 static const unsigned char s390_ft_entry_vr
[] = {
917 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
918 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
921 /* Code sequence doing the collection call for 31-bit target. %r1 contains
922 the address of the literal pool. */
924 static const unsigned char s390_ft_main_31
[] = {
925 /* Load the literals into registers. */
926 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
927 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
928 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
929 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
930 /* Save original PSWA (tracepoint address | 0x80000000). */
931 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
932 /* Construct a collecting_t object at %r15+0x2e0. */
933 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
934 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
935 /* Move its address to %r0. */
936 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
939 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
940 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
941 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
942 /* Address of the register save block to %r3. */
943 0x18, 0x3f, /* lr %r3, %r15 */
944 /* Make a stack frame, so that we can call the collector. */
945 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
947 0x0d, 0xe4, /* basr %r14, %r4 */
948 /* And get rid of the stack frame again. */
949 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
950 /* Leave the lock. */
951 0x07, 0xf0, /* br %r0 */
952 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
953 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
956 /* Code sequence doing the collection call for 64-bit target. %r1 contains
957 the address of the literal pool. */
959 static const unsigned char s390_ft_main_64
[] = {
960 /* Load the literals into registers. */
961 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
962 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
963 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
964 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
965 /* Save original PSWA (tracepoint address). */
966 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
967 /* Construct a collecting_t object at %r15+0x2e0. */
968 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
969 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
970 /* Move its address to %r0. */
971 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
974 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
975 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
976 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
977 /* Address of the register save block to %r3. */
978 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
979 /* Make a stack frame, so that we can call the collector. */
980 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
982 0x0d, 0xe4, /* basr %r14, %r4 */
983 /* And get rid of the stack frame again. */
984 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
985 /* Leave the lock. */
986 0x07, 0xf0, /* br %r0 */
987 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
988 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
991 /* Code sequence restoring FRs, for targets with no VX support. */
993 static const unsigned char s390_ft_exit_fr
[] = {
994 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
995 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
996 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
997 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
998 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
999 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1000 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1001 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1002 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1003 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1004 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1005 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1006 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1007 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1008 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1009 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1012 /* Code sequence restoring VRs. */
1014 static const unsigned char s390_ft_exit_vr
[] = {
1015 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1016 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1019 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1020 modified by C code, so we use the alr instruction to restore it by
1021 manufacturing an operand that'll result in the original flags. */
1023 static const unsigned char s390_ft_exit_misc
[] = {
1024 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1025 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1026 /* Extract CC to high 2 bits of %r0. */
1027 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1028 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1029 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1030 will have carry iff CC bit 1 is set - resulting in the same flags
1032 0x1e, 0x00, /* alr %r0, %r0 */
1033 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1036 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1038 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1039 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1040 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1041 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1042 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1043 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1044 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1045 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1046 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1047 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1048 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1049 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1050 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1051 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1052 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1053 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1054 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1057 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1060 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1061 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1064 /* Writes instructions to target, updating the to pointer. */
1067 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1069 write_inferior_memory (*to
, buf
, len
);
1073 /* Relocates an instruction from oldloc to *to, updating to. */
1076 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1081 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1084 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1087 else if (buf
[0] < 0xc0)
1093 case 0x05: /* BALR */
1094 case 0x0c: /* BASSM */
1095 case 0x0d: /* BASR */
1096 case 0x45: /* BAL */
1097 case 0x4d: /* BAS */
1098 /* These save a return address and mess around with registers.
1099 We can't relocate them. */
1101 case 0x84: /* BRXH */
1102 case 0x85: /* BRXLE */
1107 /* BRC, BRAS, BRCT, BRCTG */
1108 if (op2
>= 4 && op2
<= 7)
1116 /* LARL, BRCL, BRASL */
1117 if (op2
== 0 || op2
== 4 || op2
== 5)
1125 /* PC-relative addressing instructions. */
1128 case 0xc5: /* BPRP */
1129 case 0xc7: /* BPP */
1130 /* Branch prediction - just skip it. */
1142 case 0x44: /* BRXHG */
1143 case 0x45: /* BRXLG */
1144 case 0x64: /* CGRJ */
1145 case 0x65: /* CLGRJ */
1146 case 0x76: /* CRJ */
1147 case 0x77: /* CLRJ */
1156 /* We'll have to relocate an instruction with a PC-relative field.
1157 First, compute the target. */
1158 int64_t loffset
= 0;
1162 int16_t soffset
= 0;
1163 memcpy (&soffset
, buf
+ 2, 2);
1168 int32_t soffset
= 0;
1169 memcpy (&soffset
, buf
+ 2, 4);
1172 target
= oldloc
+ loffset
* 2;
1174 target
&= 0x7fffffff;
1178 /* BRAS or BRASL was used. We cannot just relocate those, since
1179 they save the return address in a register. We can, however,
1180 replace them with a LARL+JG sequence. */
1182 /* Make the LARL. */
1186 loffset
= oldloc
+ ilen
- *to
;
1189 if (soffset
!= loffset
&& is_64
)
1191 memcpy (buf
+ 2, &soffset
, 4);
1192 append_insns (to
, 6, buf
);
1194 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1195 an address with the top bit 0, while BRAS/BRASL will write it
1196 with top bit 1. It should not matter much, since linux compilers
1197 use BR and not BSM to return from functions, but it could confuse
1198 some poor stack unwinder. */
1200 /* We'll now be writing a JG. */
1207 /* Compute the new offset and write it to the buffer. */
1208 loffset
= target
- *to
;
1213 int16_t soffset
= loffset
;
1214 if (soffset
!= loffset
)
1216 memcpy (buf
+ 2, &soffset
, 2);
1220 int32_t soffset
= loffset
;
1221 if (soffset
!= loffset
&& is_64
)
1223 memcpy (buf
+ 2, &soffset
, 4);
1226 append_insns (to
, ilen
, buf
);
1230 /* Implementation of linux_target_ops method
1231 "install_fast_tracepoint_jump_pad". */
1234 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1236 CORE_ADDR collector
,
1239 CORE_ADDR
*jump_entry
,
1240 CORE_ADDR
*trampoline
,
1241 ULONGEST
*trampoline_size
,
1242 unsigned char *jjump_pad_insn
,
1243 ULONGEST
*jjump_pad_insn_size
,
1244 CORE_ADDR
*adjusted_insn_addr
,
1245 CORE_ADDR
*adjusted_insn_addr_end
,
1251 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1252 CORE_ADDR buildaddr
= *jump_entry
;
1254 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1255 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1256 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1257 int has_vx
= have_hwcap_s390_vx
;
1259 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1261 CORE_ADDR literals
[4] = {
1268 /* First, store the GPRs. */
1270 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1271 s390_ft_entry_gpr_zarch
);
1273 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1274 s390_ft_entry_gpr_esa
);
1276 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1277 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1279 /* Third, FRs or VRs. */
1281 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1283 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1285 /* Now, the main part of code - store PSWA, take lock, call collector,
1286 leave lock. First, we'll need to fetch 4 literals. */
1288 unsigned char buf
[] = {
1289 0x07, 0x07, /* nopr %r7 */
1290 0x07, 0x07, /* nopr %r7 */
1291 0x07, 0x07, /* nopr %r7 */
1292 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1293 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1294 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1295 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1296 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1299 /* Find the proper start place in buf, so that literals will be
1301 int bufpos
= (buildaddr
+ 2) & 7;
1302 /* Stuff the literals into the buffer. */
1303 for (i
= 0; i
< 4; i
++) {
1304 uint64_t lit
= literals
[i
];
1305 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1307 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1308 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1310 unsigned char buf
[] = {
1311 0x07, 0x07, /* nopr %r7 */
1312 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1313 0, 0, 0, 0, /* tpaddr */
1314 0, 0, 0, 0, /* tpoint */
1315 0, 0, 0, 0, /* collector */
1316 0, 0, 0, 0, /* lockaddr */
1319 /* Find the proper start place in buf, so that literals will be
1321 int bufpos
= (buildaddr
+ 2) & 3;
1322 /* First literal will be saved as the PSWA, make sure it has the high bit
1324 literals
[0] |= 0x80000000;
1325 /* Stuff the literals into the buffer. */
1326 for (i
= 0; i
< 4; i
++) {
1327 uint32_t lit
= literals
[i
];
1328 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1330 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1331 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1334 /* Restore FRs or VRs. */
1336 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1338 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1340 /* Restore misc registers. */
1341 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1343 /* Restore the GPRs. */
1345 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1346 s390_ft_exit_gpr_zarch
);
1348 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1349 s390_ft_exit_gpr_esa
);
1351 /* Now, adjust the original instruction to execute in the jump
1353 *adjusted_insn_addr
= buildaddr
;
1354 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1356 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1359 *adjusted_insn_addr_end
= buildaddr
;
1361 /* Finally, write a jump back to the program. */
1363 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1366 if (is_64
&& offset
!= loffset
)
1369 "E.Jump back from jump pad too far from tracepoint "
1370 "(offset 0x%" PRIx64
" > int33).", loffset
);
1373 memcpy (jbuf
+ 2, &offset
, 4);
1374 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1376 /* The jump pad is now built. Wire in a jump to our jump pad. This
1377 is always done last (by our caller actually), so that we can
1378 install fast tracepoints with threads running. This relies on
1379 the agent's atomic write support. */
1380 loffset
= *jump_entry
- tpaddr
;
1383 if (is_64
&& offset
!= loffset
)
1386 "E.Jump back from jump pad too far from tracepoint "
1387 "(offset 0x%" PRIx64
" > int33).", loffset
);
1390 memcpy (jbuf
+ 2, &offset
, 4);
1391 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1392 *jjump_pad_insn_size
= sizeof jbuf
;
1394 /* Return the end address of our pad. */
1395 *jump_entry
= buildaddr
;
1400 /* Implementation of linux_target_ops method
1401 "get_min_fast_tracepoint_insn_len". */
1404 s390_get_min_fast_tracepoint_insn_len (void)
1406 /* We only support using 6-byte jumps to reach the tracepoint code.
1407 If the tracepoint buffer were allocated sufficiently close (64kiB)
1408 to the executable code, and the traced instruction itself was close
1409 enough to the beginning, we could use 4-byte jumps, but this doesn't
1410 seem to be worth the effort. */
1414 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1417 s390_get_ipa_tdesc_idx (void)
1419 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1420 const struct target_desc
*tdesc
= regcache
->tdesc
;
1423 if (tdesc
== tdesc_s390x_linux64
)
1424 return S390_TDESC_64
;
1425 if (tdesc
== tdesc_s390x_linux64v1
)
1426 return S390_TDESC_64V1
;
1427 if (tdesc
== tdesc_s390x_linux64v2
)
1428 return S390_TDESC_64V2
;
1429 if (tdesc
== tdesc_s390x_te_linux64
)
1430 return S390_TDESC_TE
;
1431 if (tdesc
== tdesc_s390x_vx_linux64
)
1432 return S390_TDESC_VX
;
1433 if (tdesc
== tdesc_s390x_tevx_linux64
)
1434 return S390_TDESC_TEVX
;
1435 if (tdesc
== tdesc_s390x_gs_linux64
)
1436 return S390_TDESC_GS
;
1439 if (tdesc
== tdesc_s390_linux32
)
1440 return S390_TDESC_32
;
1441 if (tdesc
== tdesc_s390_linux32v1
)
1442 return S390_TDESC_32V1
;
1443 if (tdesc
== tdesc_s390_linux32v2
)
1444 return S390_TDESC_32V2
;
1445 if (tdesc
== tdesc_s390_linux64
)
1446 return S390_TDESC_64
;
1447 if (tdesc
== tdesc_s390_linux64v1
)
1448 return S390_TDESC_64V1
;
1449 if (tdesc
== tdesc_s390_linux64v2
)
1450 return S390_TDESC_64V2
;
1451 if (tdesc
== tdesc_s390_te_linux64
)
1452 return S390_TDESC_TE
;
1453 if (tdesc
== tdesc_s390_vx_linux64
)
1454 return S390_TDESC_VX
;
1455 if (tdesc
== tdesc_s390_tevx_linux64
)
1456 return S390_TDESC_TEVX
;
1457 if (tdesc
== tdesc_s390_gs_linux64
)
1458 return S390_TDESC_GS
;
1463 /* Appends given buffer to current_insn_ptr in the target. */
1466 add_insns (const unsigned char *start
, int len
)
1468 CORE_ADDR buildaddr
= current_insn_ptr
;
1471 debug_printf ("Adding %d bytes of insn at %s\n",
1472 len
, paddress (buildaddr
));
1474 append_insns (&buildaddr
, len
, start
);
1475 current_insn_ptr
= buildaddr
;
1478 /* Register usage in emit:
1481 - %r2: top of stack (high word for 31-bit)
1482 - %r3: low word of top of stack (for 31-bit)
1484 - %r6, %r7, %r8: don't use
1487 - %r11: frame pointer
1488 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1489 - %r13: low word of saved top of stack (for 31-bit)
1490 - %r14: return address for calls
1491 - %r15: stack pointer
1495 /* The "emit_prologue" emit_ops method for s390. */
1498 s390_emit_prologue (void)
1500 static const unsigned char buf
[] = {
1501 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1502 0x18, 0x92, /* lr %r9, %r2 */
1503 0x18, 0xa3, /* lr %r10, %r3 */
1504 0x18, 0xbf, /* lr %r11, %r15 */
1506 add_insns (buf
, sizeof buf
);
1509 /* The "emit_epilogue" emit_ops method for s390. */
1512 s390_emit_epilogue (void)
1514 static const unsigned char buf
[] = {
1515 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1516 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1517 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1518 0x07, 0xfe, /* br %r14 */
1520 add_insns (buf
, sizeof buf
);
1523 /* The "emit_add" emit_ops method for s390. */
1526 s390_emit_add (void)
1528 static const unsigned char buf
[] = {
1529 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1530 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1531 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1533 add_insns (buf
, sizeof buf
);
1536 /* The "emit_sub" emit_ops method for s390. */
1539 s390_emit_sub (void)
1541 static const unsigned char buf
[] = {
1542 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1543 0x1f, 0x53, /* slr %r5, %r3 */
1544 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1545 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1546 0x18, 0x35, /* lr %r3, %r5 */
1547 0x18, 0x24, /* lr %r2, %r4 */
1549 add_insns (buf
, sizeof buf
);
1552 /* The "emit_mul" emit_ops method for s390. */
1555 s390_emit_mul (void)
1560 /* The "emit_lsh" emit_ops method for s390. */
1563 s390_emit_lsh (void)
1565 static const unsigned char buf
[] = {
1566 0x18, 0x43, /* lr %r4, %r3 */
1567 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1568 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1569 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1571 add_insns (buf
, sizeof buf
);
1574 /* The "emit_rsh_signed" emit_ops method for s390. */
1577 s390_emit_rsh_signed (void)
1579 static const unsigned char buf
[] = {
1580 0x18, 0x43, /* lr %r4, %r3 */
1581 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1582 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1583 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1585 add_insns (buf
, sizeof buf
);
1588 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1591 s390_emit_rsh_unsigned (void)
1593 static const unsigned char buf
[] = {
1594 0x18, 0x43, /* lr %r4, %r3 */
1595 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1596 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1597 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1599 add_insns (buf
, sizeof buf
);
1602 /* The "emit_ext" emit_ops method for s390. */
1605 s390_emit_ext (int arg
)
1607 unsigned char buf
[] = {
1608 0x8d, 0x20, 0x00, 64 - arg
, /* sldl %r2, <64-arg> */
1609 0x8e, 0x20, 0x00, 64 - arg
, /* srda %r2, <64-arg> */
1611 add_insns (buf
, sizeof buf
);
1614 /* The "emit_log_not" emit_ops method for s390. */
1617 s390_emit_log_not (void)
1619 static const unsigned char buf
[] = {
1620 0x16, 0x23, /* or %r2, %r3 */
1621 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1622 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1623 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1624 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1627 add_insns (buf
, sizeof buf
);
1630 /* The "emit_bit_and" emit_ops method for s390. */
1633 s390_emit_bit_and (void)
1635 static const unsigned char buf
[] = {
1636 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1637 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1638 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1640 add_insns (buf
, sizeof buf
);
1643 /* The "emit_bit_or" emit_ops method for s390. */
1646 s390_emit_bit_or (void)
1648 static const unsigned char buf
[] = {
1649 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1650 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1651 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1653 add_insns (buf
, sizeof buf
);
1656 /* The "emit_bit_xor" emit_ops method for s390. */
1659 s390_emit_bit_xor (void)
1661 static const unsigned char buf
[] = {
1662 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1663 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1664 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1666 add_insns (buf
, sizeof buf
);
1669 /* The "emit_bit_not" emit_ops method for s390. */
1672 s390_emit_bit_not (void)
1674 static const unsigned char buf
[] = {
1675 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1676 0x17, 0x24, /* xr %r2, %r4 */
1677 0x17, 0x34, /* xr %r3, %r4 */
1679 add_insns (buf
, sizeof buf
);
1682 /* The "emit_equal" emit_ops method for s390. */
1685 s390_emit_equal (void)
1687 s390_emit_bit_xor ();
1688 s390_emit_log_not ();
1691 /* The "emit_less_signed" emit_ops method for s390. */
1694 s390_emit_less_signed (void)
1696 static const unsigned char buf
[] = {
1697 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1698 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1699 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1700 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1701 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1703 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1704 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1706 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1708 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1709 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1711 add_insns (buf
, sizeof buf
);
1714 /* The "emit_less_unsigned" emit_ops method for s390. */
1717 s390_emit_less_unsigned (void)
1719 static const unsigned char buf
[] = {
1720 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1721 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1722 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1723 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1724 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1726 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1727 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1729 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1731 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1732 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1734 add_insns (buf
, sizeof buf
);
1737 /* The "emit_ref" emit_ops method for s390. */
1740 s390_emit_ref (int size
)
1742 static const unsigned char buf1
[] = {
1743 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1744 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1746 static const unsigned char buf2
[] = {
1747 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1748 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1750 static const unsigned char buf4
[] = {
1751 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1752 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1754 static const unsigned char buf8
[] = {
1755 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1760 add_insns (buf1
, sizeof buf1
);
1763 add_insns (buf2
, sizeof buf2
);
1766 add_insns (buf4
, sizeof buf4
);
1769 add_insns (buf8
, sizeof buf8
);
1776 /* The "emit_if_goto" emit_ops method for s390. */
1779 s390_emit_if_goto (int *offset_p
, int *size_p
)
1781 static const unsigned char buf
[] = {
1782 0x16, 0x23, /* or %r2, %r3 */
1783 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1784 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1785 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1787 add_insns (buf
, sizeof buf
);
1794 /* The "emit_goto" emit_ops method for s390 and s390x. */
1797 s390_emit_goto (int *offset_p
, int *size_p
)
1799 static const unsigned char buf
[] = {
1800 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1802 add_insns (buf
, sizeof buf
);
1809 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1812 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1814 long diff
= ((long) (to
- (from
- 2))) / 2;
1816 unsigned char buf
[sizeof sdiff
];
1818 /* We're only doing 4-byte sizes at the moment. */
1819 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1825 memcpy (buf
, &sdiff
, sizeof sdiff
);
1826 write_inferior_memory (from
, buf
, sizeof sdiff
);
1829 /* Preparation for emitting a literal pool of given size. Loads the address
1830 of the pool into %r1, and jumps over it. Called should emit the pool data
1831 immediately afterwards. Used for both s390 and s390x. */
1834 s390_emit_litpool (int size
)
1836 static const unsigned char nop
[] = {
1839 unsigned char buf
[] = {
1840 0xa7, 0x15, 0x00, (size
+ 4) / 2, /* bras %r1, .Lend+size */
1845 /* buf needs to start at even halfword for litpool to be aligned */
1846 if (current_insn_ptr
& 2)
1847 add_insns (nop
, sizeof nop
);
1851 while ((current_insn_ptr
& 6) != 4)
1852 add_insns (nop
, sizeof nop
);
1854 add_insns (buf
, sizeof buf
);
1857 /* The "emit_const" emit_ops method for s390. */
1860 s390_emit_const (LONGEST num
)
1862 unsigned long long n
= num
;
1863 unsigned char buf_s
[] = {
1864 0xa7, 0x38, num
>> 8, num
, /* lhi %r3, <num> */
1865 0x17, 0x22, /* xr %r2, %r2 */
1867 static const unsigned char buf_l
[] = {
1868 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1870 if (num
< 0x8000 && num
>= 0)
1872 add_insns (buf_s
, sizeof buf_s
);
1876 s390_emit_litpool (8);
1877 add_insns ((unsigned char *) &n
, sizeof n
);
1878 add_insns (buf_l
, sizeof buf_l
);
1882 /* The "emit_call" emit_ops method for s390. */
1885 s390_emit_call (CORE_ADDR fn
)
1887 unsigned int n
= fn
;
1888 static const unsigned char buf
[] = {
1889 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1890 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1891 0x0d, 0xe1, /* basr %r14, %r1 */
1892 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1894 s390_emit_litpool (4);
1895 add_insns ((unsigned char *) &n
, sizeof n
);
1896 add_insns (buf
, sizeof buf
);
1899 /* The "emit_reg" emit_ops method for s390. */
1902 s390_emit_reg (int reg
)
1904 unsigned char bufpre
[] = {
1905 0x18, 0x29, /* lr %r2, %r9 */
1906 0xa7, 0x38, reg
>> 8, reg
, /* lhi %r3, <reg> */
1908 add_insns (bufpre
, sizeof bufpre
);
1909 s390_emit_call (get_raw_reg_func_addr ());
1912 /* The "emit_pop" emit_ops method for s390. */
1915 s390_emit_pop (void)
1917 static const unsigned char buf
[] = {
1918 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1919 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1921 add_insns (buf
, sizeof buf
);
1924 /* The "emit_stack_flush" emit_ops method for s390. */
1927 s390_emit_stack_flush (void)
1929 static const unsigned char buf
[] = {
1930 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1931 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1933 add_insns (buf
, sizeof buf
);
1936 /* The "emit_zero_ext" emit_ops method for s390. */
1939 s390_emit_zero_ext (int arg
)
1941 unsigned char buf
[] = {
1942 0x8d, 0x20, 0x00, 64 - arg
, /* sldl %r2, <64-arg> */
1943 0x8c, 0x20, 0x00, 64 - arg
, /* srdl %r2, <64-arg> */
1945 add_insns (buf
, sizeof buf
);
1948 /* The "emit_swap" emit_ops method for s390. */
1951 s390_emit_swap (void)
1953 static const unsigned char buf
[] = {
1954 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1955 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1956 0x18, 0x24, /* lr %r2, %r4 */
1957 0x18, 0x35, /* lr %r3, %r5 */
1959 add_insns (buf
, sizeof buf
);
1962 /* The "emit_stack_adjust" emit_ops method for s390. */
1965 s390_emit_stack_adjust (int n
)
1967 unsigned char buf
[] = {
1968 0xa7, 0xfa, n
* 8 >> 8, n
* 8, /* ahi %r15, 8*n */
1970 add_insns (buf
, sizeof buf
);
1973 /* Sets %r2 to a 32-bit constant. */
1976 s390_emit_set_r2 (int arg1
)
1978 unsigned char buf_s
[] = {
1979 0xa7, 0x28, arg1
>> 8, arg1
, /* lhi %r2, <arg1> */
1981 static const unsigned char buf_l
[] = {
1982 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1984 if (arg1
< 0x8000 && arg1
>= -0x8000)
1986 add_insns (buf_s
, sizeof buf_s
);
1990 s390_emit_litpool (4);
1991 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
1992 add_insns (buf_l
, sizeof buf_l
);
1996 /* The "emit_int_call_1" emit_ops method for s390. */
1999 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2001 /* FN's prototype is `LONGEST(*fn)(int)'. */
2002 s390_emit_set_r2 (arg1
);
2003 s390_emit_call (fn
);
2006 /* The "emit_void_call_2" emit_ops method for s390. */
2009 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2011 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2012 static const unsigned char buf
[] = {
2013 0x18, 0xc2, /* lr %r12, %r2 */
2014 0x18, 0xd3, /* lr %r13, %r3 */
2015 0x18, 0x43, /* lr %r4, %r3 */
2016 0x18, 0x32, /* lr %r3, %r2 */
2018 static const unsigned char buf2
[] = {
2019 0x18, 0x2c, /* lr %r2, %r12 */
2020 0x18, 0x3d, /* lr %r3, %r13 */
2022 add_insns (buf
, sizeof buf
);
2023 s390_emit_set_r2 (arg1
);
2024 s390_emit_call (fn
);
2025 add_insns (buf2
, sizeof buf2
);
2028 /* The "emit_eq_goto" emit_ops method for s390. */
2031 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2033 static const unsigned char buf
[] = {
2034 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2035 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2036 0x16, 0x23, /* or %r2, %r3 */
2037 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2038 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2039 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2041 add_insns (buf
, sizeof buf
);
2048 /* The "emit_ne_goto" emit_ops method for s390. */
2051 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2053 static const unsigned char buf
[] = {
2054 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2055 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2056 0x16, 0x23, /* or %r2, %r3 */
2057 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2058 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2059 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2061 add_insns (buf
, sizeof buf
);
2068 /* The "emit_lt_goto" emit_ops method for s390. */
2071 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2073 static const unsigned char buf
[] = {
2074 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2075 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2076 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2077 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2078 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2080 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2081 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2082 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2084 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2085 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2086 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2089 add_insns (buf
, sizeof buf
);
2096 /* The "emit_le_goto" emit_ops method for s390. */
2099 s390_emit_le_goto (int *offset_p
, int *size_p
)
2101 static const unsigned char buf
[] = {
2102 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2103 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2104 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2105 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2106 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2108 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2109 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2110 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2112 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2113 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2114 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2117 add_insns (buf
, sizeof buf
);
2124 /* The "emit_gt_goto" emit_ops method for s390. */
2127 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2129 static const unsigned char buf
[] = {
2130 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2131 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2132 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2133 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2134 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2136 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2137 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2138 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2140 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2141 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2142 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2145 add_insns (buf
, sizeof buf
);
2152 /* The "emit_ge_goto" emit_ops method for s390. */
2155 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2157 static const unsigned char buf
[] = {
2158 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2159 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2160 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2161 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2162 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2164 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2165 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2166 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2168 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2169 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2170 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2173 add_insns (buf
, sizeof buf
);
2180 /* The "emit_ops" structure for s390. Named _impl to avoid name
2181 collision with s390_emit_ops function. */
2183 static struct emit_ops s390_emit_ops_impl
=
2191 s390_emit_rsh_signed
,
2192 s390_emit_rsh_unsigned
,
2200 s390_emit_less_signed
,
2201 s390_emit_less_unsigned
,
2205 s390_write_goto_address
,
2210 s390_emit_stack_flush
,
2213 s390_emit_stack_adjust
,
2214 s390_emit_int_call_1
,
2215 s390_emit_void_call_2
,
2226 /* The "emit_prologue" emit_ops method for s390x. */
2229 s390x_emit_prologue (void)
2231 static const unsigned char buf
[] = {
2232 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2233 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2234 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2235 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2237 add_insns (buf
, sizeof buf
);
2240 /* The "emit_epilogue" emit_ops method for s390x. */
2243 s390x_emit_epilogue (void)
2245 static const unsigned char buf
[] = {
2246 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2247 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2248 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2249 0x07, 0xfe, /* br %r14 */
2251 add_insns (buf
, sizeof buf
);
2254 /* The "emit_add" emit_ops method for s390x. */
2257 s390x_emit_add (void)
2259 static const unsigned char buf
[] = {
2260 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2261 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2263 add_insns (buf
, sizeof buf
);
2266 /* The "emit_sub" emit_ops method for s390x. */
2269 s390x_emit_sub (void)
2271 static const unsigned char buf
[] = {
2272 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2273 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2274 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2275 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2277 add_insns (buf
, sizeof buf
);
2280 /* The "emit_mul" emit_ops method for s390x. */
2283 s390x_emit_mul (void)
2288 /* The "emit_lsh" emit_ops method for s390x. */
2291 s390x_emit_lsh (void)
2293 static const unsigned char buf
[] = {
2294 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2295 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2296 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2298 add_insns (buf
, sizeof buf
);
2301 /* The "emit_rsh_signed" emit_ops method for s390x. */
2304 s390x_emit_rsh_signed (void)
2306 static const unsigned char buf
[] = {
2307 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2308 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2309 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2311 add_insns (buf
, sizeof buf
);
2314 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2317 s390x_emit_rsh_unsigned (void)
2319 static const unsigned char buf
[] = {
2320 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2321 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2322 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2324 add_insns (buf
, sizeof buf
);
2327 /* The "emit_ext" emit_ops method for s390x. */
2330 s390x_emit_ext (int arg
)
2332 unsigned char buf
[] = {
2333 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2334 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0a, /* srag %r2, %r2, <64-arg> */
2336 add_insns (buf
, sizeof buf
);
2339 /* The "emit_log_not" emit_ops method for s390x. */
2342 s390x_emit_log_not (void)
2344 static const unsigned char buf
[] = {
2345 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2346 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2347 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2349 add_insns (buf
, sizeof buf
);
2352 /* The "emit_bit_and" emit_ops method for s390x. */
2355 s390x_emit_bit_and (void)
2357 static const unsigned char buf
[] = {
2358 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2359 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2361 add_insns (buf
, sizeof buf
);
2364 /* The "emit_bit_or" emit_ops method for s390x. */
2367 s390x_emit_bit_or (void)
2369 static const unsigned char buf
[] = {
2370 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2371 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2373 add_insns (buf
, sizeof buf
);
2376 /* The "emit_bit_xor" emit_ops method for s390x. */
2379 s390x_emit_bit_xor (void)
2381 static const unsigned char buf
[] = {
2382 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2383 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2385 add_insns (buf
, sizeof buf
);
2388 /* The "emit_bit_not" emit_ops method for s390x. */
2391 s390x_emit_bit_not (void)
2393 static const unsigned char buf
[] = {
2394 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2395 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2397 add_insns (buf
, sizeof buf
);
2400 /* The "emit_equal" emit_ops method for s390x. */
2403 s390x_emit_equal (void)
2405 s390x_emit_bit_xor ();
2406 s390x_emit_log_not ();
2409 /* The "emit_less_signed" emit_ops method for s390x. */
2412 s390x_emit_less_signed (void)
2414 static const unsigned char buf
[] = {
2415 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2416 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2417 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2418 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2420 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2422 add_insns (buf
, sizeof buf
);
2425 /* The "emit_less_unsigned" emit_ops method for s390x. */
2428 s390x_emit_less_unsigned (void)
2430 static const unsigned char buf
[] = {
2431 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2432 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2433 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2434 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2436 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2438 add_insns (buf
, sizeof buf
);
2441 /* The "emit_ref" emit_ops method for s390x. */
2444 s390x_emit_ref (int size
)
2446 static const unsigned char buf1
[] = {
2447 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2449 static const unsigned char buf2
[] = {
2450 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2452 static const unsigned char buf4
[] = {
2453 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2455 static const unsigned char buf8
[] = {
2456 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2461 add_insns (buf1
, sizeof buf1
);
2464 add_insns (buf2
, sizeof buf2
);
2467 add_insns (buf4
, sizeof buf4
);
2470 add_insns (buf8
, sizeof buf8
);
2477 /* The "emit_if_goto" emit_ops method for s390x. */
2480 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2482 static const unsigned char buf
[] = {
2483 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2484 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2485 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2486 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2488 add_insns (buf
, sizeof buf
);
2495 /* The "emit_const" emit_ops method for s390x. */
2498 s390x_emit_const (LONGEST num
)
2500 unsigned long long n
= num
;
2501 unsigned char buf_s
[] = {
2502 0xa7, 0x29, num
>> 8, num
, /* lghi %r2, <num> */
2504 static const unsigned char buf_l
[] = {
2505 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2507 if (num
< 0x8000 && num
>= -0x8000)
2509 add_insns (buf_s
, sizeof buf_s
);
2513 s390_emit_litpool (8);
2514 add_insns ((unsigned char *) &n
, sizeof n
);
2515 add_insns (buf_l
, sizeof buf_l
);
2519 /* The "emit_call" emit_ops method for s390x. */
2522 s390x_emit_call (CORE_ADDR fn
)
2524 unsigned long n
= fn
;
2525 static const unsigned char buf
[] = {
2526 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2527 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2528 0x0d, 0xe1, /* basr %r14, %r1 */
2529 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2531 s390_emit_litpool (8);
2532 add_insns ((unsigned char *) &n
, sizeof n
);
2533 add_insns (buf
, sizeof buf
);
2536 /* The "emit_reg" emit_ops method for s390x. */
2539 s390x_emit_reg (int reg
)
2541 unsigned char buf
[] = {
2542 0xb9, 0x04, 0x00, 0x29, /* lgr %r2, %r9 */
2543 0xa7, 0x39, reg
>> 8, reg
, /* lghi %r3, <reg> */
2545 add_insns (buf
, sizeof buf
);
2546 s390x_emit_call (get_raw_reg_func_addr ());
2549 /* The "emit_pop" emit_ops method for s390x. */
2552 s390x_emit_pop (void)
2554 static const unsigned char buf
[] = {
2555 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2556 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2558 add_insns (buf
, sizeof buf
);
2561 /* The "emit_stack_flush" emit_ops method for s390x. */
2564 s390x_emit_stack_flush (void)
2566 static const unsigned char buf
[] = {
2567 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2568 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2570 add_insns (buf
, sizeof buf
);
2573 /* The "emit_zero_ext" emit_ops method for s390x. */
2576 s390x_emit_zero_ext (int arg
)
2578 unsigned char buf
[] = {
2579 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2580 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0c, /* srlg %r2, %r2, <64-arg> */
2582 add_insns (buf
, sizeof buf
);
2585 /* The "emit_swap" emit_ops method for s390x. */
2588 s390x_emit_swap (void)
2590 static const unsigned char buf
[] = {
2591 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2592 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2593 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2595 add_insns (buf
, sizeof buf
);
2598 /* The "emit_stack_adjust" emit_ops method for s390x. */
2601 s390x_emit_stack_adjust (int n
)
2603 unsigned char buf
[] = {
2604 0xa7, 0xfb, n
* 8 >> 8, n
* 8, /* aghi %r15, 8*n */
2606 add_insns (buf
, sizeof buf
);
2609 /* The "emit_int_call_1" emit_ops method for s390x. */
2612 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2614 /* FN's prototype is `LONGEST(*fn)(int)'. */
2615 s390x_emit_const (arg1
);
2616 s390x_emit_call (fn
);
2619 /* The "emit_void_call_2" emit_ops method for s390x. */
2622 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2624 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2625 static const unsigned char buf
[] = {
2626 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2627 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2629 static const unsigned char buf2
[] = {
2630 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2632 add_insns (buf
, sizeof buf
);
2633 s390x_emit_const (arg1
);
2634 s390x_emit_call (fn
);
2635 add_insns (buf2
, sizeof buf2
);
2638 /* The "emit_eq_goto" emit_ops method for s390x. */
2641 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2643 static const unsigned char buf
[] = {
2644 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2645 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2646 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2647 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2649 add_insns (buf
, sizeof buf
);
2656 /* The "emit_ne_goto" emit_ops method for s390x. */
2659 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2661 static const unsigned char buf
[] = {
2662 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2663 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2664 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2665 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2667 add_insns (buf
, sizeof buf
);
2674 /* The "emit_lt_goto" emit_ops method for s390x. */
2677 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2679 static const unsigned char buf
[] = {
2680 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2681 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2682 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2683 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2685 add_insns (buf
, sizeof buf
);
2692 /* The "emit_le_goto" emit_ops method for s390x. */
2695 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2697 static const unsigned char buf
[] = {
2698 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2699 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2700 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2701 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2703 add_insns (buf
, sizeof buf
);
2710 /* The "emit_gt_goto" emit_ops method for s390x. */
2713 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2715 static const unsigned char buf
[] = {
2716 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2717 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2718 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2719 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2721 add_insns (buf
, sizeof buf
);
2728 /* The "emit_ge_goto" emit_ops method for s390x. */
2731 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2733 static const unsigned char buf
[] = {
2734 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2735 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2736 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2737 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2739 add_insns (buf
, sizeof buf
);
2746 /* The "emit_ops" structure for s390x. */
2748 static struct emit_ops s390x_emit_ops
=
2750 s390x_emit_prologue
,
2751 s390x_emit_epilogue
,
2756 s390x_emit_rsh_signed
,
2757 s390x_emit_rsh_unsigned
,
2765 s390x_emit_less_signed
,
2766 s390x_emit_less_unsigned
,
2770 s390_write_goto_address
,
2775 s390x_emit_stack_flush
,
2776 s390x_emit_zero_ext
,
2778 s390x_emit_stack_adjust
,
2779 s390x_emit_int_call_1
,
2780 s390x_emit_void_call_2
,
2790 /* The "emit_ops" linux_target_ops method. */
2792 static struct emit_ops
*
2793 s390_emit_ops (void)
2796 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2798 if (register_size (regcache
->tdesc
, 0) == 8)
2799 return &s390x_emit_ops
;
2802 return &s390_emit_ops_impl
;
2805 struct linux_target_ops the_low_target
= {
2808 s390_cannot_fetch_register
,
2809 s390_cannot_store_register
,
2810 NULL
, /* fetch_register */
2813 NULL
, /* breakpoint_kind_from_pc */
2814 s390_sw_breakpoint_from_kind
,
2816 s390_breakpoint_len
,
2818 s390_supports_z_point_type
,
2823 s390_collect_ptrace_register
,
2824 s390_supply_ptrace_register
,
2825 NULL
, /* siginfo_fixup */
2826 NULL
, /* new_process */
2827 NULL
, /* delete_process */
2828 NULL
, /* new_thread */
2829 NULL
, /* delete_thread */
2830 NULL
, /* new_fork */
2831 NULL
, /* prepare_to_resume */
2832 NULL
, /* process_qsupported */
2833 s390_supports_tracepoints
,
2834 s390_get_thread_area
,
2835 s390_install_fast_tracepoint_jump_pad
,
2837 s390_get_min_fast_tracepoint_insn_len
,
2838 NULL
, /* supports_range_stepping */
2839 NULL
, /* breakpoint_kind_from_current_state */
2840 s390_supports_hardware_single_step
,
2841 NULL
, /* get_syscall_trapinfo */
2842 s390_get_ipa_tdesc_idx
,
2846 initialize_low_arch (void)
2848 /* Initialize the Linux target descriptions. */
2850 init_registers_s390_linux32 ();
2851 init_registers_s390_linux32v1 ();
2852 init_registers_s390_linux32v2 ();
2853 init_registers_s390_linux64 ();
2854 init_registers_s390_linux64v1 ();
2855 init_registers_s390_linux64v2 ();
2856 init_registers_s390_te_linux64 ();
2857 init_registers_s390_vx_linux64 ();
2858 init_registers_s390_tevx_linux64 ();
2859 init_registers_s390_gs_linux64 ();
2861 init_registers_s390x_linux64 ();
2862 init_registers_s390x_linux64v1 ();
2863 init_registers_s390x_linux64v2 ();
2864 init_registers_s390x_te_linux64 ();
2865 init_registers_s390x_vx_linux64 ();
2866 init_registers_s390x_tevx_linux64 ();
2867 init_registers_s390x_gs_linux64 ();
2870 initialize_regsets_info (&s390_regsets_info
);
2871 initialize_regsets_info (&s390_regsets_info_3264
);