1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2020 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* This file is used for both 31-bit and 64-bit S/390 systems. */
23 #include "linux-low.h"
24 #include "elf/common.h"
26 #include "tracepoint.h"
28 #include <asm/ptrace.h>
29 #include "nat/gdb_ptrace.h"
34 #include "linux-s390-tdesc.h"
36 #ifndef HWCAP_S390_HIGH_GPRS
37 #define HWCAP_S390_HIGH_GPRS 512
41 #define HWCAP_S390_TE 1024
45 #define HWCAP_S390_VX 2048
49 #define HWCAP_S390_GS 16384
52 #define s390_num_regs 52
54 /* Linux target op definitions for the S/390 architecture. */
56 class s390_target
: public linux_process_target
60 const regs_info
*get_regs_info () override
;
62 const gdb_byte
*sw_breakpoint_from_kind (int kind
, int *size
) override
;
64 bool supports_z_point_type (char z_type
) override
;
66 bool supports_tracepoints () override
;
68 bool supports_fast_tracepoints () override
;
70 int install_fast_tracepoint_jump_pad
71 (CORE_ADDR tpoint
, CORE_ADDR tpaddr
, CORE_ADDR collector
,
72 CORE_ADDR lockaddr
, ULONGEST orig_size
, CORE_ADDR
*jump_entry
,
73 CORE_ADDR
*trampoline
, ULONGEST
*trampoline_size
,
74 unsigned char *jjump_pad_insn
, ULONGEST
*jjump_pad_insn_size
,
75 CORE_ADDR
*adjusted_insn_addr
, CORE_ADDR
*adjusted_insn_addr_end
,
78 int get_min_fast_tracepoint_insn_len () override
;
80 void low_collect_ptrace_register (regcache
*regcache
, int regno
,
83 void low_supply_ptrace_register (regcache
*regcache
, int regno
,
84 const char *buf
) override
;
86 struct emit_ops
*emit_ops () override
;
90 void low_arch_setup () override
;
92 bool low_cannot_fetch_register (int regno
) override
;
94 bool low_cannot_store_register (int regno
) override
;
96 bool low_supports_breakpoints () override
;
98 CORE_ADDR
low_get_pc (regcache
*regcache
) override
;
100 void low_set_pc (regcache
*regcache
, CORE_ADDR newpc
) override
;
102 int low_decr_pc_after_break () override
;
104 bool low_breakpoint_at (CORE_ADDR pc
) override
;
106 int low_get_thread_area (int lwpid
, CORE_ADDR
*addrp
) override
;
109 /* The singleton target ops object. */
111 static s390_target the_s390_target
;
113 static int s390_regmap
[] = {
114 PT_PSWMASK
, PT_PSWADDR
,
116 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
117 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
118 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
119 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
121 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
122 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
123 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
124 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
129 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
130 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
131 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
132 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
134 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
135 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
136 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
137 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
143 #define s390_num_regs_3264 68
146 static int s390_regmap_3264
[] = {
147 PT_PSWMASK
, PT_PSWADDR
,
149 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
150 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
151 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
152 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
153 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
154 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
155 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
156 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
158 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
159 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
160 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
161 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
165 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
166 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
167 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
168 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
173 static int s390_regmap_3264
[] = {
174 PT_PSWMASK
, PT_PSWADDR
,
176 -1, PT_GPR0
, -1, PT_GPR1
,
177 -1, PT_GPR2
, -1, PT_GPR3
,
178 -1, PT_GPR4
, -1, PT_GPR5
,
179 -1, PT_GPR6
, -1, PT_GPR7
,
180 -1, PT_GPR8
, -1, PT_GPR9
,
181 -1, PT_GPR10
, -1, PT_GPR11
,
182 -1, PT_GPR12
, -1, PT_GPR13
,
183 -1, PT_GPR14
, -1, PT_GPR15
,
185 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
186 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
187 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
188 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
192 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
193 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
194 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
195 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
203 s390_target::low_cannot_fetch_register (int regno
)
209 s390_target::low_cannot_store_register (int regno
)
215 s390_target::low_collect_ptrace_register (regcache
*regcache
, int regno
,
218 int size
= register_size (regcache
->tdesc
, regno
);
219 const struct regs_info
*regs_info
= get_regs_info ();
220 struct usrregs_info
*usr
= regs_info
->usrregs
;
221 int regaddr
= usr
->regmap
[regno
];
223 if (size
< sizeof (long))
225 memset (buf
, 0, sizeof (long));
227 if ((regno
^ 1) < usr
->num_regs
228 && usr
->regmap
[regno
^ 1] == regaddr
)
230 collect_register (regcache
, regno
& ~1, buf
);
231 collect_register (regcache
, (regno
& ~1) + 1,
232 buf
+ sizeof (long) - size
);
234 else if (regaddr
== PT_PSWMASK
)
236 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
237 the basic addressing mode bit from the PSW address. */
238 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
239 collect_register (regcache
, regno
, buf
);
240 collect_register (regcache
, regno
^ 1, addr
);
242 buf
[size
] |= (addr
[0] & 0x80);
244 else if (regaddr
== PT_PSWADDR
)
246 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
247 mode bit (which gets copied to the PSW mask instead). */
248 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
249 buf
[sizeof (long) - size
] &= ~0x80;
251 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
252 || regaddr
== PT_ORIGGPR2
)
253 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
255 collect_register (regcache
, regno
, buf
);
257 else if (regaddr
!= -1)
258 collect_register (regcache
, regno
, buf
);
262 s390_target::low_supply_ptrace_register (regcache
*regcache
, int regno
,
265 int size
= register_size (regcache
->tdesc
, regno
);
266 const struct regs_info
*regs_info
= get_regs_info ();
267 struct usrregs_info
*usr
= regs_info
->usrregs
;
268 int regaddr
= usr
->regmap
[regno
];
270 if (size
< sizeof (long))
272 if ((regno
^ 1) < usr
->num_regs
273 && usr
->regmap
[regno
^ 1] == regaddr
)
275 supply_register (regcache
, regno
& ~1, buf
);
276 supply_register (regcache
, (regno
& ~1) + 1,
277 buf
+ sizeof (long) - size
);
279 else if (regaddr
== PT_PSWMASK
)
281 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
282 the basic addressing mode into the PSW address. */
283 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
284 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
285 memcpy (mask
, buf
, size
);
287 supply_register (regcache
, regno
, mask
);
289 collect_register (regcache
, regno
^ 1, addr
);
291 addr
[0] |= (buf
[size
] & 0x80);
292 supply_register (regcache
, regno
^ 1, addr
);
294 else if (regaddr
== PT_PSWADDR
)
296 /* Convert 8-byte PSW address to 4 bytes by truncating, but
297 keeping the addressing mode bit (which was set from the mask). */
298 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
300 collect_register (regcache
, regno
, addr
);
301 amode
= addr
[0] & 0x80;
302 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
305 supply_register (regcache
, regno
, addr
);
307 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
308 || regaddr
== PT_ORIGGPR2
)
309 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
311 supply_register (regcache
, regno
, buf
);
313 else if (regaddr
!= -1)
314 supply_register (regcache
, regno
, buf
);
317 /* Provide only a fill function for the general register set. ps_lgetregs
318 will use this for NPTL support. */
321 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
324 const struct regs_info
*regs_info
= the_linux_target
->get_regs_info ();
325 struct usrregs_info
*usr
= regs_info
->usrregs
;
327 for (i
= 0; i
< usr
->num_regs
; i
++)
329 if (usr
->regmap
[i
] < PT_PSWMASK
330 || usr
->regmap
[i
] > PT_ACR15
)
333 ((s390_target
*) the_linux_target
)->low_collect_ptrace_register
334 (regcache
, i
, (char *) buf
+ usr
->regmap
[i
]);
338 /* Fill and store functions for extended register sets. */
342 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
344 int r0h
= find_regno (regcache
->tdesc
, "r0h");
347 for (i
= 0; i
< 16; i
++)
348 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
352 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
354 int r0h
= find_regno (regcache
->tdesc
, "r0h");
357 for (i
= 0; i
< 16; i
++)
358 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
363 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
367 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
368 supply_register_by_name (regcache
, "last_break", p
);
372 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
374 collect_register_by_name (regcache
, "system_call", buf
);
378 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
380 supply_register_by_name (regcache
, "system_call", buf
);
384 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
386 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
387 int tr0
= find_regno (regcache
->tdesc
, "tr0");
390 for (i
= 0; i
< 4; i
++)
391 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
393 for (i
= 0; i
< 16; i
++)
394 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
398 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
400 int v0
= find_regno (regcache
->tdesc
, "v0l");
403 for (i
= 0; i
< 16; i
++)
404 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
408 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
410 int v0
= find_regno (regcache
->tdesc
, "v0l");
413 for (i
= 0; i
< 16; i
++)
414 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
418 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
420 int v16
= find_regno (regcache
->tdesc
, "v16");
423 for (i
= 0; i
< 16; i
++)
424 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
428 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
430 int v16
= find_regno (regcache
->tdesc
, "v16");
433 for (i
= 0; i
< 16; i
++)
434 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
438 s390_store_gs (struct regcache
*regcache
, const void *buf
)
440 int gsd
= find_regno (regcache
->tdesc
, "gsd");
443 for (i
= 0; i
< 3; i
++)
444 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
448 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
450 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
453 for (i
= 0; i
< 3; i
++)
454 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
457 static struct regset_info s390_regsets
[] = {
458 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
460 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
461 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
463 /* Last break address is read-only; no fill function. */
464 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
465 NULL
, s390_store_last_break
},
466 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
467 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
468 /* TDB is read-only. */
469 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
470 NULL
, s390_store_tdb
},
471 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
472 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
473 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
474 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
475 /* Guarded storage registers are read-only. */
476 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
477 NULL
, s390_store_gs
},
478 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
479 NULL
, s390_store_gsbc
},
484 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
485 #define s390_breakpoint_len 2
487 /* Implementation of target ops method "sw_breakpoint_from_kind". */
490 s390_target::sw_breakpoint_from_kind (int kind
, int *size
)
492 *size
= s390_breakpoint_len
;
493 return s390_breakpoint
;
497 s390_target::low_supports_breakpoints ()
503 s390_target::low_get_pc (regcache
*regcache
)
505 if (register_size (regcache
->tdesc
, 0) == 4)
508 collect_register_by_name (regcache
, "pswa", &pswa
);
509 return pswa
& 0x7fffffff;
514 collect_register_by_name (regcache
, "pswa", &pc
);
520 s390_target::low_set_pc (regcache
*regcache
, CORE_ADDR newpc
)
522 if (register_size (regcache
->tdesc
, 0) == 4)
525 collect_register_by_name (regcache
, "pswa", &pswa
);
526 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
527 supply_register_by_name (regcache
, "pswa", &pswa
);
531 unsigned long pc
= newpc
;
532 supply_register_by_name (regcache
, "pswa", &pc
);
537 s390_target::low_decr_pc_after_break ()
539 return s390_breakpoint_len
;
542 /* Determine the word size for the given PID, in bytes. */
546 s390_get_wordsize (int pid
)
549 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
550 (PTRACE_TYPE_ARG3
) 0,
551 (PTRACE_TYPE_ARG4
) 0);
554 warning (_("Couldn't determine word size, assuming 64-bit."));
557 /* Derive word size from extended addressing mode (PSW bit 31). */
558 return pswm
& (1L << 32) ? 8 : 4;
561 #define s390_get_wordsize(pid) 4
565 s390_check_regset (int pid
, int regset
, int regsize
)
567 void *buf
= alloca (regsize
);
571 iov
.iov_len
= regsize
;
573 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
579 /* For a 31-bit inferior, whether the kernel supports using the full
581 static int have_hwcap_s390_high_gprs
= 0;
582 static int have_hwcap_s390_vx
= 0;
585 s390_target::low_arch_setup ()
587 const struct target_desc
*tdesc
;
588 struct regset_info
*regset
;
590 /* Determine word size and HWCAP. */
591 int pid
= pid_of (current_thread
);
592 int wordsize
= s390_get_wordsize (pid
);
593 unsigned long hwcap
= linux_get_hwcap (wordsize
);
595 /* Check whether the kernel supports extra register sets. */
596 int have_regset_last_break
597 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
598 int have_regset_system_call
599 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
601 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
602 && (hwcap
& HWCAP_S390_TE
) != 0);
604 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
605 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
606 && (hwcap
& HWCAP_S390_VX
) != 0);
608 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
609 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
610 && (hwcap
& HWCAP_S390_GS
) != 0);
617 tdesc
= tdesc_s390x_gs_linux64
;
618 else if (have_regset_vxrs
)
619 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
620 tdesc_s390x_vx_linux64
);
621 else if (have_regset_tdb
)
622 tdesc
= tdesc_s390x_te_linux64
;
623 else if (have_regset_system_call
)
624 tdesc
= tdesc_s390x_linux64v2
;
625 else if (have_regset_last_break
)
626 tdesc
= tdesc_s390x_linux64v1
;
628 tdesc
= tdesc_s390x_linux64
;
631 /* For a 31-bit inferior, check whether the kernel supports
632 using the full 64-bit GPRs. */
635 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
637 have_hwcap_s390_high_gprs
= 1;
639 tdesc
= tdesc_s390_gs_linux64
;
640 else if (have_regset_vxrs
)
641 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
642 tdesc_s390_vx_linux64
);
643 else if (have_regset_tdb
)
644 tdesc
= tdesc_s390_te_linux64
;
645 else if (have_regset_system_call
)
646 tdesc
= tdesc_s390_linux64v2
;
647 else if (have_regset_last_break
)
648 tdesc
= tdesc_s390_linux64v1
;
650 tdesc
= tdesc_s390_linux64
;
654 /* Assume 31-bit inferior process. */
655 if (have_regset_system_call
)
656 tdesc
= tdesc_s390_linux32v2
;
657 else if (have_regset_last_break
)
658 tdesc
= tdesc_s390_linux32v1
;
660 tdesc
= tdesc_s390_linux32
;
663 have_hwcap_s390_vx
= have_regset_vxrs
;
666 /* Update target_regsets according to available register sets. */
667 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
668 if (regset
->get_request
== PTRACE_GETREGSET
)
669 switch (regset
->nt_type
)
672 case NT_S390_HIGH_GPRS
:
673 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
676 case NT_S390_LAST_BREAK
:
677 regset
->size
= have_regset_last_break
? 8 : 0;
679 case NT_S390_SYSTEM_CALL
:
680 regset
->size
= have_regset_system_call
? 4 : 0;
683 regset
->size
= have_regset_tdb
? 256 : 0;
685 case NT_S390_VXRS_LOW
:
686 regset
->size
= have_regset_vxrs
? 128 : 0;
688 case NT_S390_VXRS_HIGH
:
689 regset
->size
= have_regset_vxrs
? 256 : 0;
693 regset
->size
= have_regset_gs
? 32 : 0;
698 current_process ()->tdesc
= tdesc
;
703 s390_target::low_breakpoint_at (CORE_ADDR pc
)
705 unsigned char c
[s390_breakpoint_len
];
706 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
707 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
710 /* Breakpoint/Watchpoint support. */
712 /* The "supports_z_point_type" target ops method. */
715 s390_target::supports_z_point_type (char z_type
)
726 /* Support for hardware single step. */
729 s390_supports_hardware_single_step (void)
734 static struct usrregs_info s390_usrregs_info
=
740 static struct regsets_info s390_regsets_info
=
742 s390_regsets
, /* regsets */
744 NULL
, /* disabled_regsets */
747 static struct regs_info myregs_info
=
749 NULL
, /* regset_bitmap */
754 static struct usrregs_info s390_usrregs_info_3264
=
760 static struct regsets_info s390_regsets_info_3264
=
762 s390_regsets
, /* regsets */
764 NULL
, /* disabled_regsets */
767 static struct regs_info regs_info_3264
=
769 NULL
, /* regset_bitmap */
770 &s390_usrregs_info_3264
,
771 &s390_regsets_info_3264
775 s390_target::get_regs_info ()
777 if (have_hwcap_s390_high_gprs
)
780 const struct target_desc
*tdesc
= current_process ()->tdesc
;
782 if (register_size (tdesc
, 0) == 4)
783 return ®s_info_3264
;
785 return ®s_info_3264
;
791 /* The "supports_tracepoints" target ops method. */
794 s390_target::supports_tracepoints ()
799 /* Implementation of linux target ops method "low_get_thread_area". */
802 s390_target::low_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
804 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
806 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
808 if (register_size (regcache
->tdesc
, 0) == 4)
809 res
&= 0xffffffffull
;
816 /* Fast tracepoint support.
818 The register save area on stack is identical for all targets:
820 0x000+i*0x10: VR0-VR31
827 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
828 Likewise, if there's no VX support, we just store the FRs into the slots
829 of low VR halves. The agent code is responsible for rearranging that
832 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
833 one trick used at the very beginning: since there's no way to allocate
834 stack space without destroying CC (lay instruction can do it, but it's
835 only supported on later CPUs), we take 4 different execution paths for
836 every possible value of CC, allocate stack space, save %r0, stuff the
837 CC value in %r0 (shifted to match its position in PSWM high word),
838 then branch to common path. */
840 static const unsigned char s390_ft_entry_gpr_esa
[] = {
841 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
842 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
843 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
845 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
846 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
847 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
848 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
850 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
851 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
852 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
853 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
855 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
856 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
857 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
858 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
860 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
861 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
862 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
864 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
865 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
866 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
867 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
868 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
869 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
870 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
871 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
872 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
873 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
874 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
875 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
876 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
877 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
878 /* Compute original value of %r15 and store it. We use ahi instead
879 of la to preserve the whole value, and not just the low 31 bits.
880 This is not particularly important here, but essential in the
881 zarch case where someone might be using the high word of %r15
882 as an extra register. */
883 0x18, 0x1f, /* lr %r1, %r15 */
884 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
885 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
888 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
889 target. Same as above, except this time we can use load/store multiple,
890 since the 64-bit regs are tightly packed. */
892 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
893 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
894 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
895 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
897 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
898 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
899 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
900 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
902 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
903 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
904 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
905 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
907 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
908 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
909 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
910 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
912 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
913 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
914 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
916 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
917 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
918 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
921 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
922 current PSWM (read by epsw) and CC from entry (in %r0). */
924 static const unsigned char s390_ft_entry_misc
[] = {
925 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
926 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
927 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
928 0x14, 0x21, /* nr %r2, %r1 */
929 0x16, 0x20, /* or %r2, %r0 */
930 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
931 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
932 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
935 /* Code sequence saving FRs, used if VX not supported. */
937 static const unsigned char s390_ft_entry_fr
[] = {
938 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
939 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
940 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
941 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
942 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
943 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
944 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
945 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
946 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
947 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
948 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
949 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
950 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
951 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
952 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
953 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
956 /* Code sequence saving VRs, used if VX not supported. */
958 static const unsigned char s390_ft_entry_vr
[] = {
959 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
960 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
963 /* Code sequence doing the collection call for 31-bit target. %r1 contains
964 the address of the literal pool. */
966 static const unsigned char s390_ft_main_31
[] = {
967 /* Load the literals into registers. */
968 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
969 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
970 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
971 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
972 /* Save original PSWA (tracepoint address | 0x80000000). */
973 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
974 /* Construct a collecting_t object at %r15+0x2e0. */
975 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
976 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
977 /* Move its address to %r0. */
978 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
981 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
982 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
983 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
984 /* Address of the register save block to %r3. */
985 0x18, 0x3f, /* lr %r3, %r15 */
986 /* Make a stack frame, so that we can call the collector. */
987 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
989 0x0d, 0xe4, /* basr %r14, %r4 */
990 /* And get rid of the stack frame again. */
991 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
992 /* Leave the lock. */
993 0x07, 0xf0, /* br %r0 */
994 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
995 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
998 /* Code sequence doing the collection call for 64-bit target. %r1 contains
999 the address of the literal pool. */
1001 static const unsigned char s390_ft_main_64
[] = {
1002 /* Load the literals into registers. */
1003 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
1004 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
1005 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
1006 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
1007 /* Save original PSWA (tracepoint address). */
1008 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
1009 /* Construct a collecting_t object at %r15+0x2e0. */
1010 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
1011 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
1012 /* Move its address to %r0. */
1013 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
1014 /* Take the lock. */
1016 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1017 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
1018 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
1019 /* Address of the register save block to %r3. */
1020 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
1021 /* Make a stack frame, so that we can call the collector. */
1022 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1024 0x0d, 0xe4, /* basr %r14, %r4 */
1025 /* And get rid of the stack frame again. */
1026 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1027 /* Leave the lock. */
1028 0x07, 0xf0, /* br %r0 */
1029 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1030 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1033 /* Code sequence restoring FRs, for targets with no VX support. */
1035 static const unsigned char s390_ft_exit_fr
[] = {
1036 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1037 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1038 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1039 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1040 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1041 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1042 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1043 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1044 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1045 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1046 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1047 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1048 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1049 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1050 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1051 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1054 /* Code sequence restoring VRs. */
1056 static const unsigned char s390_ft_exit_vr
[] = {
1057 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1058 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1061 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1062 modified by C code, so we use the alr instruction to restore it by
1063 manufacturing an operand that'll result in the original flags. */
1065 static const unsigned char s390_ft_exit_misc
[] = {
1066 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1067 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1068 /* Extract CC to high 2 bits of %r0. */
1069 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1070 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1071 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1072 will have carry iff CC bit 1 is set - resulting in the same flags
1074 0x1e, 0x00, /* alr %r0, %r0 */
1075 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1078 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1080 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1081 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1082 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1083 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1084 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1085 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1086 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1087 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1088 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1089 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1090 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1091 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1092 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1093 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1094 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1095 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1096 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1099 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1102 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1103 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1106 /* Writes instructions to target, updating the to pointer. */
1109 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1111 target_write_memory (*to
, buf
, len
);
1115 /* Relocates an instruction from oldloc to *to, updating to. */
1118 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1123 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1126 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1129 else if (buf
[0] < 0xc0)
1135 case 0x05: /* BALR */
1136 case 0x0c: /* BASSM */
1137 case 0x0d: /* BASR */
1138 case 0x45: /* BAL */
1139 case 0x4d: /* BAS */
1140 /* These save a return address and mess around with registers.
1141 We can't relocate them. */
1143 case 0x84: /* BRXH */
1144 case 0x85: /* BRXLE */
1149 /* BRC, BRAS, BRCT, BRCTG */
1150 if (op2
>= 4 && op2
<= 7)
1158 /* LARL, BRCL, BRASL */
1159 if (op2
== 0 || op2
== 4 || op2
== 5)
1167 /* PC-relative addressing instructions. */
1170 case 0xc5: /* BPRP */
1171 case 0xc7: /* BPP */
1172 /* Branch prediction - just skip it. */
1184 case 0x44: /* BRXHG */
1185 case 0x45: /* BRXLG */
1186 case 0x64: /* CGRJ */
1187 case 0x65: /* CLGRJ */
1188 case 0x76: /* CRJ */
1189 case 0x77: /* CLRJ */
1198 /* We'll have to relocate an instruction with a PC-relative field.
1199 First, compute the target. */
1200 int64_t loffset
= 0;
1204 int16_t soffset
= 0;
1205 memcpy (&soffset
, buf
+ 2, 2);
1210 int32_t soffset
= 0;
1211 memcpy (&soffset
, buf
+ 2, 4);
1214 target
= oldloc
+ loffset
* 2;
1216 target
&= 0x7fffffff;
1220 /* BRAS or BRASL was used. We cannot just relocate those, since
1221 they save the return address in a register. We can, however,
1222 replace them with a LARL+JG sequence. */
1224 /* Make the LARL. */
1228 loffset
= oldloc
+ ilen
- *to
;
1231 if (soffset
!= loffset
&& is_64
)
1233 memcpy (buf
+ 2, &soffset
, 4);
1234 append_insns (to
, 6, buf
);
1236 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1237 an address with the top bit 0, while BRAS/BRASL will write it
1238 with top bit 1. It should not matter much, since linux compilers
1239 use BR and not BSM to return from functions, but it could confuse
1240 some poor stack unwinder. */
1242 /* We'll now be writing a JG. */
1249 /* Compute the new offset and write it to the buffer. */
1250 loffset
= target
- *to
;
1255 int16_t soffset
= loffset
;
1256 if (soffset
!= loffset
)
1258 memcpy (buf
+ 2, &soffset
, 2);
1262 int32_t soffset
= loffset
;
1263 if (soffset
!= loffset
&& is_64
)
1265 memcpy (buf
+ 2, &soffset
, 4);
1268 append_insns (to
, ilen
, buf
);
1273 s390_target::supports_fast_tracepoints ()
1278 /* Implementation of target ops method
1279 "install_fast_tracepoint_jump_pad". */
1282 s390_target::install_fast_tracepoint_jump_pad
1283 (CORE_ADDR tpoint
, CORE_ADDR tpaddr
, CORE_ADDR collector
,
1284 CORE_ADDR lockaddr
, ULONGEST orig_size
, CORE_ADDR
*jump_entry
,
1285 CORE_ADDR
*trampoline
, ULONGEST
*trampoline_size
,
1286 unsigned char *jjump_pad_insn
, ULONGEST
*jjump_pad_insn_size
,
1287 CORE_ADDR
*adjusted_insn_addr
, CORE_ADDR
*adjusted_insn_addr_end
,
1293 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1294 CORE_ADDR buildaddr
= *jump_entry
;
1296 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1297 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1298 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1299 int has_vx
= have_hwcap_s390_vx
;
1301 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1303 CORE_ADDR literals
[4] = {
1310 /* First, store the GPRs. */
1312 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1313 s390_ft_entry_gpr_zarch
);
1315 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1316 s390_ft_entry_gpr_esa
);
1318 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1319 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1321 /* Third, FRs or VRs. */
1323 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1325 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1327 /* Now, the main part of code - store PSWA, take lock, call collector,
1328 leave lock. First, we'll need to fetch 4 literals. */
1330 unsigned char buf
[] = {
1331 0x07, 0x07, /* nopr %r7 */
1332 0x07, 0x07, /* nopr %r7 */
1333 0x07, 0x07, /* nopr %r7 */
1334 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1335 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1336 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1337 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1338 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1341 /* Find the proper start place in buf, so that literals will be
1343 int bufpos
= (buildaddr
+ 2) & 7;
1344 /* Stuff the literals into the buffer. */
1345 for (i
= 0; i
< 4; i
++) {
1346 uint64_t lit
= literals
[i
];
1347 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1349 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1350 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1352 unsigned char buf
[] = {
1353 0x07, 0x07, /* nopr %r7 */
1354 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1355 0, 0, 0, 0, /* tpaddr */
1356 0, 0, 0, 0, /* tpoint */
1357 0, 0, 0, 0, /* collector */
1358 0, 0, 0, 0, /* lockaddr */
1361 /* Find the proper start place in buf, so that literals will be
1363 int bufpos
= (buildaddr
+ 2) & 3;
1364 /* First literal will be saved as the PSWA, make sure it has the high bit
1366 literals
[0] |= 0x80000000;
1367 /* Stuff the literals into the buffer. */
1368 for (i
= 0; i
< 4; i
++) {
1369 uint32_t lit
= literals
[i
];
1370 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1372 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1373 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1376 /* Restore FRs or VRs. */
1378 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1380 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1382 /* Restore misc registers. */
1383 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1385 /* Restore the GPRs. */
1387 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1388 s390_ft_exit_gpr_zarch
);
1390 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1391 s390_ft_exit_gpr_esa
);
1393 /* Now, adjust the original instruction to execute in the jump
1395 *adjusted_insn_addr
= buildaddr
;
1396 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1398 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1401 *adjusted_insn_addr_end
= buildaddr
;
1403 /* Finally, write a jump back to the program. */
1405 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1408 if (is_64
&& offset
!= loffset
)
1411 "E.Jump back from jump pad too far from tracepoint "
1412 "(offset 0x%" PRIx64
" > int33).", loffset
);
1415 memcpy (jbuf
+ 2, &offset
, 4);
1416 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1418 /* The jump pad is now built. Wire in a jump to our jump pad. This
1419 is always done last (by our caller actually), so that we can
1420 install fast tracepoints with threads running. This relies on
1421 the agent's atomic write support. */
1422 loffset
= *jump_entry
- tpaddr
;
1425 if (is_64
&& offset
!= loffset
)
1428 "E.Jump back from jump pad too far from tracepoint "
1429 "(offset 0x%" PRIx64
" > int33).", loffset
);
1432 memcpy (jbuf
+ 2, &offset
, 4);
1433 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1434 *jjump_pad_insn_size
= sizeof jbuf
;
1436 /* Return the end address of our pad. */
1437 *jump_entry
= buildaddr
;
1442 /* Implementation of target ops method
1443 "get_min_fast_tracepoint_insn_len". */
1446 s390_target::get_min_fast_tracepoint_insn_len ()
1448 /* We only support using 6-byte jumps to reach the tracepoint code.
1449 If the tracepoint buffer were allocated sufficiently close (64kiB)
1450 to the executable code, and the traced instruction itself was close
1451 enough to the beginning, we could use 4-byte jumps, but this doesn't
1452 seem to be worth the effort. */
1456 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1459 s390_get_ipa_tdesc_idx (void)
1461 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1462 const struct target_desc
*tdesc
= regcache
->tdesc
;
1465 if (tdesc
== tdesc_s390x_linux64
)
1466 return S390_TDESC_64
;
1467 if (tdesc
== tdesc_s390x_linux64v1
)
1468 return S390_TDESC_64V1
;
1469 if (tdesc
== tdesc_s390x_linux64v2
)
1470 return S390_TDESC_64V2
;
1471 if (tdesc
== tdesc_s390x_te_linux64
)
1472 return S390_TDESC_TE
;
1473 if (tdesc
== tdesc_s390x_vx_linux64
)
1474 return S390_TDESC_VX
;
1475 if (tdesc
== tdesc_s390x_tevx_linux64
)
1476 return S390_TDESC_TEVX
;
1477 if (tdesc
== tdesc_s390x_gs_linux64
)
1478 return S390_TDESC_GS
;
1481 if (tdesc
== tdesc_s390_linux32
)
1482 return S390_TDESC_32
;
1483 if (tdesc
== tdesc_s390_linux32v1
)
1484 return S390_TDESC_32V1
;
1485 if (tdesc
== tdesc_s390_linux32v2
)
1486 return S390_TDESC_32V2
;
1487 if (tdesc
== tdesc_s390_linux64
)
1488 return S390_TDESC_64
;
1489 if (tdesc
== tdesc_s390_linux64v1
)
1490 return S390_TDESC_64V1
;
1491 if (tdesc
== tdesc_s390_linux64v2
)
1492 return S390_TDESC_64V2
;
1493 if (tdesc
== tdesc_s390_te_linux64
)
1494 return S390_TDESC_TE
;
1495 if (tdesc
== tdesc_s390_vx_linux64
)
1496 return S390_TDESC_VX
;
1497 if (tdesc
== tdesc_s390_tevx_linux64
)
1498 return S390_TDESC_TEVX
;
1499 if (tdesc
== tdesc_s390_gs_linux64
)
1500 return S390_TDESC_GS
;
1505 /* Appends given buffer to current_insn_ptr in the target. */
1508 add_insns (const unsigned char *start
, int len
)
1510 CORE_ADDR buildaddr
= current_insn_ptr
;
1513 debug_printf ("Adding %d bytes of insn at %s\n",
1514 len
, paddress (buildaddr
));
1516 append_insns (&buildaddr
, len
, start
);
1517 current_insn_ptr
= buildaddr
;
1520 /* Register usage in emit:
1523 - %r2: top of stack (high word for 31-bit)
1524 - %r3: low word of top of stack (for 31-bit)
1526 - %r6, %r7, %r8: don't use
1529 - %r11: frame pointer
1530 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1531 - %r13: low word of saved top of stack (for 31-bit)
1532 - %r14: return address for calls
1533 - %r15: stack pointer
1537 /* The "emit_prologue" emit_ops method for s390. */
1540 s390_emit_prologue (void)
1542 static const unsigned char buf
[] = {
1543 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1544 0x18, 0x92, /* lr %r9, %r2 */
1545 0x18, 0xa3, /* lr %r10, %r3 */
1546 0x18, 0xbf, /* lr %r11, %r15 */
1548 add_insns (buf
, sizeof buf
);
1551 /* The "emit_epilogue" emit_ops method for s390. */
1554 s390_emit_epilogue (void)
1556 static const unsigned char buf
[] = {
1557 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1558 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1559 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1560 0x07, 0xfe, /* br %r14 */
1562 add_insns (buf
, sizeof buf
);
1565 /* The "emit_add" emit_ops method for s390. */
1568 s390_emit_add (void)
1570 static const unsigned char buf
[] = {
1571 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1572 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1573 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1575 add_insns (buf
, sizeof buf
);
1578 /* The "emit_sub" emit_ops method for s390. */
1581 s390_emit_sub (void)
1583 static const unsigned char buf
[] = {
1584 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1585 0x1f, 0x53, /* slr %r5, %r3 */
1586 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1587 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1588 0x18, 0x35, /* lr %r3, %r5 */
1589 0x18, 0x24, /* lr %r2, %r4 */
1591 add_insns (buf
, sizeof buf
);
1594 /* The "emit_mul" emit_ops method for s390. */
1597 s390_emit_mul (void)
1602 /* The "emit_lsh" emit_ops method for s390. */
1605 s390_emit_lsh (void)
1607 static const unsigned char buf
[] = {
1608 0x18, 0x43, /* lr %r4, %r3 */
1609 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1610 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1611 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1613 add_insns (buf
, sizeof buf
);
1616 /* The "emit_rsh_signed" emit_ops method for s390. */
1619 s390_emit_rsh_signed (void)
1621 static const unsigned char buf
[] = {
1622 0x18, 0x43, /* lr %r4, %r3 */
1623 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1624 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1625 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1627 add_insns (buf
, sizeof buf
);
1630 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1633 s390_emit_rsh_unsigned (void)
1635 static const unsigned char buf
[] = {
1636 0x18, 0x43, /* lr %r4, %r3 */
1637 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1638 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1639 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1641 add_insns (buf
, sizeof buf
);
1644 /* The "emit_ext" emit_ops method for s390. */
1647 s390_emit_ext (int arg
)
1649 unsigned char buf
[] = {
1650 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1651 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1653 add_insns (buf
, sizeof buf
);
1656 /* The "emit_log_not" emit_ops method for s390. */
1659 s390_emit_log_not (void)
1661 static const unsigned char buf
[] = {
1662 0x16, 0x23, /* or %r2, %r3 */
1663 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1664 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1665 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1666 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1669 add_insns (buf
, sizeof buf
);
1672 /* The "emit_bit_and" emit_ops method for s390. */
1675 s390_emit_bit_and (void)
1677 static const unsigned char buf
[] = {
1678 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1679 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1680 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1682 add_insns (buf
, sizeof buf
);
1685 /* The "emit_bit_or" emit_ops method for s390. */
1688 s390_emit_bit_or (void)
1690 static const unsigned char buf
[] = {
1691 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1692 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1693 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1695 add_insns (buf
, sizeof buf
);
1698 /* The "emit_bit_xor" emit_ops method for s390. */
1701 s390_emit_bit_xor (void)
1703 static const unsigned char buf
[] = {
1704 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1705 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1706 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1708 add_insns (buf
, sizeof buf
);
1711 /* The "emit_bit_not" emit_ops method for s390. */
1714 s390_emit_bit_not (void)
1716 static const unsigned char buf
[] = {
1717 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1718 0x17, 0x24, /* xr %r2, %r4 */
1719 0x17, 0x34, /* xr %r3, %r4 */
1721 add_insns (buf
, sizeof buf
);
1724 /* The "emit_equal" emit_ops method for s390. */
1727 s390_emit_equal (void)
1729 s390_emit_bit_xor ();
1730 s390_emit_log_not ();
1733 /* The "emit_less_signed" emit_ops method for s390. */
1736 s390_emit_less_signed (void)
1738 static const unsigned char buf
[] = {
1739 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1740 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1741 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1742 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1743 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1745 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1746 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1748 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1750 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1751 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1753 add_insns (buf
, sizeof buf
);
1756 /* The "emit_less_unsigned" emit_ops method for s390. */
1759 s390_emit_less_unsigned (void)
1761 static const unsigned char buf
[] = {
1762 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1763 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1764 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1765 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1766 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1768 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1769 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1771 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1773 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1774 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1776 add_insns (buf
, sizeof buf
);
1779 /* The "emit_ref" emit_ops method for s390. */
1782 s390_emit_ref (int size
)
1784 static const unsigned char buf1
[] = {
1785 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1786 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1788 static const unsigned char buf2
[] = {
1789 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1790 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1792 static const unsigned char buf4
[] = {
1793 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1794 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1796 static const unsigned char buf8
[] = {
1797 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1802 add_insns (buf1
, sizeof buf1
);
1805 add_insns (buf2
, sizeof buf2
);
1808 add_insns (buf4
, sizeof buf4
);
1811 add_insns (buf8
, sizeof buf8
);
1818 /* The "emit_if_goto" emit_ops method for s390. */
1821 s390_emit_if_goto (int *offset_p
, int *size_p
)
1823 static const unsigned char buf
[] = {
1824 0x16, 0x23, /* or %r2, %r3 */
1825 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1826 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1827 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1829 add_insns (buf
, sizeof buf
);
1836 /* The "emit_goto" emit_ops method for s390 and s390x. */
1839 s390_emit_goto (int *offset_p
, int *size_p
)
1841 static const unsigned char buf
[] = {
1842 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1844 add_insns (buf
, sizeof buf
);
1851 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1854 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1856 long diff
= ((long) (to
- (from
- 2))) / 2;
1858 unsigned char buf
[sizeof sdiff
];
1860 /* We're only doing 4-byte sizes at the moment. */
1861 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1867 memcpy (buf
, &sdiff
, sizeof sdiff
);
1868 target_write_memory (from
, buf
, sizeof sdiff
);
1871 /* Preparation for emitting a literal pool of given size. Loads the address
1872 of the pool into %r1, and jumps over it. Called should emit the pool data
1873 immediately afterwards. Used for both s390 and s390x. */
1876 s390_emit_litpool (int size
)
1878 static const unsigned char nop
[] = {
1881 unsigned char buf
[] = {
1883 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1888 /* buf needs to start at even halfword for litpool to be aligned */
1889 if (current_insn_ptr
& 2)
1890 add_insns (nop
, sizeof nop
);
1894 while ((current_insn_ptr
& 6) != 4)
1895 add_insns (nop
, sizeof nop
);
1897 add_insns (buf
, sizeof buf
);
1900 /* The "emit_const" emit_ops method for s390. */
1903 s390_emit_const (LONGEST num
)
1905 unsigned long long n
= num
;
1906 unsigned char buf_s
[] = {
1907 /* lhi %r3, <num> */
1909 (unsigned char) (num
>> 8), (unsigned char) num
,
1913 static const unsigned char buf_l
[] = {
1914 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1916 if (num
< 0x8000 && num
>= 0)
1918 add_insns (buf_s
, sizeof buf_s
);
1922 s390_emit_litpool (8);
1923 add_insns ((unsigned char *) &n
, sizeof n
);
1924 add_insns (buf_l
, sizeof buf_l
);
1928 /* The "emit_call" emit_ops method for s390. */
1931 s390_emit_call (CORE_ADDR fn
)
1933 unsigned int n
= fn
;
1934 static const unsigned char buf
[] = {
1935 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1936 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1937 0x0d, 0xe1, /* basr %r14, %r1 */
1938 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1940 s390_emit_litpool (4);
1941 add_insns ((unsigned char *) &n
, sizeof n
);
1942 add_insns (buf
, sizeof buf
);
1945 /* The "emit_reg" emit_ops method for s390. */
1948 s390_emit_reg (int reg
)
1950 unsigned char bufpre
[] = {
1953 /* lhi %r3, <reg> */
1954 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1956 add_insns (bufpre
, sizeof bufpre
);
1957 s390_emit_call (get_raw_reg_func_addr ());
1960 /* The "emit_pop" emit_ops method for s390. */
1963 s390_emit_pop (void)
1965 static const unsigned char buf
[] = {
1966 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1967 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1969 add_insns (buf
, sizeof buf
);
1972 /* The "emit_stack_flush" emit_ops method for s390. */
1975 s390_emit_stack_flush (void)
1977 static const unsigned char buf
[] = {
1978 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1979 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1981 add_insns (buf
, sizeof buf
);
1984 /* The "emit_zero_ext" emit_ops method for s390. */
1987 s390_emit_zero_ext (int arg
)
1989 unsigned char buf
[] = {
1990 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1991 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1993 add_insns (buf
, sizeof buf
);
1996 /* The "emit_swap" emit_ops method for s390. */
1999 s390_emit_swap (void)
2001 static const unsigned char buf
[] = {
2002 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
2003 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
2004 0x18, 0x24, /* lr %r2, %r4 */
2005 0x18, 0x35, /* lr %r3, %r5 */
2007 add_insns (buf
, sizeof buf
);
2010 /* The "emit_stack_adjust" emit_ops method for s390. */
2013 s390_emit_stack_adjust (int n
)
2015 unsigned char buf
[] = {
2018 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
2020 add_insns (buf
, sizeof buf
);
2023 /* Sets %r2 to a 32-bit constant. */
2026 s390_emit_set_r2 (int arg1
)
2028 unsigned char buf_s
[] = {
2029 /* lhi %r2, <arg1> */
2030 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
2032 static const unsigned char buf_l
[] = {
2033 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
2035 if (arg1
< 0x8000 && arg1
>= -0x8000)
2037 add_insns (buf_s
, sizeof buf_s
);
2041 s390_emit_litpool (4);
2042 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
2043 add_insns (buf_l
, sizeof buf_l
);
2047 /* The "emit_int_call_1" emit_ops method for s390. */
2050 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2052 /* FN's prototype is `LONGEST(*fn)(int)'. */
2053 s390_emit_set_r2 (arg1
);
2054 s390_emit_call (fn
);
2057 /* The "emit_void_call_2" emit_ops method for s390. */
2060 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2062 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2063 static const unsigned char buf
[] = {
2064 0x18, 0xc2, /* lr %r12, %r2 */
2065 0x18, 0xd3, /* lr %r13, %r3 */
2066 0x18, 0x43, /* lr %r4, %r3 */
2067 0x18, 0x32, /* lr %r3, %r2 */
2069 static const unsigned char buf2
[] = {
2070 0x18, 0x2c, /* lr %r2, %r12 */
2071 0x18, 0x3d, /* lr %r3, %r13 */
2073 add_insns (buf
, sizeof buf
);
2074 s390_emit_set_r2 (arg1
);
2075 s390_emit_call (fn
);
2076 add_insns (buf2
, sizeof buf2
);
2079 /* The "emit_eq_goto" emit_ops method for s390. */
2082 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2084 static const unsigned char buf
[] = {
2085 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2086 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2087 0x16, 0x23, /* or %r2, %r3 */
2088 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2089 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2090 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2092 add_insns (buf
, sizeof buf
);
2099 /* The "emit_ne_goto" emit_ops method for s390. */
2102 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2104 static const unsigned char buf
[] = {
2105 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2106 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2107 0x16, 0x23, /* or %r2, %r3 */
2108 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2109 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2110 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2112 add_insns (buf
, sizeof buf
);
2119 /* The "emit_lt_goto" emit_ops method for s390. */
2122 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2124 static const unsigned char buf
[] = {
2125 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2126 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2127 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2128 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2129 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2131 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2132 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2133 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2135 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2136 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2137 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2140 add_insns (buf
, sizeof buf
);
2147 /* The "emit_le_goto" emit_ops method for s390. */
2150 s390_emit_le_goto (int *offset_p
, int *size_p
)
2152 static const unsigned char buf
[] = {
2153 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2154 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2155 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2156 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2157 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2159 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2160 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2161 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2163 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2164 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2165 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2168 add_insns (buf
, sizeof buf
);
2175 /* The "emit_gt_goto" emit_ops method for s390. */
2178 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2180 static const unsigned char buf
[] = {
2181 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2182 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2183 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2184 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2185 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2187 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2188 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2189 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2191 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2192 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2193 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2196 add_insns (buf
, sizeof buf
);
2203 /* The "emit_ge_goto" emit_ops method for s390. */
2206 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2208 static const unsigned char buf
[] = {
2209 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2210 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2211 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2212 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2213 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2215 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2216 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2217 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2219 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2220 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2221 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2224 add_insns (buf
, sizeof buf
);
2231 /* The "emit_ops" structure for s390. Named _impl to avoid name
2232 collision with s390_emit_ops function. */
2234 static struct emit_ops s390_emit_ops_impl
=
2242 s390_emit_rsh_signed
,
2243 s390_emit_rsh_unsigned
,
2251 s390_emit_less_signed
,
2252 s390_emit_less_unsigned
,
2256 s390_write_goto_address
,
2261 s390_emit_stack_flush
,
2264 s390_emit_stack_adjust
,
2265 s390_emit_int_call_1
,
2266 s390_emit_void_call_2
,
2277 /* The "emit_prologue" emit_ops method for s390x. */
2280 s390x_emit_prologue (void)
2282 static const unsigned char buf
[] = {
2283 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2284 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2285 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2286 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2288 add_insns (buf
, sizeof buf
);
2291 /* The "emit_epilogue" emit_ops method for s390x. */
2294 s390x_emit_epilogue (void)
2296 static const unsigned char buf
[] = {
2297 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2298 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2299 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2300 0x07, 0xfe, /* br %r14 */
2302 add_insns (buf
, sizeof buf
);
2305 /* The "emit_add" emit_ops method for s390x. */
2308 s390x_emit_add (void)
2310 static const unsigned char buf
[] = {
2311 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2312 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2314 add_insns (buf
, sizeof buf
);
2317 /* The "emit_sub" emit_ops method for s390x. */
2320 s390x_emit_sub (void)
2322 static const unsigned char buf
[] = {
2323 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2324 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2325 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2326 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2328 add_insns (buf
, sizeof buf
);
2331 /* The "emit_mul" emit_ops method for s390x. */
2334 s390x_emit_mul (void)
2339 /* The "emit_lsh" emit_ops method for s390x. */
2342 s390x_emit_lsh (void)
2344 static const unsigned char buf
[] = {
2345 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2346 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2347 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2349 add_insns (buf
, sizeof buf
);
2352 /* The "emit_rsh_signed" emit_ops method for s390x. */
2355 s390x_emit_rsh_signed (void)
2357 static const unsigned char buf
[] = {
2358 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2359 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2360 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2362 add_insns (buf
, sizeof buf
);
2365 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2368 s390x_emit_rsh_unsigned (void)
2370 static const unsigned char buf
[] = {
2371 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2372 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2373 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2375 add_insns (buf
, sizeof buf
);
2378 /* The "emit_ext" emit_ops method for s390x. */
2381 s390x_emit_ext (int arg
)
2383 unsigned char buf
[] = {
2384 /* sllg %r2, %r2, <64-arg> */
2385 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2386 /* srag %r2, %r2, <64-arg> */
2387 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2389 add_insns (buf
, sizeof buf
);
2392 /* The "emit_log_not" emit_ops method for s390x. */
2395 s390x_emit_log_not (void)
2397 static const unsigned char buf
[] = {
2398 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2399 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2400 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2402 add_insns (buf
, sizeof buf
);
2405 /* The "emit_bit_and" emit_ops method for s390x. */
2408 s390x_emit_bit_and (void)
2410 static const unsigned char buf
[] = {
2411 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2412 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2414 add_insns (buf
, sizeof buf
);
2417 /* The "emit_bit_or" emit_ops method for s390x. */
2420 s390x_emit_bit_or (void)
2422 static const unsigned char buf
[] = {
2423 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2424 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2426 add_insns (buf
, sizeof buf
);
2429 /* The "emit_bit_xor" emit_ops method for s390x. */
2432 s390x_emit_bit_xor (void)
2434 static const unsigned char buf
[] = {
2435 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2436 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2438 add_insns (buf
, sizeof buf
);
2441 /* The "emit_bit_not" emit_ops method for s390x. */
2444 s390x_emit_bit_not (void)
2446 static const unsigned char buf
[] = {
2447 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2448 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2450 add_insns (buf
, sizeof buf
);
2453 /* The "emit_equal" emit_ops method for s390x. */
2456 s390x_emit_equal (void)
2458 s390x_emit_bit_xor ();
2459 s390x_emit_log_not ();
2462 /* The "emit_less_signed" emit_ops method for s390x. */
2465 s390x_emit_less_signed (void)
2467 static const unsigned char buf
[] = {
2468 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2469 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2470 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2471 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2473 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2475 add_insns (buf
, sizeof buf
);
2478 /* The "emit_less_unsigned" emit_ops method for s390x. */
2481 s390x_emit_less_unsigned (void)
2483 static const unsigned char buf
[] = {
2484 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2485 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2486 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2487 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2489 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2491 add_insns (buf
, sizeof buf
);
2494 /* The "emit_ref" emit_ops method for s390x. */
2497 s390x_emit_ref (int size
)
2499 static const unsigned char buf1
[] = {
2500 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2502 static const unsigned char buf2
[] = {
2503 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2505 static const unsigned char buf4
[] = {
2506 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2508 static const unsigned char buf8
[] = {
2509 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2514 add_insns (buf1
, sizeof buf1
);
2517 add_insns (buf2
, sizeof buf2
);
2520 add_insns (buf4
, sizeof buf4
);
2523 add_insns (buf8
, sizeof buf8
);
2530 /* The "emit_if_goto" emit_ops method for s390x. */
2533 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2535 static const unsigned char buf
[] = {
2536 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2537 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2538 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2539 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2541 add_insns (buf
, sizeof buf
);
2548 /* The "emit_const" emit_ops method for s390x. */
2551 s390x_emit_const (LONGEST num
)
2553 unsigned long long n
= num
;
2554 unsigned char buf_s
[] = {
2555 /* lghi %r2, <num> */
2556 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2558 static const unsigned char buf_l
[] = {
2559 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2561 if (num
< 0x8000 && num
>= -0x8000)
2563 add_insns (buf_s
, sizeof buf_s
);
2567 s390_emit_litpool (8);
2568 add_insns ((unsigned char *) &n
, sizeof n
);
2569 add_insns (buf_l
, sizeof buf_l
);
2573 /* The "emit_call" emit_ops method for s390x. */
2576 s390x_emit_call (CORE_ADDR fn
)
2578 unsigned long n
= fn
;
2579 static const unsigned char buf
[] = {
2580 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2581 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2582 0x0d, 0xe1, /* basr %r14, %r1 */
2583 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2585 s390_emit_litpool (8);
2586 add_insns ((unsigned char *) &n
, sizeof n
);
2587 add_insns (buf
, sizeof buf
);
2590 /* The "emit_reg" emit_ops method for s390x. */
2593 s390x_emit_reg (int reg
)
2595 unsigned char buf
[] = {
2597 0xb9, 0x04, 0x00, 0x29,
2598 /* lghi %r3, <reg> */
2599 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2601 add_insns (buf
, sizeof buf
);
2602 s390x_emit_call (get_raw_reg_func_addr ());
2605 /* The "emit_pop" emit_ops method for s390x. */
2608 s390x_emit_pop (void)
2610 static const unsigned char buf
[] = {
2611 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2612 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2614 add_insns (buf
, sizeof buf
);
2617 /* The "emit_stack_flush" emit_ops method for s390x. */
2620 s390x_emit_stack_flush (void)
2622 static const unsigned char buf
[] = {
2623 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2624 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2626 add_insns (buf
, sizeof buf
);
2629 /* The "emit_zero_ext" emit_ops method for s390x. */
2632 s390x_emit_zero_ext (int arg
)
2634 unsigned char buf
[] = {
2635 /* sllg %r2, %r2, <64-arg> */
2636 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2637 /* srlg %r2, %r2, <64-arg> */
2638 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2640 add_insns (buf
, sizeof buf
);
2643 /* The "emit_swap" emit_ops method for s390x. */
2646 s390x_emit_swap (void)
2648 static const unsigned char buf
[] = {
2649 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2650 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2651 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2653 add_insns (buf
, sizeof buf
);
2656 /* The "emit_stack_adjust" emit_ops method for s390x. */
2659 s390x_emit_stack_adjust (int n
)
2661 unsigned char buf
[] = {
2662 /* aghi %r15, 8*n */
2664 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2666 add_insns (buf
, sizeof buf
);
2669 /* The "emit_int_call_1" emit_ops method for s390x. */
2672 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2674 /* FN's prototype is `LONGEST(*fn)(int)'. */
2675 s390x_emit_const (arg1
);
2676 s390x_emit_call (fn
);
2679 /* The "emit_void_call_2" emit_ops method for s390x. */
2682 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2684 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2685 static const unsigned char buf
[] = {
2686 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2687 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2689 static const unsigned char buf2
[] = {
2690 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2692 add_insns (buf
, sizeof buf
);
2693 s390x_emit_const (arg1
);
2694 s390x_emit_call (fn
);
2695 add_insns (buf2
, sizeof buf2
);
2698 /* The "emit_eq_goto" emit_ops method for s390x. */
2701 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2703 static const unsigned char buf
[] = {
2704 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2705 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2706 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2707 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2709 add_insns (buf
, sizeof buf
);
2716 /* The "emit_ne_goto" emit_ops method for s390x. */
2719 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2721 static const unsigned char buf
[] = {
2722 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2723 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2724 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2725 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2727 add_insns (buf
, sizeof buf
);
2734 /* The "emit_lt_goto" emit_ops method for s390x. */
2737 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2739 static const unsigned char buf
[] = {
2740 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2741 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2742 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2743 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2745 add_insns (buf
, sizeof buf
);
2752 /* The "emit_le_goto" emit_ops method for s390x. */
2755 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2757 static const unsigned char buf
[] = {
2758 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2759 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2760 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2761 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2763 add_insns (buf
, sizeof buf
);
2770 /* The "emit_gt_goto" emit_ops method for s390x. */
2773 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2775 static const unsigned char buf
[] = {
2776 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2777 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2778 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2779 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2781 add_insns (buf
, sizeof buf
);
2788 /* The "emit_ge_goto" emit_ops method for s390x. */
2791 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2793 static const unsigned char buf
[] = {
2794 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2795 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2796 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2797 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2799 add_insns (buf
, sizeof buf
);
2806 /* The "emit_ops" structure for s390x. */
2808 static struct emit_ops s390x_emit_ops
=
2810 s390x_emit_prologue
,
2811 s390x_emit_epilogue
,
2816 s390x_emit_rsh_signed
,
2817 s390x_emit_rsh_unsigned
,
2825 s390x_emit_less_signed
,
2826 s390x_emit_less_unsigned
,
2830 s390_write_goto_address
,
2835 s390x_emit_stack_flush
,
2836 s390x_emit_zero_ext
,
2838 s390x_emit_stack_adjust
,
2839 s390x_emit_int_call_1
,
2840 s390x_emit_void_call_2
,
2850 /* The "emit_ops" target ops method. */
2853 s390_target::emit_ops ()
2856 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2858 if (register_size (regcache
->tdesc
, 0) == 8)
2859 return &s390x_emit_ops
;
2862 return &s390_emit_ops_impl
;
2865 struct linux_target_ops the_low_target
= {
2866 NULL
, /* supports_range_stepping */
2867 s390_supports_hardware_single_step
,
2868 NULL
, /* get_syscall_trapinfo */
2869 s390_get_ipa_tdesc_idx
,
2872 /* The linux target ops object. */
2874 linux_process_target
*the_linux_target
= &the_s390_target
;
2877 initialize_low_arch (void)
2879 /* Initialize the Linux target descriptions. */
2881 init_registers_s390_linux32 ();
2882 init_registers_s390_linux32v1 ();
2883 init_registers_s390_linux32v2 ();
2884 init_registers_s390_linux64 ();
2885 init_registers_s390_linux64v1 ();
2886 init_registers_s390_linux64v2 ();
2887 init_registers_s390_te_linux64 ();
2888 init_registers_s390_vx_linux64 ();
2889 init_registers_s390_tevx_linux64 ();
2890 init_registers_s390_gs_linux64 ();
2892 init_registers_s390x_linux64 ();
2893 init_registers_s390x_linux64v1 ();
2894 init_registers_s390x_linux64v2 ();
2895 init_registers_s390x_te_linux64 ();
2896 init_registers_s390x_vx_linux64 ();
2897 init_registers_s390x_tevx_linux64 ();
2898 init_registers_s390x_gs_linux64 ();
2901 initialize_regsets_info (&s390_regsets_info
);
2902 initialize_regsets_info (&s390_regsets_info_3264
);