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