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