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