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 static struct usrregs_info s390_usrregs_info
=
732 static struct regsets_info s390_regsets_info
=
734 s390_regsets
, /* regsets */
736 NULL
, /* disabled_regsets */
739 static struct regs_info myregs_info
=
741 NULL
, /* regset_bitmap */
746 static struct usrregs_info s390_usrregs_info_3264
=
752 static struct regsets_info s390_regsets_info_3264
=
754 s390_regsets
, /* regsets */
756 NULL
, /* disabled_regsets */
759 static struct regs_info regs_info_3264
=
761 NULL
, /* regset_bitmap */
762 &s390_usrregs_info_3264
,
763 &s390_regsets_info_3264
767 s390_target::get_regs_info ()
769 if (have_hwcap_s390_high_gprs
)
772 const struct target_desc
*tdesc
= current_process ()->tdesc
;
774 if (register_size (tdesc
, 0) == 4)
775 return ®s_info_3264
;
777 return ®s_info_3264
;
783 /* The "supports_tracepoints" target ops method. */
786 s390_target::supports_tracepoints ()
791 /* Implementation of linux target ops method "low_get_thread_area". */
794 s390_target::low_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
796 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
798 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
800 if (register_size (regcache
->tdesc
, 0) == 4)
801 res
&= 0xffffffffull
;
808 /* Fast tracepoint support.
810 The register save area on stack is identical for all targets:
812 0x000+i*0x10: VR0-VR31
819 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
820 Likewise, if there's no VX support, we just store the FRs into the slots
821 of low VR halves. The agent code is responsible for rearranging that
824 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
825 one trick used at the very beginning: since there's no way to allocate
826 stack space without destroying CC (lay instruction can do it, but it's
827 only supported on later CPUs), we take 4 different execution paths for
828 every possible value of CC, allocate stack space, save %r0, stuff the
829 CC value in %r0 (shifted to match its position in PSWM high word),
830 then branch to common path. */
832 static const unsigned char s390_ft_entry_gpr_esa
[] = {
833 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
834 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
835 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
837 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
838 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
839 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
840 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
842 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
843 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
844 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
845 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
847 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
848 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
849 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
850 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
852 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
853 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
854 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
856 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
857 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
858 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
859 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
860 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
861 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
862 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
863 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
864 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
865 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
866 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
867 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
868 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
869 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
870 /* Compute original value of %r15 and store it. We use ahi instead
871 of la to preserve the whole value, and not just the low 31 bits.
872 This is not particularly important here, but essential in the
873 zarch case where someone might be using the high word of %r15
874 as an extra register. */
875 0x18, 0x1f, /* lr %r1, %r15 */
876 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
877 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
880 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
881 target. Same as above, except this time we can use load/store multiple,
882 since the 64-bit regs are tightly packed. */
884 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
885 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
886 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
887 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
889 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
890 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
891 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
892 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
894 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
895 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
896 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
897 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
899 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
900 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
901 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
902 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
904 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
905 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
906 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
908 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
909 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
910 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
913 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
914 current PSWM (read by epsw) and CC from entry (in %r0). */
916 static const unsigned char s390_ft_entry_misc
[] = {
917 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
918 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
919 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
920 0x14, 0x21, /* nr %r2, %r1 */
921 0x16, 0x20, /* or %r2, %r0 */
922 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
923 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
924 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
927 /* Code sequence saving FRs, used if VX not supported. */
929 static const unsigned char s390_ft_entry_fr
[] = {
930 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
931 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
932 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
933 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
934 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
935 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
936 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
937 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
938 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
939 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
940 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
941 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
942 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
943 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
944 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
945 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
948 /* Code sequence saving VRs, used if VX not supported. */
950 static const unsigned char s390_ft_entry_vr
[] = {
951 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
952 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
955 /* Code sequence doing the collection call for 31-bit target. %r1 contains
956 the address of the literal pool. */
958 static const unsigned char s390_ft_main_31
[] = {
959 /* Load the literals into registers. */
960 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
961 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
962 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
963 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
964 /* Save original PSWA (tracepoint address | 0x80000000). */
965 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
966 /* Construct a collecting_t object at %r15+0x2e0. */
967 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
968 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
969 /* Move its address to %r0. */
970 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
973 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
974 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
975 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
976 /* Address of the register save block to %r3. */
977 0x18, 0x3f, /* lr %r3, %r15 */
978 /* Make a stack frame, so that we can call the collector. */
979 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
981 0x0d, 0xe4, /* basr %r14, %r4 */
982 /* And get rid of the stack frame again. */
983 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
984 /* Leave the lock. */
985 0x07, 0xf0, /* br %r0 */
986 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
987 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
990 /* Code sequence doing the collection call for 64-bit target. %r1 contains
991 the address of the literal pool. */
993 static const unsigned char s390_ft_main_64
[] = {
994 /* Load the literals into registers. */
995 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
996 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
997 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
998 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
999 /* Save original PSWA (tracepoint address). */
1000 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
1001 /* Construct a collecting_t object at %r15+0x2e0. */
1002 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
1003 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
1004 /* Move its address to %r0. */
1005 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
1006 /* Take the lock. */
1008 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1009 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
1010 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
1011 /* Address of the register save block to %r3. */
1012 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
1013 /* Make a stack frame, so that we can call the collector. */
1014 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1016 0x0d, 0xe4, /* basr %r14, %r4 */
1017 /* And get rid of the stack frame again. */
1018 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1019 /* Leave the lock. */
1020 0x07, 0xf0, /* br %r0 */
1021 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1022 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1025 /* Code sequence restoring FRs, for targets with no VX support. */
1027 static const unsigned char s390_ft_exit_fr
[] = {
1028 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1029 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1030 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1031 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1032 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1033 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1034 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1035 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1036 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1037 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1038 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1039 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1040 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1041 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1042 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1043 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1046 /* Code sequence restoring VRs. */
1048 static const unsigned char s390_ft_exit_vr
[] = {
1049 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1050 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1053 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1054 modified by C code, so we use the alr instruction to restore it by
1055 manufacturing an operand that'll result in the original flags. */
1057 static const unsigned char s390_ft_exit_misc
[] = {
1058 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1059 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1060 /* Extract CC to high 2 bits of %r0. */
1061 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1062 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1063 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1064 will have carry iff CC bit 1 is set - resulting in the same flags
1066 0x1e, 0x00, /* alr %r0, %r0 */
1067 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1070 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1072 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1073 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1074 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1075 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1076 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1077 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1078 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1079 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1080 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1081 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1082 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1083 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1084 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1085 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1086 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1087 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1088 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1091 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1094 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1095 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1098 /* Writes instructions to target, updating the to pointer. */
1101 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1103 target_write_memory (*to
, buf
, len
);
1107 /* Relocates an instruction from oldloc to *to, updating to. */
1110 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1115 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1118 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1121 else if (buf
[0] < 0xc0)
1127 case 0x05: /* BALR */
1128 case 0x0c: /* BASSM */
1129 case 0x0d: /* BASR */
1130 case 0x45: /* BAL */
1131 case 0x4d: /* BAS */
1132 /* These save a return address and mess around with registers.
1133 We can't relocate them. */
1135 case 0x84: /* BRXH */
1136 case 0x85: /* BRXLE */
1141 /* BRC, BRAS, BRCT, BRCTG */
1142 if (op2
>= 4 && op2
<= 7)
1150 /* LARL, BRCL, BRASL */
1151 if (op2
== 0 || op2
== 4 || op2
== 5)
1159 /* PC-relative addressing instructions. */
1162 case 0xc5: /* BPRP */
1163 case 0xc7: /* BPP */
1164 /* Branch prediction - just skip it. */
1176 case 0x44: /* BRXHG */
1177 case 0x45: /* BRXLG */
1178 case 0x64: /* CGRJ */
1179 case 0x65: /* CLGRJ */
1180 case 0x76: /* CRJ */
1181 case 0x77: /* CLRJ */
1190 /* We'll have to relocate an instruction with a PC-relative field.
1191 First, compute the target. */
1192 int64_t loffset
= 0;
1196 int16_t soffset
= 0;
1197 memcpy (&soffset
, buf
+ 2, 2);
1202 int32_t soffset
= 0;
1203 memcpy (&soffset
, buf
+ 2, 4);
1206 target
= oldloc
+ loffset
* 2;
1208 target
&= 0x7fffffff;
1212 /* BRAS or BRASL was used. We cannot just relocate those, since
1213 they save the return address in a register. We can, however,
1214 replace them with a LARL+JG sequence. */
1216 /* Make the LARL. */
1220 loffset
= oldloc
+ ilen
- *to
;
1223 if (soffset
!= loffset
&& is_64
)
1225 memcpy (buf
+ 2, &soffset
, 4);
1226 append_insns (to
, 6, buf
);
1228 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1229 an address with the top bit 0, while BRAS/BRASL will write it
1230 with top bit 1. It should not matter much, since linux compilers
1231 use BR and not BSM to return from functions, but it could confuse
1232 some poor stack unwinder. */
1234 /* We'll now be writing a JG. */
1241 /* Compute the new offset and write it to the buffer. */
1242 loffset
= target
- *to
;
1247 int16_t soffset
= loffset
;
1248 if (soffset
!= loffset
)
1250 memcpy (buf
+ 2, &soffset
, 2);
1254 int32_t soffset
= loffset
;
1255 if (soffset
!= loffset
&& is_64
)
1257 memcpy (buf
+ 2, &soffset
, 4);
1260 append_insns (to
, ilen
, buf
);
1265 s390_target::supports_fast_tracepoints ()
1270 /* Implementation of target ops method
1271 "install_fast_tracepoint_jump_pad". */
1274 s390_target::install_fast_tracepoint_jump_pad
1275 (CORE_ADDR tpoint
, CORE_ADDR tpaddr
, CORE_ADDR collector
,
1276 CORE_ADDR lockaddr
, ULONGEST orig_size
, CORE_ADDR
*jump_entry
,
1277 CORE_ADDR
*trampoline
, ULONGEST
*trampoline_size
,
1278 unsigned char *jjump_pad_insn
, ULONGEST
*jjump_pad_insn_size
,
1279 CORE_ADDR
*adjusted_insn_addr
, CORE_ADDR
*adjusted_insn_addr_end
,
1285 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1286 CORE_ADDR buildaddr
= *jump_entry
;
1288 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1289 int is_64
= register_size (regcache
->tdesc
, 0) == 8;
1290 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1291 int has_vx
= have_hwcap_s390_vx
;
1293 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1295 CORE_ADDR literals
[4] = {
1302 /* First, store the GPRs. */
1304 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1305 s390_ft_entry_gpr_zarch
);
1307 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1308 s390_ft_entry_gpr_esa
);
1310 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1311 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1313 /* Third, FRs or VRs. */
1315 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1317 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1319 /* Now, the main part of code - store PSWA, take lock, call collector,
1320 leave lock. First, we'll need to fetch 4 literals. */
1322 unsigned char buf
[] = {
1323 0x07, 0x07, /* nopr %r7 */
1324 0x07, 0x07, /* nopr %r7 */
1325 0x07, 0x07, /* nopr %r7 */
1326 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1327 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1328 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1329 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1330 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1333 /* Find the proper start place in buf, so that literals will be
1335 int bufpos
= (buildaddr
+ 2) & 7;
1336 /* Stuff the literals into the buffer. */
1337 for (i
= 0; i
< 4; i
++) {
1338 uint64_t lit
= literals
[i
];
1339 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1341 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1342 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1344 unsigned char buf
[] = {
1345 0x07, 0x07, /* nopr %r7 */
1346 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1347 0, 0, 0, 0, /* tpaddr */
1348 0, 0, 0, 0, /* tpoint */
1349 0, 0, 0, 0, /* collector */
1350 0, 0, 0, 0, /* lockaddr */
1353 /* Find the proper start place in buf, so that literals will be
1355 int bufpos
= (buildaddr
+ 2) & 3;
1356 /* First literal will be saved as the PSWA, make sure it has the high bit
1358 literals
[0] |= 0x80000000;
1359 /* Stuff the literals into the buffer. */
1360 for (i
= 0; i
< 4; i
++) {
1361 uint32_t lit
= literals
[i
];
1362 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1364 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1365 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1368 /* Restore FRs or VRs. */
1370 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1372 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1374 /* Restore misc registers. */
1375 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1377 /* Restore the GPRs. */
1379 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1380 s390_ft_exit_gpr_zarch
);
1382 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1383 s390_ft_exit_gpr_esa
);
1385 /* Now, adjust the original instruction to execute in the jump
1387 *adjusted_insn_addr
= buildaddr
;
1388 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1390 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1393 *adjusted_insn_addr_end
= buildaddr
;
1395 /* Finally, write a jump back to the program. */
1397 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1400 if (is_64
&& offset
!= loffset
)
1403 "E.Jump back from jump pad too far from tracepoint "
1404 "(offset 0x%" PRIx64
" > int33).", loffset
);
1407 memcpy (jbuf
+ 2, &offset
, 4);
1408 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1410 /* The jump pad is now built. Wire in a jump to our jump pad. This
1411 is always done last (by our caller actually), so that we can
1412 install fast tracepoints with threads running. This relies on
1413 the agent's atomic write support. */
1414 loffset
= *jump_entry
- tpaddr
;
1417 if (is_64
&& offset
!= loffset
)
1420 "E.Jump back from jump pad too far from tracepoint "
1421 "(offset 0x%" PRIx64
" > int33).", loffset
);
1424 memcpy (jbuf
+ 2, &offset
, 4);
1425 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1426 *jjump_pad_insn_size
= sizeof jbuf
;
1428 /* Return the end address of our pad. */
1429 *jump_entry
= buildaddr
;
1434 /* Implementation of target ops method
1435 "get_min_fast_tracepoint_insn_len". */
1438 s390_target::get_min_fast_tracepoint_insn_len ()
1440 /* We only support using 6-byte jumps to reach the tracepoint code.
1441 If the tracepoint buffer were allocated sufficiently close (64kiB)
1442 to the executable code, and the traced instruction itself was close
1443 enough to the beginning, we could use 4-byte jumps, but this doesn't
1444 seem to be worth the effort. */
1448 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1451 s390_get_ipa_tdesc_idx (void)
1453 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
1454 const struct target_desc
*tdesc
= regcache
->tdesc
;
1457 if (tdesc
== tdesc_s390x_linux64
)
1458 return S390_TDESC_64
;
1459 if (tdesc
== tdesc_s390x_linux64v1
)
1460 return S390_TDESC_64V1
;
1461 if (tdesc
== tdesc_s390x_linux64v2
)
1462 return S390_TDESC_64V2
;
1463 if (tdesc
== tdesc_s390x_te_linux64
)
1464 return S390_TDESC_TE
;
1465 if (tdesc
== tdesc_s390x_vx_linux64
)
1466 return S390_TDESC_VX
;
1467 if (tdesc
== tdesc_s390x_tevx_linux64
)
1468 return S390_TDESC_TEVX
;
1469 if (tdesc
== tdesc_s390x_gs_linux64
)
1470 return S390_TDESC_GS
;
1473 if (tdesc
== tdesc_s390_linux32
)
1474 return S390_TDESC_32
;
1475 if (tdesc
== tdesc_s390_linux32v1
)
1476 return S390_TDESC_32V1
;
1477 if (tdesc
== tdesc_s390_linux32v2
)
1478 return S390_TDESC_32V2
;
1479 if (tdesc
== tdesc_s390_linux64
)
1480 return S390_TDESC_64
;
1481 if (tdesc
== tdesc_s390_linux64v1
)
1482 return S390_TDESC_64V1
;
1483 if (tdesc
== tdesc_s390_linux64v2
)
1484 return S390_TDESC_64V2
;
1485 if (tdesc
== tdesc_s390_te_linux64
)
1486 return S390_TDESC_TE
;
1487 if (tdesc
== tdesc_s390_vx_linux64
)
1488 return S390_TDESC_VX
;
1489 if (tdesc
== tdesc_s390_tevx_linux64
)
1490 return S390_TDESC_TEVX
;
1491 if (tdesc
== tdesc_s390_gs_linux64
)
1492 return S390_TDESC_GS
;
1497 /* Appends given buffer to current_insn_ptr in the target. */
1500 add_insns (const unsigned char *start
, int len
)
1502 CORE_ADDR buildaddr
= current_insn_ptr
;
1505 debug_printf ("Adding %d bytes of insn at %s\n",
1506 len
, paddress (buildaddr
));
1508 append_insns (&buildaddr
, len
, start
);
1509 current_insn_ptr
= buildaddr
;
1512 /* Register usage in emit:
1515 - %r2: top of stack (high word for 31-bit)
1516 - %r3: low word of top of stack (for 31-bit)
1518 - %r6, %r7, %r8: don't use
1521 - %r11: frame pointer
1522 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1523 - %r13: low word of saved top of stack (for 31-bit)
1524 - %r14: return address for calls
1525 - %r15: stack pointer
1529 /* The "emit_prologue" emit_ops method for s390. */
1532 s390_emit_prologue (void)
1534 static const unsigned char buf
[] = {
1535 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1536 0x18, 0x92, /* lr %r9, %r2 */
1537 0x18, 0xa3, /* lr %r10, %r3 */
1538 0x18, 0xbf, /* lr %r11, %r15 */
1540 add_insns (buf
, sizeof buf
);
1543 /* The "emit_epilogue" emit_ops method for s390. */
1546 s390_emit_epilogue (void)
1548 static const unsigned char buf
[] = {
1549 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1550 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1551 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1552 0x07, 0xfe, /* br %r14 */
1554 add_insns (buf
, sizeof buf
);
1557 /* The "emit_add" emit_ops method for s390. */
1560 s390_emit_add (void)
1562 static const unsigned char buf
[] = {
1563 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1564 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1565 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1567 add_insns (buf
, sizeof buf
);
1570 /* The "emit_sub" emit_ops method for s390. */
1573 s390_emit_sub (void)
1575 static const unsigned char buf
[] = {
1576 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1577 0x1f, 0x53, /* slr %r5, %r3 */
1578 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1579 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1580 0x18, 0x35, /* lr %r3, %r5 */
1581 0x18, 0x24, /* lr %r2, %r4 */
1583 add_insns (buf
, sizeof buf
);
1586 /* The "emit_mul" emit_ops method for s390. */
1589 s390_emit_mul (void)
1594 /* The "emit_lsh" emit_ops method for s390. */
1597 s390_emit_lsh (void)
1599 static const unsigned char buf
[] = {
1600 0x18, 0x43, /* lr %r4, %r3 */
1601 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1602 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1603 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1605 add_insns (buf
, sizeof buf
);
1608 /* The "emit_rsh_signed" emit_ops method for s390. */
1611 s390_emit_rsh_signed (void)
1613 static const unsigned char buf
[] = {
1614 0x18, 0x43, /* lr %r4, %r3 */
1615 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1616 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1617 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1619 add_insns (buf
, sizeof buf
);
1622 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1625 s390_emit_rsh_unsigned (void)
1627 static const unsigned char buf
[] = {
1628 0x18, 0x43, /* lr %r4, %r3 */
1629 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1630 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1631 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1633 add_insns (buf
, sizeof buf
);
1636 /* The "emit_ext" emit_ops method for s390. */
1639 s390_emit_ext (int arg
)
1641 unsigned char buf
[] = {
1642 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1643 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1645 add_insns (buf
, sizeof buf
);
1648 /* The "emit_log_not" emit_ops method for s390. */
1651 s390_emit_log_not (void)
1653 static const unsigned char buf
[] = {
1654 0x16, 0x23, /* or %r2, %r3 */
1655 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1656 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1657 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1658 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1661 add_insns (buf
, sizeof buf
);
1664 /* The "emit_bit_and" emit_ops method for s390. */
1667 s390_emit_bit_and (void)
1669 static const unsigned char buf
[] = {
1670 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1671 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1672 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1674 add_insns (buf
, sizeof buf
);
1677 /* The "emit_bit_or" emit_ops method for s390. */
1680 s390_emit_bit_or (void)
1682 static const unsigned char buf
[] = {
1683 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1684 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1685 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1687 add_insns (buf
, sizeof buf
);
1690 /* The "emit_bit_xor" emit_ops method for s390. */
1693 s390_emit_bit_xor (void)
1695 static const unsigned char buf
[] = {
1696 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1697 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1698 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1700 add_insns (buf
, sizeof buf
);
1703 /* The "emit_bit_not" emit_ops method for s390. */
1706 s390_emit_bit_not (void)
1708 static const unsigned char buf
[] = {
1709 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1710 0x17, 0x24, /* xr %r2, %r4 */
1711 0x17, 0x34, /* xr %r3, %r4 */
1713 add_insns (buf
, sizeof buf
);
1716 /* The "emit_equal" emit_ops method for s390. */
1719 s390_emit_equal (void)
1721 s390_emit_bit_xor ();
1722 s390_emit_log_not ();
1725 /* The "emit_less_signed" emit_ops method for s390. */
1728 s390_emit_less_signed (void)
1730 static const unsigned char buf
[] = {
1731 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1732 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1733 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1734 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1735 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1737 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1738 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1740 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1742 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1743 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1745 add_insns (buf
, sizeof buf
);
1748 /* The "emit_less_unsigned" emit_ops method for s390. */
1751 s390_emit_less_unsigned (void)
1753 static const unsigned char buf
[] = {
1754 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1755 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1756 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1757 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1758 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1760 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1761 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1763 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1765 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1766 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1768 add_insns (buf
, sizeof buf
);
1771 /* The "emit_ref" emit_ops method for s390. */
1774 s390_emit_ref (int size
)
1776 static const unsigned char buf1
[] = {
1777 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1778 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1780 static const unsigned char buf2
[] = {
1781 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1782 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1784 static const unsigned char buf4
[] = {
1785 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1786 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1788 static const unsigned char buf8
[] = {
1789 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1794 add_insns (buf1
, sizeof buf1
);
1797 add_insns (buf2
, sizeof buf2
);
1800 add_insns (buf4
, sizeof buf4
);
1803 add_insns (buf8
, sizeof buf8
);
1810 /* The "emit_if_goto" emit_ops method for s390. */
1813 s390_emit_if_goto (int *offset_p
, int *size_p
)
1815 static const unsigned char buf
[] = {
1816 0x16, 0x23, /* or %r2, %r3 */
1817 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1818 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1819 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1821 add_insns (buf
, sizeof buf
);
1828 /* The "emit_goto" emit_ops method for s390 and s390x. */
1831 s390_emit_goto (int *offset_p
, int *size_p
)
1833 static const unsigned char buf
[] = {
1834 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1836 add_insns (buf
, sizeof buf
);
1843 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1846 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1848 long diff
= ((long) (to
- (from
- 2))) / 2;
1850 unsigned char buf
[sizeof sdiff
];
1852 /* We're only doing 4-byte sizes at the moment. */
1853 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1859 memcpy (buf
, &sdiff
, sizeof sdiff
);
1860 target_write_memory (from
, buf
, sizeof sdiff
);
1863 /* Preparation for emitting a literal pool of given size. Loads the address
1864 of the pool into %r1, and jumps over it. Called should emit the pool data
1865 immediately afterwards. Used for both s390 and s390x. */
1868 s390_emit_litpool (int size
)
1870 static const unsigned char nop
[] = {
1873 unsigned char buf
[] = {
1875 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1880 /* buf needs to start at even halfword for litpool to be aligned */
1881 if (current_insn_ptr
& 2)
1882 add_insns (nop
, sizeof nop
);
1886 while ((current_insn_ptr
& 6) != 4)
1887 add_insns (nop
, sizeof nop
);
1889 add_insns (buf
, sizeof buf
);
1892 /* The "emit_const" emit_ops method for s390. */
1895 s390_emit_const (LONGEST num
)
1897 unsigned long long n
= num
;
1898 unsigned char buf_s
[] = {
1899 /* lhi %r3, <num> */
1901 (unsigned char) (num
>> 8), (unsigned char) num
,
1905 static const unsigned char buf_l
[] = {
1906 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1908 if (num
< 0x8000 && num
>= 0)
1910 add_insns (buf_s
, sizeof buf_s
);
1914 s390_emit_litpool (8);
1915 add_insns ((unsigned char *) &n
, sizeof n
);
1916 add_insns (buf_l
, sizeof buf_l
);
1920 /* The "emit_call" emit_ops method for s390. */
1923 s390_emit_call (CORE_ADDR fn
)
1925 unsigned int n
= fn
;
1926 static const unsigned char buf
[] = {
1927 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1928 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1929 0x0d, 0xe1, /* basr %r14, %r1 */
1930 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1932 s390_emit_litpool (4);
1933 add_insns ((unsigned char *) &n
, sizeof n
);
1934 add_insns (buf
, sizeof buf
);
1937 /* The "emit_reg" emit_ops method for s390. */
1940 s390_emit_reg (int reg
)
1942 unsigned char bufpre
[] = {
1945 /* lhi %r3, <reg> */
1946 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1948 add_insns (bufpre
, sizeof bufpre
);
1949 s390_emit_call (get_raw_reg_func_addr ());
1952 /* The "emit_pop" emit_ops method for s390. */
1955 s390_emit_pop (void)
1957 static const unsigned char buf
[] = {
1958 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1959 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1961 add_insns (buf
, sizeof buf
);
1964 /* The "emit_stack_flush" emit_ops method for s390. */
1967 s390_emit_stack_flush (void)
1969 static const unsigned char buf
[] = {
1970 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1971 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1973 add_insns (buf
, sizeof buf
);
1976 /* The "emit_zero_ext" emit_ops method for s390. */
1979 s390_emit_zero_ext (int arg
)
1981 unsigned char buf
[] = {
1982 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1983 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1985 add_insns (buf
, sizeof buf
);
1988 /* The "emit_swap" emit_ops method for s390. */
1991 s390_emit_swap (void)
1993 static const unsigned char buf
[] = {
1994 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1995 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1996 0x18, 0x24, /* lr %r2, %r4 */
1997 0x18, 0x35, /* lr %r3, %r5 */
1999 add_insns (buf
, sizeof buf
);
2002 /* The "emit_stack_adjust" emit_ops method for s390. */
2005 s390_emit_stack_adjust (int n
)
2007 unsigned char buf
[] = {
2010 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
2012 add_insns (buf
, sizeof buf
);
2015 /* Sets %r2 to a 32-bit constant. */
2018 s390_emit_set_r2 (int arg1
)
2020 unsigned char buf_s
[] = {
2021 /* lhi %r2, <arg1> */
2022 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
2024 static const unsigned char buf_l
[] = {
2025 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
2027 if (arg1
< 0x8000 && arg1
>= -0x8000)
2029 add_insns (buf_s
, sizeof buf_s
);
2033 s390_emit_litpool (4);
2034 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
2035 add_insns (buf_l
, sizeof buf_l
);
2039 /* The "emit_int_call_1" emit_ops method for s390. */
2042 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2044 /* FN's prototype is `LONGEST(*fn)(int)'. */
2045 s390_emit_set_r2 (arg1
);
2046 s390_emit_call (fn
);
2049 /* The "emit_void_call_2" emit_ops method for s390. */
2052 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2054 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2055 static const unsigned char buf
[] = {
2056 0x18, 0xc2, /* lr %r12, %r2 */
2057 0x18, 0xd3, /* lr %r13, %r3 */
2058 0x18, 0x43, /* lr %r4, %r3 */
2059 0x18, 0x32, /* lr %r3, %r2 */
2061 static const unsigned char buf2
[] = {
2062 0x18, 0x2c, /* lr %r2, %r12 */
2063 0x18, 0x3d, /* lr %r3, %r13 */
2065 add_insns (buf
, sizeof buf
);
2066 s390_emit_set_r2 (arg1
);
2067 s390_emit_call (fn
);
2068 add_insns (buf2
, sizeof buf2
);
2071 /* The "emit_eq_goto" emit_ops method for s390. */
2074 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2076 static const unsigned char buf
[] = {
2077 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2078 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2079 0x16, 0x23, /* or %r2, %r3 */
2080 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2081 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2082 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2084 add_insns (buf
, sizeof buf
);
2091 /* The "emit_ne_goto" emit_ops method for s390. */
2094 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2096 static const unsigned char buf
[] = {
2097 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2098 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2099 0x16, 0x23, /* or %r2, %r3 */
2100 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2101 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2102 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2104 add_insns (buf
, sizeof buf
);
2111 /* The "emit_lt_goto" emit_ops method for s390. */
2114 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2116 static const unsigned char buf
[] = {
2117 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2118 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2119 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2120 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2121 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2123 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2124 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2125 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2127 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2128 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2129 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2132 add_insns (buf
, sizeof buf
);
2139 /* The "emit_le_goto" emit_ops method for s390. */
2142 s390_emit_le_goto (int *offset_p
, int *size_p
)
2144 static const unsigned char buf
[] = {
2145 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2146 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2147 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2148 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2149 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2151 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2152 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2153 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2155 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2156 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2157 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2160 add_insns (buf
, sizeof buf
);
2167 /* The "emit_gt_goto" emit_ops method for s390. */
2170 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2172 static const unsigned char buf
[] = {
2173 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2174 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2175 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2176 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2177 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2179 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2180 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2181 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2183 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2184 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2185 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2188 add_insns (buf
, sizeof buf
);
2195 /* The "emit_ge_goto" emit_ops method for s390. */
2198 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2200 static const unsigned char buf
[] = {
2201 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2202 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2203 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2204 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2205 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2207 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2208 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2209 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2211 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2212 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2213 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2216 add_insns (buf
, sizeof buf
);
2223 /* The "emit_ops" structure for s390. Named _impl to avoid name
2224 collision with s390_emit_ops function. */
2226 static struct emit_ops s390_emit_ops_impl
=
2234 s390_emit_rsh_signed
,
2235 s390_emit_rsh_unsigned
,
2243 s390_emit_less_signed
,
2244 s390_emit_less_unsigned
,
2248 s390_write_goto_address
,
2253 s390_emit_stack_flush
,
2256 s390_emit_stack_adjust
,
2257 s390_emit_int_call_1
,
2258 s390_emit_void_call_2
,
2269 /* The "emit_prologue" emit_ops method for s390x. */
2272 s390x_emit_prologue (void)
2274 static const unsigned char buf
[] = {
2275 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2276 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2277 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2278 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2280 add_insns (buf
, sizeof buf
);
2283 /* The "emit_epilogue" emit_ops method for s390x. */
2286 s390x_emit_epilogue (void)
2288 static const unsigned char buf
[] = {
2289 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2290 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2291 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2292 0x07, 0xfe, /* br %r14 */
2294 add_insns (buf
, sizeof buf
);
2297 /* The "emit_add" emit_ops method for s390x. */
2300 s390x_emit_add (void)
2302 static const unsigned char buf
[] = {
2303 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2304 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2306 add_insns (buf
, sizeof buf
);
2309 /* The "emit_sub" emit_ops method for s390x. */
2312 s390x_emit_sub (void)
2314 static const unsigned char buf
[] = {
2315 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2316 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2317 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2318 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2320 add_insns (buf
, sizeof buf
);
2323 /* The "emit_mul" emit_ops method for s390x. */
2326 s390x_emit_mul (void)
2331 /* The "emit_lsh" emit_ops method for s390x. */
2334 s390x_emit_lsh (void)
2336 static const unsigned char buf
[] = {
2337 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2338 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2339 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2341 add_insns (buf
, sizeof buf
);
2344 /* The "emit_rsh_signed" emit_ops method for s390x. */
2347 s390x_emit_rsh_signed (void)
2349 static const unsigned char buf
[] = {
2350 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2351 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2352 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2354 add_insns (buf
, sizeof buf
);
2357 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2360 s390x_emit_rsh_unsigned (void)
2362 static const unsigned char buf
[] = {
2363 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2364 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2365 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2367 add_insns (buf
, sizeof buf
);
2370 /* The "emit_ext" emit_ops method for s390x. */
2373 s390x_emit_ext (int arg
)
2375 unsigned char buf
[] = {
2376 /* sllg %r2, %r2, <64-arg> */
2377 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2378 /* srag %r2, %r2, <64-arg> */
2379 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2381 add_insns (buf
, sizeof buf
);
2384 /* The "emit_log_not" emit_ops method for s390x. */
2387 s390x_emit_log_not (void)
2389 static const unsigned char buf
[] = {
2390 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2391 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2392 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2394 add_insns (buf
, sizeof buf
);
2397 /* The "emit_bit_and" emit_ops method for s390x. */
2400 s390x_emit_bit_and (void)
2402 static const unsigned char buf
[] = {
2403 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2404 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2406 add_insns (buf
, sizeof buf
);
2409 /* The "emit_bit_or" emit_ops method for s390x. */
2412 s390x_emit_bit_or (void)
2414 static const unsigned char buf
[] = {
2415 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2416 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2418 add_insns (buf
, sizeof buf
);
2421 /* The "emit_bit_xor" emit_ops method for s390x. */
2424 s390x_emit_bit_xor (void)
2426 static const unsigned char buf
[] = {
2427 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2428 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2430 add_insns (buf
, sizeof buf
);
2433 /* The "emit_bit_not" emit_ops method for s390x. */
2436 s390x_emit_bit_not (void)
2438 static const unsigned char buf
[] = {
2439 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2440 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2442 add_insns (buf
, sizeof buf
);
2445 /* The "emit_equal" emit_ops method for s390x. */
2448 s390x_emit_equal (void)
2450 s390x_emit_bit_xor ();
2451 s390x_emit_log_not ();
2454 /* The "emit_less_signed" emit_ops method for s390x. */
2457 s390x_emit_less_signed (void)
2459 static const unsigned char buf
[] = {
2460 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2461 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2462 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2463 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2465 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2467 add_insns (buf
, sizeof buf
);
2470 /* The "emit_less_unsigned" emit_ops method for s390x. */
2473 s390x_emit_less_unsigned (void)
2475 static const unsigned char buf
[] = {
2476 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2477 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2478 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2479 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2481 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2483 add_insns (buf
, sizeof buf
);
2486 /* The "emit_ref" emit_ops method for s390x. */
2489 s390x_emit_ref (int size
)
2491 static const unsigned char buf1
[] = {
2492 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2494 static const unsigned char buf2
[] = {
2495 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2497 static const unsigned char buf4
[] = {
2498 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2500 static const unsigned char buf8
[] = {
2501 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2506 add_insns (buf1
, sizeof buf1
);
2509 add_insns (buf2
, sizeof buf2
);
2512 add_insns (buf4
, sizeof buf4
);
2515 add_insns (buf8
, sizeof buf8
);
2522 /* The "emit_if_goto" emit_ops method for s390x. */
2525 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2527 static const unsigned char buf
[] = {
2528 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2529 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2530 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2531 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2533 add_insns (buf
, sizeof buf
);
2540 /* The "emit_const" emit_ops method for s390x. */
2543 s390x_emit_const (LONGEST num
)
2545 unsigned long long n
= num
;
2546 unsigned char buf_s
[] = {
2547 /* lghi %r2, <num> */
2548 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2550 static const unsigned char buf_l
[] = {
2551 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2553 if (num
< 0x8000 && num
>= -0x8000)
2555 add_insns (buf_s
, sizeof buf_s
);
2559 s390_emit_litpool (8);
2560 add_insns ((unsigned char *) &n
, sizeof n
);
2561 add_insns (buf_l
, sizeof buf_l
);
2565 /* The "emit_call" emit_ops method for s390x. */
2568 s390x_emit_call (CORE_ADDR fn
)
2570 unsigned long n
= fn
;
2571 static const unsigned char buf
[] = {
2572 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2573 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2574 0x0d, 0xe1, /* basr %r14, %r1 */
2575 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2577 s390_emit_litpool (8);
2578 add_insns ((unsigned char *) &n
, sizeof n
);
2579 add_insns (buf
, sizeof buf
);
2582 /* The "emit_reg" emit_ops method for s390x. */
2585 s390x_emit_reg (int reg
)
2587 unsigned char buf
[] = {
2589 0xb9, 0x04, 0x00, 0x29,
2590 /* lghi %r3, <reg> */
2591 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2593 add_insns (buf
, sizeof buf
);
2594 s390x_emit_call (get_raw_reg_func_addr ());
2597 /* The "emit_pop" emit_ops method for s390x. */
2600 s390x_emit_pop (void)
2602 static const unsigned char buf
[] = {
2603 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2604 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2606 add_insns (buf
, sizeof buf
);
2609 /* The "emit_stack_flush" emit_ops method for s390x. */
2612 s390x_emit_stack_flush (void)
2614 static const unsigned char buf
[] = {
2615 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2616 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2618 add_insns (buf
, sizeof buf
);
2621 /* The "emit_zero_ext" emit_ops method for s390x. */
2624 s390x_emit_zero_ext (int arg
)
2626 unsigned char buf
[] = {
2627 /* sllg %r2, %r2, <64-arg> */
2628 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2629 /* srlg %r2, %r2, <64-arg> */
2630 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2632 add_insns (buf
, sizeof buf
);
2635 /* The "emit_swap" emit_ops method for s390x. */
2638 s390x_emit_swap (void)
2640 static const unsigned char buf
[] = {
2641 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2642 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2643 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2645 add_insns (buf
, sizeof buf
);
2648 /* The "emit_stack_adjust" emit_ops method for s390x. */
2651 s390x_emit_stack_adjust (int n
)
2653 unsigned char buf
[] = {
2654 /* aghi %r15, 8*n */
2656 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2658 add_insns (buf
, sizeof buf
);
2661 /* The "emit_int_call_1" emit_ops method for s390x. */
2664 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2666 /* FN's prototype is `LONGEST(*fn)(int)'. */
2667 s390x_emit_const (arg1
);
2668 s390x_emit_call (fn
);
2671 /* The "emit_void_call_2" emit_ops method for s390x. */
2674 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2676 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2677 static const unsigned char buf
[] = {
2678 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2679 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2681 static const unsigned char buf2
[] = {
2682 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2684 add_insns (buf
, sizeof buf
);
2685 s390x_emit_const (arg1
);
2686 s390x_emit_call (fn
);
2687 add_insns (buf2
, sizeof buf2
);
2690 /* The "emit_eq_goto" emit_ops method for s390x. */
2693 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2695 static const unsigned char buf
[] = {
2696 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2697 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2698 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2699 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2701 add_insns (buf
, sizeof buf
);
2708 /* The "emit_ne_goto" emit_ops method for s390x. */
2711 s390x_emit_ne_goto (int *offset_p
, int *size_p
)
2713 static const unsigned char buf
[] = {
2714 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2715 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2716 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2717 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2719 add_insns (buf
, sizeof buf
);
2726 /* The "emit_lt_goto" emit_ops method for s390x. */
2729 s390x_emit_lt_goto (int *offset_p
, int *size_p
)
2731 static const unsigned char buf
[] = {
2732 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2733 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2734 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2735 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2737 add_insns (buf
, sizeof buf
);
2744 /* The "emit_le_goto" emit_ops method for s390x. */
2747 s390x_emit_le_goto (int *offset_p
, int *size_p
)
2749 static const unsigned char buf
[] = {
2750 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2751 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2752 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2753 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2755 add_insns (buf
, sizeof buf
);
2762 /* The "emit_gt_goto" emit_ops method for s390x. */
2765 s390x_emit_gt_goto (int *offset_p
, int *size_p
)
2767 static const unsigned char buf
[] = {
2768 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2769 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2770 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2771 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2773 add_insns (buf
, sizeof buf
);
2780 /* The "emit_ge_goto" emit_ops method for s390x. */
2783 s390x_emit_ge_goto (int *offset_p
, int *size_p
)
2785 static const unsigned char buf
[] = {
2786 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2787 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2788 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2789 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2791 add_insns (buf
, sizeof buf
);
2798 /* The "emit_ops" structure for s390x. */
2800 static struct emit_ops s390x_emit_ops
=
2802 s390x_emit_prologue
,
2803 s390x_emit_epilogue
,
2808 s390x_emit_rsh_signed
,
2809 s390x_emit_rsh_unsigned
,
2817 s390x_emit_less_signed
,
2818 s390x_emit_less_unsigned
,
2822 s390_write_goto_address
,
2827 s390x_emit_stack_flush
,
2828 s390x_emit_zero_ext
,
2830 s390x_emit_stack_adjust
,
2831 s390x_emit_int_call_1
,
2832 s390x_emit_void_call_2
,
2842 /* The "emit_ops" target ops method. */
2845 s390_target::emit_ops ()
2848 struct regcache
*regcache
= get_thread_regcache (current_thread
, 0);
2850 if (register_size (regcache
->tdesc
, 0) == 8)
2851 return &s390x_emit_ops
;
2854 return &s390_emit_ops_impl
;
2857 struct linux_target_ops the_low_target
= {
2858 s390_get_ipa_tdesc_idx
,
2861 /* The linux target ops object. */
2863 linux_process_target
*the_linux_target
= &the_s390_target
;
2866 initialize_low_arch (void)
2868 /* Initialize the Linux target descriptions. */
2870 init_registers_s390_linux32 ();
2871 init_registers_s390_linux32v1 ();
2872 init_registers_s390_linux32v2 ();
2873 init_registers_s390_linux64 ();
2874 init_registers_s390_linux64v1 ();
2875 init_registers_s390_linux64v2 ();
2876 init_registers_s390_te_linux64 ();
2877 init_registers_s390_vx_linux64 ();
2878 init_registers_s390_tevx_linux64 ();
2879 init_registers_s390_gs_linux64 ();
2881 init_registers_s390x_linux64 ();
2882 init_registers_s390x_linux64v1 ();
2883 init_registers_s390x_linux64v2 ();
2884 init_registers_s390x_te_linux64 ();
2885 init_registers_s390x_vx_linux64 ();
2886 init_registers_s390x_tevx_linux64 ();
2887 init_registers_s390x_gs_linux64 ();
2890 initialize_regsets_info (&s390_regsets_info
);
2891 initialize_regsets_info (&s390_regsets_info_3264
);