1 /* GNU/Linux S/390 specific low level interface, for the remote server
3 Copyright (C) 2001-2024 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. */
22 #include "linux-low.h"
23 #include "elf/common.h"
25 #include "tracepoint.h"
27 #include <asm/ptrace.h>
28 #include "nat/gdb_ptrace.h"
33 #include "linux-s390-tdesc.h"
35 #ifndef HWCAP_S390_HIGH_GPRS
36 #define HWCAP_S390_HIGH_GPRS 512
40 #define HWCAP_S390_TE 1024
44 #define HWCAP_S390_VX 2048
48 #define HWCAP_S390_GS 16384
51 #define s390_num_regs 52
53 /* Linux target op definitions for the S/390 architecture. */
55 class s390_target
: public linux_process_target
59 const regs_info
*get_regs_info () override
;
61 const gdb_byte
*sw_breakpoint_from_kind (int kind
, int *size
) override
;
63 bool supports_z_point_type (char z_type
) override
;
65 bool supports_tracepoints () override
;
67 bool supports_fast_tracepoints () override
;
69 int install_fast_tracepoint_jump_pad
70 (CORE_ADDR tpoint
, CORE_ADDR tpaddr
, CORE_ADDR collector
,
71 CORE_ADDR lockaddr
, ULONGEST orig_size
, CORE_ADDR
*jump_entry
,
72 CORE_ADDR
*trampoline
, ULONGEST
*trampoline_size
,
73 unsigned char *jjump_pad_insn
, ULONGEST
*jjump_pad_insn_size
,
74 CORE_ADDR
*adjusted_insn_addr
, CORE_ADDR
*adjusted_insn_addr_end
,
77 int get_min_fast_tracepoint_insn_len () override
;
79 void low_collect_ptrace_register (regcache
*regcache
, int regno
,
82 void low_supply_ptrace_register (regcache
*regcache
, int regno
,
83 const char *buf
) override
;
85 struct emit_ops
*emit_ops () override
;
87 int get_ipa_tdesc_idx () override
;
91 void low_arch_setup () override
;
93 bool low_cannot_fetch_register (int regno
) override
;
95 bool low_cannot_store_register (int regno
) override
;
97 bool low_supports_breakpoints () override
;
99 CORE_ADDR
low_get_pc (regcache
*regcache
) override
;
101 void low_set_pc (regcache
*regcache
, CORE_ADDR newpc
) override
;
103 int low_decr_pc_after_break () override
;
105 bool low_breakpoint_at (CORE_ADDR pc
) override
;
107 int low_get_thread_area (int lwpid
, CORE_ADDR
*addrp
) override
;
110 /* The singleton target ops object. */
112 static s390_target the_s390_target
;
114 static int s390_regmap
[] = {
115 PT_PSWMASK
, PT_PSWADDR
,
117 PT_GPR0
, PT_GPR1
, PT_GPR2
, PT_GPR3
,
118 PT_GPR4
, PT_GPR5
, PT_GPR6
, PT_GPR7
,
119 PT_GPR8
, PT_GPR9
, PT_GPR10
, PT_GPR11
,
120 PT_GPR12
, PT_GPR13
, PT_GPR14
, PT_GPR15
,
122 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
123 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
124 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
125 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
130 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
131 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
132 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
133 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
135 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
136 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
137 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
138 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
144 #define s390_num_regs_3264 68
147 static int s390_regmap_3264
[] = {
148 PT_PSWMASK
, PT_PSWADDR
,
150 PT_GPR0
, PT_GPR0
, PT_GPR1
, PT_GPR1
,
151 PT_GPR2
, PT_GPR2
, PT_GPR3
, PT_GPR3
,
152 PT_GPR4
, PT_GPR4
, PT_GPR5
, PT_GPR5
,
153 PT_GPR6
, PT_GPR6
, PT_GPR7
, PT_GPR7
,
154 PT_GPR8
, PT_GPR8
, PT_GPR9
, PT_GPR9
,
155 PT_GPR10
, PT_GPR10
, PT_GPR11
, PT_GPR11
,
156 PT_GPR12
, PT_GPR12
, PT_GPR13
, PT_GPR13
,
157 PT_GPR14
, PT_GPR14
, PT_GPR15
, PT_GPR15
,
159 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
160 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
161 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
162 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
166 PT_FPR0
, PT_FPR1
, PT_FPR2
, PT_FPR3
,
167 PT_FPR4
, PT_FPR5
, PT_FPR6
, PT_FPR7
,
168 PT_FPR8
, PT_FPR9
, PT_FPR10
, PT_FPR11
,
169 PT_FPR12
, PT_FPR13
, PT_FPR14
, PT_FPR15
,
174 static int s390_regmap_3264
[] = {
175 PT_PSWMASK
, PT_PSWADDR
,
177 -1, PT_GPR0
, -1, PT_GPR1
,
178 -1, PT_GPR2
, -1, PT_GPR3
,
179 -1, PT_GPR4
, -1, PT_GPR5
,
180 -1, PT_GPR6
, -1, PT_GPR7
,
181 -1, PT_GPR8
, -1, PT_GPR9
,
182 -1, PT_GPR10
, -1, PT_GPR11
,
183 -1, PT_GPR12
, -1, PT_GPR13
,
184 -1, PT_GPR14
, -1, PT_GPR15
,
186 PT_ACR0
, PT_ACR1
, PT_ACR2
, PT_ACR3
,
187 PT_ACR4
, PT_ACR5
, PT_ACR6
, PT_ACR7
,
188 PT_ACR8
, PT_ACR9
, PT_ACR10
, PT_ACR11
,
189 PT_ACR12
, PT_ACR13
, PT_ACR14
, PT_ACR15
,
193 PT_FPR0_HI
, PT_FPR1_HI
, PT_FPR2_HI
, PT_FPR3_HI
,
194 PT_FPR4_HI
, PT_FPR5_HI
, PT_FPR6_HI
, PT_FPR7_HI
,
195 PT_FPR8_HI
, PT_FPR9_HI
, PT_FPR10_HI
, PT_FPR11_HI
,
196 PT_FPR12_HI
, PT_FPR13_HI
, PT_FPR14_HI
, PT_FPR15_HI
,
204 s390_target::low_cannot_fetch_register (int regno
)
210 s390_target::low_cannot_store_register (int regno
)
216 s390_target::low_collect_ptrace_register (regcache
*regcache
, int regno
,
219 int size
= register_size (regcache
->tdesc
, regno
);
220 const struct regs_info
*regs_info
= get_regs_info ();
221 struct usrregs_info
*usr
= regs_info
->usrregs
;
222 int regaddr
= usr
->regmap
[regno
];
224 if (size
< sizeof (long))
226 memset (buf
, 0, sizeof (long));
228 if ((regno
^ 1) < usr
->num_regs
229 && usr
->regmap
[regno
^ 1] == regaddr
)
231 collect_register (regcache
, regno
& ~1, buf
);
232 collect_register (regcache
, (regno
& ~1) + 1,
233 buf
+ sizeof (long) - size
);
235 else if (regaddr
== PT_PSWMASK
)
237 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
238 the basic addressing mode bit from the PSW address. */
239 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
240 collect_register (regcache
, regno
, buf
);
241 collect_register (regcache
, regno
^ 1, addr
);
243 buf
[size
] |= (addr
[0] & 0x80);
245 else if (regaddr
== PT_PSWADDR
)
247 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
248 mode bit (which gets copied to the PSW mask instead). */
249 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
250 buf
[sizeof (long) - size
] &= ~0x80;
252 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
253 || regaddr
== PT_ORIGGPR2
)
254 collect_register (regcache
, regno
, buf
+ sizeof (long) - size
);
256 collect_register (regcache
, regno
, buf
);
258 else if (regaddr
!= -1)
259 collect_register (regcache
, regno
, buf
);
263 s390_target::low_supply_ptrace_register (regcache
*regcache
, int regno
,
266 int size
= register_size (regcache
->tdesc
, regno
);
267 const struct regs_info
*regs_info
= get_regs_info ();
268 struct usrregs_info
*usr
= regs_info
->usrregs
;
269 int regaddr
= usr
->regmap
[regno
];
271 if (size
< sizeof (long))
273 if ((regno
^ 1) < usr
->num_regs
274 && usr
->regmap
[regno
^ 1] == regaddr
)
276 supply_register (regcache
, regno
& ~1, buf
);
277 supply_register (regcache
, (regno
& ~1) + 1,
278 buf
+ sizeof (long) - size
);
280 else if (regaddr
== PT_PSWMASK
)
282 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
283 the basic addressing mode into the PSW address. */
284 gdb_byte
*mask
= (gdb_byte
*) alloca (size
);
285 gdb_byte
*addr
= (gdb_byte
*) alloca (register_size (regcache
->tdesc
, regno
^ 1));
286 memcpy (mask
, buf
, size
);
288 supply_register (regcache
, regno
, mask
);
290 collect_register (regcache
, regno
^ 1, addr
);
292 addr
[0] |= (buf
[size
] & 0x80);
293 supply_register (regcache
, regno
^ 1, addr
);
295 else if (regaddr
== PT_PSWADDR
)
297 /* Convert 8-byte PSW address to 4 bytes by truncating, but
298 keeping the addressing mode bit (which was set from the mask). */
299 gdb_byte
*addr
= (gdb_byte
*) alloca (size
);
301 collect_register (regcache
, regno
, addr
);
302 amode
= addr
[0] & 0x80;
303 memcpy (addr
, buf
+ sizeof (long) - size
, size
);
306 supply_register (regcache
, regno
, addr
);
308 else if ((regaddr
>= PT_GPR0
&& regaddr
<= PT_GPR15
)
309 || regaddr
== PT_ORIGGPR2
)
310 supply_register (regcache
, regno
, buf
+ sizeof (long) - size
);
312 supply_register (regcache
, regno
, buf
);
314 else if (regaddr
!= -1)
315 supply_register (regcache
, regno
, buf
);
318 /* Provide only a fill function for the general register set. ps_lgetregs
319 will use this for NPTL support. */
322 s390_fill_gregset (struct regcache
*regcache
, void *buf
)
325 const struct regs_info
*regs_info
= the_linux_target
->get_regs_info ();
326 struct usrregs_info
*usr
= regs_info
->usrregs
;
328 for (i
= 0; i
< usr
->num_regs
; i
++)
330 if (usr
->regmap
[i
] < PT_PSWMASK
331 || usr
->regmap
[i
] > PT_ACR15
)
334 ((s390_target
*) the_linux_target
)->low_collect_ptrace_register
335 (regcache
, i
, (char *) buf
+ usr
->regmap
[i
]);
339 /* Fill and store functions for extended register sets. */
343 s390_fill_gprs_high (struct regcache
*regcache
, void *buf
)
345 int r0h
= find_regno (regcache
->tdesc
, "r0h");
348 for (i
= 0; i
< 16; i
++)
349 collect_register (regcache
, r0h
+ 2 * i
, (char *) buf
+ 4 * i
);
353 s390_store_gprs_high (struct regcache
*regcache
, const void *buf
)
355 int r0h
= find_regno (regcache
->tdesc
, "r0h");
358 for (i
= 0; i
< 16; i
++)
359 supply_register (regcache
, r0h
+ 2 * i
, (const char *) buf
+ 4 * i
);
364 s390_store_last_break (struct regcache
*regcache
, const void *buf
)
368 p
= (const char *) buf
+ 8 - register_size (regcache
->tdesc
, 0);
369 supply_register_by_name (regcache
, "last_break", p
);
373 s390_fill_system_call (struct regcache
*regcache
, void *buf
)
375 collect_register_by_name (regcache
, "system_call", buf
);
379 s390_store_system_call (struct regcache
*regcache
, const void *buf
)
381 supply_register_by_name (regcache
, "system_call", buf
);
385 s390_store_tdb (struct regcache
*regcache
, const void *buf
)
387 int tdb0
= find_regno (regcache
->tdesc
, "tdb0");
388 int tr0
= find_regno (regcache
->tdesc
, "tr0");
391 for (i
= 0; i
< 4; i
++)
392 supply_register (regcache
, tdb0
+ i
, (const char *) buf
+ 8 * i
);
394 for (i
= 0; i
< 16; i
++)
395 supply_register (regcache
, tr0
+ i
, (const char *) buf
+ 8 * (16 + i
));
399 s390_fill_vxrs_low (struct regcache
*regcache
, void *buf
)
401 int v0
= find_regno (regcache
->tdesc
, "v0l");
404 for (i
= 0; i
< 16; i
++)
405 collect_register (regcache
, v0
+ i
, (char *) buf
+ 8 * i
);
409 s390_store_vxrs_low (struct regcache
*regcache
, const void *buf
)
411 int v0
= find_regno (regcache
->tdesc
, "v0l");
414 for (i
= 0; i
< 16; i
++)
415 supply_register (regcache
, v0
+ i
, (const char *) buf
+ 8 * i
);
419 s390_fill_vxrs_high (struct regcache
*regcache
, void *buf
)
421 int v16
= find_regno (regcache
->tdesc
, "v16");
424 for (i
= 0; i
< 16; i
++)
425 collect_register (regcache
, v16
+ i
, (char *) buf
+ 16 * i
);
429 s390_store_vxrs_high (struct regcache
*regcache
, const void *buf
)
431 int v16
= find_regno (regcache
->tdesc
, "v16");
434 for (i
= 0; i
< 16; i
++)
435 supply_register (regcache
, v16
+ i
, (const char *) buf
+ 16 * i
);
439 s390_store_gs (struct regcache
*regcache
, const void *buf
)
441 int gsd
= find_regno (regcache
->tdesc
, "gsd");
444 for (i
= 0; i
< 3; i
++)
445 supply_register (regcache
, gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
449 s390_store_gsbc (struct regcache
*regcache
, const void *buf
)
451 int bc_gsd
= find_regno (regcache
->tdesc
, "bc_gsd");
454 for (i
= 0; i
< 3; i
++)
455 supply_register (regcache
, bc_gsd
+ i
, (const char *) buf
+ 8 * (i
+ 1));
458 static struct regset_info s390_regsets
[] = {
459 { 0, 0, 0, 0, GENERAL_REGS
, s390_fill_gregset
, NULL
},
461 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_HIGH_GPRS
, 0,
462 EXTENDED_REGS
, s390_fill_gprs_high
, s390_store_gprs_high
},
464 /* Last break address is read-only; no fill function. */
465 { PTRACE_GETREGSET
, -1, NT_S390_LAST_BREAK
, 0, EXTENDED_REGS
,
466 NULL
, s390_store_last_break
},
467 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_SYSTEM_CALL
, 0,
468 EXTENDED_REGS
, s390_fill_system_call
, s390_store_system_call
},
469 /* TDB is read-only. */
470 { PTRACE_GETREGSET
, -1, NT_S390_TDB
, 0, EXTENDED_REGS
,
471 NULL
, s390_store_tdb
},
472 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_LOW
, 0,
473 EXTENDED_REGS
, s390_fill_vxrs_low
, s390_store_vxrs_low
},
474 { PTRACE_GETREGSET
, PTRACE_SETREGSET
, NT_S390_VXRS_HIGH
, 0,
475 EXTENDED_REGS
, s390_fill_vxrs_high
, s390_store_vxrs_high
},
476 /* Guarded storage registers are read-only. */
477 { PTRACE_GETREGSET
, -1, NT_S390_GS_CB
, 0, EXTENDED_REGS
,
478 NULL
, s390_store_gs
},
479 { PTRACE_GETREGSET
, -1, NT_S390_GS_BC
, 0, EXTENDED_REGS
,
480 NULL
, s390_store_gsbc
},
485 static const gdb_byte s390_breakpoint
[] = { 0, 1 };
486 #define s390_breakpoint_len 2
488 /* Implementation of target ops method "sw_breakpoint_from_kind". */
491 s390_target::sw_breakpoint_from_kind (int kind
, int *size
)
493 *size
= s390_breakpoint_len
;
494 return s390_breakpoint
;
498 s390_target::low_supports_breakpoints ()
504 s390_target::low_get_pc (regcache
*regcache
)
506 if (register_size (regcache
->tdesc
, 0) == 4)
509 collect_register_by_name (regcache
, "pswa", &pswa
);
510 return pswa
& 0x7fffffff;
515 collect_register_by_name (regcache
, "pswa", &pc
);
521 s390_target::low_set_pc (regcache
*regcache
, CORE_ADDR newpc
)
523 if (register_size (regcache
->tdesc
, 0) == 4)
526 collect_register_by_name (regcache
, "pswa", &pswa
);
527 pswa
= (pswa
& 0x80000000) | (newpc
& 0x7fffffff);
528 supply_register_by_name (regcache
, "pswa", &pswa
);
532 unsigned long pc
= newpc
;
533 supply_register_by_name (regcache
, "pswa", &pc
);
538 s390_target::low_decr_pc_after_break ()
540 return s390_breakpoint_len
;
543 /* Determine the word size for the given PID, in bytes. */
547 s390_get_wordsize (int pid
)
550 PTRACE_XFER_TYPE pswm
= ptrace (PTRACE_PEEKUSER
, pid
,
551 (PTRACE_TYPE_ARG3
) 0,
552 (PTRACE_TYPE_ARG4
) 0);
555 warning (_("Couldn't determine word size, assuming 64-bit."));
558 /* Derive word size from extended addressing mode (PSW bit 31). */
559 return pswm
& (1L << 32) ? 8 : 4;
562 #define s390_get_wordsize(pid) 4
566 s390_check_regset (int pid
, int regset
, int regsize
)
568 void *buf
= alloca (regsize
);
572 iov
.iov_len
= regsize
;
574 if (ptrace (PTRACE_GETREGSET
, pid
, (long) regset
, (long) &iov
) >= 0
580 /* For a 31-bit inferior, whether the kernel supports using the full
582 static int have_hwcap_s390_high_gprs
= 0;
583 static int have_hwcap_s390_vx
= 0;
586 s390_target::low_arch_setup ()
588 const struct target_desc
*tdesc
;
589 struct regset_info
*regset
;
591 /* Determine word size and HWCAP. */
592 int pid
= current_thread
->id
.pid ();
593 int wordsize
= s390_get_wordsize (pid
);
594 unsigned long hwcap
= linux_get_hwcap (pid
, wordsize
);
596 /* Check whether the kernel supports extra register sets. */
597 int have_regset_last_break
598 = s390_check_regset (pid
, NT_S390_LAST_BREAK
, 8);
599 int have_regset_system_call
600 = s390_check_regset (pid
, NT_S390_SYSTEM_CALL
, 4);
602 = (s390_check_regset (pid
, NT_S390_TDB
, 256)
603 && (hwcap
& HWCAP_S390_TE
) != 0);
605 = (s390_check_regset (pid
, NT_S390_VXRS_LOW
, 128)
606 && s390_check_regset (pid
, NT_S390_VXRS_HIGH
, 256)
607 && (hwcap
& HWCAP_S390_VX
) != 0);
609 = (s390_check_regset (pid
, NT_S390_GS_CB
, 32)
610 && s390_check_regset (pid
, NT_S390_GS_BC
, 32)
611 && (hwcap
& HWCAP_S390_GS
) != 0);
618 tdesc
= tdesc_s390x_gs_linux64
;
619 else if (have_regset_vxrs
)
620 tdesc
= (have_regset_tdb
? tdesc_s390x_tevx_linux64
:
621 tdesc_s390x_vx_linux64
);
622 else if (have_regset_tdb
)
623 tdesc
= tdesc_s390x_te_linux64
;
624 else if (have_regset_system_call
)
625 tdesc
= tdesc_s390x_linux64v2
;
626 else if (have_regset_last_break
)
627 tdesc
= tdesc_s390x_linux64v1
;
629 tdesc
= tdesc_s390x_linux64
;
632 /* For a 31-bit inferior, check whether the kernel supports
633 using the full 64-bit GPRs. */
636 if (hwcap
& HWCAP_S390_HIGH_GPRS
)
638 have_hwcap_s390_high_gprs
= 1;
640 tdesc
= tdesc_s390_gs_linux64
;
641 else if (have_regset_vxrs
)
642 tdesc
= (have_regset_tdb
? tdesc_s390_tevx_linux64
:
643 tdesc_s390_vx_linux64
);
644 else if (have_regset_tdb
)
645 tdesc
= tdesc_s390_te_linux64
;
646 else if (have_regset_system_call
)
647 tdesc
= tdesc_s390_linux64v2
;
648 else if (have_regset_last_break
)
649 tdesc
= tdesc_s390_linux64v1
;
651 tdesc
= tdesc_s390_linux64
;
655 /* Assume 31-bit inferior process. */
656 if (have_regset_system_call
)
657 tdesc
= tdesc_s390_linux32v2
;
658 else if (have_regset_last_break
)
659 tdesc
= tdesc_s390_linux32v1
;
661 tdesc
= tdesc_s390_linux32
;
664 have_hwcap_s390_vx
= have_regset_vxrs
;
667 /* Update target_regsets according to available register sets. */
668 for (regset
= s390_regsets
; regset
->size
>= 0; regset
++)
669 if (regset
->get_request
== PTRACE_GETREGSET
)
670 switch (regset
->nt_type
)
673 case NT_S390_HIGH_GPRS
:
674 regset
->size
= have_hwcap_s390_high_gprs
? 64 : 0;
677 case NT_S390_LAST_BREAK
:
678 regset
->size
= have_regset_last_break
? 8 : 0;
680 case NT_S390_SYSTEM_CALL
:
681 regset
->size
= have_regset_system_call
? 4 : 0;
684 regset
->size
= have_regset_tdb
? 256 : 0;
686 case NT_S390_VXRS_LOW
:
687 regset
->size
= have_regset_vxrs
? 128 : 0;
689 case NT_S390_VXRS_HIGH
:
690 regset
->size
= have_regset_vxrs
? 256 : 0;
694 regset
->size
= have_regset_gs
? 32 : 0;
699 current_process ()->tdesc
= tdesc
;
704 s390_target::low_breakpoint_at (CORE_ADDR pc
)
706 unsigned char c
[s390_breakpoint_len
];
707 read_inferior_memory (pc
, c
, s390_breakpoint_len
);
708 return memcmp (c
, s390_breakpoint
, s390_breakpoint_len
) == 0;
711 /* Breakpoint/Watchpoint support. */
713 /* The "supports_z_point_type" target ops method. */
716 s390_target::supports_z_point_type (char z_type
)
727 static struct usrregs_info s390_usrregs_info
=
733 static struct regsets_info s390_regsets_info
=
735 s390_regsets
, /* regsets */
737 NULL
, /* disabled_regsets */
740 static struct regs_info myregs_info
=
742 NULL
, /* regset_bitmap */
747 static struct usrregs_info s390_usrregs_info_3264
=
753 static struct regsets_info s390_regsets_info_3264
=
755 s390_regsets
, /* regsets */
757 NULL
, /* disabled_regsets */
760 static struct regs_info regs_info_3264
=
762 NULL
, /* regset_bitmap */
763 &s390_usrregs_info_3264
,
764 &s390_regsets_info_3264
768 s390_target::get_regs_info ()
770 if (have_hwcap_s390_high_gprs
)
773 const struct target_desc
*tdesc
= current_process ()->tdesc
;
775 if (register_size (tdesc
, 0) == 4)
776 return ®s_info_3264
;
778 return ®s_info_3264
;
784 /* The "supports_tracepoints" target ops method. */
787 s390_target::supports_tracepoints ()
792 /* Implementation of linux target ops method "low_get_thread_area". */
795 s390_target::low_get_thread_area (int lwpid
, CORE_ADDR
*addrp
)
797 CORE_ADDR res
= ptrace (PTRACE_PEEKUSER
, lwpid
, (long) PT_ACR0
, (long) 0);
799 if (register_size (current_process ()->tdesc
, 0) == 4)
800 res
&= 0xffffffffull
;
807 /* Fast tracepoint support.
809 The register save area on stack is identical for all targets:
811 0x000+i*0x10: VR0-VR31
818 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
819 Likewise, if there's no VX support, we just store the FRs into the slots
820 of low VR halves. The agent code is responsible for rearranging that
823 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
824 one trick used at the very beginning: since there's no way to allocate
825 stack space without destroying CC (lay instruction can do it, but it's
826 only supported on later CPUs), we take 4 different execution paths for
827 every possible value of CC, allocate stack space, save %r0, stuff the
828 CC value in %r0 (shifted to match its position in PSWM high word),
829 then branch to common path. */
831 static const unsigned char s390_ft_entry_gpr_esa
[] = {
832 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
833 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
834 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
836 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
837 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
838 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
839 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
841 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
842 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
843 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
844 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
846 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
847 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
848 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
849 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
851 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
852 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
853 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
855 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
856 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
857 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
858 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
859 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
860 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
861 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
862 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
863 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
864 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
865 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
866 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
867 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
868 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
869 /* Compute original value of %r15 and store it. We use ahi instead
870 of la to preserve the whole value, and not just the low 31 bits.
871 This is not particularly important here, but essential in the
872 zarch case where someone might be using the high word of %r15
873 as an extra register. */
874 0x18, 0x1f, /* lr %r1, %r15 */
875 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
876 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
879 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
880 target. Same as above, except this time we can use load/store multiple,
881 since the 64-bit regs are tightly packed. */
883 static const unsigned char s390_ft_entry_gpr_zarch
[] = {
884 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
885 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
886 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
888 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
889 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
890 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
891 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
893 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
894 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
895 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
896 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
898 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
899 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
900 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
901 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
903 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
904 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
905 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
907 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
908 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
909 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
912 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
913 current PSWM (read by epsw) and CC from entry (in %r0). */
915 static const unsigned char s390_ft_entry_misc
[] = {
916 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
917 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
918 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
919 0x14, 0x21, /* nr %r2, %r1 */
920 0x16, 0x20, /* or %r2, %r0 */
921 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
922 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
923 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
926 /* Code sequence saving FRs, used if VX not supported. */
928 static const unsigned char s390_ft_entry_fr
[] = {
929 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
930 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
931 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
932 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
933 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
934 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
935 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
936 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
937 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
938 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
939 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
940 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
941 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
942 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
943 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
944 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
947 /* Code sequence saving VRs, used if VX not supported. */
949 static const unsigned char s390_ft_entry_vr
[] = {
950 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
951 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
954 /* Code sequence doing the collection call for 31-bit target. %r1 contains
955 the address of the literal pool. */
957 static const unsigned char s390_ft_main_31
[] = {
958 /* Load the literals into registers. */
959 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
960 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
961 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
962 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
963 /* Save original PSWA (tracepoint address | 0x80000000). */
964 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
965 /* Construct a collecting_t object at %r15+0x2e0. */
966 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
967 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
968 /* Move its address to %r0. */
969 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
972 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
973 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
974 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
975 /* Address of the register save block to %r3. */
976 0x18, 0x3f, /* lr %r3, %r15 */
977 /* Make a stack frame, so that we can call the collector. */
978 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
980 0x0d, 0xe4, /* basr %r14, %r4 */
981 /* And get rid of the stack frame again. */
982 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
983 /* Leave the lock. */
984 0x07, 0xf0, /* br %r0 */
985 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
986 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
989 /* Code sequence doing the collection call for 64-bit target. %r1 contains
990 the address of the literal pool. */
992 static const unsigned char s390_ft_main_64
[] = {
993 /* Load the literals into registers. */
994 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
995 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
996 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
997 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
998 /* Save original PSWA (tracepoint address). */
999 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
1000 /* Construct a collecting_t object at %r15+0x2e0. */
1001 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
1002 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
1003 /* Move its address to %r0. */
1004 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
1005 /* Take the lock. */
1007 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1008 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
1009 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
1010 /* Address of the register save block to %r3. */
1011 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
1012 /* Make a stack frame, so that we can call the collector. */
1013 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1015 0x0d, 0xe4, /* basr %r14, %r4 */
1016 /* And get rid of the stack frame again. */
1017 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1018 /* Leave the lock. */
1019 0x07, 0xf0, /* br %r0 */
1020 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1021 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1024 /* Code sequence restoring FRs, for targets with no VX support. */
1026 static const unsigned char s390_ft_exit_fr
[] = {
1027 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1028 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1029 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1030 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1031 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1032 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1033 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1034 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1035 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1036 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1037 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1038 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1039 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1040 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1041 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1042 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1045 /* Code sequence restoring VRs. */
1047 static const unsigned char s390_ft_exit_vr
[] = {
1048 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1049 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1052 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1053 modified by C code, so we use the alr instruction to restore it by
1054 manufacturing an operand that'll result in the original flags. */
1056 static const unsigned char s390_ft_exit_misc
[] = {
1057 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1058 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1059 /* Extract CC to high 2 bits of %r0. */
1060 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1061 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1062 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1063 will have carry iff CC bit 1 is set - resulting in the same flags
1065 0x1e, 0x00, /* alr %r0, %r0 */
1066 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1069 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1071 static const unsigned char s390_ft_exit_gpr_esa
[] = {
1072 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1073 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1074 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1075 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1076 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1077 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1078 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1079 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1080 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1081 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1082 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1083 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1084 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1085 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1086 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1087 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1090 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1093 static const unsigned char s390_ft_exit_gpr_zarch
[] = {
1094 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1097 /* Writes instructions to target, updating the to pointer. */
1100 append_insns (CORE_ADDR
*to
, size_t len
, const unsigned char *buf
)
1102 target_write_memory (*to
, buf
, len
);
1106 /* Relocates an instruction from oldloc to *to, updating to. */
1109 s390_relocate_instruction (CORE_ADDR
*to
, CORE_ADDR oldloc
, int is_64
)
1114 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1117 read_inferior_memory (oldloc
, buf
, sizeof buf
);
1120 else if (buf
[0] < 0xc0)
1126 case 0x05: /* BALR */
1127 case 0x0c: /* BASSM */
1128 case 0x0d: /* BASR */
1129 case 0x45: /* BAL */
1130 case 0x4d: /* BAS */
1131 /* These save a return address and mess around with registers.
1132 We can't relocate them. */
1134 case 0x84: /* BRXH */
1135 case 0x85: /* BRXLE */
1140 /* BRC, BRAS, BRCT, BRCTG */
1141 if (op2
>= 4 && op2
<= 7)
1149 /* LARL, BRCL, BRASL */
1150 if (op2
== 0 || op2
== 4 || op2
== 5)
1158 /* PC-relative addressing instructions. */
1161 case 0xc5: /* BPRP */
1162 case 0xc7: /* BPP */
1163 /* Branch prediction - just skip it. */
1175 case 0x44: /* BRXHG */
1176 case 0x45: /* BRXLG */
1177 case 0x64: /* CGRJ */
1178 case 0x65: /* CLGRJ */
1179 case 0x76: /* CRJ */
1180 case 0x77: /* CLRJ */
1189 /* We'll have to relocate an instruction with a PC-relative field.
1190 First, compute the target. */
1191 int64_t loffset
= 0;
1195 int16_t soffset
= 0;
1196 memcpy (&soffset
, buf
+ 2, 2);
1201 int32_t soffset
= 0;
1202 memcpy (&soffset
, buf
+ 2, 4);
1205 target
= oldloc
+ loffset
* 2;
1207 target
&= 0x7fffffff;
1211 /* BRAS or BRASL was used. We cannot just relocate those, since
1212 they save the return address in a register. We can, however,
1213 replace them with a LARL+JG sequence. */
1215 /* Make the LARL. */
1219 loffset
= oldloc
+ ilen
- *to
;
1222 if (soffset
!= loffset
&& is_64
)
1224 memcpy (buf
+ 2, &soffset
, 4);
1225 append_insns (to
, 6, buf
);
1227 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1228 an address with the top bit 0, while BRAS/BRASL will write it
1229 with top bit 1. It should not matter much, since linux compilers
1230 use BR and not BSM to return from functions, but it could confuse
1231 some poor stack unwinder. */
1233 /* We'll now be writing a JG. */
1240 /* Compute the new offset and write it to the buffer. */
1241 loffset
= target
- *to
;
1246 int16_t soffset
= loffset
;
1247 if (soffset
!= loffset
)
1249 memcpy (buf
+ 2, &soffset
, 2);
1253 int32_t soffset
= loffset
;
1254 if (soffset
!= loffset
&& is_64
)
1256 memcpy (buf
+ 2, &soffset
, 4);
1259 append_insns (to
, ilen
, buf
);
1264 s390_target::supports_fast_tracepoints ()
1269 /* Implementation of target ops method
1270 "install_fast_tracepoint_jump_pad". */
1273 s390_target::install_fast_tracepoint_jump_pad
1274 (CORE_ADDR tpoint
, CORE_ADDR tpaddr
, CORE_ADDR collector
,
1275 CORE_ADDR lockaddr
, ULONGEST orig_size
, CORE_ADDR
*jump_entry
,
1276 CORE_ADDR
*trampoline
, ULONGEST
*trampoline_size
,
1277 unsigned char *jjump_pad_insn
, ULONGEST
*jjump_pad_insn_size
,
1278 CORE_ADDR
*adjusted_insn_addr
, CORE_ADDR
*adjusted_insn_addr_end
,
1284 unsigned char jbuf
[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1285 CORE_ADDR buildaddr
= *jump_entry
;
1287 int is_64
= register_size (current_process ()->tdesc
, 0) == 8;
1288 int is_zarch
= is_64
|| have_hwcap_s390_high_gprs
;
1289 int has_vx
= have_hwcap_s390_vx
;
1291 int is_64
= 0, is_zarch
= 0, has_vx
= 0;
1293 CORE_ADDR literals
[4] = {
1300 /* First, store the GPRs. */
1302 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_zarch
,
1303 s390_ft_entry_gpr_zarch
);
1305 append_insns (&buildaddr
, sizeof s390_ft_entry_gpr_esa
,
1306 s390_ft_entry_gpr_esa
);
1308 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1309 append_insns (&buildaddr
, sizeof s390_ft_entry_misc
, s390_ft_entry_misc
);
1311 /* Third, FRs or VRs. */
1313 append_insns (&buildaddr
, sizeof s390_ft_entry_vr
, s390_ft_entry_vr
);
1315 append_insns (&buildaddr
, sizeof s390_ft_entry_fr
, s390_ft_entry_fr
);
1317 /* Now, the main part of code - store PSWA, take lock, call collector,
1318 leave lock. First, we'll need to fetch 4 literals. */
1320 unsigned char buf
[] = {
1321 0x07, 0x07, /* nopr %r7 */
1322 0x07, 0x07, /* nopr %r7 */
1323 0x07, 0x07, /* nopr %r7 */
1324 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1325 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1326 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1327 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1328 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1331 /* Find the proper start place in buf, so that literals will be
1333 int bufpos
= (buildaddr
+ 2) & 7;
1334 /* Stuff the literals into the buffer. */
1335 for (i
= 0; i
< 4; i
++) {
1336 uint64_t lit
= literals
[i
];
1337 memcpy (&buf
[sizeof buf
- 32 + i
* 8], &lit
, 8);
1339 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1340 append_insns (&buildaddr
, sizeof s390_ft_main_64
, s390_ft_main_64
);
1342 unsigned char buf
[] = {
1343 0x07, 0x07, /* nopr %r7 */
1344 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1345 0, 0, 0, 0, /* tpaddr */
1346 0, 0, 0, 0, /* tpoint */
1347 0, 0, 0, 0, /* collector */
1348 0, 0, 0, 0, /* lockaddr */
1351 /* Find the proper start place in buf, so that literals will be
1353 int bufpos
= (buildaddr
+ 2) & 3;
1354 /* First literal will be saved as the PSWA, make sure it has the high bit
1356 literals
[0] |= 0x80000000;
1357 /* Stuff the literals into the buffer. */
1358 for (i
= 0; i
< 4; i
++) {
1359 uint32_t lit
= literals
[i
];
1360 memcpy (&buf
[sizeof buf
- 16 + i
* 4], &lit
, 4);
1362 append_insns (&buildaddr
, sizeof buf
- bufpos
, buf
+ bufpos
);
1363 append_insns (&buildaddr
, sizeof s390_ft_main_31
, s390_ft_main_31
);
1366 /* Restore FRs or VRs. */
1368 append_insns (&buildaddr
, sizeof s390_ft_exit_vr
, s390_ft_exit_vr
);
1370 append_insns (&buildaddr
, sizeof s390_ft_exit_fr
, s390_ft_exit_fr
);
1372 /* Restore misc registers. */
1373 append_insns (&buildaddr
, sizeof s390_ft_exit_misc
, s390_ft_exit_misc
);
1375 /* Restore the GPRs. */
1377 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_zarch
,
1378 s390_ft_exit_gpr_zarch
);
1380 append_insns (&buildaddr
, sizeof s390_ft_exit_gpr_esa
,
1381 s390_ft_exit_gpr_esa
);
1383 /* Now, adjust the original instruction to execute in the jump
1385 *adjusted_insn_addr
= buildaddr
;
1386 if (s390_relocate_instruction (&buildaddr
, tpaddr
, is_64
))
1388 sprintf (err
, "E.Could not relocate instruction for tracepoint.");
1391 *adjusted_insn_addr_end
= buildaddr
;
1393 /* Finally, write a jump back to the program. */
1395 loffset
= (tpaddr
+ orig_size
) - buildaddr
;
1398 if (is_64
&& offset
!= loffset
)
1401 "E.Jump back from jump pad too far from tracepoint "
1402 "(offset 0x%" PRIx64
" > int33).", loffset
);
1405 memcpy (jbuf
+ 2, &offset
, 4);
1406 append_insns (&buildaddr
, sizeof jbuf
, jbuf
);
1408 /* The jump pad is now built. Wire in a jump to our jump pad. This
1409 is always done last (by our caller actually), so that we can
1410 install fast tracepoints with threads running. This relies on
1411 the agent's atomic write support. */
1412 loffset
= *jump_entry
- tpaddr
;
1415 if (is_64
&& offset
!= loffset
)
1418 "E.Jump back from jump pad too far from tracepoint "
1419 "(offset 0x%" PRIx64
" > int33).", loffset
);
1422 memcpy (jbuf
+ 2, &offset
, 4);
1423 memcpy (jjump_pad_insn
, jbuf
, sizeof jbuf
);
1424 *jjump_pad_insn_size
= sizeof jbuf
;
1426 /* Return the end address of our pad. */
1427 *jump_entry
= buildaddr
;
1432 /* Implementation of target ops method
1433 "get_min_fast_tracepoint_insn_len". */
1436 s390_target::get_min_fast_tracepoint_insn_len ()
1438 /* We only support using 6-byte jumps to reach the tracepoint code.
1439 If the tracepoint buffer were allocated sufficiently close (64kiB)
1440 to the executable code, and the traced instruction itself was close
1441 enough to the beginning, we could use 4-byte jumps, but this doesn't
1442 seem to be worth the effort. */
1446 /* Implementation of target ops method "get_ipa_tdesc_idx". */
1449 s390_target::get_ipa_tdesc_idx ()
1451 const target_desc
*tdesc
= current_process ()->tdesc
;
1454 if (tdesc
== tdesc_s390x_linux64
)
1455 return S390_TDESC_64
;
1456 if (tdesc
== tdesc_s390x_linux64v1
)
1457 return S390_TDESC_64V1
;
1458 if (tdesc
== tdesc_s390x_linux64v2
)
1459 return S390_TDESC_64V2
;
1460 if (tdesc
== tdesc_s390x_te_linux64
)
1461 return S390_TDESC_TE
;
1462 if (tdesc
== tdesc_s390x_vx_linux64
)
1463 return S390_TDESC_VX
;
1464 if (tdesc
== tdesc_s390x_tevx_linux64
)
1465 return S390_TDESC_TEVX
;
1466 if (tdesc
== tdesc_s390x_gs_linux64
)
1467 return S390_TDESC_GS
;
1470 if (tdesc
== tdesc_s390_linux32
)
1471 return S390_TDESC_32
;
1472 if (tdesc
== tdesc_s390_linux32v1
)
1473 return S390_TDESC_32V1
;
1474 if (tdesc
== tdesc_s390_linux32v2
)
1475 return S390_TDESC_32V2
;
1476 if (tdesc
== tdesc_s390_linux64
)
1477 return S390_TDESC_64
;
1478 if (tdesc
== tdesc_s390_linux64v1
)
1479 return S390_TDESC_64V1
;
1480 if (tdesc
== tdesc_s390_linux64v2
)
1481 return S390_TDESC_64V2
;
1482 if (tdesc
== tdesc_s390_te_linux64
)
1483 return S390_TDESC_TE
;
1484 if (tdesc
== tdesc_s390_vx_linux64
)
1485 return S390_TDESC_VX
;
1486 if (tdesc
== tdesc_s390_tevx_linux64
)
1487 return S390_TDESC_TEVX
;
1488 if (tdesc
== tdesc_s390_gs_linux64
)
1489 return S390_TDESC_GS
;
1494 /* Appends given buffer to current_insn_ptr in the target. */
1497 add_insns (const unsigned char *start
, int len
)
1499 CORE_ADDR buildaddr
= current_insn_ptr
;
1501 threads_debug_printf ("Adding %d bytes of insn at %s",
1502 len
, paddress (buildaddr
));
1504 append_insns (&buildaddr
, len
, start
);
1505 current_insn_ptr
= buildaddr
;
1508 /* Register usage in emit:
1511 - %r2: top of stack (high word for 31-bit)
1512 - %r3: low word of top of stack (for 31-bit)
1514 - %r6, %r7, %r8: don't use
1517 - %r11: frame pointer
1518 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1519 - %r13: low word of saved top of stack (for 31-bit)
1520 - %r14: return address for calls
1521 - %r15: stack pointer
1525 /* The "emit_prologue" emit_ops method for s390. */
1528 s390_emit_prologue (void)
1530 static const unsigned char buf
[] = {
1531 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1532 0x18, 0x92, /* lr %r9, %r2 */
1533 0x18, 0xa3, /* lr %r10, %r3 */
1534 0x18, 0xbf, /* lr %r11, %r15 */
1536 add_insns (buf
, sizeof buf
);
1539 /* The "emit_epilogue" emit_ops method for s390. */
1542 s390_emit_epilogue (void)
1544 static const unsigned char buf
[] = {
1545 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1546 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1547 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1548 0x07, 0xfe, /* br %r14 */
1550 add_insns (buf
, sizeof buf
);
1553 /* The "emit_add" emit_ops method for s390. */
1556 s390_emit_add (void)
1558 static const unsigned char buf
[] = {
1559 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1560 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1561 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1563 add_insns (buf
, sizeof buf
);
1566 /* The "emit_sub" emit_ops method for s390. */
1569 s390_emit_sub (void)
1571 static const unsigned char buf
[] = {
1572 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1573 0x1f, 0x53, /* slr %r5, %r3 */
1574 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1575 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1576 0x18, 0x35, /* lr %r3, %r5 */
1577 0x18, 0x24, /* lr %r2, %r4 */
1579 add_insns (buf
, sizeof buf
);
1582 /* The "emit_mul" emit_ops method for s390. */
1585 s390_emit_mul (void)
1590 /* The "emit_lsh" emit_ops method for s390. */
1593 s390_emit_lsh (void)
1595 static const unsigned char buf
[] = {
1596 0x18, 0x43, /* lr %r4, %r3 */
1597 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1598 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1599 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1601 add_insns (buf
, sizeof buf
);
1604 /* The "emit_rsh_signed" emit_ops method for s390. */
1607 s390_emit_rsh_signed (void)
1609 static const unsigned char buf
[] = {
1610 0x18, 0x43, /* lr %r4, %r3 */
1611 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1612 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1613 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1615 add_insns (buf
, sizeof buf
);
1618 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1621 s390_emit_rsh_unsigned (void)
1623 static const unsigned char buf
[] = {
1624 0x18, 0x43, /* lr %r4, %r3 */
1625 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1626 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1627 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1629 add_insns (buf
, sizeof buf
);
1632 /* The "emit_ext" emit_ops method for s390. */
1635 s390_emit_ext (int arg
)
1637 unsigned char buf
[] = {
1638 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1639 0x8e, 0x20, 0x00, (unsigned char) (64 - arg
), /* srda %r2, <64-arg> */
1641 add_insns (buf
, sizeof buf
);
1644 /* The "emit_log_not" emit_ops method for s390. */
1647 s390_emit_log_not (void)
1649 static const unsigned char buf
[] = {
1650 0x16, 0x23, /* or %r2, %r3 */
1651 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1652 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1653 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1654 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1657 add_insns (buf
, sizeof buf
);
1660 /* The "emit_bit_and" emit_ops method for s390. */
1663 s390_emit_bit_and (void)
1665 static const unsigned char buf
[] = {
1666 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1667 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1668 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1670 add_insns (buf
, sizeof buf
);
1673 /* The "emit_bit_or" emit_ops method for s390. */
1676 s390_emit_bit_or (void)
1678 static const unsigned char buf
[] = {
1679 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1680 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1681 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1683 add_insns (buf
, sizeof buf
);
1686 /* The "emit_bit_xor" emit_ops method for s390. */
1689 s390_emit_bit_xor (void)
1691 static const unsigned char buf
[] = {
1692 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1693 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1694 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1696 add_insns (buf
, sizeof buf
);
1699 /* The "emit_bit_not" emit_ops method for s390. */
1702 s390_emit_bit_not (void)
1704 static const unsigned char buf
[] = {
1705 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1706 0x17, 0x24, /* xr %r2, %r4 */
1707 0x17, 0x34, /* xr %r3, %r4 */
1709 add_insns (buf
, sizeof buf
);
1712 /* The "emit_equal" emit_ops method for s390. */
1715 s390_emit_equal (void)
1717 s390_emit_bit_xor ();
1718 s390_emit_log_not ();
1721 /* The "emit_less_signed" emit_ops method for s390. */
1724 s390_emit_less_signed (void)
1726 static const unsigned char buf
[] = {
1727 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1728 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1729 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1730 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1731 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1733 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1734 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1736 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1738 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1739 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1741 add_insns (buf
, sizeof buf
);
1744 /* The "emit_less_unsigned" emit_ops method for s390. */
1747 s390_emit_less_unsigned (void)
1749 static const unsigned char buf
[] = {
1750 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1751 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1752 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1753 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1754 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1756 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1757 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1759 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1761 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1762 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1764 add_insns (buf
, sizeof buf
);
1767 /* The "emit_ref" emit_ops method for s390. */
1770 s390_emit_ref (int size
)
1772 static const unsigned char buf1
[] = {
1773 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1774 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1776 static const unsigned char buf2
[] = {
1777 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1778 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1780 static const unsigned char buf4
[] = {
1781 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1782 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1784 static const unsigned char buf8
[] = {
1785 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1790 add_insns (buf1
, sizeof buf1
);
1793 add_insns (buf2
, sizeof buf2
);
1796 add_insns (buf4
, sizeof buf4
);
1799 add_insns (buf8
, sizeof buf8
);
1806 /* The "emit_if_goto" emit_ops method for s390. */
1809 s390_emit_if_goto (int *offset_p
, int *size_p
)
1811 static const unsigned char buf
[] = {
1812 0x16, 0x23, /* or %r2, %r3 */
1813 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1814 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1815 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1817 add_insns (buf
, sizeof buf
);
1824 /* The "emit_goto" emit_ops method for s390 and s390x. */
1827 s390_emit_goto (int *offset_p
, int *size_p
)
1829 static const unsigned char buf
[] = {
1830 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1832 add_insns (buf
, sizeof buf
);
1839 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1842 s390_write_goto_address (CORE_ADDR from
, CORE_ADDR to
, int size
)
1844 long diff
= ((long) (to
- (from
- 2))) / 2;
1846 unsigned char buf
[sizeof sdiff
];
1848 /* We're only doing 4-byte sizes at the moment. */
1849 if (size
!= sizeof sdiff
|| sdiff
!= diff
)
1855 memcpy (buf
, &sdiff
, sizeof sdiff
);
1856 target_write_memory (from
, buf
, sizeof sdiff
);
1859 /* Preparation for emitting a literal pool of given size. Loads the address
1860 of the pool into %r1, and jumps over it. Called should emit the pool data
1861 immediately afterwards. Used for both s390 and s390x. */
1864 s390_emit_litpool (int size
)
1866 static const unsigned char nop
[] = {
1869 unsigned char buf
[] = {
1871 (unsigned char) ((size
+ 4) / 2), /* bras %r1, .Lend+size */
1876 /* buf needs to start at even halfword for litpool to be aligned */
1877 if (current_insn_ptr
& 2)
1878 add_insns (nop
, sizeof nop
);
1882 while ((current_insn_ptr
& 6) != 4)
1883 add_insns (nop
, sizeof nop
);
1885 add_insns (buf
, sizeof buf
);
1888 /* The "emit_const" emit_ops method for s390. */
1891 s390_emit_const (LONGEST num
)
1893 unsigned long long n
= num
;
1894 unsigned char buf_s
[] = {
1895 /* lhi %r3, <num> */
1897 (unsigned char) (num
>> 8), (unsigned char) num
,
1901 static const unsigned char buf_l
[] = {
1902 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1904 if (num
< 0x8000 && num
>= 0)
1905 add_insns (buf_s
, sizeof buf_s
);
1908 s390_emit_litpool (8);
1909 add_insns ((unsigned char *) &n
, sizeof n
);
1910 add_insns (buf_l
, sizeof buf_l
);
1914 /* The "emit_call" emit_ops method for s390. */
1917 s390_emit_call (CORE_ADDR fn
)
1919 unsigned int n
= fn
;
1920 static const unsigned char buf
[] = {
1921 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1922 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1923 0x0d, 0xe1, /* basr %r14, %r1 */
1924 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1926 s390_emit_litpool (4);
1927 add_insns ((unsigned char *) &n
, sizeof n
);
1928 add_insns (buf
, sizeof buf
);
1931 /* The "emit_reg" emit_ops method for s390. */
1934 s390_emit_reg (int reg
)
1936 unsigned char bufpre
[] = {
1939 /* lhi %r3, <reg> */
1940 0xa7, 0x38, (unsigned char) (reg
>> 8), (unsigned char) reg
,
1942 add_insns (bufpre
, sizeof bufpre
);
1943 s390_emit_call (get_raw_reg_func_addr ());
1946 /* The "emit_pop" emit_ops method for s390. */
1949 s390_emit_pop (void)
1951 static const unsigned char buf
[] = {
1952 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1953 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1955 add_insns (buf
, sizeof buf
);
1958 /* The "emit_stack_flush" emit_ops method for s390. */
1961 s390_emit_stack_flush (void)
1963 static const unsigned char buf
[] = {
1964 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1965 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1967 add_insns (buf
, sizeof buf
);
1970 /* The "emit_zero_ext" emit_ops method for s390. */
1973 s390_emit_zero_ext (int arg
)
1975 unsigned char buf
[] = {
1976 0x8d, 0x20, 0x00, (unsigned char) (64 - arg
), /* sldl %r2, <64-arg> */
1977 0x8c, 0x20, 0x00, (unsigned char) (64 - arg
), /* srdl %r2, <64-arg> */
1979 add_insns (buf
, sizeof buf
);
1982 /* The "emit_swap" emit_ops method for s390. */
1985 s390_emit_swap (void)
1987 static const unsigned char buf
[] = {
1988 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1989 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1990 0x18, 0x24, /* lr %r2, %r4 */
1991 0x18, 0x35, /* lr %r3, %r5 */
1993 add_insns (buf
, sizeof buf
);
1996 /* The "emit_stack_adjust" emit_ops method for s390. */
1999 s390_emit_stack_adjust (int n
)
2001 unsigned char buf
[] = {
2004 (unsigned char ) (n
* 8 >> 8), (unsigned char) (n
* 8),
2006 add_insns (buf
, sizeof buf
);
2009 /* Sets %r2 to a 32-bit constant. */
2012 s390_emit_set_r2 (int arg1
)
2014 unsigned char buf_s
[] = {
2015 /* lhi %r2, <arg1> */
2016 0xa7, 0x28, (unsigned char) (arg1
>> 8), (unsigned char) arg1
,
2018 static const unsigned char buf_l
[] = {
2019 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
2021 if (arg1
< 0x8000 && arg1
>= -0x8000)
2022 add_insns (buf_s
, sizeof buf_s
);
2025 s390_emit_litpool (4);
2026 add_insns ((unsigned char *) &arg1
, sizeof arg1
);
2027 add_insns (buf_l
, sizeof buf_l
);
2031 /* The "emit_int_call_1" emit_ops method for s390. */
2034 s390_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2036 /* FN's prototype is `LONGEST(*fn)(int)'. */
2037 s390_emit_set_r2 (arg1
);
2038 s390_emit_call (fn
);
2041 /* The "emit_void_call_2" emit_ops method for s390. */
2044 s390_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2046 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2047 static const unsigned char buf
[] = {
2048 0x18, 0xc2, /* lr %r12, %r2 */
2049 0x18, 0xd3, /* lr %r13, %r3 */
2050 0x18, 0x43, /* lr %r4, %r3 */
2051 0x18, 0x32, /* lr %r3, %r2 */
2053 static const unsigned char buf2
[] = {
2054 0x18, 0x2c, /* lr %r2, %r12 */
2055 0x18, 0x3d, /* lr %r3, %r13 */
2057 add_insns (buf
, sizeof buf
);
2058 s390_emit_set_r2 (arg1
);
2059 s390_emit_call (fn
);
2060 add_insns (buf2
, sizeof buf2
);
2063 /* The "emit_eq_goto" emit_ops method for s390. */
2066 s390_emit_eq_goto (int *offset_p
, int *size_p
)
2068 static const unsigned char buf
[] = {
2069 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2070 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2071 0x16, 0x23, /* or %r2, %r3 */
2072 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2073 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2074 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2076 add_insns (buf
, sizeof buf
);
2083 /* The "emit_ne_goto" emit_ops method for s390. */
2086 s390_emit_ne_goto (int *offset_p
, int *size_p
)
2088 static const unsigned char buf
[] = {
2089 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2090 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2091 0x16, 0x23, /* or %r2, %r3 */
2092 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2093 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2094 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2096 add_insns (buf
, sizeof buf
);
2103 /* The "emit_lt_goto" emit_ops method for s390. */
2106 s390_emit_lt_goto (int *offset_p
, int *size_p
)
2108 static const unsigned char buf
[] = {
2109 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2110 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2111 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2112 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2113 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2115 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2116 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2117 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2119 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2120 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2121 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2124 add_insns (buf
, sizeof buf
);
2131 /* The "emit_le_goto" emit_ops method for s390. */
2134 s390_emit_le_goto (int *offset_p
, int *size_p
)
2136 static const unsigned char buf
[] = {
2137 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2138 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2139 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2140 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2141 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2143 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2144 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2145 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2147 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2148 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2149 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2152 add_insns (buf
, sizeof buf
);
2159 /* The "emit_gt_goto" emit_ops method for s390. */
2162 s390_emit_gt_goto (int *offset_p
, int *size_p
)
2164 static const unsigned char buf
[] = {
2165 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2166 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2167 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2168 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2169 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2171 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2172 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2173 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2175 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2176 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2177 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2180 add_insns (buf
, sizeof buf
);
2187 /* The "emit_ge_goto" emit_ops method for s390. */
2190 s390_emit_ge_goto (int *offset_p
, int *size_p
)
2192 static const unsigned char buf
[] = {
2193 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2194 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2195 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2196 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2197 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2199 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2200 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2201 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2203 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2204 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2205 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2208 add_insns (buf
, sizeof buf
);
2215 /* The "emit_ops" structure for s390. Named _impl to avoid name
2216 collision with s390_emit_ops function. */
2218 static struct emit_ops s390_emit_ops_impl
=
2226 s390_emit_rsh_signed
,
2227 s390_emit_rsh_unsigned
,
2235 s390_emit_less_signed
,
2236 s390_emit_less_unsigned
,
2240 s390_write_goto_address
,
2245 s390_emit_stack_flush
,
2248 s390_emit_stack_adjust
,
2249 s390_emit_int_call_1
,
2250 s390_emit_void_call_2
,
2261 /* The "emit_prologue" emit_ops method for s390x. */
2264 s390x_emit_prologue (void)
2266 static const unsigned char buf
[] = {
2267 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2268 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2269 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2270 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2272 add_insns (buf
, sizeof buf
);
2275 /* The "emit_epilogue" emit_ops method for s390x. */
2278 s390x_emit_epilogue (void)
2280 static const unsigned char buf
[] = {
2281 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2282 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2283 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2284 0x07, 0xfe, /* br %r14 */
2286 add_insns (buf
, sizeof buf
);
2289 /* The "emit_add" emit_ops method for s390x. */
2292 s390x_emit_add (void)
2294 static const unsigned char buf
[] = {
2295 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2296 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2298 add_insns (buf
, sizeof buf
);
2301 /* The "emit_sub" emit_ops method for s390x. */
2304 s390x_emit_sub (void)
2306 static const unsigned char buf
[] = {
2307 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2308 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2309 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2310 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2312 add_insns (buf
, sizeof buf
);
2315 /* The "emit_mul" emit_ops method for s390x. */
2318 s390x_emit_mul (void)
2323 /* The "emit_lsh" emit_ops method for s390x. */
2326 s390x_emit_lsh (void)
2328 static const unsigned char buf
[] = {
2329 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2330 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2331 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2333 add_insns (buf
, sizeof buf
);
2336 /* The "emit_rsh_signed" emit_ops method for s390x. */
2339 s390x_emit_rsh_signed (void)
2341 static const unsigned char buf
[] = {
2342 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2343 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2344 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2346 add_insns (buf
, sizeof buf
);
2349 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2352 s390x_emit_rsh_unsigned (void)
2354 static const unsigned char buf
[] = {
2355 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2356 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2357 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2359 add_insns (buf
, sizeof buf
);
2362 /* The "emit_ext" emit_ops method for s390x. */
2365 s390x_emit_ext (int arg
)
2367 unsigned char buf
[] = {
2368 /* sllg %r2, %r2, <64-arg> */
2369 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2370 /* srag %r2, %r2, <64-arg> */
2371 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0a,
2373 add_insns (buf
, sizeof buf
);
2376 /* The "emit_log_not" emit_ops method for s390x. */
2379 s390x_emit_log_not (void)
2381 static const unsigned char buf
[] = {
2382 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2383 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2384 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2386 add_insns (buf
, sizeof buf
);
2389 /* The "emit_bit_and" emit_ops method for s390x. */
2392 s390x_emit_bit_and (void)
2394 static const unsigned char buf
[] = {
2395 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2396 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2398 add_insns (buf
, sizeof buf
);
2401 /* The "emit_bit_or" emit_ops method for s390x. */
2404 s390x_emit_bit_or (void)
2406 static const unsigned char buf
[] = {
2407 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2408 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2410 add_insns (buf
, sizeof buf
);
2413 /* The "emit_bit_xor" emit_ops method for s390x. */
2416 s390x_emit_bit_xor (void)
2418 static const unsigned char buf
[] = {
2419 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2420 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2422 add_insns (buf
, sizeof buf
);
2425 /* The "emit_bit_not" emit_ops method for s390x. */
2428 s390x_emit_bit_not (void)
2430 static const unsigned char buf
[] = {
2431 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2432 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2434 add_insns (buf
, sizeof buf
);
2437 /* The "emit_equal" emit_ops method for s390x. */
2440 s390x_emit_equal (void)
2442 s390x_emit_bit_xor ();
2443 s390x_emit_log_not ();
2446 /* The "emit_less_signed" emit_ops method for s390x. */
2449 s390x_emit_less_signed (void)
2451 static const unsigned char buf
[] = {
2452 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2453 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2454 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2455 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2457 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2459 add_insns (buf
, sizeof buf
);
2462 /* The "emit_less_unsigned" emit_ops method for s390x. */
2465 s390x_emit_less_unsigned (void)
2467 static const unsigned char buf
[] = {
2468 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %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_ref" emit_ops method for s390x. */
2481 s390x_emit_ref (int size
)
2483 static const unsigned char buf1
[] = {
2484 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2486 static const unsigned char buf2
[] = {
2487 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2489 static const unsigned char buf4
[] = {
2490 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2492 static const unsigned char buf8
[] = {
2493 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2498 add_insns (buf1
, sizeof buf1
);
2501 add_insns (buf2
, sizeof buf2
);
2504 add_insns (buf4
, sizeof buf4
);
2507 add_insns (buf8
, sizeof buf8
);
2514 /* The "emit_if_goto" emit_ops method for s390x. */
2517 s390x_emit_if_goto (int *offset_p
, int *size_p
)
2519 static const unsigned char buf
[] = {
2520 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2521 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2522 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2523 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2525 add_insns (buf
, sizeof buf
);
2532 /* The "emit_const" emit_ops method for s390x. */
2535 s390x_emit_const (LONGEST num
)
2537 unsigned long long n
= num
;
2538 unsigned char buf_s
[] = {
2539 /* lghi %r2, <num> */
2540 0xa7, 0x29, (unsigned char) (num
>> 8), (unsigned char) num
,
2542 static const unsigned char buf_l
[] = {
2543 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2545 if (num
< 0x8000 && num
>= -0x8000)
2546 add_insns (buf_s
, sizeof buf_s
);
2549 s390_emit_litpool (8);
2550 add_insns ((unsigned char *) &n
, sizeof n
);
2551 add_insns (buf_l
, sizeof buf_l
);
2555 /* The "emit_call" emit_ops method for s390x. */
2558 s390x_emit_call (CORE_ADDR fn
)
2560 unsigned long n
= fn
;
2561 static const unsigned char buf
[] = {
2562 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2563 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2564 0x0d, 0xe1, /* basr %r14, %r1 */
2565 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2567 s390_emit_litpool (8);
2568 add_insns ((unsigned char *) &n
, sizeof n
);
2569 add_insns (buf
, sizeof buf
);
2572 /* The "emit_reg" emit_ops method for s390x. */
2575 s390x_emit_reg (int reg
)
2577 unsigned char buf
[] = {
2579 0xb9, 0x04, 0x00, 0x29,
2580 /* lghi %r3, <reg> */
2581 0xa7, 0x39, (unsigned char) (reg
>> 8), (unsigned char) reg
,
2583 add_insns (buf
, sizeof buf
);
2584 s390x_emit_call (get_raw_reg_func_addr ());
2587 /* The "emit_pop" emit_ops method for s390x. */
2590 s390x_emit_pop (void)
2592 static const unsigned char buf
[] = {
2593 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2594 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2596 add_insns (buf
, sizeof buf
);
2599 /* The "emit_stack_flush" emit_ops method for s390x. */
2602 s390x_emit_stack_flush (void)
2604 static const unsigned char buf
[] = {
2605 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2606 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2608 add_insns (buf
, sizeof buf
);
2611 /* The "emit_zero_ext" emit_ops method for s390x. */
2614 s390x_emit_zero_ext (int arg
)
2616 unsigned char buf
[] = {
2617 /* sllg %r2, %r2, <64-arg> */
2618 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0d,
2619 /* srlg %r2, %r2, <64-arg> */
2620 0xeb, 0x22, 0x00, (unsigned char) (64 - arg
), 0x00, 0x0c,
2622 add_insns (buf
, sizeof buf
);
2625 /* The "emit_swap" emit_ops method for s390x. */
2628 s390x_emit_swap (void)
2630 static const unsigned char buf
[] = {
2631 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2632 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2633 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2635 add_insns (buf
, sizeof buf
);
2638 /* The "emit_stack_adjust" emit_ops method for s390x. */
2641 s390x_emit_stack_adjust (int n
)
2643 unsigned char buf
[] = {
2644 /* aghi %r15, 8*n */
2646 (unsigned char) (n
* 8 >> 8), (unsigned char) (n
* 8),
2648 add_insns (buf
, sizeof buf
);
2651 /* The "emit_int_call_1" emit_ops method for s390x. */
2654 s390x_emit_int_call_1 (CORE_ADDR fn
, int arg1
)
2656 /* FN's prototype is `LONGEST(*fn)(int)'. */
2657 s390x_emit_const (arg1
);
2658 s390x_emit_call (fn
);
2661 /* The "emit_void_call_2" emit_ops method for s390x. */
2664 s390x_emit_void_call_2 (CORE_ADDR fn
, int arg1
)
2666 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2667 static const unsigned char buf
[] = {
2668 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2669 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2671 static const unsigned char buf2
[] = {
2672 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2674 add_insns (buf
, sizeof buf
);
2675 s390x_emit_const (arg1
);
2676 s390x_emit_call (fn
);
2677 add_insns (buf2
, sizeof buf2
);
2680 /* The "emit_eq_goto" emit_ops method for s390x. */
2683 s390x_emit_eq_goto (int *offset_p
, int *size_p
)
2685 static const unsigned char buf
[] = {
2686 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2687 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2688 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2689 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2691 add_insns (buf
, sizeof buf
);
2698 /* The "emit_ne_goto" emit_ops method for s390x. */
2701 s390x_emit_ne_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, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2709 add_insns (buf
, sizeof buf
);
2716 /* The "emit_lt_goto" emit_ops method for s390x. */
2719 s390x_emit_lt_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, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2727 add_insns (buf
, sizeof buf
);
2734 /* The "emit_le_goto" emit_ops method for s390x. */
2737 s390x_emit_le_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, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2745 add_insns (buf
, sizeof buf
);
2752 /* The "emit_gt_goto" emit_ops method for s390x. */
2755 s390x_emit_gt_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, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2763 add_insns (buf
, sizeof buf
);
2770 /* The "emit_ge_goto" emit_ops method for s390x. */
2773 s390x_emit_ge_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, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2781 add_insns (buf
, sizeof buf
);
2788 /* The "emit_ops" structure for s390x. */
2790 static struct emit_ops s390x_emit_ops
=
2792 s390x_emit_prologue
,
2793 s390x_emit_epilogue
,
2798 s390x_emit_rsh_signed
,
2799 s390x_emit_rsh_unsigned
,
2807 s390x_emit_less_signed
,
2808 s390x_emit_less_unsigned
,
2812 s390_write_goto_address
,
2817 s390x_emit_stack_flush
,
2818 s390x_emit_zero_ext
,
2820 s390x_emit_stack_adjust
,
2821 s390x_emit_int_call_1
,
2822 s390x_emit_void_call_2
,
2832 /* The "emit_ops" target ops method. */
2835 s390_target::emit_ops ()
2838 if (register_size (current_process ()->tdesc
, 0) == 8)
2839 return &s390x_emit_ops
;
2842 return &s390_emit_ops_impl
;
2845 /* The linux target ops object. */
2847 linux_process_target
*the_linux_target
= &the_s390_target
;
2850 initialize_low_arch (void)
2852 /* Initialize the Linux target descriptions. */
2854 init_registers_s390_linux32 ();
2855 init_registers_s390_linux32v1 ();
2856 init_registers_s390_linux32v2 ();
2857 init_registers_s390_linux64 ();
2858 init_registers_s390_linux64v1 ();
2859 init_registers_s390_linux64v2 ();
2860 init_registers_s390_te_linux64 ();
2861 init_registers_s390_vx_linux64 ();
2862 init_registers_s390_tevx_linux64 ();
2863 init_registers_s390_gs_linux64 ();
2865 init_registers_s390x_linux64 ();
2866 init_registers_s390x_linux64v1 ();
2867 init_registers_s390x_linux64v2 ();
2868 init_registers_s390x_te_linux64 ();
2869 init_registers_s390x_vx_linux64 ();
2870 init_registers_s390x_tevx_linux64 ();
2871 init_registers_s390x_gs_linux64 ();
2874 initialize_regsets_info (&s390_regsets_info
);
2875 initialize_regsets_info (&s390_regsets_info_3264
);