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