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