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