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