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_fill_gs (struct regcache
*regcache
, void *buf
)
380 int gsd
= find_regno (regcache
->tdesc
, "gsd");
383 for (i
= 0; i
< 3; i
++)
384 collect_register (regcache
, gsd
+ i
, (char *) buf
+ 8 * (i
+ 1));
388 s390_store_gs (struct regcache
*regcache
, const void *buf
)
390 int gsd
= find_regno (regcache
->tdesc
, "gsd");
393 for (i
= 0; i
< 3; i
++)
394 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
398 s390_fill_gsbc (struct regcache
*regcache
, void *buf
)
400 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
403 for (i
= 0; i
< 3; i
++)
404 collect_register (regcache
, bc_gsd
+ i
, (char *) buf
+ 8 * (i
+ 1));
408 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
410 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
413 for (i
= 0; i
< 3; i
++)
414 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
417 static struct regset_info s390_regsets
[] = {
418 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
420 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
421 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
423 /* Last break address is read-only; no fill function. */
424 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
425 NULL
, s390_store_last_break
},
426 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
427 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
428 /* TDB is read-only. */
429 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
430 NULL
, s390_store_tdb
},
431 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
432 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
433 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
434 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
435 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_GS_CB
, 0,
436 EXTENDED_REGS
, s390_fill_gs
, s390_store_gs
},
437 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_GS_BC
, 0,
438 EXTENDED_REGS
, s390_fill_gsbc
, s390_store_gsbc
},
443 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
444 #define s390_breakpoint_len 2
446 /* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
448 static const gdb_byte
*
449 s390_sw_breakpoint_from_kind (int kind
, int *size
)
451 *size
= s390_breakpoint_len
;
452 return s390_breakpoint
;
456 s390_get_pc (struct regcache
*regcache
)
458 if (register_size (regcache
->tdesc
, 0) == 4)
461 collect_register_by_name (regcache
, "pswa", &pswa
);
462 return pswa
& 0x7fffffff;
467 collect_register_by_name (regcache
, "pswa", &pc
);
473 s390_set_pc (struct regcache
*regcache
, CORE_ADDR newpc
)
475 if (register_size (regcache
->tdesc
, 0) == 4)
478 collect_register_by_name (regcache
, "pswa", &pswa
);
479 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
480 supply_register_by_name (regcache
, "pswa", &pswa
);
484 unsigned long pc
= newpc
;
485 supply_register_by_name (regcache
, "pswa", &pc
);
489 /* Get HWCAP from AUXV, using the given WORDSIZE. Return the HWCAP, or
490 zero if not found. */
493 s390_get_hwcap (int wordsize
)
495 gdb_byte
*data
= (gdb_byte
*) alloca (2 * wordsize
);
498 while ((*the_target
->read_auxv
) (offset
, data
, 2 * wordsize
) == 2 * wordsize
)
502 unsigned int *data_p
= (unsigned int *)data
;
503 if (data_p
[0] == AT_HWCAP
)
508 unsigned long *data_p
= (unsigned long *)data
;
509 if (data_p
[0] == AT_HWCAP
)
513 offset
+= 2 * wordsize
;
519 /* Determine the word size for the given PID, in bytes. */
523 s390_get_wordsize (int pid
)
526 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
527 (PTRACE_TYPE_ARG3
) 0,
528 (PTRACE_TYPE_ARG4
) 0);
530 warning (_("Couldn't determine word size, assuming 64-bit.\n"));
533 /* Derive word size from extended addressing mode (PSW bit 31). */
534 return pswm
& (1L << 32) ? 8 : 4;
537 #define s390_get_wordsize(pid) 4
541 s390_check_regset (int pid
, int regset
, int regsize
)
543 void *buf
= alloca (regsize
);
547 iov
.iov_len
= regsize
;
549 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
555 /* For a 31-bit inferior, whether the kernel supports using the full
557 static int have_hwcap_s390_high_gprs
= 0;
558 static int have_hwcap_s390_vx
= 0;
561 s390_arch_setup (void)
563 const struct target_desc
*tdesc
;
564 struct regset_info
*regset
;
566 /* Determine word size and HWCAP. */
567 int pid
= pid_of (current_thread
);
568 int wordsize
= s390_get_wordsize (pid
);
569 unsigned long hwcap
= s390_get_hwcap (wordsize
);
571 /* Check whether the kernel supports extra register sets. */
572 int have_regset_last_break
573 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
574 int have_regset_system_call
575 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
577 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
578 && (hwcap
& HWCAP_S390_TE
) != 0);
580 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
581 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
582 && (hwcap
& HWCAP_S390_VX
) != 0);
584 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
585 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
586 && (hwcap
& HWCAP_S390_GS
) != 0);
593 tdesc
= tdesc_s390x_gs_linux64
;
594 else if (have_regset_vxrs
)
595 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
596 tdesc_s390x_vx_linux64
);
597 else if (have_regset_tdb
)
598 tdesc
= tdesc_s390x_te_linux64
;
599 else if (have_regset_system_call
)
600 tdesc
= tdesc_s390x_linux64v2
;
601 else if (have_regset_last_break
)
602 tdesc
= tdesc_s390x_linux64v1
;
604 tdesc
= tdesc_s390x_linux64
;
607 /* For a 31-bit inferior, check whether the kernel supports
608 using the full 64-bit GPRs. */
611 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
613 have_hwcap_s390_high_gprs
= 1;
615 tdesc
= tdesc_s390_gs_linux64
;
616 else if (have_regset_vxrs
)
617 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
618 tdesc_s390_vx_linux64
);
619 else if (have_regset_tdb
)
620 tdesc
= tdesc_s390_te_linux64
;
621 else if (have_regset_system_call
)
622 tdesc
= tdesc_s390_linux64v2
;
623 else if (have_regset_last_break
)
624 tdesc
= tdesc_s390_linux64v1
;
626 tdesc
= tdesc_s390_linux64
;
630 /* Assume 31-bit inferior process. */
631 if (have_regset_system_call
)
632 tdesc
= tdesc_s390_linux32v2
;
633 else if (have_regset_last_break
)
634 tdesc
= tdesc_s390_linux32v1
;
636 tdesc
= tdesc_s390_linux32
;
639 have_hwcap_s390_vx
= have_regset_vxrs
;
642 /* Update target_regsets according to available register sets. */
643 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
644 if (regset
->get_request
== PTRACE_GETREGSET
)
645 switch (regset
->nt_type
)
648 case NT_S390_HIGH_GPRS
:
649 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
652 case NT_S390_LAST_BREAK
:
653 regset
->size
= have_regset_last_break
? 8 : 0;
655 case NT_S390_SYSTEM_CALL
:
656 regset
->size
= have_regset_system_call
? 4 : 0;
659 regset
->size
= have_regset_tdb
? 256 : 0;
661 case NT_S390_VXRS_LOW
:
662 regset
->size
= have_regset_vxrs
? 128 : 0;
664 case NT_S390_VXRS_HIGH
:
665 regset
->size
= have_regset_vxrs
? 256 : 0;
669 regset
->size
= have_regset_gs
? 32 : 0;
674 current_process ()->tdesc
= tdesc
;
679 s390_breakpoint_at (CORE_ADDR pc
)
681 unsigned char c
[s390_breakpoint_len
];
682 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
683 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
686 /* Breakpoint/Watchpoint support. */
688 /* The "supports_z_point_type" linux_target_ops method. */
691 s390_supports_z_point_type (char z_type
)
702 /* Support for hardware single step. */
705 s390_supports_hardware_single_step (void)
710 static struct usrregs_info s390_usrregs_info
=
716 static struct regsets_info s390_regsets_info
=
718 s390_regsets
, /* regsets */
720 NULL
, /* disabled_regsets */
723 static struct regs_info regs_info
=
725 NULL
, /* regset_bitmap */
730 static struct usrregs_info s390_usrregs_info_3264
=
736 static struct regsets_info s390_regsets_info_3264
=
738 s390_regsets
, /* regsets */
740 NULL
, /* disabled_regsets */
743 static struct regs_info regs_info_3264
=
745 NULL
, /* regset_bitmap */
746 &s390_usrregs_info_3264
,
747 &s390_regsets_info_3264
750 static const struct regs_info
*
751 s390_regs_info (void)
753 if (have_hwcap_s390_high_gprs
)
756 const struct target_desc
*tdesc
= current_process ()->tdesc
;
758 if (register_size (tdesc
, 0) == 4)
759 return ®s_info_3264
;
761 return ®s_info_3264
;
767 /* The "supports_tracepoints" linux_target_ops method. */
770 s390_supports_tracepoints (void)
775 /* Implementation of linux_target_ops method "get_thread_area". */
778 s390_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
780 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
782 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
784 if (register_size (regcache
->tdesc
, 0) == 4)
785 res
&= 0xffffffffull
;
792 /* Fast tracepoint support.
794 The register save area on stack is identical for all targets:
796 0x000+i*0x10: VR0-VR31
803 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
804 Likewise, if there's no VX support, we just store the FRs into the slots
805 of low VR halves. The agent code is responsible for rearranging that
808 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
809 one trick used at the very beginning: since there's no way to allocate
810 stack space without destroying CC (lay instruction can do it, but it's
811 only supported on later CPUs), we take 4 different execution paths for
812 every possible value of CC, allocate stack space, save %r0, stuff the
813 CC value in %r0 (shifted to match its position in PSWM high word),
814 then branch to common path. */
816 static const unsigned char s390_ft_entry_gpr_esa
[] = {
817 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
818 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
819 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
821 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
822 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
823 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
824 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
826 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
827 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
828 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
829 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
831 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
832 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
833 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
834 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
836 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
837 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
838 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
840 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
841 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
842 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
843 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
844 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
845 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
846 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
847 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
848 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
849 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
850 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
851 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
852 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
853 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
854 /* Compute original value of %r15 and store it. We use ahi instead
855 of la to preserve the whole value, and not just the low 31 bits.
856 This is not particularly important here, but essential in the
857 zarch case where someone might be using the high word of %r15
858 as an extra register. */
859 0x18, 0x1f, /* lr %r1, %r15 */
860 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
861 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
864 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
865 target. Same as above, except this time we can use load/store multiple,
866 since the 64-bit regs are tightly packed. */
868 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
869 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
870 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
871 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
873 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
874 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
875 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
876 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
878 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
879 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
880 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
881 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
883 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
884 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
885 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
886 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
888 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
889 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
890 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
892 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
893 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
894 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
897 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
898 current PSWM (read by epsw) and CC from entry (in %r0). */
900 static const unsigned char s390_ft_entry_misc
[] = {
901 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
902 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
903 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
904 0x14, 0x21, /* nr %r2, %r1 */
905 0x16, 0x20, /* or %r2, %r0 */
906 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
907 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
908 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
911 /* Code sequence saving FRs, used if VX not supported. */
913 static const unsigned char s390_ft_entry_fr
[] = {
914 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
915 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
916 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
917 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
918 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
919 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
920 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
921 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
922 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
923 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
924 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
925 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
926 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
927 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
928 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
929 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
932 /* Code sequence saving VRs, used if VX not supported. */
934 static const unsigned char s390_ft_entry_vr
[] = {
935 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
936 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
939 /* Code sequence doing the collection call for 31-bit target. %r1 contains
940 the address of the literal pool. */
942 static const unsigned char s390_ft_main_31
[] = {
943 /* Load the literals into registers. */
944 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
945 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
946 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
947 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
948 /* Save original PSWA (tracepoint address | 0x80000000). */
949 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
950 /* Construct a collecting_t object at %r15+0x2e0. */
951 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
952 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
953 /* Move its address to %r0. */
954 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
957 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
958 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
959 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
960 /* Address of the register save block to %r3. */
961 0x18, 0x3f, /* lr %r3, %r15 */
962 /* Make a stack frame, so that we can call the collector. */
963 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
965 0x0d, 0xe4, /* basr %r14, %r4 */
966 /* And get rid of the stack frame again. */
967 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
968 /* Leave the lock. */
969 0x07, 0xf0, /* br %r0 */
970 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
971 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
974 /* Code sequence doing the collection call for 64-bit target. %r1 contains
975 the address of the literal pool. */
977 static const unsigned char s390_ft_main_64
[] = {
978 /* Load the literals into registers. */
979 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
980 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
981 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
982 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
983 /* Save original PSWA (tracepoint address). */
984 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
985 /* Construct a collecting_t object at %r15+0x2e0. */
986 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
987 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
988 /* Move its address to %r0. */
989 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
992 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
993 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
994 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
995 /* Address of the register save block to %r3. */
996 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
997 /* Make a stack frame, so that we can call the collector. */
998 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1000 0x0d, 0xe4, /* basr %r14, %r4 */
1001 /* And get rid of the stack frame again. */
1002 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1003 /* Leave the lock. */
1004 0x07, 0xf0, /* br %r0 */
1005 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1006 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1009 /* Code sequence restoring FRs, for targets with no VX support. */
1011 static const unsigned char s390_ft_exit_fr
[] = {
1012 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1013 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1014 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1015 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1016 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1017 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1018 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1019 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1020 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1021 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1022 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1023 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1024 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1025 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1026 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1027 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1030 /* Code sequence restoring VRs. */
1032 static const unsigned char s390_ft_exit_vr
[] = {
1033 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1034 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1037 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1038 modified by C code, so we use the alr instruction to restore it by
1039 manufacturing an operand that'll result in the original flags. */
1041 static const unsigned char s390_ft_exit_misc
[] = {
1042 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1043 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1044 /* Extract CC to high 2 bits of %r0. */
1045 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1046 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1047 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1048 will have carry iff CC bit 1 is set - resulting in the same flags
1050 0x1e, 0x00, /* alr %r0, %r0 */
1051 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1054 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1056 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1057 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1058 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1059 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1060 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1061 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1062 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1063 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1064 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1065 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1066 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1067 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1068 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1069 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1070 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1071 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1072 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1075 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1078 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1079 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1082 /* Writes instructions to target, updating the to pointer. */
1085 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1087 write_inferior_memory (*to
, buf
, len
);
1091 /* Relocates an instruction from oldloc to *to, updating to. */
1094 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1099 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1102 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1105 else if (buf
[0] < 0xc0)
1111 case 0x05: /* BALR */
1112 case 0x0c: /* BASSM */
1113 case 0x0d: /* BASR */
1114 case 0x45: /* BAL */
1115 case 0x4d: /* BAS */
1116 /* These save a return address and mess around with registers.
1117 We can't relocate them. */
1119 case 0x84: /* BRXH */
1120 case 0x85: /* BRXLE */
1125 /* BRC, BRAS, BRCT, BRCTG */
1126 if (op2
>= 4 && op2
<= 7)
1134 /* LARL, BRCL, BRASL */
1135 if (op2
== 0 || op2
== 4 || op2
== 5)
1143 /* PC-relative addressing instructions. */
1146 case 0xc5: /* BPRP */
1147 case 0xc7: /* BPP */
1148 /* Branch prediction - just skip it. */
1160 case 0x44: /* BRXHG */
1161 case 0x45: /* BRXLG */
1162 case 0x64: /* CGRJ */
1163 case 0x65: /* CLGRJ */
1164 case 0x76: /* CRJ */
1165 case 0x77: /* CLRJ */
1174 /* We'll have to relocate an instruction with a PC-relative field.
1175 First, compute the target. */
1176 int64_t loffset
= 0;
1180 int16_t soffset
= 0;
1181 memcpy (&soffset
, buf
+ 2, 2);
1186 int32_t soffset
= 0;
1187 memcpy (&soffset
, buf
+ 2, 4);
1190 target
= oldloc
+ loffset
* 2;
1192 target
&= 0x7fffffff;
1196 /* BRAS or BRASL was used. We cannot just relocate those, since
1197 they save the return address in a register. We can, however,
1198 replace them with a LARL+JG sequence. */
1200 /* Make the LARL. */
1204 loffset
= oldloc
+ ilen
- *to
;
1207 if (soffset
!= loffset
&& is_64
)
1209 memcpy (buf
+ 2, &soffset
, 4);
1210 append_insns (to
, 6, buf
);
1212 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1213 an address with the top bit 0, while BRAS/BRASL will write it
1214 with top bit 1. It should not matter much, since linux compilers
1215 use BR and not BSM to return from functions, but it could confuse
1216 some poor stack unwinder. */
1218 /* We'll now be writing a JG. */
1225 /* Compute the new offset and write it to the buffer. */
1226 loffset
= target
- *to
;
1231 int16_t soffset
= loffset
;
1232 if (soffset
!= loffset
)
1234 memcpy (buf
+ 2, &soffset
, 2);
1238 int32_t soffset
= loffset
;
1239 if (soffset
!= loffset
&& is_64
)
1241 memcpy (buf
+ 2, &soffset
, 4);
1244 append_insns (to
, ilen
, buf
);
1248 /* Implementation of linux_target_ops method
1249 "install_fast_tracepoint_jump_pad". */
1252 s390_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint
,
1254 CORE_ADDR collector
,
1257 CORE_ADDR
*jump_entry
,
1258 CORE_ADDR
*trampoline
,
1259 ULONGEST
*trampoline_size
,
1260 unsigned char *jjump_pad_insn
,
1261 ULONGEST
*jjump_pad_insn_size
,
1262 CORE_ADDR
*adjusted_insn_addr
,
1263 CORE_ADDR
*adjusted_insn_addr_end
,
1269 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1270 CORE_ADDR buildaddr
= *jump_entry
;
1272 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1273 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1274 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1275 int has_vx
= have_hwcap_s390_vx
;
1277 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1279 CORE_ADDR literals
[4] = {
1286 /* First, store the GPRs. */
1288 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1289 s390_ft_entry_gpr_zarch
);
1291 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1292 s390_ft_entry_gpr_esa
);
1294 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1295 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1297 /* Third, FRs or VRs. */
1299 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1301 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1303 /* Now, the main part of code - store PSWA, take lock, call collector,
1304 leave lock. First, we'll need to fetch 4 literals. */
1306 unsigned char buf
[] = {
1307 0x07, 0x07, /* nopr %r7 */
1308 0x07, 0x07, /* nopr %r7 */
1309 0x07, 0x07, /* nopr %r7 */
1310 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1311 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1312 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1313 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1314 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1317 /* Find the proper start place in buf, so that literals will be
1319 int bufpos
= (buildaddr
+ 2) & 7;
1320 /* Stuff the literals into the buffer. */
1321 for (i
= 0; i
< 4; i
++) {
1322 uint64_t lit
= literals
[i
];
1323 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1325 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1326 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1328 unsigned char buf
[] = {
1329 0x07, 0x07, /* nopr %r7 */
1330 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1331 0, 0, 0, 0, /* tpaddr */
1332 0, 0, 0, 0, /* tpoint */
1333 0, 0, 0, 0, /* collector */
1334 0, 0, 0, 0, /* lockaddr */
1337 /* Find the proper start place in buf, so that literals will be
1339 int bufpos
= (buildaddr
+ 2) & 3;
1340 /* First literal will be saved as the PSWA, make sure it has the high bit
1342 literals
[0] |= 0x80000000;
1343 /* Stuff the literals into the buffer. */
1344 for (i
= 0; i
< 4; i
++) {
1345 uint32_t lit
= literals
[i
];
1346 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1348 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1349 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1352 /* Restore FRs or VRs. */
1354 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1356 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1358 /* Restore misc registers. */
1359 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1361 /* Restore the GPRs. */
1363 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1364 s390_ft_exit_gpr_zarch
);
1366 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1367 s390_ft_exit_gpr_esa
);
1369 /* Now, adjust the original instruction to execute in the jump
1371 *adjusted_insn_addr
= buildaddr
;
1372 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1374 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1377 *adjusted_insn_addr_end
= buildaddr
;
1379 /* Finally, write a jump back to the program. */
1381 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1384 if (is_64
&& offset
!= loffset
)
1387 "E.Jump back from jump pad too far from tracepoint "
1388 "(offset 0x%" PRIx64
" > int33).", loffset
);
1391 memcpy (jbuf
+ 2, &offset
, 4);
1392 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1394 /* The jump pad is now built. Wire in a jump to our jump pad. This
1395 is always done last (by our caller actually), so that we can
1396 install fast tracepoints with threads running. This relies on
1397 the agent's atomic write support. */
1398 loffset
= *jump_entry
- tpaddr
;
1401 if (is_64
&& offset
!= loffset
)
1404 "E.Jump back from jump pad too far from tracepoint "
1405 "(offset 0x%" PRIx64
" > int33).", loffset
);
1408 memcpy (jbuf
+ 2, &offset
, 4);
1409 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1410 *jjump_pad_insn_size
= sizeof jbuf
;
1412 /* Return the end address of our pad. */
1413 *jump_entry
= buildaddr
;
1418 /* Implementation of linux_target_ops method
1419 "get_min_fast_tracepoint_insn_len". */
1422 s390_get_min_fast_tracepoint_insn_len (void)
1424 /* We only support using 6-byte jumps to reach the tracepoint code.
1425 If the tracepoint buffer were allocated sufficiently close (64kiB)
1426 to the executable code, and the traced instruction itself was close
1427 enough to the beginning, we could use 4-byte jumps, but this doesn't
1428 seem to be worth the effort. */
1432 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1435 s390_get_ipa_tdesc_idx (void)
1437 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1438 const struct target_desc
*tdesc
= regcache
->tdesc
;
1441 if (tdesc
== tdesc_s390x_linux64
)
1442 return S390_TDESC_64
;
1443 if (tdesc
== tdesc_s390x_linux64v1
)
1444 return S390_TDESC_64V1
;
1445 if (tdesc
== tdesc_s390x_linux64v2
)
1446 return S390_TDESC_64V2
;
1447 if (tdesc
== tdesc_s390x_te_linux64
)
1448 return S390_TDESC_TE
;
1449 if (tdesc
== tdesc_s390x_vx_linux64
)
1450 return S390_TDESC_VX
;
1451 if (tdesc
== tdesc_s390x_tevx_linux64
)
1452 return S390_TDESC_TEVX
;
1455 if (tdesc
== tdesc_s390_linux32
)
1456 return S390_TDESC_32
;
1457 if (tdesc
== tdesc_s390_linux32v1
)
1458 return S390_TDESC_32V1
;
1459 if (tdesc
== tdesc_s390_linux32v2
)
1460 return S390_TDESC_32V2
;
1461 if (tdesc
== tdesc_s390_linux64
)
1462 return S390_TDESC_64
;
1463 if (tdesc
== tdesc_s390_linux64v1
)
1464 return S390_TDESC_64V1
;
1465 if (tdesc
== tdesc_s390_linux64v2
)
1466 return S390_TDESC_64V2
;
1467 if (tdesc
== tdesc_s390_te_linux64
)
1468 return S390_TDESC_TE
;
1469 if (tdesc
== tdesc_s390_vx_linux64
)
1470 return S390_TDESC_VX
;
1471 if (tdesc
== tdesc_s390_tevx_linux64
)
1472 return S390_TDESC_TEVX
;
1477 /* Appends given buffer to current_insn_ptr in the target. */
1480 add_insns (const unsigned char *start
, int len
)
1482 CORE_ADDR buildaddr
= current_insn_ptr
;
1485 debug_printf ("Adding %d bytes of insn at %s\n",
1486 len
, paddress (buildaddr
));
1488 append_insns (&buildaddr
, len
, start
);
1489 current_insn_ptr
= buildaddr
;
1492 /* Register usage in emit:
1495 - %r2: top of stack (high word for 31-bit)
1496 - %r3: low word of top of stack (for 31-bit)
1498 - %r6, %r7, %r8: don't use
1501 - %r11: frame pointer
1502 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1503 - %r13: low word of saved top of stack (for 31-bit)
1504 - %r14: return address for calls
1505 - %r15: stack pointer
1509 /* The "emit_prologue" emit_ops method for s390. */
1512 s390_emit_prologue (void)
1514 static const unsigned char buf
[] = {
1515 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1516 0x18, 0x92, /* lr %r9, %r2 */
1517 0x18, 0xa3, /* lr %r10, %r3 */
1518 0x18, 0xbf, /* lr %r11, %r15 */
1520 add_insns (buf
, sizeof buf
);
1523 /* The "emit_epilogue" emit_ops method for s390. */
1526 s390_emit_epilogue (void)
1528 static const unsigned char buf
[] = {
1529 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1530 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1531 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1532 0x07, 0xfe, /* br %r14 */
1534 add_insns (buf
, sizeof buf
);
1537 /* The "emit_add" emit_ops method for s390. */
1540 s390_emit_add (void)
1542 static const unsigned char buf
[] = {
1543 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1544 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1545 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1547 add_insns (buf
, sizeof buf
);
1550 /* The "emit_sub" emit_ops method for s390. */
1553 s390_emit_sub (void)
1555 static const unsigned char buf
[] = {
1556 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1557 0x1f, 0x53, /* slr %r5, %r3 */
1558 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1559 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1560 0x18, 0x35, /* lr %r3, %r5 */
1561 0x18, 0x24, /* lr %r2, %r4 */
1563 add_insns (buf
, sizeof buf
);
1566 /* The "emit_mul" emit_ops method for s390. */
1569 s390_emit_mul (void)
1574 /* The "emit_lsh" emit_ops method for s390. */
1577 s390_emit_lsh (void)
1579 static const unsigned char buf
[] = {
1580 0x18, 0x43, /* lr %r4, %r3 */
1581 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1582 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1583 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1585 add_insns (buf
, sizeof buf
);
1588 /* The "emit_rsh_signed" emit_ops method for s390. */
1591 s390_emit_rsh_signed (void)
1593 static const unsigned char buf
[] = {
1594 0x18, 0x43, /* lr %r4, %r3 */
1595 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1596 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1597 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1599 add_insns (buf
, sizeof buf
);
1602 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1605 s390_emit_rsh_unsigned (void)
1607 static const unsigned char buf
[] = {
1608 0x18, 0x43, /* lr %r4, %r3 */
1609 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1610 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1611 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1613 add_insns (buf
, sizeof buf
);
1616 /* The "emit_ext" emit_ops method for s390. */
1619 s390_emit_ext (int arg
)
1621 unsigned char buf
[] = {
1622 0x8d, 0x20, 0x00, 64 - arg
, /* sldl %r2, <64-arg> */
1623 0x8e, 0x20, 0x00, 64 - arg
, /* srda %r2, <64-arg> */
1625 add_insns (buf
, sizeof buf
);
1628 /* The "emit_log_not" emit_ops method for s390. */
1631 s390_emit_log_not (void)
1633 static const unsigned char buf
[] = {
1634 0x16, 0x23, /* or %r2, %r3 */
1635 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1636 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1637 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1638 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1641 add_insns (buf
, sizeof buf
);
1644 /* The "emit_bit_and" emit_ops method for s390. */
1647 s390_emit_bit_and (void)
1649 static const unsigned char buf
[] = {
1650 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1651 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1652 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1654 add_insns (buf
, sizeof buf
);
1657 /* The "emit_bit_or" emit_ops method for s390. */
1660 s390_emit_bit_or (void)
1662 static const unsigned char buf
[] = {
1663 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1664 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1665 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1667 add_insns (buf
, sizeof buf
);
1670 /* The "emit_bit_xor" emit_ops method for s390. */
1673 s390_emit_bit_xor (void)
1675 static const unsigned char buf
[] = {
1676 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1677 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1678 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1680 add_insns (buf
, sizeof buf
);
1683 /* The "emit_bit_not" emit_ops method for s390. */
1686 s390_emit_bit_not (void)
1688 static const unsigned char buf
[] = {
1689 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1690 0x17, 0x24, /* xr %r2, %r4 */
1691 0x17, 0x34, /* xr %r3, %r4 */
1693 add_insns (buf
, sizeof buf
);
1696 /* The "emit_equal" emit_ops method for s390. */
1699 s390_emit_equal (void)
1701 s390_emit_bit_xor ();
1702 s390_emit_log_not ();
1705 /* The "emit_less_signed" emit_ops method for s390. */
1708 s390_emit_less_signed (void)
1710 static const unsigned char buf
[] = {
1711 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1712 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1713 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1714 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1715 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1717 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1718 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1720 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1722 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1723 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1725 add_insns (buf
, sizeof buf
);
1728 /* The "emit_less_unsigned" emit_ops method for s390. */
1731 s390_emit_less_unsigned (void)
1733 static const unsigned char buf
[] = {
1734 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1735 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1736 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1737 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1738 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1740 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1741 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1743 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1745 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1746 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1748 add_insns (buf
, sizeof buf
);
1751 /* The "emit_ref" emit_ops method for s390. */
1754 s390_emit_ref (int size
)
1756 static const unsigned char buf1
[] = {
1757 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1758 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1760 static const unsigned char buf2
[] = {
1761 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1762 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1764 static const unsigned char buf4
[] = {
1765 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1766 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1768 static const unsigned char buf8
[] = {
1769 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1774 add_insns (buf1
, sizeof buf1
);
1777 add_insns (buf2
, sizeof buf2
);
1780 add_insns (buf4
, sizeof buf4
);
1783 add_insns (buf8
, sizeof buf8
);
1790 /* The "emit_if_goto" emit_ops method for s390. */
1793 s390_emit_if_goto (int *offset_p
, int *size_p
)
1795 static const unsigned char buf
[] = {
1796 0x16, 0x23, /* or %r2, %r3 */
1797 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1798 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1799 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1801 add_insns (buf
, sizeof buf
);
1808 /* The "emit_goto" emit_ops method for s390 and s390x. */
1811 s390_emit_goto (int *offset_p
, int *size_p
)
1813 static const unsigned char buf
[] = {
1814 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1816 add_insns (buf
, sizeof buf
);
1823 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1826 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1828 long diff
= ((long) (to
- (from
- 2))) / 2;
1830 unsigned char buf
[sizeof sdiff
];
1832 /* We're only doing 4-byte sizes at the moment. */
1833 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1839 memcpy (buf
, &sdiff
, sizeof sdiff
);
1840 write_inferior_memory (from
, buf
, sizeof sdiff
);
1843 /* Preparation for emitting a literal pool of given size. Loads the address
1844 of the pool into %r1, and jumps over it. Called should emit the pool data
1845 immediately afterwards. Used for both s390 and s390x. */
1848 s390_emit_litpool (int size
)
1850 static const unsigned char nop
[] = {
1853 unsigned char buf
[] = {
1854 0xa7, 0x15, 0x00, (size
+ 4) / 2, /* bras %r1, .Lend+size */
1859 /* buf needs to start at even halfword for litpool to be aligned */
1860 if (current_insn_ptr
& 2)
1861 add_insns (nop
, sizeof nop
);
1865 while ((current_insn_ptr
& 6) != 4)
1866 add_insns (nop
, sizeof nop
);
1868 add_insns (buf
, sizeof buf
);
1871 /* The "emit_const" emit_ops method for s390. */
1874 s390_emit_const (LONGEST num
)
1876 unsigned long long n
= num
;
1877 unsigned char buf_s
[] = {
1878 0xa7, 0x38, num
>> 8, num
, /* lhi %r3, <num> */
1879 0x17, 0x22, /* xr %r2, %r2 */
1881 static const unsigned char buf_l
[] = {
1882 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1884 if (num
< 0x8000 && num
>= 0)
1886 add_insns (buf_s
, sizeof buf_s
);
1890 s390_emit_litpool (8);
1891 add_insns ((unsigned char *) &n
, sizeof n
);
1892 add_insns (buf_l
, sizeof buf_l
);
1896 /* The "emit_call" emit_ops method for s390. */
1899 s390_emit_call (CORE_ADDR fn
)
1901 unsigned int n
= fn
;
1902 static const unsigned char buf
[] = {
1903 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1904 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1905 0x0d, 0xe1, /* basr %r14, %r1 */
1906 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1908 s390_emit_litpool (4);
1909 add_insns ((unsigned char *) &n
, sizeof n
);
1910 add_insns (buf
, sizeof buf
);
1913 /* The "emit_reg" emit_ops method for s390. */
1916 s390_emit_reg (int reg
)
1918 unsigned char bufpre
[] = {
1919 0x18, 0x29, /* lr %r2, %r9 */
1920 0xa7, 0x38, reg
>> 8, reg
, /* lhi %r3, <reg> */
1922 add_insns (bufpre
, sizeof bufpre
);
1923 s390_emit_call (get_raw_reg_func_addr ());
1926 /* The "emit_pop" emit_ops method for s390. */
1929 s390_emit_pop (void)
1931 static const unsigned char buf
[] = {
1932 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1933 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1935 add_insns (buf
, sizeof buf
);
1938 /* The "emit_stack_flush" emit_ops method for s390. */
1941 s390_emit_stack_flush (void)
1943 static const unsigned char buf
[] = {
1944 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1945 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1947 add_insns (buf
, sizeof buf
);
1950 /* The "emit_zero_ext" emit_ops method for s390. */
1953 s390_emit_zero_ext (int arg
)
1955 unsigned char buf
[] = {
1956 0x8d, 0x20, 0x00, 64 - arg
, /* sldl %r2, <64-arg> */
1957 0x8c, 0x20, 0x00, 64 - arg
, /* srdl %r2, <64-arg> */
1959 add_insns (buf
, sizeof buf
);
1962 /* The "emit_swap" emit_ops method for s390. */
1965 s390_emit_swap (void)
1967 static const unsigned char buf
[] = {
1968 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1969 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1970 0x18, 0x24, /* lr %r2, %r4 */
1971 0x18, 0x35, /* lr %r3, %r5 */
1973 add_insns (buf
, sizeof buf
);
1976 /* The "emit_stack_adjust" emit_ops method for s390. */
1979 s390_emit_stack_adjust (int n
)
1981 unsigned char buf
[] = {
1982 0xa7, 0xfa, n
* 8 >> 8, n
* 8, /* ahi %r15, 8*n */
1984 add_insns (buf
, sizeof buf
);
1987 /* Sets %r2 to a 32-bit constant. */
1990 s390_emit_set_r2 (int arg1
)
1992 unsigned char buf_s
[] = {
1993 0xa7, 0x28, arg1
>> 8, arg1
, /* lhi %r2, <arg1> */
1995 static const unsigned char buf_l
[] = {
1996 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
1998 if (arg1
< 0x8000 && arg1
>= -0x8000)
2000 add_insns (buf_s
, sizeof buf_s
);
2004 s390_emit_litpool (4);
2005 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
2006 add_insns (buf_l
, sizeof buf_l
);
2010 /* The "emit_int_call_1" emit_ops method for s390. */
2013 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2015 /* FN's prototype is `LONGEST(*fn)(int)'. */
2016 s390_emit_set_r2 (arg1
);
2017 s390_emit_call (fn
);
2020 /* The "emit_void_call_2" emit_ops method for s390. */
2023 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2025 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2026 static const unsigned char buf
[] = {
2027 0x18, 0xc2, /* lr %r12, %r2 */
2028 0x18, 0xd3, /* lr %r13, %r3 */
2029 0x18, 0x43, /* lr %r4, %r3 */
2030 0x18, 0x32, /* lr %r3, %r2 */
2032 static const unsigned char buf2
[] = {
2033 0x18, 0x2c, /* lr %r2, %r12 */
2034 0x18, 0x3d, /* lr %r3, %r13 */
2036 add_insns (buf
, sizeof buf
);
2037 s390_emit_set_r2 (arg1
);
2038 s390_emit_call (fn
);
2039 add_insns (buf2
, sizeof buf2
);
2042 /* The "emit_eq_goto" emit_ops method for s390. */
2045 s390_emit_eq_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, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2055 add_insns (buf
, sizeof buf
);
2062 /* The "emit_ne_goto" emit_ops method for s390. */
2065 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2067 static const unsigned char buf
[] = {
2068 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2069 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2070 0x16, 0x23, /* or %r2, %r3 */
2071 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2072 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2073 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2075 add_insns (buf
, sizeof buf
);
2082 /* The "emit_lt_goto" emit_ops method for s390. */
2085 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2087 static const unsigned char buf
[] = {
2088 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2089 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2090 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2091 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2092 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2094 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2095 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2096 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2098 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2099 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2100 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2103 add_insns (buf
, sizeof buf
);
2110 /* The "emit_le_goto" emit_ops method for s390. */
2113 s390_emit_le_goto (int *offset_p
, int *size_p
)
2115 static const unsigned char buf
[] = {
2116 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2117 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2118 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2119 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2120 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2122 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2123 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2124 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2126 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2127 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2128 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2131 add_insns (buf
, sizeof buf
);
2138 /* The "emit_gt_goto" emit_ops method for s390. */
2141 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2143 static const unsigned char buf
[] = {
2144 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2145 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2146 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2147 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2148 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2150 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2151 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2152 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2154 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2155 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2156 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2159 add_insns (buf
, sizeof buf
);
2166 /* The "emit_ge_goto" emit_ops method for s390. */
2169 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2171 static const unsigned char buf
[] = {
2172 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2173 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2174 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2175 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2176 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2178 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2179 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2180 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2182 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2183 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2184 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2187 add_insns (buf
, sizeof buf
);
2194 /* The "emit_ops" structure for s390. Named _impl to avoid name
2195 collision with s390_emit_ops function. */
2197 static struct emit_ops s390_emit_ops_impl
=
2205 s390_emit_rsh_signed
,
2206 s390_emit_rsh_unsigned
,
2214 s390_emit_less_signed
,
2215 s390_emit_less_unsigned
,
2219 s390_write_goto_address
,
2224 s390_emit_stack_flush
,
2227 s390_emit_stack_adjust
,
2228 s390_emit_int_call_1
,
2229 s390_emit_void_call_2
,
2240 /* The "emit_prologue" emit_ops method for s390x. */
2243 s390x_emit_prologue (void)
2245 static const unsigned char buf
[] = {
2246 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2247 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2248 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2249 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2251 add_insns (buf
, sizeof buf
);
2254 /* The "emit_epilogue" emit_ops method for s390x. */
2257 s390x_emit_epilogue (void)
2259 static const unsigned char buf
[] = {
2260 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2261 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2262 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2263 0x07, 0xfe, /* br %r14 */
2265 add_insns (buf
, sizeof buf
);
2268 /* The "emit_add" emit_ops method for s390x. */
2271 s390x_emit_add (void)
2273 static const unsigned char buf
[] = {
2274 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2275 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2277 add_insns (buf
, sizeof buf
);
2280 /* The "emit_sub" emit_ops method for s390x. */
2283 s390x_emit_sub (void)
2285 static const unsigned char buf
[] = {
2286 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2287 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2288 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2289 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2291 add_insns (buf
, sizeof buf
);
2294 /* The "emit_mul" emit_ops method for s390x. */
2297 s390x_emit_mul (void)
2302 /* The "emit_lsh" emit_ops method for s390x. */
2305 s390x_emit_lsh (void)
2307 static const unsigned char buf
[] = {
2308 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2309 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2310 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2312 add_insns (buf
, sizeof buf
);
2315 /* The "emit_rsh_signed" emit_ops method for s390x. */
2318 s390x_emit_rsh_signed (void)
2320 static const unsigned char buf
[] = {
2321 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2322 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2323 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2325 add_insns (buf
, sizeof buf
);
2328 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2331 s390x_emit_rsh_unsigned (void)
2333 static const unsigned char buf
[] = {
2334 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2335 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2336 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2338 add_insns (buf
, sizeof buf
);
2341 /* The "emit_ext" emit_ops method for s390x. */
2344 s390x_emit_ext (int arg
)
2346 unsigned char buf
[] = {
2347 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2348 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0a, /* srag %r2, %r2, <64-arg> */
2350 add_insns (buf
, sizeof buf
);
2353 /* The "emit_log_not" emit_ops method for s390x. */
2356 s390x_emit_log_not (void)
2358 static const unsigned char buf
[] = {
2359 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2360 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2361 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2363 add_insns (buf
, sizeof buf
);
2366 /* The "emit_bit_and" emit_ops method for s390x. */
2369 s390x_emit_bit_and (void)
2371 static const unsigned char buf
[] = {
2372 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2373 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2375 add_insns (buf
, sizeof buf
);
2378 /* The "emit_bit_or" emit_ops method for s390x. */
2381 s390x_emit_bit_or (void)
2383 static const unsigned char buf
[] = {
2384 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2385 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2387 add_insns (buf
, sizeof buf
);
2390 /* The "emit_bit_xor" emit_ops method for s390x. */
2393 s390x_emit_bit_xor (void)
2395 static const unsigned char buf
[] = {
2396 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2397 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2399 add_insns (buf
, sizeof buf
);
2402 /* The "emit_bit_not" emit_ops method for s390x. */
2405 s390x_emit_bit_not (void)
2407 static const unsigned char buf
[] = {
2408 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2409 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2411 add_insns (buf
, sizeof buf
);
2414 /* The "emit_equal" emit_ops method for s390x. */
2417 s390x_emit_equal (void)
2419 s390x_emit_bit_xor ();
2420 s390x_emit_log_not ();
2423 /* The "emit_less_signed" emit_ops method for s390x. */
2426 s390x_emit_less_signed (void)
2428 static const unsigned char buf
[] = {
2429 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2430 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2431 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2432 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2434 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2436 add_insns (buf
, sizeof buf
);
2439 /* The "emit_less_unsigned" emit_ops method for s390x. */
2442 s390x_emit_less_unsigned (void)
2444 static const unsigned char buf
[] = {
2445 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2446 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2447 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2448 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2450 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2452 add_insns (buf
, sizeof buf
);
2455 /* The "emit_ref" emit_ops method for s390x. */
2458 s390x_emit_ref (int size
)
2460 static const unsigned char buf1
[] = {
2461 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2463 static const unsigned char buf2
[] = {
2464 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2466 static const unsigned char buf4
[] = {
2467 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2469 static const unsigned char buf8
[] = {
2470 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2475 add_insns (buf1
, sizeof buf1
);
2478 add_insns (buf2
, sizeof buf2
);
2481 add_insns (buf4
, sizeof buf4
);
2484 add_insns (buf8
, sizeof buf8
);
2491 /* The "emit_if_goto" emit_ops method for s390x. */
2494 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2496 static const unsigned char buf
[] = {
2497 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2498 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2499 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2500 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2502 add_insns (buf
, sizeof buf
);
2509 /* The "emit_const" emit_ops method for s390x. */
2512 s390x_emit_const (LONGEST num
)
2514 unsigned long long n
= num
;
2515 unsigned char buf_s
[] = {
2516 0xa7, 0x29, num
>> 8, num
, /* lghi %r2, <num> */
2518 static const unsigned char buf_l
[] = {
2519 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2521 if (num
< 0x8000 && num
>= -0x8000)
2523 add_insns (buf_s
, sizeof buf_s
);
2527 s390_emit_litpool (8);
2528 add_insns ((unsigned char *) &n
, sizeof n
);
2529 add_insns (buf_l
, sizeof buf_l
);
2533 /* The "emit_call" emit_ops method for s390x. */
2536 s390x_emit_call (CORE_ADDR fn
)
2538 unsigned long n
= fn
;
2539 static const unsigned char buf
[] = {
2540 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2541 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2542 0x0d, 0xe1, /* basr %r14, %r1 */
2543 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2545 s390_emit_litpool (8);
2546 add_insns ((unsigned char *) &n
, sizeof n
);
2547 add_insns (buf
, sizeof buf
);
2550 /* The "emit_reg" emit_ops method for s390x. */
2553 s390x_emit_reg (int reg
)
2555 unsigned char buf
[] = {
2556 0xb9, 0x04, 0x00, 0x29, /* lgr %r2, %r9 */
2557 0xa7, 0x39, reg
>> 8, reg
, /* lghi %r3, <reg> */
2559 add_insns (buf
, sizeof buf
);
2560 s390x_emit_call (get_raw_reg_func_addr ());
2563 /* The "emit_pop" emit_ops method for s390x. */
2566 s390x_emit_pop (void)
2568 static const unsigned char buf
[] = {
2569 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2570 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2572 add_insns (buf
, sizeof buf
);
2575 /* The "emit_stack_flush" emit_ops method for s390x. */
2578 s390x_emit_stack_flush (void)
2580 static const unsigned char buf
[] = {
2581 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2582 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2584 add_insns (buf
, sizeof buf
);
2587 /* The "emit_zero_ext" emit_ops method for s390x. */
2590 s390x_emit_zero_ext (int arg
)
2592 unsigned char buf
[] = {
2593 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0d, /* sllg %r2, %r2, <64-arg> */
2594 0xeb, 0x22, 0x00, 64 - arg
, 0x00, 0x0c, /* srlg %r2, %r2, <64-arg> */
2596 add_insns (buf
, sizeof buf
);
2599 /* The "emit_swap" emit_ops method for s390x. */
2602 s390x_emit_swap (void)
2604 static const unsigned char buf
[] = {
2605 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2606 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2607 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2609 add_insns (buf
, sizeof buf
);
2612 /* The "emit_stack_adjust" emit_ops method for s390x. */
2615 s390x_emit_stack_adjust (int n
)
2617 unsigned char buf
[] = {
2618 0xa7, 0xfb, n
* 8 >> 8, n
* 8, /* aghi %r15, 8*n */
2620 add_insns (buf
, sizeof buf
);
2623 /* The "emit_int_call_1" emit_ops method for s390x. */
2626 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2628 /* FN's prototype is `LONGEST(*fn)(int)'. */
2629 s390x_emit_const (arg1
);
2630 s390x_emit_call (fn
);
2633 /* The "emit_void_call_2" emit_ops method for s390x. */
2636 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2638 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2639 static const unsigned char buf
[] = {
2640 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2641 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2643 static const unsigned char buf2
[] = {
2644 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2646 add_insns (buf
, sizeof buf
);
2647 s390x_emit_const (arg1
);
2648 s390x_emit_call (fn
);
2649 add_insns (buf2
, sizeof buf2
);
2652 /* The "emit_eq_goto" emit_ops method for s390x. */
2655 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2657 static const unsigned char buf
[] = {
2658 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2659 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2660 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2661 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2663 add_insns (buf
, sizeof buf
);
2670 /* The "emit_ne_goto" emit_ops method for s390x. */
2673 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2675 static const unsigned char buf
[] = {
2676 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2677 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2678 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2679 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2681 add_insns (buf
, sizeof buf
);
2688 /* The "emit_lt_goto" emit_ops method for s390x. */
2691 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2693 static const unsigned char buf
[] = {
2694 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2695 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2696 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2697 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2699 add_insns (buf
, sizeof buf
);
2706 /* The "emit_le_goto" emit_ops method for s390x. */
2709 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2711 static const unsigned char buf
[] = {
2712 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2713 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2714 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2715 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2717 add_insns (buf
, sizeof buf
);
2724 /* The "emit_gt_goto" emit_ops method for s390x. */
2727 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2729 static const unsigned char buf
[] = {
2730 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2731 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2732 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2733 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2735 add_insns (buf
, sizeof buf
);
2742 /* The "emit_ge_goto" emit_ops method for s390x. */
2745 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2747 static const unsigned char buf
[] = {
2748 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2749 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2750 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2751 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2753 add_insns (buf
, sizeof buf
);
2760 /* The "emit_ops" structure for s390x. */
2762 static struct emit_ops s390x_emit_ops
=
2764 s390x_emit_prologue
,
2765 s390x_emit_epilogue
,
2770 s390x_emit_rsh_signed
,
2771 s390x_emit_rsh_unsigned
,
2779 s390x_emit_less_signed
,
2780 s390x_emit_less_unsigned
,
2784 s390_write_goto_address
,
2789 s390x_emit_stack_flush
,
2790 s390x_emit_zero_ext
,
2792 s390x_emit_stack_adjust
,
2793 s390x_emit_int_call_1
,
2794 s390x_emit_void_call_2
,
2804 /* The "emit_ops" linux_target_ops method. */
2806 static struct emit_ops
*
2807 s390_emit_ops (void)
2810 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2812 if (register_size (regcache
->tdesc
, 0) == 8)
2813 return &s390x_emit_ops
;
2816 return &s390_emit_ops_impl
;
2819 struct linux_target_ops the_low_target
= {
2822 s390_cannot_fetch_register
,
2823 s390_cannot_store_register
,
2824 NULL
, /* fetch_register */
2827 NULL
, /* breakpoint_kind_from_pc */
2828 s390_sw_breakpoint_from_kind
,
2830 s390_breakpoint_len
,
2832 s390_supports_z_point_type
,
2837 s390_collect_ptrace_register
,
2838 s390_supply_ptrace_register
,
2839 NULL
, /* siginfo_fixup */
2840 NULL
, /* new_process */
2841 NULL
, /* delete_process */
2842 NULL
, /* new_thread */
2843 NULL
, /* delete_thread */
2844 NULL
, /* new_fork */
2845 NULL
, /* prepare_to_resume */
2846 NULL
, /* process_qsupported */
2847 s390_supports_tracepoints
,
2848 s390_get_thread_area
,
2849 s390_install_fast_tracepoint_jump_pad
,
2851 s390_get_min_fast_tracepoint_insn_len
,
2852 NULL
, /* supports_range_stepping */
2853 NULL
, /* breakpoint_kind_from_current_state */
2854 s390_supports_hardware_single_step
,
2855 NULL
, /* get_syscall_trapinfo */
2856 s390_get_ipa_tdesc_idx
,
2860 initialize_low_arch (void)
2862 /* Initialize the Linux target descriptions. */
2864 init_registers_s390_linux32 ();
2865 init_registers_s390_linux32v1 ();
2866 init_registers_s390_linux32v2 ();
2867 init_registers_s390_linux64 ();
2868 init_registers_s390_linux64v1 ();
2869 init_registers_s390_linux64v2 ();
2870 init_registers_s390_te_linux64 ();
2871 init_registers_s390_vx_linux64 ();
2872 init_registers_s390_tevx_linux64 ();
2873 init_registers_s390_gs_linux64 ();
2875 init_registers_s390x_linux64 ();
2876 init_registers_s390x_linux64v1 ();
2877 init_registers_s390x_linux64v2 ();
2878 init_registers_s390x_te_linux64 ();
2879 init_registers_s390x_vx_linux64 ();
2880 init_registers_s390x_tevx_linux64 ();
2881 init_registers_s390x_gs_linux64 ();
2884 initialize_regsets_info (&s390_regsets_info
);
2885 initialize_regsets_info (&s390_regsets_info_3264
);