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