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