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