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