gdbserver/linux-low: turn 'emit_ops' 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 /* Support for hardware single step. */
727
728 static int
729 s390_supports_hardware_single_step (void)
730 {
731 return 1;
732 }
733
734 static struct usrregs_info s390_usrregs_info =
735 {
736 s390_num_regs,
737 s390_regmap,
738 };
739
740 static struct regsets_info s390_regsets_info =
741 {
742 s390_regsets, /* regsets */
743 0, /* num_regsets */
744 NULL, /* disabled_regsets */
745 };
746
747 static struct regs_info myregs_info =
748 {
749 NULL, /* regset_bitmap */
750 &s390_usrregs_info,
751 &s390_regsets_info
752 };
753
754 static struct usrregs_info s390_usrregs_info_3264 =
755 {
756 s390_num_regs_3264,
757 s390_regmap_3264
758 };
759
760 static struct regsets_info s390_regsets_info_3264 =
761 {
762 s390_regsets, /* regsets */
763 0, /* num_regsets */
764 NULL, /* disabled_regsets */
765 };
766
767 static struct regs_info regs_info_3264 =
768 {
769 NULL, /* regset_bitmap */
770 &s390_usrregs_info_3264,
771 &s390_regsets_info_3264
772 };
773
774 const regs_info *
775 s390_target::get_regs_info ()
776 {
777 if (have_hwcap_s390_high_gprs)
778 {
779 #ifdef __s390x__
780 const struct target_desc *tdesc = current_process ()->tdesc;
781
782 if (register_size (tdesc, 0) == 4)
783 return &regs_info_3264;
784 #else
785 return &regs_info_3264;
786 #endif
787 }
788 return &myregs_info;
789 }
790
791 /* The "supports_tracepoints" target ops method. */
792
793 bool
794 s390_target::supports_tracepoints ()
795 {
796 return true;
797 }
798
799 /* Implementation of linux target ops method "low_get_thread_area". */
800
801 int
802 s390_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
803 {
804 CORE_ADDR res = ptrace (PTRACE_PEEKUSER, lwpid, (long) PT_ACR0, (long) 0);
805 #ifdef __s390x__
806 struct regcache *regcache = get_thread_regcache (current_thread, 0);
807
808 if (register_size (regcache->tdesc, 0) == 4)
809 res &= 0xffffffffull;
810 #endif
811 *addrp = res;
812 return 0;
813 }
814
815
816 /* Fast tracepoint support.
817
818 The register save area on stack is identical for all targets:
819
820 0x000+i*0x10: VR0-VR31
821 0x200+i*8: GR0-GR15
822 0x280+i*4: AR0-AR15
823 0x2c0: PSWM [64-bit]
824 0x2c8: PSWA [64-bit]
825 0x2d0: FPC
826
827 If we're on 31-bit linux, we just don't store the high parts of the GPRs.
828 Likewise, if there's no VX support, we just store the FRs into the slots
829 of low VR halves. The agent code is responsible for rearranging that
830 into regcache. */
831
832 /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's
833 one trick used at the very beginning: since there's no way to allocate
834 stack space without destroying CC (lay instruction can do it, but it's
835 only supported on later CPUs), we take 4 different execution paths for
836 every possible value of CC, allocate stack space, save %r0, stuff the
837 CC value in %r0 (shifted to match its position in PSWM high word),
838 then branch to common path. */
839
840 static const unsigned char s390_ft_entry_gpr_esa[] = {
841 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */
842 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */
843 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */
844 /* CC = 0 */
845 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
846 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
847 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
848 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */
849 /* .Lcc1: */
850 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
851 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
852 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
853 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */
854 /* .Lcc2: */
855 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
856 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
857 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
858 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */
859 /* .Lcc3: */
860 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */
861 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */
862 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
863 /* .Lccdone: */
864 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */
865 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */
866 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */
867 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */
868 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */
869 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */
870 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */
871 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */
872 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */
873 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */
874 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */
875 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */
876 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */
877 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */
878 /* Compute original value of %r15 and store it. We use ahi instead
879 of la to preserve the whole value, and not just the low 31 bits.
880 This is not particularly important here, but essential in the
881 zarch case where someone might be using the high word of %r15
882 as an extra register. */
883 0x18, 0x1f, /* lr %r1, %r15 */
884 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */
885 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */
886 };
887
888 /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit
889 target. Same as above, except this time we can use load/store multiple,
890 since the 64-bit regs are tightly packed. */
891
892 static const unsigned char s390_ft_entry_gpr_zarch[] = {
893 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */
894 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */
895 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */
896 /* CC = 0 */
897 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
898 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
899 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */
900 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */
901 /* .Lcc1: */
902 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
903 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
904 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */
905 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */
906 /* .Lcc2: */
907 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
908 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
909 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */
910 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */
911 /* .Lcc3: */
912 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */
913 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */
914 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */
915 /* .Lccdone: */
916 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */
917 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */
918 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */
919 };
920
921 /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from
922 current PSWM (read by epsw) and CC from entry (in %r0). */
923
924 static const unsigned char s390_ft_entry_misc[] = {
925 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */
926 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */
927 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */
928 0x14, 0x21, /* nr %r2, %r1 */
929 0x16, 0x20, /* or %r2, %r0 */
930 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */
931 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */
932 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */
933 };
934
935 /* Code sequence saving FRs, used if VX not supported. */
936
937 static const unsigned char s390_ft_entry_fr[] = {
938 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */
939 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */
940 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */
941 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */
942 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */
943 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */
944 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */
945 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */
946 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */
947 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */
948 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */
949 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */
950 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */
951 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */
952 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */
953 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */
954 };
955
956 /* Code sequence saving VRs, used if VX not supported. */
957
958 static const unsigned char s390_ft_entry_vr[] = {
959 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */
960 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */
961 };
962
963 /* Code sequence doing the collection call for 31-bit target. %r1 contains
964 the address of the literal pool. */
965
966 static const unsigned char s390_ft_main_31[] = {
967 /* Load the literals into registers. */
968 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */
969 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */
970 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */
971 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */
972 /* Save original PSWA (tracepoint address | 0x80000000). */
973 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */
974 /* Construct a collecting_t object at %r15+0x2e0. */
975 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */
976 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */
977 /* Move its address to %r0. */
978 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
979 /* Take the lock. */
980 /* .Lloop: */
981 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
982 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */
983 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */
984 /* Address of the register save block to %r3. */
985 0x18, 0x3f, /* lr %r3, %r15 */
986 /* Make a stack frame, so that we can call the collector. */
987 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
988 /* Call it. */
989 0x0d, 0xe4, /* basr %r14, %r4 */
990 /* And get rid of the stack frame again. */
991 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */
992 /* Leave the lock. */
993 0x07, 0xf0, /* br %r0 */
994 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */
995 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */
996 };
997
998 /* Code sequence doing the collection call for 64-bit target. %r1 contains
999 the address of the literal pool. */
1000
1001 static const unsigned char s390_ft_main_64[] = {
1002 /* Load the literals into registers. */
1003 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */
1004 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */
1005 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */
1006 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */
1007 /* Save original PSWA (tracepoint address). */
1008 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */
1009 /* Construct a collecting_t object at %r15+0x2e0. */
1010 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */
1011 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */
1012 /* Move its address to %r0. */
1013 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */
1014 /* Take the lock. */
1015 /* .Lloop: */
1016 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1017 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */
1018 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */
1019 /* Address of the register save block to %r3. */
1020 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */
1021 /* Make a stack frame, so that we can call the collector. */
1022 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
1023 /* Call it. */
1024 0x0d, 0xe4, /* basr %r14, %r4 */
1025 /* And get rid of the stack frame again. */
1026 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */
1027 /* Leave the lock. */
1028 0x07, 0xf0, /* br %r0 */
1029 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */
1030 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */
1031 };
1032
1033 /* Code sequence restoring FRs, for targets with no VX support. */
1034
1035 static const unsigned char s390_ft_exit_fr[] = {
1036 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */
1037 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */
1038 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */
1039 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */
1040 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */
1041 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */
1042 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */
1043 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */
1044 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */
1045 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */
1046 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */
1047 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */
1048 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */
1049 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */
1050 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */
1051 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */
1052 };
1053
1054 /* Code sequence restoring VRs. */
1055
1056 static const unsigned char s390_ft_exit_vr[] = {
1057 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */
1058 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */
1059 };
1060
1061 /* Code sequence restoring misc registers. As for PSWM, only CC should be
1062 modified by C code, so we use the alr instruction to restore it by
1063 manufacturing an operand that'll result in the original flags. */
1064
1065 static const unsigned char s390_ft_exit_misc[] = {
1066 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */
1067 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */
1068 /* Extract CC to high 2 bits of %r0. */
1069 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */
1070 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */
1071 /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and
1072 will have carry iff CC bit 1 is set - resulting in the same flags
1073 as the original. */
1074 0x1e, 0x00, /* alr %r0, %r0 */
1075 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */
1076 };
1077
1078 /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */
1079
1080 static const unsigned char s390_ft_exit_gpr_esa[] = {
1081 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */
1082 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */
1083 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */
1084 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */
1085 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */
1086 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */
1087 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */
1088 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */
1089 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */
1090 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */
1091 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */
1092 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */
1093 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */
1094 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */
1095 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */
1096 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */
1097 };
1098
1099 /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets
1100 with high GPRs. */
1101
1102 static const unsigned char s390_ft_exit_gpr_zarch[] = {
1103 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */
1104 };
1105
1106 /* Writes instructions to target, updating the to pointer. */
1107
1108 static void
1109 append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf)
1110 {
1111 target_write_memory (*to, buf, len);
1112 *to += len;
1113 }
1114
1115 /* Relocates an instruction from oldloc to *to, updating to. */
1116
1117 static int
1118 s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64)
1119 {
1120 gdb_byte buf[6];
1121 int ilen;
1122 int op2;
1123 /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */
1124 int mode = 0;
1125 int is_bras = 0;
1126 read_inferior_memory (oldloc, buf, sizeof buf);
1127 if (buf[0] < 0x40)
1128 ilen = 2;
1129 else if (buf[0] < 0xc0)
1130 ilen = 4;
1131 else
1132 ilen = 6;
1133 switch (buf[0])
1134 {
1135 case 0x05: /* BALR */
1136 case 0x0c: /* BASSM */
1137 case 0x0d: /* BASR */
1138 case 0x45: /* BAL */
1139 case 0x4d: /* BAS */
1140 /* These save a return address and mess around with registers.
1141 We can't relocate them. */
1142 return 1;
1143 case 0x84: /* BRXH */
1144 case 0x85: /* BRXLE */
1145 mode = 1;
1146 break;
1147 case 0xa7:
1148 op2 = buf[1] & 0xf;
1149 /* BRC, BRAS, BRCT, BRCTG */
1150 if (op2 >= 4 && op2 <= 7)
1151 mode = 1;
1152 /* BRAS */
1153 if (op2 == 5)
1154 is_bras = 1;
1155 break;
1156 case 0xc0:
1157 op2 = buf[1] & 0xf;
1158 /* LARL, BRCL, BRASL */
1159 if (op2 == 0 || op2 == 4 || op2 == 5)
1160 mode = 2;
1161 /* BRASL */
1162 if (op2 == 5)
1163 is_bras = 1;
1164 break;
1165 case 0xc4:
1166 case 0xc6:
1167 /* PC-relative addressing instructions. */
1168 mode = 2;
1169 break;
1170 case 0xc5: /* BPRP */
1171 case 0xc7: /* BPP */
1172 /* Branch prediction - just skip it. */
1173 return 0;
1174 case 0xcc:
1175 op2 = buf[1] & 0xf;
1176 /* BRCTH */
1177 if (op2 == 6)
1178 mode = 2;
1179 break;
1180 case 0xec:
1181 op2 = buf[5];
1182 switch (op2)
1183 {
1184 case 0x44: /* BRXHG */
1185 case 0x45: /* BRXLG */
1186 case 0x64: /* CGRJ */
1187 case 0x65: /* CLGRJ */
1188 case 0x76: /* CRJ */
1189 case 0x77: /* CLRJ */
1190 mode = 1;
1191 break;
1192 }
1193 break;
1194 }
1195
1196 if (mode != 0)
1197 {
1198 /* We'll have to relocate an instruction with a PC-relative field.
1199 First, compute the target. */
1200 int64_t loffset = 0;
1201 CORE_ADDR target;
1202 if (mode == 1)
1203 {
1204 int16_t soffset = 0;
1205 memcpy (&soffset, buf + 2, 2);
1206 loffset = soffset;
1207 }
1208 else if (mode == 2)
1209 {
1210 int32_t soffset = 0;
1211 memcpy (&soffset, buf + 2, 4);
1212 loffset = soffset;
1213 }
1214 target = oldloc + loffset * 2;
1215 if (!is_64)
1216 target &= 0x7fffffff;
1217
1218 if (is_bras)
1219 {
1220 /* BRAS or BRASL was used. We cannot just relocate those, since
1221 they save the return address in a register. We can, however,
1222 replace them with a LARL+JG sequence. */
1223
1224 /* Make the LARL. */
1225 int32_t soffset;
1226 buf[0] = 0xc0;
1227 buf[1] &= 0xf0;
1228 loffset = oldloc + ilen - *to;
1229 loffset >>= 1;
1230 soffset = loffset;
1231 if (soffset != loffset && is_64)
1232 return 1;
1233 memcpy (buf + 2, &soffset, 4);
1234 append_insns (to, 6, buf);
1235
1236 /* Note: this is not fully correct. In 31-bit mode, LARL will write
1237 an address with the top bit 0, while BRAS/BRASL will write it
1238 with top bit 1. It should not matter much, since linux compilers
1239 use BR and not BSM to return from functions, but it could confuse
1240 some poor stack unwinder. */
1241
1242 /* We'll now be writing a JG. */
1243 mode = 2;
1244 buf[0] = 0xc0;
1245 buf[1] = 0xf4;
1246 ilen = 6;
1247 }
1248
1249 /* Compute the new offset and write it to the buffer. */
1250 loffset = target - *to;
1251 loffset >>= 1;
1252
1253 if (mode == 1)
1254 {
1255 int16_t soffset = loffset;
1256 if (soffset != loffset)
1257 return 1;
1258 memcpy (buf + 2, &soffset, 2);
1259 }
1260 else if (mode == 2)
1261 {
1262 int32_t soffset = loffset;
1263 if (soffset != loffset && is_64)
1264 return 1;
1265 memcpy (buf + 2, &soffset, 4);
1266 }
1267 }
1268 append_insns (to, ilen, buf);
1269 return 0;
1270 }
1271
1272 bool
1273 s390_target::supports_fast_tracepoints ()
1274 {
1275 return true;
1276 }
1277
1278 /* Implementation of target ops method
1279 "install_fast_tracepoint_jump_pad". */
1280
1281 int
1282 s390_target::install_fast_tracepoint_jump_pad
1283 (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
1284 CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
1285 CORE_ADDR *trampoline, ULONGEST *trampoline_size,
1286 unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
1287 CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
1288 char *err)
1289 {
1290 int i;
1291 int64_t loffset;
1292 int32_t offset;
1293 unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */
1294 CORE_ADDR buildaddr = *jump_entry;
1295 #ifdef __s390x__
1296 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1297 int is_64 = register_size (regcache->tdesc, 0) == 8;
1298 int is_zarch = is_64 || have_hwcap_s390_high_gprs;
1299 int has_vx = have_hwcap_s390_vx;
1300 #else
1301 int is_64 = 0, is_zarch = 0, has_vx = 0;
1302 #endif
1303 CORE_ADDR literals[4] = {
1304 tpaddr,
1305 tpoint,
1306 collector,
1307 lockaddr,
1308 };
1309
1310 /* First, store the GPRs. */
1311 if (is_zarch)
1312 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch,
1313 s390_ft_entry_gpr_zarch);
1314 else
1315 append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa,
1316 s390_ft_entry_gpr_esa);
1317
1318 /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */
1319 append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc);
1320
1321 /* Third, FRs or VRs. */
1322 if (has_vx)
1323 append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr);
1324 else
1325 append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr);
1326
1327 /* Now, the main part of code - store PSWA, take lock, call collector,
1328 leave lock. First, we'll need to fetch 4 literals. */
1329 if (is_64) {
1330 unsigned char buf[] = {
1331 0x07, 0x07, /* nopr %r7 */
1332 0x07, 0x07, /* nopr %r7 */
1333 0x07, 0x07, /* nopr %r7 */
1334 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */
1335 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */
1336 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */
1337 0, 0, 0, 0, 0, 0, 0, 0, /* collector */
1338 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */
1339 /* .Lend: */
1340 };
1341 /* Find the proper start place in buf, so that literals will be
1342 aligned. */
1343 int bufpos = (buildaddr + 2) & 7;
1344 /* Stuff the literals into the buffer. */
1345 for (i = 0; i < 4; i++) {
1346 uint64_t lit = literals[i];
1347 memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8);
1348 }
1349 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1350 append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64);
1351 } else {
1352 unsigned char buf[] = {
1353 0x07, 0x07, /* nopr %r7 */
1354 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */
1355 0, 0, 0, 0, /* tpaddr */
1356 0, 0, 0, 0, /* tpoint */
1357 0, 0, 0, 0, /* collector */
1358 0, 0, 0, 0, /* lockaddr */
1359 /* .Lend: */
1360 };
1361 /* Find the proper start place in buf, so that literals will be
1362 aligned. */
1363 int bufpos = (buildaddr + 2) & 3;
1364 /* First literal will be saved as the PSWA, make sure it has the high bit
1365 set. */
1366 literals[0] |= 0x80000000;
1367 /* Stuff the literals into the buffer. */
1368 for (i = 0; i < 4; i++) {
1369 uint32_t lit = literals[i];
1370 memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4);
1371 }
1372 append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos);
1373 append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31);
1374 }
1375
1376 /* Restore FRs or VRs. */
1377 if (has_vx)
1378 append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr);
1379 else
1380 append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr);
1381
1382 /* Restore misc registers. */
1383 append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc);
1384
1385 /* Restore the GPRs. */
1386 if (is_zarch)
1387 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch,
1388 s390_ft_exit_gpr_zarch);
1389 else
1390 append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa,
1391 s390_ft_exit_gpr_esa);
1392
1393 /* Now, adjust the original instruction to execute in the jump
1394 pad. */
1395 *adjusted_insn_addr = buildaddr;
1396 if (s390_relocate_instruction (&buildaddr, tpaddr, is_64))
1397 {
1398 sprintf (err, "E.Could not relocate instruction for tracepoint.");
1399 return 1;
1400 }
1401 *adjusted_insn_addr_end = buildaddr;
1402
1403 /* Finally, write a jump back to the program. */
1404
1405 loffset = (tpaddr + orig_size) - buildaddr;
1406 loffset >>= 1;
1407 offset = loffset;
1408 if (is_64 && offset != loffset)
1409 {
1410 sprintf (err,
1411 "E.Jump back from jump pad too far from tracepoint "
1412 "(offset 0x%" PRIx64 " > int33).", loffset);
1413 return 1;
1414 }
1415 memcpy (jbuf + 2, &offset, 4);
1416 append_insns (&buildaddr, sizeof jbuf, jbuf);
1417
1418 /* The jump pad is now built. Wire in a jump to our jump pad. This
1419 is always done last (by our caller actually), so that we can
1420 install fast tracepoints with threads running. This relies on
1421 the agent's atomic write support. */
1422 loffset = *jump_entry - tpaddr;
1423 loffset >>= 1;
1424 offset = loffset;
1425 if (is_64 && offset != loffset)
1426 {
1427 sprintf (err,
1428 "E.Jump back from jump pad too far from tracepoint "
1429 "(offset 0x%" PRIx64 " > int33).", loffset);
1430 return 1;
1431 }
1432 memcpy (jbuf + 2, &offset, 4);
1433 memcpy (jjump_pad_insn, jbuf, sizeof jbuf);
1434 *jjump_pad_insn_size = sizeof jbuf;
1435
1436 /* Return the end address of our pad. */
1437 *jump_entry = buildaddr;
1438
1439 return 0;
1440 }
1441
1442 /* Implementation of target ops method
1443 "get_min_fast_tracepoint_insn_len". */
1444
1445 int
1446 s390_target::get_min_fast_tracepoint_insn_len ()
1447 {
1448 /* We only support using 6-byte jumps to reach the tracepoint code.
1449 If the tracepoint buffer were allocated sufficiently close (64kiB)
1450 to the executable code, and the traced instruction itself was close
1451 enough to the beginning, we could use 4-byte jumps, but this doesn't
1452 seem to be worth the effort. */
1453 return 6;
1454 }
1455
1456 /* Implementation of linux_target_ops method "get_ipa_tdesc_idx". */
1457
1458 static int
1459 s390_get_ipa_tdesc_idx (void)
1460 {
1461 struct regcache *regcache = get_thread_regcache (current_thread, 0);
1462 const struct target_desc *tdesc = regcache->tdesc;
1463
1464 #ifdef __s390x__
1465 if (tdesc == tdesc_s390x_linux64)
1466 return S390_TDESC_64;
1467 if (tdesc == tdesc_s390x_linux64v1)
1468 return S390_TDESC_64V1;
1469 if (tdesc == tdesc_s390x_linux64v2)
1470 return S390_TDESC_64V2;
1471 if (tdesc == tdesc_s390x_te_linux64)
1472 return S390_TDESC_TE;
1473 if (tdesc == tdesc_s390x_vx_linux64)
1474 return S390_TDESC_VX;
1475 if (tdesc == tdesc_s390x_tevx_linux64)
1476 return S390_TDESC_TEVX;
1477 if (tdesc == tdesc_s390x_gs_linux64)
1478 return S390_TDESC_GS;
1479 #endif
1480
1481 if (tdesc == tdesc_s390_linux32)
1482 return S390_TDESC_32;
1483 if (tdesc == tdesc_s390_linux32v1)
1484 return S390_TDESC_32V1;
1485 if (tdesc == tdesc_s390_linux32v2)
1486 return S390_TDESC_32V2;
1487 if (tdesc == tdesc_s390_linux64)
1488 return S390_TDESC_64;
1489 if (tdesc == tdesc_s390_linux64v1)
1490 return S390_TDESC_64V1;
1491 if (tdesc == tdesc_s390_linux64v2)
1492 return S390_TDESC_64V2;
1493 if (tdesc == tdesc_s390_te_linux64)
1494 return S390_TDESC_TE;
1495 if (tdesc == tdesc_s390_vx_linux64)
1496 return S390_TDESC_VX;
1497 if (tdesc == tdesc_s390_tevx_linux64)
1498 return S390_TDESC_TEVX;
1499 if (tdesc == tdesc_s390_gs_linux64)
1500 return S390_TDESC_GS;
1501
1502 return 0;
1503 }
1504
1505 /* Appends given buffer to current_insn_ptr in the target. */
1506
1507 static void
1508 add_insns (const unsigned char *start, int len)
1509 {
1510 CORE_ADDR buildaddr = current_insn_ptr;
1511
1512 if (debug_threads)
1513 debug_printf ("Adding %d bytes of insn at %s\n",
1514 len, paddress (buildaddr));
1515
1516 append_insns (&buildaddr, len, start);
1517 current_insn_ptr = buildaddr;
1518 }
1519
1520 /* Register usage in emit:
1521
1522 - %r0, %r1: temp
1523 - %r2: top of stack (high word for 31-bit)
1524 - %r3: low word of top of stack (for 31-bit)
1525 - %r4, %r5: temp
1526 - %r6, %r7, %r8: don't use
1527 - %r9: saved arg1
1528 - %r10: saved arg2
1529 - %r11: frame pointer
1530 - %r12: saved top of stack for void_call_2 (high word for 31-bit)
1531 - %r13: low word of saved top of stack (for 31-bit)
1532 - %r14: return address for calls
1533 - %r15: stack pointer
1534
1535 */
1536
1537 /* The "emit_prologue" emit_ops method for s390. */
1538
1539 static void
1540 s390_emit_prologue (void)
1541 {
1542 static const unsigned char buf[] = {
1543 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */
1544 0x18, 0x92, /* lr %r9, %r2 */
1545 0x18, 0xa3, /* lr %r10, %r3 */
1546 0x18, 0xbf, /* lr %r11, %r15 */
1547 };
1548 add_insns (buf, sizeof buf);
1549 }
1550
1551 /* The "emit_epilogue" emit_ops method for s390. */
1552
1553 static void
1554 s390_emit_epilogue (void)
1555 {
1556 static const unsigned char buf[] = {
1557 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */
1558 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1559 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */
1560 0x07, 0xfe, /* br %r14 */
1561 };
1562 add_insns (buf, sizeof buf);
1563 }
1564
1565 /* The "emit_add" emit_ops method for s390. */
1566
1567 static void
1568 s390_emit_add (void)
1569 {
1570 static const unsigned char buf[] = {
1571 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */
1572 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */
1573 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1574 };
1575 add_insns (buf, sizeof buf);
1576 }
1577
1578 /* The "emit_sub" emit_ops method for s390. */
1579
1580 static void
1581 s390_emit_sub (void)
1582 {
1583 static const unsigned char buf[] = {
1584 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
1585 0x1f, 0x53, /* slr %r5, %r3 */
1586 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */
1587 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1588 0x18, 0x35, /* lr %r3, %r5 */
1589 0x18, 0x24, /* lr %r2, %r4 */
1590 };
1591 add_insns (buf, sizeof buf);
1592 }
1593
1594 /* The "emit_mul" emit_ops method for s390. */
1595
1596 static void
1597 s390_emit_mul (void)
1598 {
1599 emit_error = 1;
1600 }
1601
1602 /* The "emit_lsh" emit_ops method for s390. */
1603
1604 static void
1605 s390_emit_lsh (void)
1606 {
1607 static const unsigned char buf[] = {
1608 0x18, 0x43, /* lr %r4, %r3 */
1609 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1610 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */
1611 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1612 };
1613 add_insns (buf, sizeof buf);
1614 }
1615
1616 /* The "emit_rsh_signed" emit_ops method for s390. */
1617
1618 static void
1619 s390_emit_rsh_signed (void)
1620 {
1621 static const unsigned char buf[] = {
1622 0x18, 0x43, /* lr %r4, %r3 */
1623 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1624 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */
1625 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1626 };
1627 add_insns (buf, sizeof buf);
1628 }
1629
1630 /* The "emit_rsh_unsigned" emit_ops method for s390. */
1631
1632 static void
1633 s390_emit_rsh_unsigned (void)
1634 {
1635 static const unsigned char buf[] = {
1636 0x18, 0x43, /* lr %r4, %r3 */
1637 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1638 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */
1639 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1640 };
1641 add_insns (buf, sizeof buf);
1642 }
1643
1644 /* The "emit_ext" emit_ops method for s390. */
1645
1646 static void
1647 s390_emit_ext (int arg)
1648 {
1649 unsigned char buf[] = {
1650 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1651 0x8e, 0x20, 0x00, (unsigned char) (64 - arg), /* srda %r2, <64-arg> */
1652 };
1653 add_insns (buf, sizeof buf);
1654 }
1655
1656 /* The "emit_log_not" emit_ops method for s390. */
1657
1658 static void
1659 s390_emit_log_not (void)
1660 {
1661 static const unsigned char buf[] = {
1662 0x16, 0x23, /* or %r2, %r3 */
1663 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1664 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1665 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */
1666 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1667 /* .Lskip: */
1668 };
1669 add_insns (buf, sizeof buf);
1670 }
1671
1672 /* The "emit_bit_and" emit_ops method for s390. */
1673
1674 static void
1675 s390_emit_bit_and (void)
1676 {
1677 static const unsigned char buf[] = {
1678 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */
1679 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */
1680 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1681 };
1682 add_insns (buf, sizeof buf);
1683 }
1684
1685 /* The "emit_bit_or" emit_ops method for s390. */
1686
1687 static void
1688 s390_emit_bit_or (void)
1689 {
1690 static const unsigned char buf[] = {
1691 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */
1692 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */
1693 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1694 };
1695 add_insns (buf, sizeof buf);
1696 }
1697
1698 /* The "emit_bit_xor" emit_ops method for s390. */
1699
1700 static void
1701 s390_emit_bit_xor (void)
1702 {
1703 static const unsigned char buf[] = {
1704 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
1705 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
1706 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1707 };
1708 add_insns (buf, sizeof buf);
1709 }
1710
1711 /* The "emit_bit_not" emit_ops method for s390. */
1712
1713 static void
1714 s390_emit_bit_not (void)
1715 {
1716 static const unsigned char buf[] = {
1717 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */
1718 0x17, 0x24, /* xr %r2, %r4 */
1719 0x17, 0x34, /* xr %r3, %r4 */
1720 };
1721 add_insns (buf, sizeof buf);
1722 }
1723
1724 /* The "emit_equal" emit_ops method for s390. */
1725
1726 static void
1727 s390_emit_equal (void)
1728 {
1729 s390_emit_bit_xor ();
1730 s390_emit_log_not ();
1731 }
1732
1733 /* The "emit_less_signed" emit_ops method for s390. */
1734
1735 static void
1736 s390_emit_less_signed (void)
1737 {
1738 static const unsigned char buf[] = {
1739 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
1740 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1741 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1742 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1743 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1744 /* .Lhigh: */
1745 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1746 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1747 /* .Lless: */
1748 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1749 /* .Lend: */
1750 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1751 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1752 };
1753 add_insns (buf, sizeof buf);
1754 }
1755
1756 /* The "emit_less_unsigned" emit_ops method for s390. */
1757
1758 static void
1759 s390_emit_less_unsigned (void)
1760 {
1761 static const unsigned char buf[] = {
1762 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */
1763 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */
1764 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */
1765 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
1766 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */
1767 /* .Lhigh: */
1768 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */
1769 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */
1770 /* .Lless: */
1771 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */
1772 /* .Lend: */
1773 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1774 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1775 };
1776 add_insns (buf, sizeof buf);
1777 }
1778
1779 /* The "emit_ref" emit_ops method for s390. */
1780
1781 static void
1782 s390_emit_ref (int size)
1783 {
1784 static const unsigned char buf1[] = {
1785 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1786 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */
1787 };
1788 static const unsigned char buf2[] = {
1789 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1790 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */
1791 };
1792 static const unsigned char buf4[] = {
1793 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */
1794 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */
1795 };
1796 static const unsigned char buf8[] = {
1797 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */
1798 };
1799 switch (size)
1800 {
1801 case 1:
1802 add_insns (buf1, sizeof buf1);
1803 break;
1804 case 2:
1805 add_insns (buf2, sizeof buf2);
1806 break;
1807 case 4:
1808 add_insns (buf4, sizeof buf4);
1809 break;
1810 case 8:
1811 add_insns (buf8, sizeof buf8);
1812 break;
1813 default:
1814 emit_error = 1;
1815 }
1816 }
1817
1818 /* The "emit_if_goto" emit_ops method for s390. */
1819
1820 static void
1821 s390_emit_if_goto (int *offset_p, int *size_p)
1822 {
1823 static const unsigned char buf[] = {
1824 0x16, 0x23, /* or %r2, %r3 */
1825 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1826 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1827 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */
1828 };
1829 add_insns (buf, sizeof buf);
1830 if (offset_p)
1831 *offset_p = 12;
1832 if (size_p)
1833 *size_p = 4;
1834 }
1835
1836 /* The "emit_goto" emit_ops method for s390 and s390x. */
1837
1838 static void
1839 s390_emit_goto (int *offset_p, int *size_p)
1840 {
1841 static const unsigned char buf[] = {
1842 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
1843 };
1844 add_insns (buf, sizeof buf);
1845 if (offset_p)
1846 *offset_p = 2;
1847 if (size_p)
1848 *size_p = 4;
1849 }
1850
1851 /* The "write_goto_address" emit_ops method for s390 and s390x. */
1852
1853 static void
1854 s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size)
1855 {
1856 long diff = ((long) (to - (from - 2))) / 2;
1857 int sdiff = diff;
1858 unsigned char buf[sizeof sdiff];
1859
1860 /* We're only doing 4-byte sizes at the moment. */
1861 if (size != sizeof sdiff || sdiff != diff)
1862 {
1863 emit_error = 1;
1864 return;
1865 }
1866
1867 memcpy (buf, &sdiff, sizeof sdiff);
1868 target_write_memory (from, buf, sizeof sdiff);
1869 }
1870
1871 /* Preparation for emitting a literal pool of given size. Loads the address
1872 of the pool into %r1, and jumps over it. Called should emit the pool data
1873 immediately afterwards. Used for both s390 and s390x. */
1874
1875 static void
1876 s390_emit_litpool (int size)
1877 {
1878 static const unsigned char nop[] = {
1879 0x07, 0x07,
1880 };
1881 unsigned char buf[] = {
1882 0xa7, 0x15, 0x00,
1883 (unsigned char) ((size + 4) / 2), /* bras %r1, .Lend+size */
1884 /* .Lend: */
1885 };
1886 if (size == 4)
1887 {
1888 /* buf needs to start at even halfword for litpool to be aligned */
1889 if (current_insn_ptr & 2)
1890 add_insns (nop, sizeof nop);
1891 }
1892 else
1893 {
1894 while ((current_insn_ptr & 6) != 4)
1895 add_insns (nop, sizeof nop);
1896 }
1897 add_insns (buf, sizeof buf);
1898 }
1899
1900 /* The "emit_const" emit_ops method for s390. */
1901
1902 static void
1903 s390_emit_const (LONGEST num)
1904 {
1905 unsigned long long n = num;
1906 unsigned char buf_s[] = {
1907 /* lhi %r3, <num> */
1908 0xa7, 0x38,
1909 (unsigned char) (num >> 8), (unsigned char) num,
1910 /* xr %r2, %r2 */
1911 0x17, 0x22,
1912 };
1913 static const unsigned char buf_l[] = {
1914 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */
1915 };
1916 if (num < 0x8000 && num >= 0)
1917 {
1918 add_insns (buf_s, sizeof buf_s);
1919 }
1920 else
1921 {
1922 s390_emit_litpool (8);
1923 add_insns ((unsigned char *) &n, sizeof n);
1924 add_insns (buf_l, sizeof buf_l);
1925 }
1926 }
1927
1928 /* The "emit_call" emit_ops method for s390. */
1929
1930 static void
1931 s390_emit_call (CORE_ADDR fn)
1932 {
1933 unsigned int n = fn;
1934 static const unsigned char buf[] = {
1935 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */
1936 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */
1937 0x0d, 0xe1, /* basr %r14, %r1 */
1938 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */
1939 };
1940 s390_emit_litpool (4);
1941 add_insns ((unsigned char *) &n, sizeof n);
1942 add_insns (buf, sizeof buf);
1943 }
1944
1945 /* The "emit_reg" emit_ops method for s390. */
1946
1947 static void
1948 s390_emit_reg (int reg)
1949 {
1950 unsigned char bufpre[] = {
1951 /* lr %r2, %r9 */
1952 0x18, 0x29,
1953 /* lhi %r3, <reg> */
1954 0xa7, 0x38, (unsigned char) (reg >> 8), (unsigned char) reg,
1955 };
1956 add_insns (bufpre, sizeof bufpre);
1957 s390_emit_call (get_raw_reg_func_addr ());
1958 }
1959
1960 /* The "emit_pop" emit_ops method for s390. */
1961
1962 static void
1963 s390_emit_pop (void)
1964 {
1965 static const unsigned char buf[] = {
1966 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */
1967 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
1968 };
1969 add_insns (buf, sizeof buf);
1970 }
1971
1972 /* The "emit_stack_flush" emit_ops method for s390. */
1973
1974 static void
1975 s390_emit_stack_flush (void)
1976 {
1977 static const unsigned char buf[] = {
1978 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */
1979 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
1980 };
1981 add_insns (buf, sizeof buf);
1982 }
1983
1984 /* The "emit_zero_ext" emit_ops method for s390. */
1985
1986 static void
1987 s390_emit_zero_ext (int arg)
1988 {
1989 unsigned char buf[] = {
1990 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */
1991 0x8c, 0x20, 0x00, (unsigned char) (64 - arg), /* srdl %r2, <64-arg> */
1992 };
1993 add_insns (buf, sizeof buf);
1994 }
1995
1996 /* The "emit_swap" emit_ops method for s390. */
1997
1998 static void
1999 s390_emit_swap (void)
2000 {
2001 static const unsigned char buf[] = {
2002 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */
2003 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */
2004 0x18, 0x24, /* lr %r2, %r4 */
2005 0x18, 0x35, /* lr %r3, %r5 */
2006 };
2007 add_insns (buf, sizeof buf);
2008 }
2009
2010 /* The "emit_stack_adjust" emit_ops method for s390. */
2011
2012 static void
2013 s390_emit_stack_adjust (int n)
2014 {
2015 unsigned char buf[] = {
2016 /* ahi %r15, 8*n */
2017 0xa7, 0xfa,
2018 (unsigned char ) (n * 8 >> 8), (unsigned char) (n * 8),
2019 };
2020 add_insns (buf, sizeof buf);
2021 }
2022
2023 /* Sets %r2 to a 32-bit constant. */
2024
2025 static void
2026 s390_emit_set_r2 (int arg1)
2027 {
2028 unsigned char buf_s[] = {
2029 /* lhi %r2, <arg1> */
2030 0xa7, 0x28, (unsigned char) (arg1 >> 8), (unsigned char) arg1,
2031 };
2032 static const unsigned char buf_l[] = {
2033 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */
2034 };
2035 if (arg1 < 0x8000 && arg1 >= -0x8000)
2036 {
2037 add_insns (buf_s, sizeof buf_s);
2038 }
2039 else
2040 {
2041 s390_emit_litpool (4);
2042 add_insns ((unsigned char *) &arg1, sizeof arg1);
2043 add_insns (buf_l, sizeof buf_l);
2044 }
2045 }
2046
2047 /* The "emit_int_call_1" emit_ops method for s390. */
2048
2049 static void
2050 s390_emit_int_call_1 (CORE_ADDR fn, int arg1)
2051 {
2052 /* FN's prototype is `LONGEST(*fn)(int)'. */
2053 s390_emit_set_r2 (arg1);
2054 s390_emit_call (fn);
2055 }
2056
2057 /* The "emit_void_call_2" emit_ops method for s390. */
2058
2059 static void
2060 s390_emit_void_call_2 (CORE_ADDR fn, int arg1)
2061 {
2062 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2063 static const unsigned char buf[] = {
2064 0x18, 0xc2, /* lr %r12, %r2 */
2065 0x18, 0xd3, /* lr %r13, %r3 */
2066 0x18, 0x43, /* lr %r4, %r3 */
2067 0x18, 0x32, /* lr %r3, %r2 */
2068 };
2069 static const unsigned char buf2[] = {
2070 0x18, 0x2c, /* lr %r2, %r12 */
2071 0x18, 0x3d, /* lr %r3, %r13 */
2072 };
2073 add_insns (buf, sizeof buf);
2074 s390_emit_set_r2 (arg1);
2075 s390_emit_call (fn);
2076 add_insns (buf2, sizeof buf2);
2077 }
2078
2079 /* The "emit_eq_goto" emit_ops method for s390. */
2080
2081 static void
2082 s390_emit_eq_goto (int *offset_p, int *size_p)
2083 {
2084 static const unsigned char buf[] = {
2085 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2086 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2087 0x16, 0x23, /* or %r2, %r3 */
2088 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2089 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2090 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2091 };
2092 add_insns (buf, sizeof buf);
2093 if (offset_p)
2094 *offset_p = 20;
2095 if (size_p)
2096 *size_p = 4;
2097 }
2098
2099 /* The "emit_ne_goto" emit_ops method for s390. */
2100
2101 static void
2102 s390_emit_ne_goto (int *offset_p, int *size_p)
2103 {
2104 static const unsigned char buf[] = {
2105 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */
2106 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */
2107 0x16, 0x23, /* or %r2, %r3 */
2108 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2109 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2110 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2111 };
2112 add_insns (buf, sizeof buf);
2113 if (offset_p)
2114 *offset_p = 20;
2115 if (size_p)
2116 *size_p = 4;
2117 }
2118
2119 /* The "emit_lt_goto" emit_ops method for s390. */
2120
2121 static void
2122 s390_emit_lt_goto (int *offset_p, int *size_p)
2123 {
2124 static const unsigned char buf[] = {
2125 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2126 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2127 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2128 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2129 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */
2130 /* .Lfalse: */
2131 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2132 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2133 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2134 /* .Ltrue: */
2135 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2136 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2137 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2138 /* .Lend: */
2139 };
2140 add_insns (buf, sizeof buf);
2141 if (offset_p)
2142 *offset_p = 42;
2143 if (size_p)
2144 *size_p = 4;
2145 }
2146
2147 /* The "emit_le_goto" emit_ops method for s390. */
2148
2149 static void
2150 s390_emit_le_goto (int *offset_p, int *size_p)
2151 {
2152 static const unsigned char buf[] = {
2153 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2154 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */
2155 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */
2156 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2157 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */
2158 /* .Lfalse: */
2159 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2160 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2161 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2162 /* .Ltrue: */
2163 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2164 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2165 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2166 /* .Lend: */
2167 };
2168 add_insns (buf, sizeof buf);
2169 if (offset_p)
2170 *offset_p = 42;
2171 if (size_p)
2172 *size_p = 4;
2173 }
2174
2175 /* The "emit_gt_goto" emit_ops method for s390. */
2176
2177 static void
2178 s390_emit_gt_goto (int *offset_p, int *size_p)
2179 {
2180 static const unsigned char buf[] = {
2181 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2182 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2183 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2184 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2185 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */
2186 /* .Lfalse: */
2187 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2188 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2189 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2190 /* .Ltrue: */
2191 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2192 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2193 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2194 /* .Lend: */
2195 };
2196 add_insns (buf, sizeof buf);
2197 if (offset_p)
2198 *offset_p = 42;
2199 if (size_p)
2200 *size_p = 4;
2201 }
2202
2203 /* The "emit_ge_goto" emit_ops method for s390. */
2204
2205 static void
2206 s390_emit_ge_goto (int *offset_p, int *size_p)
2207 {
2208 static const unsigned char buf[] = {
2209 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */
2210 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */
2211 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */
2212 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */
2213 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */
2214 /* .Lfalse: */
2215 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2216 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2217 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */
2218 /* .Ltrue: */
2219 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */
2220 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2221 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */
2222 /* .Lend: */
2223 };
2224 add_insns (buf, sizeof buf);
2225 if (offset_p)
2226 *offset_p = 42;
2227 if (size_p)
2228 *size_p = 4;
2229 }
2230
2231 /* The "emit_ops" structure for s390. Named _impl to avoid name
2232 collision with s390_emit_ops function. */
2233
2234 static struct emit_ops s390_emit_ops_impl =
2235 {
2236 s390_emit_prologue,
2237 s390_emit_epilogue,
2238 s390_emit_add,
2239 s390_emit_sub,
2240 s390_emit_mul,
2241 s390_emit_lsh,
2242 s390_emit_rsh_signed,
2243 s390_emit_rsh_unsigned,
2244 s390_emit_ext,
2245 s390_emit_log_not,
2246 s390_emit_bit_and,
2247 s390_emit_bit_or,
2248 s390_emit_bit_xor,
2249 s390_emit_bit_not,
2250 s390_emit_equal,
2251 s390_emit_less_signed,
2252 s390_emit_less_unsigned,
2253 s390_emit_ref,
2254 s390_emit_if_goto,
2255 s390_emit_goto,
2256 s390_write_goto_address,
2257 s390_emit_const,
2258 s390_emit_call,
2259 s390_emit_reg,
2260 s390_emit_pop,
2261 s390_emit_stack_flush,
2262 s390_emit_zero_ext,
2263 s390_emit_swap,
2264 s390_emit_stack_adjust,
2265 s390_emit_int_call_1,
2266 s390_emit_void_call_2,
2267 s390_emit_eq_goto,
2268 s390_emit_ne_goto,
2269 s390_emit_lt_goto,
2270 s390_emit_le_goto,
2271 s390_emit_gt_goto,
2272 s390_emit_ge_goto
2273 };
2274
2275 #ifdef __s390x__
2276
2277 /* The "emit_prologue" emit_ops method for s390x. */
2278
2279 static void
2280 s390x_emit_prologue (void)
2281 {
2282 static const unsigned char buf[] = {
2283 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */
2284 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */
2285 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */
2286 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */
2287 };
2288 add_insns (buf, sizeof buf);
2289 }
2290
2291 /* The "emit_epilogue" emit_ops method for s390x. */
2292
2293 static void
2294 s390x_emit_epilogue (void)
2295 {
2296 static const unsigned char buf[] = {
2297 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */
2298 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2299 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */
2300 0x07, 0xfe, /* br %r14 */
2301 };
2302 add_insns (buf, sizeof buf);
2303 }
2304
2305 /* The "emit_add" emit_ops method for s390x. */
2306
2307 static void
2308 s390x_emit_add (void)
2309 {
2310 static const unsigned char buf[] = {
2311 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */
2312 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2313 };
2314 add_insns (buf, sizeof buf);
2315 }
2316
2317 /* The "emit_sub" emit_ops method for s390x. */
2318
2319 static void
2320 s390x_emit_sub (void)
2321 {
2322 static const unsigned char buf[] = {
2323 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2324 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */
2325 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2326 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2327 };
2328 add_insns (buf, sizeof buf);
2329 }
2330
2331 /* The "emit_mul" emit_ops method for s390x. */
2332
2333 static void
2334 s390x_emit_mul (void)
2335 {
2336 emit_error = 1;
2337 }
2338
2339 /* The "emit_lsh" emit_ops method for s390x. */
2340
2341 static void
2342 s390x_emit_lsh (void)
2343 {
2344 static const unsigned char buf[] = {
2345 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2346 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */
2347 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2348 };
2349 add_insns (buf, sizeof buf);
2350 }
2351
2352 /* The "emit_rsh_signed" emit_ops method for s390x. */
2353
2354 static void
2355 s390x_emit_rsh_signed (void)
2356 {
2357 static const unsigned char buf[] = {
2358 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2359 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */
2360 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2361 };
2362 add_insns (buf, sizeof buf);
2363 }
2364
2365 /* The "emit_rsh_unsigned" emit_ops method for s390x. */
2366
2367 static void
2368 s390x_emit_rsh_unsigned (void)
2369 {
2370 static const unsigned char buf[] = {
2371 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2372 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */
2373 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2374 };
2375 add_insns (buf, sizeof buf);
2376 }
2377
2378 /* The "emit_ext" emit_ops method for s390x. */
2379
2380 static void
2381 s390x_emit_ext (int arg)
2382 {
2383 unsigned char buf[] = {
2384 /* sllg %r2, %r2, <64-arg> */
2385 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2386 /* srag %r2, %r2, <64-arg> */
2387 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0a,
2388 };
2389 add_insns (buf, sizeof buf);
2390 }
2391
2392 /* The "emit_log_not" emit_ops method for s390x. */
2393
2394 static void
2395 s390x_emit_log_not (void)
2396 {
2397 static const unsigned char buf[] = {
2398 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */
2399 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */
2400 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */
2401 };
2402 add_insns (buf, sizeof buf);
2403 }
2404
2405 /* The "emit_bit_and" emit_ops method for s390x. */
2406
2407 static void
2408 s390x_emit_bit_and (void)
2409 {
2410 static const unsigned char buf[] = {
2411 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */
2412 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2413 };
2414 add_insns (buf, sizeof buf);
2415 }
2416
2417 /* The "emit_bit_or" emit_ops method for s390x. */
2418
2419 static void
2420 s390x_emit_bit_or (void)
2421 {
2422 static const unsigned char buf[] = {
2423 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */
2424 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2425 };
2426 add_insns (buf, sizeof buf);
2427 }
2428
2429 /* The "emit_bit_xor" emit_ops method for s390x. */
2430
2431 static void
2432 s390x_emit_bit_xor (void)
2433 {
2434 static const unsigned char buf[] = {
2435 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */
2436 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2437 };
2438 add_insns (buf, sizeof buf);
2439 }
2440
2441 /* The "emit_bit_not" emit_ops method for s390x. */
2442
2443 static void
2444 s390x_emit_bit_not (void)
2445 {
2446 static const unsigned char buf[] = {
2447 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */
2448 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */
2449 };
2450 add_insns (buf, sizeof buf);
2451 }
2452
2453 /* The "emit_equal" emit_ops method for s390x. */
2454
2455 static void
2456 s390x_emit_equal (void)
2457 {
2458 s390x_emit_bit_xor ();
2459 s390x_emit_log_not ();
2460 }
2461
2462 /* The "emit_less_signed" emit_ops method for s390x. */
2463
2464 static void
2465 s390x_emit_less_signed (void)
2466 {
2467 static const unsigned char buf[] = {
2468 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2469 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2470 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2471 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2472 /* .Lend: */
2473 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2474 };
2475 add_insns (buf, sizeof buf);
2476 }
2477
2478 /* The "emit_less_unsigned" emit_ops method for s390x. */
2479
2480 static void
2481 s390x_emit_less_unsigned (void)
2482 {
2483 static const unsigned char buf[] = {
2484 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */
2485 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */
2486 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */
2487 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */
2488 /* .Lend: */
2489 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2490 };
2491 add_insns (buf, sizeof buf);
2492 }
2493
2494 /* The "emit_ref" emit_ops method for s390x. */
2495
2496 static void
2497 s390x_emit_ref (int size)
2498 {
2499 static const unsigned char buf1[] = {
2500 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */
2501 };
2502 static const unsigned char buf2[] = {
2503 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */
2504 };
2505 static const unsigned char buf4[] = {
2506 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */
2507 };
2508 static const unsigned char buf8[] = {
2509 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */
2510 };
2511 switch (size)
2512 {
2513 case 1:
2514 add_insns (buf1, sizeof buf1);
2515 break;
2516 case 2:
2517 add_insns (buf2, sizeof buf2);
2518 break;
2519 case 4:
2520 add_insns (buf4, sizeof buf4);
2521 break;
2522 case 8:
2523 add_insns (buf8, sizeof buf8);
2524 break;
2525 default:
2526 emit_error = 1;
2527 }
2528 }
2529
2530 /* The "emit_if_goto" emit_ops method for s390x. */
2531
2532 static void
2533 s390x_emit_if_goto (int *offset_p, int *size_p)
2534 {
2535 static const unsigned char buf[] = {
2536 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */
2537 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2538 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2539 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2540 };
2541 add_insns (buf, sizeof buf);
2542 if (offset_p)
2543 *offset_p = 16;
2544 if (size_p)
2545 *size_p = 4;
2546 }
2547
2548 /* The "emit_const" emit_ops method for s390x. */
2549
2550 static void
2551 s390x_emit_const (LONGEST num)
2552 {
2553 unsigned long long n = num;
2554 unsigned char buf_s[] = {
2555 /* lghi %r2, <num> */
2556 0xa7, 0x29, (unsigned char) (num >> 8), (unsigned char) num,
2557 };
2558 static const unsigned char buf_l[] = {
2559 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */
2560 };
2561 if (num < 0x8000 && num >= -0x8000)
2562 {
2563 add_insns (buf_s, sizeof buf_s);
2564 }
2565 else
2566 {
2567 s390_emit_litpool (8);
2568 add_insns ((unsigned char *) &n, sizeof n);
2569 add_insns (buf_l, sizeof buf_l);
2570 }
2571 }
2572
2573 /* The "emit_call" emit_ops method for s390x. */
2574
2575 static void
2576 s390x_emit_call (CORE_ADDR fn)
2577 {
2578 unsigned long n = fn;
2579 static const unsigned char buf[] = {
2580 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */
2581 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */
2582 0x0d, 0xe1, /* basr %r14, %r1 */
2583 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */
2584 };
2585 s390_emit_litpool (8);
2586 add_insns ((unsigned char *) &n, sizeof n);
2587 add_insns (buf, sizeof buf);
2588 }
2589
2590 /* The "emit_reg" emit_ops method for s390x. */
2591
2592 static void
2593 s390x_emit_reg (int reg)
2594 {
2595 unsigned char buf[] = {
2596 /* lgr %r2, %r9 */
2597 0xb9, 0x04, 0x00, 0x29,
2598 /* lghi %r3, <reg> */
2599 0xa7, 0x39, (unsigned char) (reg >> 8), (unsigned char) reg,
2600 };
2601 add_insns (buf, sizeof buf);
2602 s390x_emit_call (get_raw_reg_func_addr ());
2603 }
2604
2605 /* The "emit_pop" emit_ops method for s390x. */
2606
2607 static void
2608 s390x_emit_pop (void)
2609 {
2610 static const unsigned char buf[] = {
2611 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */
2612 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */
2613 };
2614 add_insns (buf, sizeof buf);
2615 }
2616
2617 /* The "emit_stack_flush" emit_ops method for s390x. */
2618
2619 static void
2620 s390x_emit_stack_flush (void)
2621 {
2622 static const unsigned char buf[] = {
2623 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */
2624 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2625 };
2626 add_insns (buf, sizeof buf);
2627 }
2628
2629 /* The "emit_zero_ext" emit_ops method for s390x. */
2630
2631 static void
2632 s390x_emit_zero_ext (int arg)
2633 {
2634 unsigned char buf[] = {
2635 /* sllg %r2, %r2, <64-arg> */
2636 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d,
2637 /* srlg %r2, %r2, <64-arg> */
2638 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0c,
2639 };
2640 add_insns (buf, sizeof buf);
2641 }
2642
2643 /* The "emit_swap" emit_ops method for s390x. */
2644
2645 static void
2646 s390x_emit_swap (void)
2647 {
2648 static const unsigned char buf[] = {
2649 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */
2650 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */
2651 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */
2652 };
2653 add_insns (buf, sizeof buf);
2654 }
2655
2656 /* The "emit_stack_adjust" emit_ops method for s390x. */
2657
2658 static void
2659 s390x_emit_stack_adjust (int n)
2660 {
2661 unsigned char buf[] = {
2662 /* aghi %r15, 8*n */
2663 0xa7, 0xfb,
2664 (unsigned char) (n * 8 >> 8), (unsigned char) (n * 8),
2665 };
2666 add_insns (buf, sizeof buf);
2667 }
2668
2669 /* The "emit_int_call_1" emit_ops method for s390x. */
2670
2671 static void
2672 s390x_emit_int_call_1 (CORE_ADDR fn, int arg1)
2673 {
2674 /* FN's prototype is `LONGEST(*fn)(int)'. */
2675 s390x_emit_const (arg1);
2676 s390x_emit_call (fn);
2677 }
2678
2679 /* The "emit_void_call_2" emit_ops method for s390x. */
2680
2681 static void
2682 s390x_emit_void_call_2 (CORE_ADDR fn, int arg1)
2683 {
2684 /* FN's prototype is `void(*fn)(int,LONGEST)'. */
2685 static const unsigned char buf[] = {
2686 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */
2687 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */
2688 };
2689 static const unsigned char buf2[] = {
2690 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */
2691 };
2692 add_insns (buf, sizeof buf);
2693 s390x_emit_const (arg1);
2694 s390x_emit_call (fn);
2695 add_insns (buf2, sizeof buf2);
2696 }
2697
2698 /* The "emit_eq_goto" emit_ops method for s390x. */
2699
2700 static void
2701 s390x_emit_eq_goto (int *offset_p, int *size_p)
2702 {
2703 static const unsigned char buf[] = {
2704 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2705 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2706 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2707 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */
2708 };
2709 add_insns (buf, sizeof buf);
2710 if (offset_p)
2711 *offset_p = 18;
2712 if (size_p)
2713 *size_p = 4;
2714 }
2715
2716 /* The "emit_ne_goto" emit_ops method for s390x. */
2717
2718 static void
2719 s390x_emit_ne_goto (int *offset_p, int *size_p)
2720 {
2721 static const unsigned char buf[] = {
2722 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2723 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2724 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2725 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */
2726 };
2727 add_insns (buf, sizeof buf);
2728 if (offset_p)
2729 *offset_p = 18;
2730 if (size_p)
2731 *size_p = 4;
2732 }
2733
2734 /* The "emit_lt_goto" emit_ops method for s390x. */
2735
2736 static void
2737 s390x_emit_lt_goto (int *offset_p, int *size_p)
2738 {
2739 static const unsigned char buf[] = {
2740 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2741 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2742 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2743 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */
2744 };
2745 add_insns (buf, sizeof buf);
2746 if (offset_p)
2747 *offset_p = 18;
2748 if (size_p)
2749 *size_p = 4;
2750 }
2751
2752 /* The "emit_le_goto" emit_ops method for s390x. */
2753
2754 static void
2755 s390x_emit_le_goto (int *offset_p, int *size_p)
2756 {
2757 static const unsigned char buf[] = {
2758 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2759 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2760 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2761 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */
2762 };
2763 add_insns (buf, sizeof buf);
2764 if (offset_p)
2765 *offset_p = 18;
2766 if (size_p)
2767 *size_p = 4;
2768 }
2769
2770 /* The "emit_gt_goto" emit_ops method for s390x. */
2771
2772 static void
2773 s390x_emit_gt_goto (int *offset_p, int *size_p)
2774 {
2775 static const unsigned char buf[] = {
2776 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2777 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2778 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2779 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */
2780 };
2781 add_insns (buf, sizeof buf);
2782 if (offset_p)
2783 *offset_p = 18;
2784 if (size_p)
2785 *size_p = 4;
2786 }
2787
2788 /* The "emit_ge_goto" emit_ops method for s390x. */
2789
2790 static void
2791 s390x_emit_ge_goto (int *offset_p, int *size_p)
2792 {
2793 static const unsigned char buf[] = {
2794 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */
2795 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */
2796 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */
2797 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */
2798 };
2799 add_insns (buf, sizeof buf);
2800 if (offset_p)
2801 *offset_p = 18;
2802 if (size_p)
2803 *size_p = 4;
2804 }
2805
2806 /* The "emit_ops" structure for s390x. */
2807
2808 static struct emit_ops s390x_emit_ops =
2809 {
2810 s390x_emit_prologue,
2811 s390x_emit_epilogue,
2812 s390x_emit_add,
2813 s390x_emit_sub,
2814 s390x_emit_mul,
2815 s390x_emit_lsh,
2816 s390x_emit_rsh_signed,
2817 s390x_emit_rsh_unsigned,
2818 s390x_emit_ext,
2819 s390x_emit_log_not,
2820 s390x_emit_bit_and,
2821 s390x_emit_bit_or,
2822 s390x_emit_bit_xor,
2823 s390x_emit_bit_not,
2824 s390x_emit_equal,
2825 s390x_emit_less_signed,
2826 s390x_emit_less_unsigned,
2827 s390x_emit_ref,
2828 s390x_emit_if_goto,
2829 s390_emit_goto,
2830 s390_write_goto_address,
2831 s390x_emit_const,
2832 s390x_emit_call,
2833 s390x_emit_reg,
2834 s390x_emit_pop,
2835 s390x_emit_stack_flush,
2836 s390x_emit_zero_ext,
2837 s390x_emit_swap,
2838 s390x_emit_stack_adjust,
2839 s390x_emit_int_call_1,
2840 s390x_emit_void_call_2,
2841 s390x_emit_eq_goto,
2842 s390x_emit_ne_goto,
2843 s390x_emit_lt_goto,
2844 s390x_emit_le_goto,
2845 s390x_emit_gt_goto,
2846 s390x_emit_ge_goto
2847 };
2848 #endif
2849
2850 /* The "emit_ops" target ops method. */
2851
2852 emit_ops *
2853 s390_target::emit_ops ()
2854 {
2855 #ifdef __s390x__
2856 struct regcache *regcache = get_thread_regcache (current_thread, 0);
2857
2858 if (register_size (regcache->tdesc, 0) == 8)
2859 return &s390x_emit_ops;
2860 else
2861 #endif
2862 return &s390_emit_ops_impl;
2863 }
2864
2865 struct linux_target_ops the_low_target = {
2866 NULL, /* supports_range_stepping */
2867 s390_supports_hardware_single_step,
2868 NULL, /* get_syscall_trapinfo */
2869 s390_get_ipa_tdesc_idx,
2870 };
2871
2872 /* The linux target ops object. */
2873
2874 linux_process_target *the_linux_target = &the_s390_target;
2875
2876 void
2877 initialize_low_arch (void)
2878 {
2879 /* Initialize the Linux target descriptions. */
2880
2881 init_registers_s390_linux32 ();
2882 init_registers_s390_linux32v1 ();
2883 init_registers_s390_linux32v2 ();
2884 init_registers_s390_linux64 ();
2885 init_registers_s390_linux64v1 ();
2886 init_registers_s390_linux64v2 ();
2887 init_registers_s390_te_linux64 ();
2888 init_registers_s390_vx_linux64 ();
2889 init_registers_s390_tevx_linux64 ();
2890 init_registers_s390_gs_linux64 ();
2891 #ifdef __s390x__
2892 init_registers_s390x_linux64 ();
2893 init_registers_s390x_linux64v1 ();
2894 init_registers_s390x_linux64v2 ();
2895 init_registers_s390x_te_linux64 ();
2896 init_registers_s390x_vx_linux64 ();
2897 init_registers_s390x_tevx_linux64 ();
2898 init_registers_s390x_gs_linux64 ();
2899 #endif
2900
2901 initialize_regsets_info (&s390_regsets_info);
2902 initialize_regsets_info (&s390_regsets_info_3264);
2903 }
This page took 0.138737 seconds and 4 git commands to generate.