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