]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdbserver/linux-s390-low.cc
New Romanian translation for gas sub-directory
[thirdparty/binutils-gdb.git] / gdbserver / linux-s390-low.cc
1 /* GNU/Linux S/390 specific low level interface, for the remote server
2 for GDB.
3 Copyright (C) 2001-2024 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20 /* This file is used for both 31-bit and 64-bit S/390 systems. */
21
22 #include "server.h"
23 #include "linux-low.h"
24 #include "elf/common.h"
25 #include "ax.h"
26 #include "tracepoint.h"
27
28 #include <asm/ptrace.h>
29 #include "nat/gdb_ptrace.h"
30 #include <sys/uio.h>
31 #include <elf.h>
32 #include <inttypes.h>
33
34 #include "linux-s390-tdesc.h"
35
36 #ifndef HWCAP_S390_HIGH_GPRS
37 #define HWCAP_S390_HIGH_GPRS 512
38 #endif
39
40 #ifndef HWCAP_S390_TE
41 #define HWCAP_S390_TE 1024
42 #endif
43
44 #ifndef HWCAP_S390_VX
45 #define HWCAP_S390_VX 2048
46 #endif
47
48 #ifndef HWCAP_S390_GS
49 #define HWCAP_S390_GS 16384
50 #endif
51
52 #define s390_num_regs 52
53
54 /* Linux target op definitions for the S/390 architecture. */
55
56 class s390_target : public linux_process_target
57 {
58 public:
59
60 const regs_info *get_regs_info () override;
61
62 const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
63
64 bool supports_z_point_type (char z_type) override;
65
66 bool supports_tracepoints () override;
67
68 bool supports_fast_tracepoints () override;
69
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,
76 char *err) override;
77
78 int get_min_fast_tracepoint_insn_len () override;
79
80 void low_collect_ptrace_register (regcache *regcache, int regno,
81 char *buf) override;
82
83 void low_supply_ptrace_register (regcache *regcache, int regno,
84 const char *buf) override;
85
86 struct emit_ops *emit_ops () override;
87
88 int get_ipa_tdesc_idx () override;
89
90 protected:
91
92 void low_arch_setup () override;
93
94 bool low_cannot_fetch_register (int regno) override;
95
96 bool low_cannot_store_register (int regno) override;
97
98 bool low_supports_breakpoints () override;
99
100 CORE_ADDR low_get_pc (regcache *regcache) override;
101
102 void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
103
104 int low_decr_pc_after_break () override;
105
106 bool low_breakpoint_at (CORE_ADDR pc) override;
107
108 int low_get_thread_area (int lwpid, CORE_ADDR *addrp) override;
109 };
110
111 /* The singleton target ops object. */
112
113 static s390_target the_s390_target;
114
115 static int s390_regmap[] = {
116 PT_PSWMASK, PT_PSWADDR,
117
118 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
119 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
120 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
121 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15,
122
123 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
124 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
125 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
126 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
127
128 PT_FPC,
129
130 #ifndef __s390x__
131 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
132 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
133 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
134 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
135 #else
136 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
137 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
138 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
139 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
140 #endif
141
142 PT_ORIGGPR2,
143 };
144
145 #define s390_num_regs_3264 68
146
147 #ifdef __s390x__
148 static int s390_regmap_3264[] = {
149 PT_PSWMASK, PT_PSWADDR,
150
151 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1,
152 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3,
153 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5,
154 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7,
155 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9,
156 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11,
157 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13,
158 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15,
159
160 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
161 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
162 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
163 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
164
165 PT_FPC,
166
167 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3,
168 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7,
169 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11,
170 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15,
171
172 PT_ORIGGPR2,
173 };
174 #else
175 static int s390_regmap_3264[] = {
176 PT_PSWMASK, PT_PSWADDR,
177
178 -1, PT_GPR0, -1, PT_GPR1,
179 -1, PT_GPR2, -1, PT_GPR3,
180 -1, PT_GPR4, -1, PT_GPR5,
181 -1, PT_GPR6, -1, PT_GPR7,
182 -1, PT_GPR8, -1, PT_GPR9,
183 -1, PT_GPR10, -1, PT_GPR11,
184 -1, PT_GPR12, -1, PT_GPR13,
185 -1, PT_GPR14, -1, PT_GPR15,
186
187 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3,
188 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7,
189 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
190 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
191
192 PT_FPC,
193
194 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
195 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
196 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
197 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI,
198
199 PT_ORIGGPR2,
200 };
201 #endif
202
203
204 bool
205 s390_target::low_cannot_fetch_register (int regno)
206 {
207 return false;
208 }
209
210 bool
211 s390_target::low_cannot_store_register (int regno)
212 {
213 return false;
214 }
215
216 void
217 s390_target::low_collect_ptrace_register (regcache *regcache, int regno,
218 char *buf)
219 {
220 int size = register_size (regcache->tdesc, regno);
221 const struct regs_info *regs_info = get_regs_info ();
222 struct usrregs_info *usr = regs_info->usrregs;
223 int regaddr = usr->regmap[regno];
224
225 if (size < sizeof (long))
226 {
227 memset (buf, 0, sizeof (long));
228
229 if ((regno ^ 1) < usr->num_regs
230 && usr->regmap[regno ^ 1] == regaddr)
231 {
232 collect_register (regcache, regno & ~1, buf);
233 collect_register (regcache, (regno & ~1) + 1,
234 buf + sizeof (long) - size);
235 }
236 else if (regaddr == PT_PSWMASK)
237 {
238 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying
239 the basic addressing mode bit from the PSW address. */
240 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
241 collect_register (regcache, regno, buf);
242 collect_register (regcache, regno ^ 1, addr);
243 buf[1] &= ~0x8;
244 buf[size] |= (addr[0] & 0x80);
245 }
246 else if (regaddr == PT_PSWADDR)
247 {
248 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing
249 mode bit (which gets copied to the PSW mask instead). */
250 collect_register (regcache, regno, buf + sizeof (long) - size);
251 buf[sizeof (long) - size] &= ~0x80;
252 }
253 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
254 || regaddr == PT_ORIGGPR2)
255 collect_register (regcache, regno, buf + sizeof (long) - size);
256 else
257 collect_register (regcache, regno, buf);
258 }
259 else if (regaddr != -1)
260 collect_register (regcache, regno, buf);
261 }
262
263 void
264 s390_target::low_supply_ptrace_register (regcache *regcache, int regno,
265 const char *buf)
266 {
267 int size = register_size (regcache->tdesc, regno);
268 const struct regs_info *regs_info = get_regs_info ();
269 struct usrregs_info *usr = regs_info->usrregs;
270 int regaddr = usr->regmap[regno];
271
272 if (size < sizeof (long))
273 {
274 if ((regno ^ 1) < usr->num_regs
275 && usr->regmap[regno ^ 1] == regaddr)
276 {
277 supply_register (regcache, regno & ~1, buf);
278 supply_register (regcache, (regno & ~1) + 1,
279 buf + sizeof (long) - size);
280 }
281 else if (regaddr == PT_PSWMASK)
282 {
283 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying
284 the basic addressing mode into the PSW address. */
285 gdb_byte *mask = (gdb_byte *) alloca (size);
286 gdb_byte *addr = (gdb_byte *) alloca (register_size (regcache->tdesc, regno ^ 1));
287 memcpy (mask, buf, size);
288 mask[1] |= 0x8;
289 supply_register (regcache, regno, mask);
290
291 collect_register (regcache, regno ^ 1, addr);
292 addr[0] &= ~0x80;
293 addr[0] |= (buf[size] & 0x80);
294 supply_register (regcache, regno ^ 1, addr);
295 }
296 else if (regaddr == PT_PSWADDR)
297 {
298 /* Convert 8-byte PSW address to 4 bytes by truncating, but
299 keeping the addressing mode bit (which was set from the mask). */
300 gdb_byte *addr = (gdb_byte *) alloca (size);
301 char amode;
302 collect_register (regcache, regno, addr);
303 amode = addr[0] & 0x80;
304 memcpy (addr, buf + sizeof (long) - size, size);
305 addr[0] &= ~0x80;
306 addr[0] |= amode;
307 supply_register (regcache, regno, addr);
308 }
309 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15)
310 || regaddr == PT_ORIGGPR2)
311 supply_register (regcache, regno, buf + sizeof (long) - size);
312 else
313 supply_register (regcache, regno, buf);
314 }
315 else if (regaddr != -1)
316 supply_register (regcache, regno, buf);
317 }
318
319 /* Provide only a fill function for the general register set. ps_lgetregs
320 will use this for NPTL support. */
321
322 static void
323 s390_fill_gregset (struct regcache *regcache, void *buf)
324 {
325 int i;
326 const struct regs_info *regs_info = the_linux_target->get_regs_info ();
327 struct usrregs_info *usr = regs_info->usrregs;
328
329 for (i = 0; i < usr->num_regs; i++)
330 {
331 if (usr->regmap[i] < PT_PSWMASK
332 || usr->regmap[i] > PT_ACR15)
333 continue;
334
335 ((s390_target *) the_linux_target)->low_collect_ptrace_register
336 (regcache, i, (char *) buf + usr->regmap[i]);
337 }
338 }
339
340 /* Fill and store functions for extended register sets. */
341
342 #ifndef __s390x__
343 static void
344 s390_fill_gprs_high (struct regcache *regcache, void *buf)
345 {
346 int r0h = find_regno (regcache->tdesc, "r0h");
347 int i;
348
349 for (i = 0; i < 16; i++)
350 collect_register (regcache, r0h + 2 * i, (char *) buf + 4 * i);
351 }
352
353 static void
354 s390_store_gprs_high (struct regcache *regcache, const void *buf)
355 {
356 int r0h = find_regno (regcache->tdesc, "r0h");
357 int i;
358
359 for (i = 0; i < 16; i++)
360 supply_register (regcache, r0h + 2 * i, (const char *) buf + 4 * i);
361 }
362 #endif
363
364 static void
365 s390_store_last_break (struct regcache *regcache, const void *buf)
366 {
367 const char *p;
368
369 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0);
370 supply_register_by_name (regcache, "last_break", p);
371 }
372
373 static void
374 s390_fill_system_call (struct regcache *regcache, void *buf)
375 {
376 collect_register_by_name (regcache, "system_call", buf);
377 }
378
379 static void
380 s390_store_system_call (struct regcache *regcache, const void *buf)
381 {
382 supply_register_by_name (regcache, "system_call", buf);
383 }
384
385 static void
386 s390_store_tdb (struct regcache *regcache, const void *buf)
387 {
388 int tdb0 = find_regno (regcache->tdesc, "tdb0");
389 int tr0 = find_regno (regcache->tdesc, "tr0");
390 int i;
391
392 for (i = 0; i < 4; i++)
393 supply_register (regcache, tdb0 + i, (const char *) buf + 8 * i);
394
395 for (i = 0; i < 16; i++)
396 supply_register (regcache, tr0 + i, (const char *) buf + 8 * (16 + i));
397 }
398
399 static void
400 s390_fill_vxrs_low (struct regcache *regcache, void *buf)
401 {
402 int v0 = find_regno (regcache->tdesc, "v0l");
403 int i;
404
405 for (i = 0; i < 16; i++)
406 collect_register (regcache, v0 + i, (char *) buf + 8 * i);
407 }
408
409 static void
410 s390_store_vxrs_low (struct regcache *regcache, const void *buf)
411 {
412 int v0 = find_regno (regcache->tdesc, "v0l");
413 int i;
414
415 for (i = 0; i < 16; i++)
416 supply_register (regcache, v0 + i, (const char *) buf + 8 * i);
417 }
418
419 static void
420 s390_fill_vxrs_high (struct regcache *regcache, void *buf)
421 {
422 int v16 = find_regno (regcache->tdesc, "v16");
423 int i;
424
425 for (i = 0; i < 16; i++)
426 collect_register (regcache, v16 + i, (char *) buf + 16 * i);
427 }
428
429 static void
430 s390_store_vxrs_high (struct regcache *regcache, const void *buf)
431 {
432 int v16 = find_regno (regcache->tdesc, "v16");
433 int i;
434
435 for (i = 0; i < 16; i++)
436 supply_register (regcache, v16 + i, (const char *) buf + 16 * i);
437 }
438
439 static void
440 s390_store_gs (struct regcache *regcache, const void *buf)
441 {
442 int gsd = find_regno (regcache->tdesc, "gsd");
443 int i;
444
445 for (i = 0; i < 3; i++)
446 supply_register (regcache, gsd + i, (const char *) buf + 8 * (i + 1));
447 }
448
449 static void
450 s390_store_gsbc (struct regcache *regcache, const void *buf)
451 {
452 int bc_gsd = find_regno (regcache->tdesc, "bc_gsd");
453 int i;
454
455 for (i = 0; i < 3; i++)
456 supply_register (regcache, bc_gsd + i, (const char *) buf + 8 * (i + 1));
457 }
458
459 static struct regset_info s390_regsets[] = {
460 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL },
461 #ifndef __s390x__
462 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_HIGH_GPRS, 0,
463 EXTENDED_REGS, s390_fill_gprs_high, s390_store_gprs_high },
464 #endif
465 /* Last break address is read-only; no fill function. */
466 { PTRACE_GETREGSET, -1, NT_S390_LAST_BREAK, 0, EXTENDED_REGS,
467 NULL, s390_store_last_break },
468 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0,
469 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call },
470 /* TDB is read-only. */
471 { PTRACE_GETREGSET, -1, NT_S390_TDB, 0, EXTENDED_REGS,
472 NULL, s390_store_tdb },
473 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_LOW, 0,
474 EXTENDED_REGS, s390_fill_vxrs_low, s390_store_vxrs_low },
475 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_VXRS_HIGH, 0,
476 EXTENDED_REGS, s390_fill_vxrs_high, s390_store_vxrs_high },
477 /* Guarded storage registers are read-only. */
478 { PTRACE_GETREGSET, -1, NT_S390_GS_CB, 0, EXTENDED_REGS,
479 NULL, s390_store_gs },
480 { PTRACE_GETREGSET, -1, NT_S390_GS_BC, 0, EXTENDED_REGS,
481 NULL, s390_store_gsbc },
482 NULL_REGSET
483 };
484
485
486 static const gdb_byte s390_breakpoint[] = { 0, 1 };
487 #define s390_breakpoint_len 2
488
489 /* Implementation of target ops method "sw_breakpoint_from_kind". */
490
491 const gdb_byte *
492 s390_target::sw_breakpoint_from_kind (int kind, int *size)
493 {
494 *size = s390_breakpoint_len;
495 return s390_breakpoint;
496 }
497
498 bool
499 s390_target::low_supports_breakpoints ()
500 {
501 return true;
502 }
503
504 CORE_ADDR
505 s390_target::low_get_pc (regcache *regcache)
506 {
507 if (register_size (regcache->tdesc, 0) == 4)
508 {
509 unsigned int pswa;
510 collect_register_by_name (regcache, "pswa", &pswa);
511 return pswa & 0x7fffffff;
512 }
513 else
514 {
515 unsigned long pc;
516 collect_register_by_name (regcache, "pswa", &pc);
517 return pc;
518 }
519 }
520
521 void
522 s390_target::low_set_pc (regcache *regcache, CORE_ADDR newpc)
523 {
524 if (register_size (regcache->tdesc, 0) == 4)
525 {
526 unsigned int pswa;
527 collect_register_by_name (regcache, "pswa", &pswa);
528 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff);
529 supply_register_by_name (regcache, "pswa", &pswa);
530 }
531 else
532 {
533 unsigned long pc = newpc;
534 supply_register_by_name (regcache, "pswa", &pc);
535 }
536 }
537
538 int
539 s390_target::low_decr_pc_after_break ()
540 {
541 return s390_breakpoint_len;
542 }
543
544 /* Determine the word size for the given PID, in bytes. */
545
546 #ifdef __s390x__
547 static int
548 s390_get_wordsize (int pid)
549 {
550 errno = 0;
551 PTRACE_XFER_TYPE pswm = ptrace (PTRACE_PEEKUSER, pid,
552 (PTRACE_TYPE_ARG3) 0,
553 (PTRACE_TYPE_ARG4) 0);
554 if (errno != 0)
555 {
556 warning (_("Couldn't determine word size, assuming 64-bit."));
557 return 8;
558 }
559 /* Derive word size from extended addressing mode (PSW bit 31). */
560 return pswm & (1L << 32) ? 8 : 4;
561 }
562 #else
563 #define s390_get_wordsize(pid) 4
564 #endif
565
566 static int
567 s390_check_regset (int pid, int regset, int regsize)
568 {
569 void *buf = alloca (regsize);
570 struct iovec iov;
571
572 iov.iov_base = buf;
573 iov.iov_len = regsize;
574
575 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0
576 || errno == ENODATA)
577 return 1;
578 return 0;
579 }
580
581 /* For a 31-bit inferior, whether the kernel supports using the full
582 64-bit GPRs. */
583 static int have_hwcap_s390_high_gprs = 0;
584 static int have_hwcap_s390_vx = 0;
585
586 void
587 s390_target::low_arch_setup ()
588 {
589 const struct target_desc *tdesc;
590 struct regset_info *regset;
591
592 /* Determine word size and HWCAP. */
593 int pid = pid_of (current_thread);
594 int wordsize = s390_get_wordsize (pid);
595 unsigned long hwcap = linux_get_hwcap (pid, wordsize);
596
597 /* Check whether the kernel supports extra register sets. */
598 int have_regset_last_break
599 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
600 int have_regset_system_call
601 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
602 int have_regset_tdb
603 = (s390_check_regset (pid, NT_S390_TDB, 256)
604 && (hwcap & HWCAP_S390_TE) != 0);
605 int have_regset_vxrs
606 = (s390_check_regset (pid, NT_S390_VXRS_LOW, 128)
607 && s390_check_regset (pid, NT_S390_VXRS_HIGH, 256)
608 && (hwcap & HWCAP_S390_VX) != 0);
609 int have_regset_gs
610 = (s390_check_regset (pid, NT_S390_GS_CB, 32)
611 && s390_check_regset (pid, NT_S390_GS_BC, 32)
612 && (hwcap & HWCAP_S390_GS) != 0);
613
614 {
615 #ifdef __s390x__
616 if (wordsize == 8)
617 {
618 if (have_regset_gs)
619 tdesc = tdesc_s390x_gs_linux64;
620 else if (have_regset_vxrs)
621 tdesc = (have_regset_tdb ? tdesc_s390x_tevx_linux64 :
622 tdesc_s390x_vx_linux64);
623 else if (have_regset_tdb)
624 tdesc = tdesc_s390x_te_linux64;
625 else if (have_regset_system_call)
626 tdesc = tdesc_s390x_linux64v2;
627 else if (have_regset_last_break)
628 tdesc = tdesc_s390x_linux64v1;
629 else
630 tdesc = tdesc_s390x_linux64;
631 }
632
633 /* For a 31-bit inferior, check whether the kernel supports
634 using the full 64-bit GPRs. */
635 else
636 #endif
637 if (hwcap & HWCAP_S390_HIGH_GPRS)
638 {
639 have_hwcap_s390_high_gprs = 1;
640 if (have_regset_gs)
641 tdesc = tdesc_s390_gs_linux64;
642 else if (have_regset_vxrs)
643 tdesc = (have_regset_tdb ? tdesc_s390_tevx_linux64 :
644 tdesc_s390_vx_linux64);
645 else if (have_regset_tdb)
646 tdesc = tdesc_s390_te_linux64;
647 else if (have_regset_system_call)
648 tdesc = tdesc_s390_linux64v2;
649 else if (have_regset_last_break)
650 tdesc = tdesc_s390_linux64v1;
651 else
652 tdesc = tdesc_s390_linux64;
653 }
654 else
655 {
656 /* Assume 31-bit inferior process. */
657 if (have_regset_system_call)
658 tdesc = tdesc_s390_linux32v2;
659 else if (have_regset_last_break)
660 tdesc = tdesc_s390_linux32v1;
661 else
662 tdesc = tdesc_s390_linux32;
663 }
664
665 have_hwcap_s390_vx = have_regset_vxrs;
666 }
667
668 /* Update target_regsets according to available register sets. */
669 for (regset = s390_regsets; regset->size >= 0; regset++)
670 if (regset->get_request == PTRACE_GETREGSET)
671 switch (regset->nt_type)
672 {
673 #ifndef __s390x__
674 case NT_S390_HIGH_GPRS:
675 regset->size = have_hwcap_s390_high_gprs ? 64 : 0;
676 break;
677 #endif
678 case NT_S390_LAST_BREAK:
679 regset->size = have_regset_last_break ? 8 : 0;
680 break;
681 case NT_S390_SYSTEM_CALL:
682 regset->size = have_regset_system_call ? 4 : 0;
683 break;
684 case NT_S390_TDB:
685 regset->size = have_regset_tdb ? 256 : 0;
686 break;
687 case NT_S390_VXRS_LOW:
688 regset->size = have_regset_vxrs ? 128 : 0;
689 break;
690 case NT_S390_VXRS_HIGH:
691 regset->size = have_regset_vxrs ? 256 : 0;
692 break;
693 case NT_S390_GS_CB:
694 case NT_S390_GS_BC:
695 regset->size = have_regset_gs ? 32 : 0;
696 default:
697 break;
698 }
699
700 current_process ()->tdesc = tdesc;
701 }
702
703
704 bool
705 s390_target::low_breakpoint_at (CORE_ADDR pc)
706 {
707 unsigned char c[s390_breakpoint_len];
708 read_inferior_memory (pc, c, s390_breakpoint_len);
709 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0;
710 }
711
712 /* Breakpoint/Watchpoint support. */
713
714 /* The "supports_z_point_type" target ops method. */
715
716 bool
717 s390_target::supports_z_point_type (char z_type)
718 {
719 switch (z_type)
720 {
721 case Z_PACKET_SW_BP:
722 return true;
723 default:
724 return false;
725 }
726 }
727
728 static struct usrregs_info s390_usrregs_info =
729 {
730 s390_num_regs,
731 s390_regmap,
732 };
733
734 static struct regsets_info s390_regsets_info =
735 {
736 s390_regsets, /* regsets */
737 0, /* num_regsets */
738 NULL, /* disabled_regsets */
739 };
740
741 static struct regs_info myregs_info =
742 {
743 NULL, /* regset_bitmap */
744 &s390_usrregs_info,
745 &s390_regsets_info
746 };
747
748 static struct usrregs_info s390_usrregs_info_3264 =
749 {
750 s390_num_regs_3264,
751 s390_regmap_3264
752 };
753
754 static struct regsets_info s390_regsets_info_3264 =
755 {
756 s390_regsets, /* regsets */
757 0, /* num_regsets */
758 NULL, /* disabled_regsets */
759 };
760
761 static struct regs_info regs_info_3264 =
762 {
763 NULL, /* regset_bitmap */
764 &s390_usrregs_info_3264,
765 &s390_regsets_info_3264
766 };
767
768 const regs_info *
769 s390_target::get_regs_info ()
770 {
771 if (have_hwcap_s390_high_gprs)
772 {
773 #ifdef __s390x__
774 const struct target_desc *tdesc = current_process ()->tdesc;
775
776 if (register_size (tdesc, 0) == 4)
777 return &regs_info_3264;
778 #else
779 return &regs_info_3264;
780 #endif
781 }
782 return &myregs_info;
783 }
784
785 /* The "supports_tracepoints" target ops method. */
786
787 bool
788 s390_target::supports_tracepoints ()
789 {
790 return true;
791 }
792
793 /* Implementation of linux target ops method "low_get_thread_area". */
794
795 int
796 s390_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
797 {
798 CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, (long) 0);
799 #ifdef __s390x__
800 struct regcache *regcache = get_thread_regcache (current_thread, 0);
801
802 if (register_size (regcache->tdesc, 0) == 4)
803 res &= 0xffffffffull;
804 #endif
805 *addrp = res;
806 return 0;
807 }
808
809
810 /* Fast tracepoint support.
811
812 The register save area on stack is identical for all targets:
813
814 0x000+i*0x10: VR0-VR31
815 0x200+i*8: GR0-GR15
816 0x280+i*4: AR0-AR15
817 0x2c0: PSWM [64-bit]
818 0x2c8: PSWA [64-bit]
819 0x2d0: FPC
820
821 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
822 Likewise, if there's no VX support, we just store the FRs into the slots
823 of low VR halves. The agent code is responsible for rearranging that
824 into regcache. */
825
826 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
827 one trick used at the very beginning: since there's no way to allocate
828 stack space without destroying CC (lay instruction can do it, but it's
829 only supported on later CPUs), we take 4 different execution paths for
830 every possible value of CC, allocate stack space, save %r0, stuff the
831 CC value in %r0 (shifted to match its position in PSWM high word),
832 then branch to common path. */
833
834 static const unsigned char s390_ft_entry_gpr_esa[] = {
835 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
836 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
837 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
838 /* CC = 0 */
839 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
840 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
841 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
842 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
843 /* .Lcc1: */
844 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
845 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
846 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
847 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
848 /* .Lcc2: */
849 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
850 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
851 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
852 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
853 /* .Lcc3: */
854 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
855 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
856 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
857 /* .Lccdone: */
858 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
859 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
860 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
861 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
862 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
863 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
864 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
865 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
866 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
867 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
868 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
869 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
870 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
871 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
872 /* Compute original value of %r15 and store it. We use ahi instead
873 of la to preserve the whole value, and not just the low 31 bits.
874 This is not particularly important here, but essential in the
875 zarch case where someone might be using the high word of %r15
876 as an extra register. */
877 0x18, 0x1f, /* lr %r1, %r15 */
878 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
879 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
880 };
881
882 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
883 target. Same as above, except this time we can use load/store multiple,
884 since the 64-bit regs are tightly packed. */
885
886 static const unsigned char s390_ft_entry_gpr_zarch[] = {
887 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
888 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
889 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
890 /* CC = 0 */
891 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
892 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
893 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
894 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
895 /* .Lcc1: */
896 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
897 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
898 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
899 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
900 /* .Lcc2: */
901 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
902 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
903 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
904 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
905 /* .Lcc3: */
906 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
907 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
908 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
909 /* .Lccdone: */
910 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
911 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
912 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
913 };
914
915 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
916 current PSWM (read by epsw) and CC from entry (in %r0). */
917
918 static const unsigned char s390_ft_entry_misc[] = {
919 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
920 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
921 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
922 0x14, 0x21, /* nr %r2, %r1 */
923 0x16, 0x20, /* or %r2, %r0 */
924 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
925 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
926 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
927 };
928
929 /* Code sequence saving FRs, used if VX not supported. */
930
931 static const unsigned char s390_ft_entry_fr[] = {
932 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
933 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
934 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
935 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
936 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
937 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
938 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
939 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
940 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
941 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
942 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
943 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
944 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
945 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
946 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
947 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
948 };
949
950 /* Code sequence saving VRs, used if VX not supported. */
951
952 static const unsigned char s390_ft_entry_vr[] = {
953 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
954 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
955 };
956
957 /* Code sequence doing the collection call for 31-bit target. %r1 contains
958 the address of the literal pool. */
959
960 static const unsigned char s390_ft_main_31[] = {
961 /* Load the literals into registers. */
962 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
963 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
964 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
965 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
966 /* Save original PSWA (tracepoint address | 0x80000000). */
967 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
968 /* Construct a collecting_t object at %r15+0x2e0. */
969 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
970 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
971 /* Move its address to %r0. */
972 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
973 /* Take the lock. */
974 /* .Lloop: */
975 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
976 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
977 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
978 /* Address of the register save block to %r3. */
979 0x18, 0x3f, /* lr %r3, %r15 */
980 /* Make a stack frame, so that we can call the collector. */
981 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
982 /* Call it. */
983 0x0d, 0xe4, /* basr %r14, %r4 */
984 /* And get rid of the stack frame again. */
985 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
986 /* Leave the lock. */
987 0x07, 0xf0, /* br %r0 */
988 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
989 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
990 };
991
992 /* Code sequence doing the collection call for 64-bit target. %r1 contains
993 the address of the literal pool. */
994
995 static const unsigned char s390_ft_main_64[] = {
996 /* Load the literals into registers. */
997 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
998 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
999 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
1000 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
1001 /* Save original PSWA (tracepoint address). */
1002 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
1003 /* Construct a collecting_t object at %r15+0x2e0. */
1004 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
1005 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
1006 /* Move its address to %r0. */
1007 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
1008 /* Take the lock. */
1009 /* .Lloop: */
1010 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1011 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
1012 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
1013 /* Address of the register save block to %r3. */
1014 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
1015 /* Make a stack frame, so that we can call the collector. */
1016 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1017 /* Call it. */
1018 0x0d, 0xe4, /* basr %r14, %r4 */
1019 /* And get rid of the stack frame again. */
1020 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1021 /* Leave the lock. */
1022 0x07, 0xf0, /* br %r0 */
1023 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1024 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1025 };
1026
1027 /* Code sequence restoring FRs, for targets with no VX support. */
1028
1029 static const unsigned char s390_ft_exit_fr[] = {
1030 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1031 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1032 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1033 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1034 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1035 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1036 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1037 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1038 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1039 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1040 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1041 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1042 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1043 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1044 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1045 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1046 };
1047
1048 /* Code sequence restoring VRs. */
1049
1050 static const unsigned char s390_ft_exit_vr[] = {
1051 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1052 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1053 };
1054
1055 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1056 modified by C code, so we use the alr instruction to restore it by
1057 manufacturing an operand that'll result in the original flags. */
1058
1059 static const unsigned char s390_ft_exit_misc[] = {
1060 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1061 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1062 /* Extract CC to high 2 bits of %r0. */
1063 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1064 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1065 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1066 will have carry iff CC bit 1 is set - resulting in the same flags
1067 as the original. */
1068 0x1e, 0x00, /* alr %r0, %r0 */
1069 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1070 };
1071
1072 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1073
1074 static const unsigned char s390_ft_exit_gpr_esa[] = {
1075 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1076 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1077 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1078 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1079 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1080 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1081 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1082 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1083 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1084 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1085 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1086 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1087 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1088 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1089 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1090 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1091 };
1092
1093 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1094 with high GPRs. */
1095
1096 static const unsigned char s390_ft_exit_gpr_zarch[] = {
1097 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1098 };
1099
1100 /* Writes instructions to target, updating the to pointer. */
1101
1102 static void
1103 append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
1104 {
1105 target_write_memory (*to, buf, len);
1106 *to += len;
1107 }
1108
1109 /* Relocates an instruction from oldloc to *to, updating to. */
1110
1111 static int
1112 s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64)
1113 {
1114 gdb_byte buf[6];
1115 int ilen;
1116 int op2;
1117 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1118 int mode = 0;
1119 int is_bras = 0;
1120 read_inferior_memory (oldloc, buf, sizeof buf);
1121 if (buf[0] < 0x40)
1122 ilen = 2;
1123 else if (buf[0] < 0xc0)
1124 ilen = 4;
1125 else
1126 ilen = 6;
1127 switch (buf[0])
1128 {
1129 case 0x05: /* BALR */
1130 case 0x0c: /* BASSM */
1131 case 0x0d: /* BASR */
1132 case 0x45: /* BAL */
1133 case 0x4d: /* BAS */
1134 /* These save a return address and mess around with registers.
1135 We can't relocate them. */
1136 return 1;
1137 case 0x84: /* BRXH */
1138 case 0x85: /* BRXLE */
1139 mode = 1;
1140 break;
1141 case 0xa7:
1142 op2 = buf[1] & 0xf;
1143 /* BRC, BRAS, BRCT, BRCTG */
1144 if (op2 >= 4 && op2 <= 7)
1145 mode = 1;
1146 /* BRAS */
1147 if (op2 == 5)
1148 is_bras = 1;
1149 break;
1150 case 0xc0:
1151 op2 = buf[1] & 0xf;
1152 /* LARL, BRCL, BRASL */
1153 if (op2 == 0 || op2 == 4 || op2 == 5)
1154 mode = 2;
1155 /* BRASL */
1156 if (op2 == 5)
1157 is_bras = 1;
1158 break;
1159 case 0xc4:
1160 case 0xc6:
1161 /* PC-relative addressing instructions. */
1162 mode = 2;
1163 break;
1164 case 0xc5: /* BPRP */
1165 case 0xc7: /* BPP */
1166 /* Branch prediction - just skip it. */
1167 return 0;
1168 case 0xcc:
1169 op2 = buf[1] & 0xf;
1170 /* BRCTH */
1171 if (op2 == 6)
1172 mode = 2;
1173 break;
1174 case 0xec:
1175 op2 = buf[5];
1176 switch (op2)
1177 {
1178 case 0x44: /* BRXHG */
1179 case 0x45: /* BRXLG */
1180 case 0x64: /* CGRJ */
1181 case 0x65: /* CLGRJ */
1182 case 0x76: /* CRJ */
1183 case 0x77: /* CLRJ */
1184 mode = 1;
1185 break;
1186 }
1187 break;
1188 }
1189
1190 if (mode != 0)
1191 {
1192 /* We'll have to relocate an instruction with a PC-relative field.
1193 First, compute the target. */
1194 int64_t loffset = 0;
1195 CORE_ADDR target;
1196 if (mode == 1)
1197 {
1198 int16_t soffset = 0;
1199 memcpy (&soffset, buf + 2, 2);
1200 loffset = soffset;
1201 }
1202 else if (mode == 2)
1203 {
1204 int32_t soffset = 0;
1205 memcpy (&soffset, buf + 2, 4);
1206 loffset = soffset;
1207 }
1208 target = oldloc + loffset * 2;
1209 if (!is_64)
1210 target &= 0x7fffffff;
1211
1212 if (is_bras)
1213 {
1214 /* BRAS or BRASL was used. We cannot just relocate those, since
1215 they save the return address in a register. We can, however,
1216 replace them with a LARL+JG sequence. */
1217
1218 /* Make the LARL. */
1219 int32_t soffset;
1220 buf[0] = 0xc0;
1221 buf[1] &= 0xf0;
1222 loffset = oldloc + ilen - *to;
1223 loffset >>= 1;
1224 soffset = loffset;
1225 if (soffset != loffset && is_64)
1226 return 1;
1227 memcpy (buf + 2, &soffset, 4);
1228 append_insns (to, 6, buf);
1229
1230 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1231 an address with the top bit 0, while BRAS/BRASL will write it
1232 with top bit 1. It should not matter much, since linux compilers
1233 use BR and not BSM to return from functions, but it could confuse
1234 some poor stack unwinder. */
1235
1236 /* We'll now be writing a JG. */
1237 mode = 2;
1238 buf[0] = 0xc0;
1239 buf[1] = 0xf4;
1240 ilen = 6;
1241 }
1242
1243 /* Compute the new offset and write it to the buffer. */
1244 loffset = target - *to;
1245 loffset >>= 1;
1246
1247 if (mode == 1)
1248 {
1249 int16_t soffset = loffset;
1250 if (soffset != loffset)
1251 return 1;
1252 memcpy (buf + 2, &soffset, 2);
1253 }
1254 else if (mode == 2)
1255 {
1256 int32_t soffset = loffset;
1257 if (soffset != loffset && is_64)
1258 return 1;
1259 memcpy (buf + 2, &soffset, 4);
1260 }
1261 }
1262 append_insns (to, ilen, buf);
1263 return 0;
1264 }
1265
1266 bool
1267 s390_target::supports_fast_tracepoints ()
1268 {
1269 return true;
1270 }
1271
1272 /* Implementation of target ops method
1273 "install_fast_tracepoint_jump_pad". */
1274
1275 int
1276 s390_target::install_fast_tracepoint_jump_pad
1277 (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
1278 CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
1279 CORE_ADDR *trampoline, ULONGEST *trampoline_size,
1280 unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
1281 CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
1282 char *err)
1283 {
1284 int i;
1285 int64_t loffset;
1286 int32_t offset;
1287 unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1288 CORE_ADDR buildaddr = *jump_entry;
1289 #ifdef __s390x__
1290 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1291 int is_64 = register_size (regcache->tdesc, 0) == 8;
1292 int is_zarch = is_64 || have_hwcap_s390_high_gprs;
1293 int has_vx = have_hwcap_s390_vx;
1294 #else
1295 int is_64 = 0, is_zarch = 0, has_vx = 0;
1296 #endif
1297 CORE_ADDR literals[4] = {
1298 tpaddr,
1299 tpoint,
1300 collector,
1301 lockaddr,
1302 };
1303
1304 /* First, store the GPRs. */
1305 if (is_zarch)
1306 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch,
1307 s390_ft_entry_gpr_zarch);
1308 else
1309 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa,
1310 s390_ft_entry_gpr_esa);
1311
1312 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1313 append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc);
1314
1315 /* Third, FRs or VRs. */
1316 if (has_vx)
1317 append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr);
1318 else
1319 append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr);
1320
1321 /* Now, the main part of code - store PSWA, take lock, call collector,
1322 leave lock. First, we'll need to fetch 4 literals. */
1323 if (is_64) {
1324 unsigned char buf[] = {
1325 0x07, 0x07, /* nopr %r7 */
1326 0x07, 0x07, /* nopr %r7 */
1327 0x07, 0x07, /* nopr %r7 */
1328 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1329 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1330 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1331 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1332 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1333 /* .Lend: */
1334 };
1335 /* Find the proper start place in buf, so that literals will be
1336 aligned. */
1337 int bufpos = (buildaddr + 2) & 7;
1338 /* Stuff the literals into the buffer. */
1339 for (i = 0; i < 4; i++) {
1340 uint64_t lit = literals[i];
1341 memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8);
1342 }
1343 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1344 append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64);
1345 } else {
1346 unsigned char buf[] = {
1347 0x07, 0x07, /* nopr %r7 */
1348 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1349 0, 0, 0, 0, /* tpaddr */
1350 0, 0, 0, 0, /* tpoint */
1351 0, 0, 0, 0, /* collector */
1352 0, 0, 0, 0, /* lockaddr */
1353 /* .Lend: */
1354 };
1355 /* Find the proper start place in buf, so that literals will be
1356 aligned. */
1357 int bufpos = (buildaddr + 2) & 3;
1358 /* First literal will be saved as the PSWA, make sure it has the high bit
1359 set. */
1360 literals[0] |= 0x80000000;
1361 /* Stuff the literals into the buffer. */
1362 for (i = 0; i < 4; i++) {
1363 uint32_t lit = literals[i];
1364 memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4);
1365 }
1366 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1367 append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31);
1368 }
1369
1370 /* Restore FRs or VRs. */
1371 if (has_vx)
1372 append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr);
1373 else
1374 append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr);
1375
1376 /* Restore misc registers. */
1377 append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc);
1378
1379 /* Restore the GPRs. */
1380 if (is_zarch)
1381 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch,
1382 s390_ft_exit_gpr_zarch);
1383 else
1384 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa,
1385 s390_ft_exit_gpr_esa);
1386
1387 /* Now, adjust the original instruction to execute in the jump
1388 pad. */
1389 *adjusted_insn_addr = buildaddr;
1390 if (s390_relocate_instruction (&buildaddr, tpaddr, is_64))
1391 {
1392 sprintf (err, "E.Could not relocate instruction for tracepoint.");
1393 return 1;
1394 }
1395 *adjusted_insn_addr_end = buildaddr;
1396
1397 /* Finally, write a jump back to the program. */
1398
1399 loffset = (tpaddr + orig_size) - buildaddr;
1400 loffset >>= 1;
1401 offset = loffset;
1402 if (is_64 && offset != loffset)
1403 {
1404 sprintf (err,
1405 "E.Jump back from jump pad too far from tracepoint "
1406 "(offset 0x%" PRIx64 " > int33).", loffset);
1407 return 1;
1408 }
1409 memcpy (jbuf + 2, &offset, 4);
1410 append_insns (&buildaddr, sizeof jbuf, jbuf);
1411
1412 /* The jump pad is now built. Wire in a jump to our jump pad. This
1413 is always done last (by our caller actually), so that we can
1414 install fast tracepoints with threads running. This relies on
1415 the agent's atomic write support. */
1416 loffset = *jump_entry - tpaddr;
1417 loffset >>= 1;
1418 offset = loffset;
1419 if (is_64 && offset != loffset)
1420 {
1421 sprintf (err,
1422 "E.Jump back from jump pad too far from tracepoint "
1423 "(offset 0x%" PRIx64 " > int33).", loffset);
1424 return 1;
1425 }
1426 memcpy (jbuf + 2, &offset, 4);
1427 memcpy (jjump_pad_insn, jbuf, sizeof jbuf);
1428 *jjump_pad_insn_size = sizeof jbuf;
1429
1430 /* Return the end address of our pad. */
1431 *jump_entry = buildaddr;
1432
1433 return 0;
1434 }
1435
1436 /* Implementation of target ops method
1437 "get_min_fast_tracepoint_insn_len". */
1438
1439 int
1440 s390_target::get_min_fast_tracepoint_insn_len ()
1441 {
1442 /* We only support using 6-byte jumps to reach the tracepoint code.
1443 If the tracepoint buffer were allocated sufficiently close (64kiB)
1444 to the executable code, and the traced instruction itself was close
1445 enough to the beginning, we could use 4-byte jumps, but this doesn't
1446 seem to be worth the effort. */
1447 return 6;
1448 }
1449
1450 /* Implementation of target ops method "get_ipa_tdesc_idx". */
1451
1452 int
1453 s390_target::get_ipa_tdesc_idx ()
1454 {
1455 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1456 const struct target_desc *tdesc = regcache->tdesc;
1457
1458 #ifdef __s390x__
1459 if (tdesc == tdesc_s390x_linux64)
1460 return S390_TDESC_64;
1461 if (tdesc == tdesc_s390x_linux64v1)
1462 return S390_TDESC_64V1;
1463 if (tdesc == tdesc_s390x_linux64v2)
1464 return S390_TDESC_64V2;
1465 if (tdesc == tdesc_s390x_te_linux64)
1466 return S390_TDESC_TE;
1467 if (tdesc == tdesc_s390x_vx_linux64)
1468 return S390_TDESC_VX;
1469 if (tdesc == tdesc_s390x_tevx_linux64)
1470 return S390_TDESC_TEVX;
1471 if (tdesc == tdesc_s390x_gs_linux64)
1472 return S390_TDESC_GS;
1473 #endif
1474
1475 if (tdesc == tdesc_s390_linux32)
1476 return S390_TDESC_32;
1477 if (tdesc == tdesc_s390_linux32v1)
1478 return S390_TDESC_32V1;
1479 if (tdesc == tdesc_s390_linux32v2)
1480 return S390_TDESC_32V2;
1481 if (tdesc == tdesc_s390_linux64)
1482 return S390_TDESC_64;
1483 if (tdesc == tdesc_s390_linux64v1)
1484 return S390_TDESC_64V1;
1485 if (tdesc == tdesc_s390_linux64v2)
1486 return S390_TDESC_64V2;
1487 if (tdesc == tdesc_s390_te_linux64)
1488 return S390_TDESC_TE;
1489 if (tdesc == tdesc_s390_vx_linux64)
1490 return S390_TDESC_VX;
1491 if (tdesc == tdesc_s390_tevx_linux64)
1492 return S390_TDESC_TEVX;
1493 if (tdesc == tdesc_s390_gs_linux64)
1494 return S390_TDESC_GS;
1495
1496 return 0;
1497 }
1498
1499 /* Appends given buffer to current_insn_ptr in the target. */
1500
1501 static void
1502 add_insns (const unsigned char *start, int len)
1503 {
1504 CORE_ADDR buildaddr = current_insn_ptr;
1505
1506 threads_debug_printf ("Adding %d bytes of insn at %s",
1507 len, paddress (buildaddr));
1508
1509 append_insns (&buildaddr, len, start);
1510 current_insn_ptr = buildaddr;
1511 }
1512
1513 /* Register usage in emit:
1514
1515 - %r0, %r1: temp
1516 - %r2: top of stack (high word for 31-bit)
1517 - %r3: low word of top of stack (for 31-bit)
1518 - %r4, %r5: temp
1519 - %r6, %r7, %r8: don't use
1520 - %r9: saved arg1
1521 - %r10: saved arg2
1522 - %r11: frame pointer
1523 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1524 - %r13: low word of saved top of stack (for 31-bit)
1525 - %r14: return address for calls
1526 - %r15: stack pointer
1527
1528 */
1529
1530 /* The "emit_prologue" emit_ops method for s390. */
1531
1532 static void
1533 s390_emit_prologue (void)
1534 {
1535 static const unsigned char buf[] = {
1536 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1537 0x18, 0x92, /* lr %r9, %r2 */
1538 0x18, 0xa3, /* lr %r10, %r3 */
1539 0x18, 0xbf, /* lr %r11, %r15 */
1540 };
1541 add_insns (buf, sizeof buf);
1542 }
1543
1544 /* The "emit_epilogue" emit_ops method for s390. */
1545
1546 static void
1547 s390_emit_epilogue (void)
1548 {
1549 static const unsigned char buf[] = {
1550 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1551 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1552 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1553 0x07, 0xfe, /* br %r14 */
1554 };
1555 add_insns (buf, sizeof buf);
1556 }
1557
1558 /* The "emit_add" emit_ops method for s390. */
1559
1560 static void
1561 s390_emit_add (void)
1562 {
1563 static const unsigned char buf[] = {
1564 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1565 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1566 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1567 };
1568 add_insns (buf, sizeof buf);
1569 }
1570
1571 /* The "emit_sub" emit_ops method for s390. */
1572
1573 static void
1574 s390_emit_sub (void)
1575 {
1576 static const unsigned char buf[] = {
1577 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1578 0x1f, 0x53, /* slr %r5, %r3 */
1579 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1580 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1581 0x18, 0x35, /* lr %r3, %r5 */
1582 0x18, 0x24, /* lr %r2, %r4 */
1583 };
1584 add_insns (buf, sizeof buf);
1585 }
1586
1587 /* The "emit_mul" emit_ops method for s390. */
1588
1589 static void
1590 s390_emit_mul (void)
1591 {
1592 emit_error = 1;
1593 }
1594
1595 /* The "emit_lsh" emit_ops method for s390. */
1596
1597 static void
1598 s390_emit_lsh (void)
1599 {
1600 static const unsigned char buf[] = {
1601 0x18, 0x43, /* lr %r4, %r3 */
1602 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1603 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1604 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1605 };
1606 add_insns (buf, sizeof buf);
1607 }
1608
1609 /* The "emit_rsh_signed" emit_ops method for s390. */
1610
1611 static void
1612 s390_emit_rsh_signed (void)
1613 {
1614 static const unsigned char buf[] = {
1615 0x18, 0x43, /* lr %r4, %r3 */
1616 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1617 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1618 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1619 };
1620 add_insns (buf, sizeof buf);
1621 }
1622
1623 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1624
1625 static void
1626 s390_emit_rsh_unsigned (void)
1627 {
1628 static const unsigned char buf[] = {
1629 0x18, 0x43, /* lr %r4, %r3 */
1630 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1631 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1632 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1633 };
1634 add_insns (buf, sizeof buf);
1635 }
1636
1637 /* The "emit_ext" emit_ops method for s390. */
1638
1639 static void
1640 s390_emit_ext (int arg)
1641 {
1642 unsigned char buf[] = {
1643 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1644 0x8e, 0x20, 0x00, (unsigned char) (64 - arg), /* srda %r2, <64-arg> */
1645 };
1646 add_insns (buf, sizeof buf);
1647 }
1648
1649 /* The "emit_log_not" emit_ops method for s390. */
1650
1651 static void
1652 s390_emit_log_not (void)
1653 {
1654 static const unsigned char buf[] = {
1655 0x16, 0x23, /* or %r2, %r3 */
1656 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1657 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1658 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1659 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1660 /* .Lskip: */
1661 };
1662 add_insns (buf, sizeof buf);
1663 }
1664
1665 /* The "emit_bit_and" emit_ops method for s390. */
1666
1667 static void
1668 s390_emit_bit_and (void)
1669 {
1670 static const unsigned char buf[] = {
1671 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1672 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1673 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1674 };
1675 add_insns (buf, sizeof buf);
1676 }
1677
1678 /* The "emit_bit_or" emit_ops method for s390. */
1679
1680 static void
1681 s390_emit_bit_or (void)
1682 {
1683 static const unsigned char buf[] = {
1684 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1685 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1686 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1687 };
1688 add_insns (buf, sizeof buf);
1689 }
1690
1691 /* The "emit_bit_xor" emit_ops method for s390. */
1692
1693 static void
1694 s390_emit_bit_xor (void)
1695 {
1696 static const unsigned char buf[] = {
1697 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1698 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1699 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1700 };
1701 add_insns (buf, sizeof buf);
1702 }
1703
1704 /* The "emit_bit_not" emit_ops method for s390. */
1705
1706 static void
1707 s390_emit_bit_not (void)
1708 {
1709 static const unsigned char buf[] = {
1710 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1711 0x17, 0x24, /* xr %r2, %r4 */
1712 0x17, 0x34, /* xr %r3, %r4 */
1713 };
1714 add_insns (buf, sizeof buf);
1715 }
1716
1717 /* The "emit_equal" emit_ops method for s390. */
1718
1719 static void
1720 s390_emit_equal (void)
1721 {
1722 s390_emit_bit_xor ();
1723 s390_emit_log_not ();
1724 }
1725
1726 /* The "emit_less_signed" emit_ops method for s390. */
1727
1728 static void
1729 s390_emit_less_signed (void)
1730 {
1731 static const unsigned char buf[] = {
1732 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1733 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1734 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1735 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1736 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1737 /* .Lhigh: */
1738 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1739 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1740 /* .Lless: */
1741 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1742 /* .Lend: */
1743 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1744 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1745 };
1746 add_insns (buf, sizeof buf);
1747 }
1748
1749 /* The "emit_less_unsigned" emit_ops method for s390. */
1750
1751 static void
1752 s390_emit_less_unsigned (void)
1753 {
1754 static const unsigned char buf[] = {
1755 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1756 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1757 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1758 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1759 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1760 /* .Lhigh: */
1761 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1762 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1763 /* .Lless: */
1764 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1765 /* .Lend: */
1766 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1767 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1768 };
1769 add_insns (buf, sizeof buf);
1770 }
1771
1772 /* The "emit_ref" emit_ops method for s390. */
1773
1774 static void
1775 s390_emit_ref (int size)
1776 {
1777 static const unsigned char buf1[] = {
1778 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1779 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1780 };
1781 static const unsigned char buf2[] = {
1782 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1783 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1784 };
1785 static const unsigned char buf4[] = {
1786 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1787 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1788 };
1789 static const unsigned char buf8[] = {
1790 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1791 };
1792 switch (size)
1793 {
1794 case 1:
1795 add_insns (buf1, sizeof buf1);
1796 break;
1797 case 2:
1798 add_insns (buf2, sizeof buf2);
1799 break;
1800 case 4:
1801 add_insns (buf4, sizeof buf4);
1802 break;
1803 case 8:
1804 add_insns (buf8, sizeof buf8);
1805 break;
1806 default:
1807 emit_error = 1;
1808 }
1809 }
1810
1811 /* The "emit_if_goto" emit_ops method for s390. */
1812
1813 static void
1814 s390_emit_if_goto (int *offset_p, int *size_p)
1815 {
1816 static const unsigned char buf[] = {
1817 0x16, 0x23, /* or %r2, %r3 */
1818 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1819 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1820 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1821 };
1822 add_insns (buf, sizeof buf);
1823 if (offset_p)
1824 *offset_p = 12;
1825 if (size_p)
1826 *size_p = 4;
1827 }
1828
1829 /* The "emit_goto" emit_ops method for s390 and s390x. */
1830
1831 static void
1832 s390_emit_goto (int *offset_p, int *size_p)
1833 {
1834 static const unsigned char buf[] = {
1835 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1836 };
1837 add_insns (buf, sizeof buf);
1838 if (offset_p)
1839 *offset_p = 2;
1840 if (size_p)
1841 *size_p = 4;
1842 }
1843
1844 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1845
1846 static void
1847 s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
1848 {
1849 long diff = ((long) (to - (from - 2))) / 2;
1850 int sdiff = diff;
1851 unsigned char buf[sizeof sdiff];
1852
1853 /* We're only doing 4-byte sizes at the moment. */
1854 if (size != sizeof sdiff || sdiff != diff)
1855 {
1856 emit_error = 1;
1857 return;
1858 }
1859
1860 memcpy (buf, &sdiff, sizeof sdiff);
1861 target_write_memory (from, buf, sizeof sdiff);
1862 }
1863
1864 /* Preparation for emitting a literal pool of given size. Loads the address
1865 of the pool into %r1, and jumps over it. Called should emit the pool data
1866 immediately afterwards. Used for both s390 and s390x. */
1867
1868 static void
1869 s390_emit_litpool (int size)
1870 {
1871 static const unsigned char nop[] = {
1872 0x07, 0x07,
1873 };
1874 unsigned char buf[] = {
1875 0xa7, 0x15, 0x00,
1876 (unsigned char) ((size + 4) / 2), /* bras %r1, .Lend+size */
1877 /* .Lend: */
1878 };
1879 if (size == 4)
1880 {
1881 /* buf needs to start at even halfword for litpool to be aligned */
1882 if (current_insn_ptr & 2)
1883 add_insns (nop, sizeof nop);
1884 }
1885 else
1886 {
1887 while ((current_insn_ptr & 6) != 4)
1888 add_insns (nop, sizeof nop);
1889 }
1890 add_insns (buf, sizeof buf);
1891 }
1892
1893 /* The "emit_const" emit_ops method for s390. */
1894
1895 static void
1896 s390_emit_const (LONGEST num)
1897 {
1898 unsigned long long n = num;
1899 unsigned char buf_s[] = {
1900 /* lhi %r3, <num> */
1901 0xa7, 0x38,
1902 (unsigned char) (num >> 8), (unsigned char) num,
1903 /* xr %r2, %r2 */
1904 0x17, 0x22,
1905 };
1906 static const unsigned char buf_l[] = {
1907 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1908 };
1909 if (num < 0x8000 && num >= 0)
1910 add_insns (buf_s, sizeof buf_s);
1911 else
1912 {
1913 s390_emit_litpool (8);
1914 add_insns ((unsigned char *) &n, sizeof n);
1915 add_insns (buf_l, sizeof buf_l);
1916 }
1917 }
1918
1919 /* The "emit_call" emit_ops method for s390. */
1920
1921 static void
1922 s390_emit_call (CORE_ADDR fn)
1923 {
1924 unsigned int n = fn;
1925 static const unsigned char buf[] = {
1926 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1927 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1928 0x0d, 0xe1, /* basr %r14, %r1 */
1929 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1930 };
1931 s390_emit_litpool (4);
1932 add_insns ((unsigned char *) &n, sizeof n);
1933 add_insns (buf, sizeof buf);
1934 }
1935
1936 /* The "emit_reg" emit_ops method for s390. */
1937
1938 static void
1939 s390_emit_reg (int reg)
1940 {
1941 unsigned char bufpre[] = {
1942 /* lr %r2, %r9 */
1943 0x18, 0x29,
1944 /* lhi %r3, <reg> */
1945 0xa7, 0x38, (unsigned char) (reg >> 8), (unsigned char) reg,
1946 };
1947 add_insns (bufpre, sizeof bufpre);
1948 s390_emit_call (get_raw_reg_func_addr ());
1949 }
1950
1951 /* The "emit_pop" emit_ops method for s390. */
1952
1953 static void
1954 s390_emit_pop (void)
1955 {
1956 static const unsigned char buf[] = {
1957 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1958 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1959 };
1960 add_insns (buf, sizeof buf);
1961 }
1962
1963 /* The "emit_stack_flush" emit_ops method for s390. */
1964
1965 static void
1966 s390_emit_stack_flush (void)
1967 {
1968 static const unsigned char buf[] = {
1969 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1970 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1971 };
1972 add_insns (buf, sizeof buf);
1973 }
1974
1975 /* The "emit_zero_ext" emit_ops method for s390. */
1976
1977 static void
1978 s390_emit_zero_ext (int arg)
1979 {
1980 unsigned char buf[] = {
1981 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1982 0x8c, 0x20, 0x00, (unsigned char) (64 - arg), /* srdl %r2, <64-arg> */
1983 };
1984 add_insns (buf, sizeof buf);
1985 }
1986
1987 /* The "emit_swap" emit_ops method for s390. */
1988
1989 static void
1990 s390_emit_swap (void)
1991 {
1992 static const unsigned char buf[] = {
1993 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1994 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1995 0x18, 0x24, /* lr %r2, %r4 */
1996 0x18, 0x35, /* lr %r3, %r5 */
1997 };
1998 add_insns (buf, sizeof buf);
1999 }
2000
2001 /* The "emit_stack_adjust" emit_ops method for s390. */
2002
2003 static void
2004 s390_emit_stack_adjust (int n)
2005 {
2006 unsigned char buf[] = {
2007 /* ahi %r15, 8*n */
2008 0xa7, 0xfa,
2009 (unsigned char ) (n * 8 >> 8), (unsigned char) (n * 8),
2010 };
2011 add_insns (buf, sizeof buf);
2012 }
2013
2014 /* Sets %r2 to a 32-bit constant. */
2015
2016 static void
2017 s390_emit_set_r2 (int arg1)
2018 {
2019 unsigned char buf_s[] = {
2020 /* lhi %r2, <arg1> */
2021 0xa7, 0x28, (unsigned char) (arg1 >> 8), (unsigned char) arg1,
2022 };
2023 static const unsigned char buf_l[] = {
2024 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
2025 };
2026 if (arg1 < 0x8000 && arg1 >= -0x8000)
2027 add_insns (buf_s, sizeof buf_s);
2028 else
2029 {
2030 s390_emit_litpool (4);
2031 add_insns ((unsigned char *) &arg1, sizeof arg1);
2032 add_insns (buf_l, sizeof buf_l);
2033 }
2034 }
2035
2036 /* The "emit_int_call_1" emit_ops method for s390. */
2037
2038 static void
2039 s390_emit_int_call_1 (CORE_ADDR fn, int arg1)
2040 {
2041 /* FN's prototype is `LONGEST(*fn)(int)'. */
2042 s390_emit_set_r2 (arg1);
2043 s390_emit_call (fn);
2044 }
2045
2046 /* The "emit_void_call_2" emit_ops method for s390. */
2047
2048 static void
2049 s390_emit_void_call_2 (CORE_ADDR fn, int arg1)
2050 {
2051 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2052 static const unsigned char buf[] = {
2053 0x18, 0xc2, /* lr %r12, %r2 */
2054 0x18, 0xd3, /* lr %r13, %r3 */
2055 0x18, 0x43, /* lr %r4, %r3 */
2056 0x18, 0x32, /* lr %r3, %r2 */
2057 };
2058 static const unsigned char buf2[] = {
2059 0x18, 0x2c, /* lr %r2, %r12 */
2060 0x18, 0x3d, /* lr %r3, %r13 */
2061 };
2062 add_insns (buf, sizeof buf);
2063 s390_emit_set_r2 (arg1);
2064 s390_emit_call (fn);
2065 add_insns (buf2, sizeof buf2);
2066 }
2067
2068 /* The "emit_eq_goto" emit_ops method for s390. */
2069
2070 static void
2071 s390_emit_eq_goto (int *offset_p, int *size_p)
2072 {
2073 static const unsigned char buf[] = {
2074 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2075 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2076 0x16, 0x23, /* or %r2, %r3 */
2077 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2078 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2079 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2080 };
2081 add_insns (buf, sizeof buf);
2082 if (offset_p)
2083 *offset_p = 20;
2084 if (size_p)
2085 *size_p = 4;
2086 }
2087
2088 /* The "emit_ne_goto" emit_ops method for s390. */
2089
2090 static void
2091 s390_emit_ne_goto (int *offset_p, int *size_p)
2092 {
2093 static const unsigned char buf[] = {
2094 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2095 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2096 0x16, 0x23, /* or %r2, %r3 */
2097 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2098 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2099 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2100 };
2101 add_insns (buf, sizeof buf);
2102 if (offset_p)
2103 *offset_p = 20;
2104 if (size_p)
2105 *size_p = 4;
2106 }
2107
2108 /* The "emit_lt_goto" emit_ops method for s390. */
2109
2110 static void
2111 s390_emit_lt_goto (int *offset_p, int *size_p)
2112 {
2113 static const unsigned char buf[] = {
2114 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2115 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2116 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2117 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2118 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2119 /* .Lfalse: */
2120 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2121 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2122 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2123 /* .Ltrue: */
2124 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2125 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2126 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2127 /* .Lend: */
2128 };
2129 add_insns (buf, sizeof buf);
2130 if (offset_p)
2131 *offset_p = 42;
2132 if (size_p)
2133 *size_p = 4;
2134 }
2135
2136 /* The "emit_le_goto" emit_ops method for s390. */
2137
2138 static void
2139 s390_emit_le_goto (int *offset_p, int *size_p)
2140 {
2141 static const unsigned char buf[] = {
2142 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2143 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2144 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2145 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2146 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2147 /* .Lfalse: */
2148 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2149 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2150 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2151 /* .Ltrue: */
2152 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2153 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2154 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2155 /* .Lend: */
2156 };
2157 add_insns (buf, sizeof buf);
2158 if (offset_p)
2159 *offset_p = 42;
2160 if (size_p)
2161 *size_p = 4;
2162 }
2163
2164 /* The "emit_gt_goto" emit_ops method for s390. */
2165
2166 static void
2167 s390_emit_gt_goto (int *offset_p, int *size_p)
2168 {
2169 static const unsigned char buf[] = {
2170 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2171 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2172 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2173 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2174 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2175 /* .Lfalse: */
2176 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2177 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2178 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2179 /* .Ltrue: */
2180 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2181 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2182 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2183 /* .Lend: */
2184 };
2185 add_insns (buf, sizeof buf);
2186 if (offset_p)
2187 *offset_p = 42;
2188 if (size_p)
2189 *size_p = 4;
2190 }
2191
2192 /* The "emit_ge_goto" emit_ops method for s390. */
2193
2194 static void
2195 s390_emit_ge_goto (int *offset_p, int *size_p)
2196 {
2197 static const unsigned char buf[] = {
2198 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2199 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2200 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2201 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2202 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2203 /* .Lfalse: */
2204 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2205 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2206 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2207 /* .Ltrue: */
2208 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2209 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2210 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2211 /* .Lend: */
2212 };
2213 add_insns (buf, sizeof buf);
2214 if (offset_p)
2215 *offset_p = 42;
2216 if (size_p)
2217 *size_p = 4;
2218 }
2219
2220 /* The "emit_ops" structure for s390. Named _impl to avoid name
2221 collision with s390_emit_ops function. */
2222
2223 static struct emit_ops s390_emit_ops_impl =
2224 {
2225 s390_emit_prologue,
2226 s390_emit_epilogue,
2227 s390_emit_add,
2228 s390_emit_sub,
2229 s390_emit_mul,
2230 s390_emit_lsh,
2231 s390_emit_rsh_signed,
2232 s390_emit_rsh_unsigned,
2233 s390_emit_ext,
2234 s390_emit_log_not,
2235 s390_emit_bit_and,
2236 s390_emit_bit_or,
2237 s390_emit_bit_xor,
2238 s390_emit_bit_not,
2239 s390_emit_equal,
2240 s390_emit_less_signed,
2241 s390_emit_less_unsigned,
2242 s390_emit_ref,
2243 s390_emit_if_goto,
2244 s390_emit_goto,
2245 s390_write_goto_address,
2246 s390_emit_const,
2247 s390_emit_call,
2248 s390_emit_reg,
2249 s390_emit_pop,
2250 s390_emit_stack_flush,
2251 s390_emit_zero_ext,
2252 s390_emit_swap,
2253 s390_emit_stack_adjust,
2254 s390_emit_int_call_1,
2255 s390_emit_void_call_2,
2256 s390_emit_eq_goto,
2257 s390_emit_ne_goto,
2258 s390_emit_lt_goto,
2259 s390_emit_le_goto,
2260 s390_emit_gt_goto,
2261 s390_emit_ge_goto
2262 };
2263
2264 #ifdef __s390x__
2265
2266 /* The "emit_prologue" emit_ops method for s390x. */
2267
2268 static void
2269 s390x_emit_prologue (void)
2270 {
2271 static const unsigned char buf[] = {
2272 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2273 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2274 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2275 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2276 };
2277 add_insns (buf, sizeof buf);
2278 }
2279
2280 /* The "emit_epilogue" emit_ops method for s390x. */
2281
2282 static void
2283 s390x_emit_epilogue (void)
2284 {
2285 static const unsigned char buf[] = {
2286 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2287 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2288 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2289 0x07, 0xfe, /* br %r14 */
2290 };
2291 add_insns (buf, sizeof buf);
2292 }
2293
2294 /* The "emit_add" emit_ops method for s390x. */
2295
2296 static void
2297 s390x_emit_add (void)
2298 {
2299 static const unsigned char buf[] = {
2300 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2301 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2302 };
2303 add_insns (buf, sizeof buf);
2304 }
2305
2306 /* The "emit_sub" emit_ops method for s390x. */
2307
2308 static void
2309 s390x_emit_sub (void)
2310 {
2311 static const unsigned char buf[] = {
2312 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2313 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2314 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2315 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2316 };
2317 add_insns (buf, sizeof buf);
2318 }
2319
2320 /* The "emit_mul" emit_ops method for s390x. */
2321
2322 static void
2323 s390x_emit_mul (void)
2324 {
2325 emit_error = 1;
2326 }
2327
2328 /* The "emit_lsh" emit_ops method for s390x. */
2329
2330 static void
2331 s390x_emit_lsh (void)
2332 {
2333 static const unsigned char buf[] = {
2334 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2335 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2336 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2337 };
2338 add_insns (buf, sizeof buf);
2339 }
2340
2341 /* The "emit_rsh_signed" emit_ops method for s390x. */
2342
2343 static void
2344 s390x_emit_rsh_signed (void)
2345 {
2346 static const unsigned char buf[] = {
2347 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2348 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2349 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2350 };
2351 add_insns (buf, sizeof buf);
2352 }
2353
2354 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2355
2356 static void
2357 s390x_emit_rsh_unsigned (void)
2358 {
2359 static const unsigned char buf[] = {
2360 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2361 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2362 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2363 };
2364 add_insns (buf, sizeof buf);
2365 }
2366
2367 /* The "emit_ext" emit_ops method for s390x. */
2368
2369 static void
2370 s390x_emit_ext (int arg)
2371 {
2372 unsigned char buf[] = {
2373 /* sllg %r2, %r2, <64-arg> */
2374 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2375 /* srag %r2, %r2, <64-arg> */
2376 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0a,
2377 };
2378 add_insns (buf, sizeof buf);
2379 }
2380
2381 /* The "emit_log_not" emit_ops method for s390x. */
2382
2383 static void
2384 s390x_emit_log_not (void)
2385 {
2386 static const unsigned char buf[] = {
2387 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2388 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2389 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2390 };
2391 add_insns (buf, sizeof buf);
2392 }
2393
2394 /* The "emit_bit_and" emit_ops method for s390x. */
2395
2396 static void
2397 s390x_emit_bit_and (void)
2398 {
2399 static const unsigned char buf[] = {
2400 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2401 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2402 };
2403 add_insns (buf, sizeof buf);
2404 }
2405
2406 /* The "emit_bit_or" emit_ops method for s390x. */
2407
2408 static void
2409 s390x_emit_bit_or (void)
2410 {
2411 static const unsigned char buf[] = {
2412 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2413 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2414 };
2415 add_insns (buf, sizeof buf);
2416 }
2417
2418 /* The "emit_bit_xor" emit_ops method for s390x. */
2419
2420 static void
2421 s390x_emit_bit_xor (void)
2422 {
2423 static const unsigned char buf[] = {
2424 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2425 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2426 };
2427 add_insns (buf, sizeof buf);
2428 }
2429
2430 /* The "emit_bit_not" emit_ops method for s390x. */
2431
2432 static void
2433 s390x_emit_bit_not (void)
2434 {
2435 static const unsigned char buf[] = {
2436 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2437 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2438 };
2439 add_insns (buf, sizeof buf);
2440 }
2441
2442 /* The "emit_equal" emit_ops method for s390x. */
2443
2444 static void
2445 s390x_emit_equal (void)
2446 {
2447 s390x_emit_bit_xor ();
2448 s390x_emit_log_not ();
2449 }
2450
2451 /* The "emit_less_signed" emit_ops method for s390x. */
2452
2453 static void
2454 s390x_emit_less_signed (void)
2455 {
2456 static const unsigned char buf[] = {
2457 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2458 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2459 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2460 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2461 /* .Lend: */
2462 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2463 };
2464 add_insns (buf, sizeof buf);
2465 }
2466
2467 /* The "emit_less_unsigned" emit_ops method for s390x. */
2468
2469 static void
2470 s390x_emit_less_unsigned (void)
2471 {
2472 static const unsigned char buf[] = {
2473 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2474 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2475 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2476 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2477 /* .Lend: */
2478 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2479 };
2480 add_insns (buf, sizeof buf);
2481 }
2482
2483 /* The "emit_ref" emit_ops method for s390x. */
2484
2485 static void
2486 s390x_emit_ref (int size)
2487 {
2488 static const unsigned char buf1[] = {
2489 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2490 };
2491 static const unsigned char buf2[] = {
2492 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2493 };
2494 static const unsigned char buf4[] = {
2495 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2496 };
2497 static const unsigned char buf8[] = {
2498 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2499 };
2500 switch (size)
2501 {
2502 case 1:
2503 add_insns (buf1, sizeof buf1);
2504 break;
2505 case 2:
2506 add_insns (buf2, sizeof buf2);
2507 break;
2508 case 4:
2509 add_insns (buf4, sizeof buf4);
2510 break;
2511 case 8:
2512 add_insns (buf8, sizeof buf8);
2513 break;
2514 default:
2515 emit_error = 1;
2516 }
2517 }
2518
2519 /* The "emit_if_goto" emit_ops method for s390x. */
2520
2521 static void
2522 s390x_emit_if_goto (int *offset_p, int *size_p)
2523 {
2524 static const unsigned char buf[] = {
2525 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2526 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2527 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2528 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2529 };
2530 add_insns (buf, sizeof buf);
2531 if (offset_p)
2532 *offset_p = 16;
2533 if (size_p)
2534 *size_p = 4;
2535 }
2536
2537 /* The "emit_const" emit_ops method for s390x. */
2538
2539 static void
2540 s390x_emit_const (LONGEST num)
2541 {
2542 unsigned long long n = num;
2543 unsigned char buf_s[] = {
2544 /* lghi %r2, <num> */
2545 0xa7, 0x29, (unsigned char) (num >> 8), (unsigned char) num,
2546 };
2547 static const unsigned char buf_l[] = {
2548 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2549 };
2550 if (num < 0x8000 && num >= -0x8000)
2551 add_insns (buf_s, sizeof buf_s);
2552 else
2553 {
2554 s390_emit_litpool (8);
2555 add_insns ((unsigned char *) &n, sizeof n);
2556 add_insns (buf_l, sizeof buf_l);
2557 }
2558 }
2559
2560 /* The "emit_call" emit_ops method for s390x. */
2561
2562 static void
2563 s390x_emit_call (CORE_ADDR fn)
2564 {
2565 unsigned long n = fn;
2566 static const unsigned char buf[] = {
2567 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2568 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2569 0x0d, 0xe1, /* basr %r14, %r1 */
2570 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2571 };
2572 s390_emit_litpool (8);
2573 add_insns ((unsigned char *) &n, sizeof n);
2574 add_insns (buf, sizeof buf);
2575 }
2576
2577 /* The "emit_reg" emit_ops method for s390x. */
2578
2579 static void
2580 s390x_emit_reg (int reg)
2581 {
2582 unsigned char buf[] = {
2583 /* lgr %r2, %r9 */
2584 0xb9, 0x04, 0x00, 0x29,
2585 /* lghi %r3, <reg> */
2586 0xa7, 0x39, (unsigned char) (reg >> 8), (unsigned char) reg,
2587 };
2588 add_insns (buf, sizeof buf);
2589 s390x_emit_call (get_raw_reg_func_addr ());
2590 }
2591
2592 /* The "emit_pop" emit_ops method for s390x. */
2593
2594 static void
2595 s390x_emit_pop (void)
2596 {
2597 static const unsigned char buf[] = {
2598 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2599 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2600 };
2601 add_insns (buf, sizeof buf);
2602 }
2603
2604 /* The "emit_stack_flush" emit_ops method for s390x. */
2605
2606 static void
2607 s390x_emit_stack_flush (void)
2608 {
2609 static const unsigned char buf[] = {
2610 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2611 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2612 };
2613 add_insns (buf, sizeof buf);
2614 }
2615
2616 /* The "emit_zero_ext" emit_ops method for s390x. */
2617
2618 static void
2619 s390x_emit_zero_ext (int arg)
2620 {
2621 unsigned char buf[] = {
2622 /* sllg %r2, %r2, <64-arg> */
2623 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2624 /* srlg %r2, %r2, <64-arg> */
2625 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0c,
2626 };
2627 add_insns (buf, sizeof buf);
2628 }
2629
2630 /* The "emit_swap" emit_ops method for s390x. */
2631
2632 static void
2633 s390x_emit_swap (void)
2634 {
2635 static const unsigned char buf[] = {
2636 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2637 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2638 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2639 };
2640 add_insns (buf, sizeof buf);
2641 }
2642
2643 /* The "emit_stack_adjust" emit_ops method for s390x. */
2644
2645 static void
2646 s390x_emit_stack_adjust (int n)
2647 {
2648 unsigned char buf[] = {
2649 /* aghi %r15, 8*n */
2650 0xa7, 0xfb,
2651 (unsigned char) (n * 8 >> 8), (unsigned char) (n * 8),
2652 };
2653 add_insns (buf, sizeof buf);
2654 }
2655
2656 /* The "emit_int_call_1" emit_ops method for s390x. */
2657
2658 static void
2659 s390x_emit_int_call_1 (CORE_ADDR fn, int arg1)
2660 {
2661 /* FN's prototype is `LONGEST(*fn)(int)'. */
2662 s390x_emit_const (arg1);
2663 s390x_emit_call (fn);
2664 }
2665
2666 /* The "emit_void_call_2" emit_ops method for s390x. */
2667
2668 static void
2669 s390x_emit_void_call_2 (CORE_ADDR fn, int arg1)
2670 {
2671 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2672 static const unsigned char buf[] = {
2673 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2674 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2675 };
2676 static const unsigned char buf2[] = {
2677 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2678 };
2679 add_insns (buf, sizeof buf);
2680 s390x_emit_const (arg1);
2681 s390x_emit_call (fn);
2682 add_insns (buf2, sizeof buf2);
2683 }
2684
2685 /* The "emit_eq_goto" emit_ops method for s390x. */
2686
2687 static void
2688 s390x_emit_eq_goto (int *offset_p, int *size_p)
2689 {
2690 static const unsigned char buf[] = {
2691 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2692 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2693 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2694 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2695 };
2696 add_insns (buf, sizeof buf);
2697 if (offset_p)
2698 *offset_p = 18;
2699 if (size_p)
2700 *size_p = 4;
2701 }
2702
2703 /* The "emit_ne_goto" emit_ops method for s390x. */
2704
2705 static void
2706 s390x_emit_ne_goto (int *offset_p, int *size_p)
2707 {
2708 static const unsigned char buf[] = {
2709 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2710 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2711 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2712 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2713 };
2714 add_insns (buf, sizeof buf);
2715 if (offset_p)
2716 *offset_p = 18;
2717 if (size_p)
2718 *size_p = 4;
2719 }
2720
2721 /* The "emit_lt_goto" emit_ops method for s390x. */
2722
2723 static void
2724 s390x_emit_lt_goto (int *offset_p, int *size_p)
2725 {
2726 static const unsigned char buf[] = {
2727 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2728 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2729 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2730 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2731 };
2732 add_insns (buf, sizeof buf);
2733 if (offset_p)
2734 *offset_p = 18;
2735 if (size_p)
2736 *size_p = 4;
2737 }
2738
2739 /* The "emit_le_goto" emit_ops method for s390x. */
2740
2741 static void
2742 s390x_emit_le_goto (int *offset_p, int *size_p)
2743 {
2744 static const unsigned char buf[] = {
2745 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2746 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2747 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2748 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2749 };
2750 add_insns (buf, sizeof buf);
2751 if (offset_p)
2752 *offset_p = 18;
2753 if (size_p)
2754 *size_p = 4;
2755 }
2756
2757 /* The "emit_gt_goto" emit_ops method for s390x. */
2758
2759 static void
2760 s390x_emit_gt_goto (int *offset_p, int *size_p)
2761 {
2762 static const unsigned char buf[] = {
2763 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2764 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2765 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2766 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2767 };
2768 add_insns (buf, sizeof buf);
2769 if (offset_p)
2770 *offset_p = 18;
2771 if (size_p)
2772 *size_p = 4;
2773 }
2774
2775 /* The "emit_ge_goto" emit_ops method for s390x. */
2776
2777 static void
2778 s390x_emit_ge_goto (int *offset_p, int *size_p)
2779 {
2780 static const unsigned char buf[] = {
2781 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2782 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2783 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2784 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2785 };
2786 add_insns (buf, sizeof buf);
2787 if (offset_p)
2788 *offset_p = 18;
2789 if (size_p)
2790 *size_p = 4;
2791 }
2792
2793 /* The "emit_ops" structure for s390x. */
2794
2795 static struct emit_ops s390x_emit_ops =
2796 {
2797 s390x_emit_prologue,
2798 s390x_emit_epilogue,
2799 s390x_emit_add,
2800 s390x_emit_sub,
2801 s390x_emit_mul,
2802 s390x_emit_lsh,
2803 s390x_emit_rsh_signed,
2804 s390x_emit_rsh_unsigned,
2805 s390x_emit_ext,
2806 s390x_emit_log_not,
2807 s390x_emit_bit_and,
2808 s390x_emit_bit_or,
2809 s390x_emit_bit_xor,
2810 s390x_emit_bit_not,
2811 s390x_emit_equal,
2812 s390x_emit_less_signed,
2813 s390x_emit_less_unsigned,
2814 s390x_emit_ref,
2815 s390x_emit_if_goto,
2816 s390_emit_goto,
2817 s390_write_goto_address,
2818 s390x_emit_const,
2819 s390x_emit_call,
2820 s390x_emit_reg,
2821 s390x_emit_pop,
2822 s390x_emit_stack_flush,
2823 s390x_emit_zero_ext,
2824 s390x_emit_swap,
2825 s390x_emit_stack_adjust,
2826 s390x_emit_int_call_1,
2827 s390x_emit_void_call_2,
2828 s390x_emit_eq_goto,
2829 s390x_emit_ne_goto,
2830 s390x_emit_lt_goto,
2831 s390x_emit_le_goto,
2832 s390x_emit_gt_goto,
2833 s390x_emit_ge_goto
2834 };
2835 #endif
2836
2837 /* The "emit_ops" target ops method. */
2838
2839 emit_ops *
2840 s390_target::emit_ops ()
2841 {
2842 #ifdef __s390x__
2843 struct regcache *regcache = get_thread_regcache (current_thread, 0);
2844
2845 if (register_size (regcache->tdesc, 0) == 8)
2846 return &s390x_emit_ops;
2847 else
2848 #endif
2849 return &s390_emit_ops_impl;
2850 }
2851
2852 /* The linux target ops object. */
2853
2854 linux_process_target *the_linux_target = &the_s390_target;
2855
2856 void
2857 initialize_low_arch (void)
2858 {
2859 /* Initialize the Linux target descriptions. */
2860
2861 init_registers_s390_linux32 ();
2862 init_registers_s390_linux32v1 ();
2863 init_registers_s390_linux32v2 ();
2864 init_registers_s390_linux64 ();
2865 init_registers_s390_linux64v1 ();
2866 init_registers_s390_linux64v2 ();
2867 init_registers_s390_te_linux64 ();
2868 init_registers_s390_vx_linux64 ();
2869 init_registers_s390_tevx_linux64 ();
2870 init_registers_s390_gs_linux64 ();
2871 #ifdef __s390x__
2872 init_registers_s390x_linux64 ();
2873 init_registers_s390x_linux64v1 ();
2874 init_registers_s390x_linux64v2 ();
2875 init_registers_s390x_te_linux64 ();
2876 init_registers_s390x_vx_linux64 ();
2877 init_registers_s390x_tevx_linux64 ();
2878 init_registers_s390x_gs_linux64 ();
2879 #endif
2880
2881 initialize_regsets_info (&s390_regsets_info);
2882 initialize_regsets_info (&s390_regsets_info_3264);
2883 }