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