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