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.1.4 christos int pid = current_thread->id.pid (); 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.1.4 christos if (register_size (current_process ()->tdesc, 0) == 4) 800 1.1 christos res &= 0xffffffffull; 801 1.1 christos #endif 802 1.1 christos *addrp = res; 803 1.1 christos return 0; 804 1.1 christos } 805 1.1 christos 806 1.1 christos 807 1.1 christos /* Fast tracepoint support. 808 1.1 christos 809 1.1 christos The register save area on stack is identical for all targets: 810 1.1 christos 811 1.1 christos 0x000+i*0x10: VR0-VR31 812 1.1 christos 0x200+i*8: GR0-GR15 813 1.1 christos 0x280+i*4: AR0-AR15 814 1.1 christos 0x2c0: PSWM [64-bit] 815 1.1 christos 0x2c8: PSWA [64-bit] 816 1.1 christos 0x2d0: FPC 817 1.1 christos 818 1.1 christos If we're on 31-bit linux, we just don't store the high parts of the GPRs. 819 1.1 christos Likewise, if there's no VX support, we just store the FRs into the slots 820 1.1 christos of low VR halves. The agent code is responsible for rearranging that 821 1.1 christos into regcache. */ 822 1.1 christos 823 1.1 christos /* Code sequence saving GPRs for 31-bit target with no high GPRs. There's 824 1.1 christos one trick used at the very beginning: since there's no way to allocate 825 1.1 christos stack space without destroying CC (lay instruction can do it, but it's 826 1.1 christos only supported on later CPUs), we take 4 different execution paths for 827 1.1 christos every possible value of CC, allocate stack space, save %r0, stuff the 828 1.1 christos CC value in %r0 (shifted to match its position in PSWM high word), 829 1.1 christos then branch to common path. */ 830 1.1 christos 831 1.1 christos static const unsigned char s390_ft_entry_gpr_esa[] = { 832 1.1 christos 0xa7, 0x14, 0x00, 0x1e, /* jo .Lcc3 */ 833 1.1 christos 0xa7, 0x24, 0x00, 0x14, /* jh .Lcc2 */ 834 1.1 christos 0xa7, 0x44, 0x00, 0x0a, /* jl .Lcc1 */ 835 1.1 christos /* CC = 0 */ 836 1.1 christos 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */ 837 1.1 christos 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */ 838 1.1 christos 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */ 839 1.1 christos 0xa7, 0xf4, 0x00, 0x18, /* j .Lccdone */ 840 1.1 christos /* .Lcc1: */ 841 1.1 christos 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */ 842 1.1 christos 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */ 843 1.1 christos 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */ 844 1.1 christos 0xa7, 0xf4, 0x00, 0x10, /* j .Lccdone */ 845 1.1 christos /* .Lcc2: */ 846 1.1 christos 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */ 847 1.1 christos 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */ 848 1.1 christos 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */ 849 1.1 christos 0xa7, 0xf4, 0x00, 0x08, /* j .Lccdone */ 850 1.1 christos /* .Lcc3: */ 851 1.1 christos 0xa7, 0xfa, 0xfd, 0x00, /* ahi %r15, -0x300 */ 852 1.1 christos 0x50, 0x00, 0xf2, 0x04, /* st %r0, 0x204(%r15) */ 853 1.1 christos 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */ 854 1.1 christos /* .Lccdone: */ 855 1.1 christos 0x50, 0x10, 0xf2, 0x0c, /* st %r1, 0x20c(%r15) */ 856 1.1 christos 0x50, 0x20, 0xf2, 0x14, /* st %r2, 0x214(%r15) */ 857 1.1 christos 0x50, 0x30, 0xf2, 0x1c, /* st %r3, 0x21c(%r15) */ 858 1.1 christos 0x50, 0x40, 0xf2, 0x24, /* st %r4, 0x224(%r15) */ 859 1.1 christos 0x50, 0x50, 0xf2, 0x2c, /* st %r5, 0x22c(%r15) */ 860 1.1 christos 0x50, 0x60, 0xf2, 0x34, /* st %r6, 0x234(%r15) */ 861 1.1 christos 0x50, 0x70, 0xf2, 0x3c, /* st %r7, 0x23c(%r15) */ 862 1.1 christos 0x50, 0x80, 0xf2, 0x44, /* st %r8, 0x244(%r15) */ 863 1.1 christos 0x50, 0x90, 0xf2, 0x4c, /* st %r9, 0x24c(%r15) */ 864 1.1 christos 0x50, 0xa0, 0xf2, 0x54, /* st %r10, 0x254(%r15) */ 865 1.1 christos 0x50, 0xb0, 0xf2, 0x5c, /* st %r11, 0x25c(%r15) */ 866 1.1 christos 0x50, 0xc0, 0xf2, 0x64, /* st %r12, 0x264(%r15) */ 867 1.1 christos 0x50, 0xd0, 0xf2, 0x6c, /* st %r13, 0x26c(%r15) */ 868 1.1 christos 0x50, 0xe0, 0xf2, 0x74, /* st %r14, 0x274(%r15) */ 869 1.1 christos /* Compute original value of %r15 and store it. We use ahi instead 870 1.1 christos of la to preserve the whole value, and not just the low 31 bits. 871 1.1 christos This is not particularly important here, but essential in the 872 1.1 christos zarch case where someone might be using the high word of %r15 873 1.1 christos as an extra register. */ 874 1.1 christos 0x18, 0x1f, /* lr %r1, %r15 */ 875 1.1 christos 0xa7, 0x1a, 0x03, 0x00, /* ahi %r1, 0x300 */ 876 1.1 christos 0x50, 0x10, 0xf2, 0x7c, /* st %r1, 0x27c(%r15) */ 877 1.1 christos }; 878 1.1 christos 879 1.1 christos /* Code sequence saving GPRs for 31-bit target with high GPRs and for 64-bit 880 1.1 christos target. Same as above, except this time we can use load/store multiple, 881 1.1 christos since the 64-bit regs are tightly packed. */ 882 1.1 christos 883 1.1 christos static const unsigned char s390_ft_entry_gpr_zarch[] = { 884 1.1 christos 0xa7, 0x14, 0x00, 0x21, /* jo .Lcc3 */ 885 1.1 christos 0xa7, 0x24, 0x00, 0x16, /* jh .Lcc2 */ 886 1.1 christos 0xa7, 0x44, 0x00, 0x0b, /* jl .Lcc1 */ 887 1.1 christos /* CC = 0 */ 888 1.1 christos 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */ 889 1.1 christos 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */ 890 1.1 christos 0xa7, 0x08, 0x00, 0x00, /* lhi %r0, 0 */ 891 1.1 christos 0xa7, 0xf4, 0x00, 0x1b, /* j .Lccdone */ 892 1.1 christos /* .Lcc1: */ 893 1.1 christos 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */ 894 1.1 christos 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */ 895 1.1 christos 0xa7, 0x08, 0x10, 0x00, /* lhi %r0, 0x1000 */ 896 1.1 christos 0xa7, 0xf4, 0x00, 0x12, /* j .Lccdone */ 897 1.1 christos /* .Lcc2: */ 898 1.1 christos 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */ 899 1.1 christos 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */ 900 1.1 christos 0xa7, 0x08, 0x20, 0x00, /* lhi %r0, 0x2000 */ 901 1.1 christos 0xa7, 0xf4, 0x00, 0x09, /* j .Lccdone */ 902 1.1 christos /* .Lcc3: */ 903 1.1 christos 0xa7, 0xfb, 0xfd, 0x00, /* aghi %r15, -0x300 */ 904 1.1 christos 0xeb, 0x0e, 0xf2, 0x00, 0x00, 0x24, /* stmg %r0, %r14, 0x200(%r15) */ 905 1.1 christos 0xa7, 0x08, 0x30, 0x00, /* lhi %r0, 0x3000 */ 906 1.1 christos /* .Lccdone: */ 907 1.1 christos 0xb9, 0x04, 0x00, 0x1f, /* lgr %r1, %r15 */ 908 1.1 christos 0xa7, 0x1b, 0x03, 0x00, /* aghi %r1, 0x300 */ 909 1.1 christos 0xe3, 0x10, 0xf2, 0x78, 0x00, 0x24, /* stg %r1, 0x278(%r15) */ 910 1.1 christos }; 911 1.1 christos 912 1.1 christos /* Code sequence saving ARs, PSWM and FPC. PSWM has to be assembled from 913 1.1 christos current PSWM (read by epsw) and CC from entry (in %r0). */ 914 1.1 christos 915 1.1 christos static const unsigned char s390_ft_entry_misc[] = { 916 1.1 christos 0x9b, 0x0f, 0xf2, 0x80, /* stam %a0, %a15, 0x20(%%r15) */ 917 1.1 christos 0xb9, 0x8d, 0x00, 0x23, /* epsw %r2, %r3 */ 918 1.1 christos 0xa7, 0x18, 0xcf, 0xff, /* lhi %r1, ~0x3000 */ 919 1.1 christos 0x14, 0x21, /* nr %r2, %r1 */ 920 1.1 christos 0x16, 0x20, /* or %r2, %r0 */ 921 1.1 christos 0x50, 0x20, 0xf2, 0xc0, /* st %r2, 0x2c0(%r15) */ 922 1.1 christos 0x50, 0x30, 0xf2, 0xc4, /* st %r3, 0x2c4(%r15) */ 923 1.1 christos 0xb2, 0x9c, 0xf2, 0xd0, /* stfpc 0x2d0(%r15) */ 924 1.1 christos }; 925 1.1 christos 926 1.1 christos /* Code sequence saving FRs, used if VX not supported. */ 927 1.1 christos 928 1.1 christos static const unsigned char s390_ft_entry_fr[] = { 929 1.1 christos 0x60, 0x00, 0xf0, 0x00, /* std %f0, 0x000(%r15) */ 930 1.1 christos 0x60, 0x10, 0xf0, 0x10, /* std %f1, 0x010(%r15) */ 931 1.1 christos 0x60, 0x20, 0xf0, 0x20, /* std %f2, 0x020(%r15) */ 932 1.1 christos 0x60, 0x30, 0xf0, 0x30, /* std %f3, 0x030(%r15) */ 933 1.1 christos 0x60, 0x40, 0xf0, 0x40, /* std %f4, 0x040(%r15) */ 934 1.1 christos 0x60, 0x50, 0xf0, 0x50, /* std %f5, 0x050(%r15) */ 935 1.1 christos 0x60, 0x60, 0xf0, 0x60, /* std %f6, 0x060(%r15) */ 936 1.1 christos 0x60, 0x70, 0xf0, 0x70, /* std %f7, 0x070(%r15) */ 937 1.1 christos 0x60, 0x80, 0xf0, 0x80, /* std %f8, 0x080(%r15) */ 938 1.1 christos 0x60, 0x90, 0xf0, 0x90, /* std %f9, 0x090(%r15) */ 939 1.1 christos 0x60, 0xa0, 0xf0, 0xa0, /* std %f10, 0x0a0(%r15) */ 940 1.1 christos 0x60, 0xb0, 0xf0, 0xb0, /* std %f11, 0x0b0(%r15) */ 941 1.1 christos 0x60, 0xc0, 0xf0, 0xc0, /* std %f12, 0x0c0(%r15) */ 942 1.1 christos 0x60, 0xd0, 0xf0, 0xd0, /* std %f13, 0x0d0(%r15) */ 943 1.1 christos 0x60, 0xe0, 0xf0, 0xe0, /* std %f14, 0x0e0(%r15) */ 944 1.1 christos 0x60, 0xf0, 0xf0, 0xf0, /* std %f15, 0x0f0(%r15) */ 945 1.1 christos }; 946 1.1 christos 947 1.1 christos /* Code sequence saving VRs, used if VX not supported. */ 948 1.1 christos 949 1.1 christos static const unsigned char s390_ft_entry_vr[] = { 950 1.1 christos 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x3e, /* vstm %v0, %v15, 0x000(%r15) */ 951 1.1 christos 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x3e, /* vstm %v16, %v31, 0x100(%r15) */ 952 1.1 christos }; 953 1.1 christos 954 1.1 christos /* Code sequence doing the collection call for 31-bit target. %r1 contains 955 1.1 christos the address of the literal pool. */ 956 1.1 christos 957 1.1 christos static const unsigned char s390_ft_main_31[] = { 958 1.1 christos /* Load the literals into registers. */ 959 1.1 christos 0x58, 0x50, 0x10, 0x00, /* l %r5, 0x0(%r1) */ 960 1.1 christos 0x58, 0x20, 0x10, 0x04, /* l %r2, 0x4(%r1) */ 961 1.1 christos 0x58, 0x40, 0x10, 0x08, /* l %r4, 0x8(%r1) */ 962 1.1 christos 0x58, 0x60, 0x10, 0x0c, /* l %r6, 0xc(%r1) */ 963 1.1 christos /* Save original PSWA (tracepoint address | 0x80000000). */ 964 1.1 christos 0x50, 0x50, 0xf2, 0xcc, /* st %r5, 0x2cc(%r15) */ 965 1.1 christos /* Construct a collecting_t object at %r15+0x2e0. */ 966 1.1 christos 0x50, 0x20, 0xf2, 0xe0, /* st %r2, 0x2e0(%r15) */ 967 1.1 christos 0x9b, 0x00, 0xf2, 0xe4, /* stam %a0, %a0, 0x2e4(%r15) */ 968 1.1 christos /* Move its address to %r0. */ 969 1.1 christos 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */ 970 1.1 christos /* Take the lock. */ 971 1.1 christos /* .Lloop: */ 972 1.1 christos 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */ 973 1.1 christos 0xba, 0x10, 0x60, 0x00, /* cs %r1, %r0, 0(%r6) */ 974 1.1 christos 0xa7, 0x74, 0xff, 0xfc, /* jne .Lloop */ 975 1.1 christos /* Address of the register save block to %r3. */ 976 1.1 christos 0x18, 0x3f, /* lr %r3, %r15 */ 977 1.1 christos /* Make a stack frame, so that we can call the collector. */ 978 1.1 christos 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */ 979 1.1 christos /* Call it. */ 980 1.1 christos 0x0d, 0xe4, /* basr %r14, %r4 */ 981 1.1 christos /* And get rid of the stack frame again. */ 982 1.1 christos 0x41, 0xf0, 0xf0, 0x60, /* la %r15, 0x60(%r15) */ 983 1.1 christos /* Leave the lock. */ 984 1.1 christos 0x07, 0xf0, /* br %r0 */ 985 1.1 christos 0xa7, 0x18, 0x00, 0x00, /* lhi %r1, 0 */ 986 1.1 christos 0x50, 0x10, 0x60, 0x00, /* st %t1, 0(%r6) */ 987 1.1 christos }; 988 1.1 christos 989 1.1 christos /* Code sequence doing the collection call for 64-bit target. %r1 contains 990 1.1 christos the address of the literal pool. */ 991 1.1 christos 992 1.1 christos static const unsigned char s390_ft_main_64[] = { 993 1.1 christos /* Load the literals into registers. */ 994 1.1 christos 0xe3, 0x50, 0x10, 0x00, 0x00, 0x04, /* lg %r5, 0x00(%r1) */ 995 1.1 christos 0xe3, 0x20, 0x10, 0x08, 0x00, 0x04, /* lg %r2, 0x08(%r1) */ 996 1.1 christos 0xe3, 0x40, 0x10, 0x10, 0x00, 0x04, /* lg %r4, 0x10(%r1) */ 997 1.1 christos 0xe3, 0x60, 0x10, 0x18, 0x00, 0x04, /* lg %r6, 0x18(%r1) */ 998 1.1 christos /* Save original PSWA (tracepoint address). */ 999 1.1 christos 0xe3, 0x50, 0xf2, 0xc8, 0x00, 0x24, /* stg %r5, 0x2c8(%r15) */ 1000 1.1 christos /* Construct a collecting_t object at %r15+0x2e0. */ 1001 1.1 christos 0xe3, 0x20, 0xf2, 0xe0, 0x00, 0x24, /* stg %r2, 0x2e0(%r15) */ 1002 1.1 christos 0x9b, 0x01, 0xf2, 0xe8, /* stam %a0, %a1, 0x2e8(%r15) */ 1003 1.1 christos /* Move its address to %r0. */ 1004 1.1 christos 0x41, 0x00, 0xf2, 0xe0, /* la %r0, 0x2e0(%r15) */ 1005 1.1 christos /* Take the lock. */ 1006 1.1 christos /* .Lloop: */ 1007 1.1 christos 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */ 1008 1.1 christos 0xeb, 0x10, 0x60, 0x00, 0x00, 0x30, /* csg %r1, %r0, 0(%r6) */ 1009 1.1 christos 0xa7, 0x74, 0xff, 0xfb, /* jne .Lloop */ 1010 1.1 christos /* Address of the register save block to %r3. */ 1011 1.1 christos 0xb9, 0x04, 0x00, 0x3f, /* lgr %r3, %r15 */ 1012 1.1 christos /* Make a stack frame, so that we can call the collector. */ 1013 1.1 christos 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */ 1014 1.1 christos /* Call it. */ 1015 1.1 christos 0x0d, 0xe4, /* basr %r14, %r4 */ 1016 1.1 christos /* And get rid of the stack frame again. */ 1017 1.1 christos 0x41, 0xf0, 0xf0, 0xa0, /* la %r15, 0xa0(%r15) */ 1018 1.1 christos /* Leave the lock. */ 1019 1.1 christos 0x07, 0xf0, /* br %r0 */ 1020 1.1 christos 0xa7, 0x19, 0x00, 0x00, /* lghi %r1, 0 */ 1021 1.1 christos 0xe3, 0x10, 0x60, 0x00, 0x00, 0x24, /* stg %t1, 0(%r6) */ 1022 1.1 christos }; 1023 1.1 christos 1024 1.1 christos /* Code sequence restoring FRs, for targets with no VX support. */ 1025 1.1 christos 1026 1.1 christos static const unsigned char s390_ft_exit_fr[] = { 1027 1.1 christos 0x68, 0x00, 0xf0, 0x00, /* ld %f0, 0x000(%r15) */ 1028 1.1 christos 0x68, 0x10, 0xf0, 0x10, /* ld %f1, 0x010(%r15) */ 1029 1.1 christos 0x68, 0x20, 0xf0, 0x20, /* ld %f2, 0x020(%r15) */ 1030 1.1 christos 0x68, 0x30, 0xf0, 0x30, /* ld %f3, 0x030(%r15) */ 1031 1.1 christos 0x68, 0x40, 0xf0, 0x40, /* ld %f4, 0x040(%r15) */ 1032 1.1 christos 0x68, 0x50, 0xf0, 0x50, /* ld %f5, 0x050(%r15) */ 1033 1.1 christos 0x68, 0x60, 0xf0, 0x60, /* ld %f6, 0x060(%r15) */ 1034 1.1 christos 0x68, 0x70, 0xf0, 0x70, /* ld %f7, 0x070(%r15) */ 1035 1.1 christos 0x68, 0x80, 0xf0, 0x80, /* ld %f8, 0x080(%r15) */ 1036 1.1 christos 0x68, 0x90, 0xf0, 0x90, /* ld %f9, 0x090(%r15) */ 1037 1.1 christos 0x68, 0xa0, 0xf0, 0xa0, /* ld %f10, 0x0a0(%r15) */ 1038 1.1 christos 0x68, 0xb0, 0xf0, 0xb0, /* ld %f11, 0x0b0(%r15) */ 1039 1.1 christos 0x68, 0xc0, 0xf0, 0xc0, /* ld %f12, 0x0c0(%r15) */ 1040 1.1 christos 0x68, 0xd0, 0xf0, 0xd0, /* ld %f13, 0x0d0(%r15) */ 1041 1.1 christos 0x68, 0xe0, 0xf0, 0xe0, /* ld %f14, 0x0e0(%r15) */ 1042 1.1 christos 0x68, 0xf0, 0xf0, 0xf0, /* ld %f15, 0x0f0(%r15) */ 1043 1.1 christos }; 1044 1.1 christos 1045 1.1 christos /* Code sequence restoring VRs. */ 1046 1.1 christos 1047 1.1 christos static const unsigned char s390_ft_exit_vr[] = { 1048 1.1 christos 0xe7, 0x0f, 0xf0, 0x00, 0x00, 0x36, /* vlm %v0, %v15, 0x000(%r15) */ 1049 1.1 christos 0xe7, 0x0f, 0xf1, 0x00, 0x0c, 0x36, /* vlm %v16, %v31, 0x100(%r15) */ 1050 1.1 christos }; 1051 1.1 christos 1052 1.1 christos /* Code sequence restoring misc registers. As for PSWM, only CC should be 1053 1.1 christos modified by C code, so we use the alr instruction to restore it by 1054 1.1 christos manufacturing an operand that'll result in the original flags. */ 1055 1.1 christos 1056 1.1 christos static const unsigned char s390_ft_exit_misc[] = { 1057 1.1 christos 0xb2, 0x9d, 0xf2, 0xd0, /* lfpc 0x2d0(%r15) */ 1058 1.1 christos 0x58, 0x00, 0xf2, 0xc0, /* l %r0, 0x2c0(%r15) */ 1059 1.1 christos /* Extract CC to high 2 bits of %r0. */ 1060 1.1 christos 0x88, 0x00, 0x00, 0x0c, /* srl %r0, 12 */ 1061 1.1 christos 0x89, 0x00, 0x00, 0x1e, /* sll %r0, 30 */ 1062 1.1 christos /* Add %r0 to itself. Result will be nonzero iff CC bit 0 is set, and 1063 1.1 christos will have carry iff CC bit 1 is set - resulting in the same flags 1064 1.1 christos as the original. */ 1065 1.1 christos 0x1e, 0x00, /* alr %r0, %r0 */ 1066 1.1 christos 0x9a, 0x0f, 0xf2, 0x80, /* lam %a0, %a15, 0x280(%r15) */ 1067 1.1 christos }; 1068 1.1 christos 1069 1.1 christos /* Code sequence restoring GPRs, for 31-bit targets with no high GPRs. */ 1070 1.1 christos 1071 1.1 christos static const unsigned char s390_ft_exit_gpr_esa[] = { 1072 1.1 christos 0x58, 0x00, 0xf2, 0x04, /* l %r0, 0x204(%r15) */ 1073 1.1 christos 0x58, 0x10, 0xf2, 0x0c, /* l %r1, 0x20c(%r15) */ 1074 1.1 christos 0x58, 0x20, 0xf2, 0x14, /* l %r2, 0x214(%r15) */ 1075 1.1 christos 0x58, 0x30, 0xf2, 0x1c, /* l %r3, 0x21c(%r15) */ 1076 1.1 christos 0x58, 0x40, 0xf2, 0x24, /* l %r4, 0x224(%r15) */ 1077 1.1 christos 0x58, 0x50, 0xf2, 0x2c, /* l %r5, 0x22c(%r15) */ 1078 1.1 christos 0x58, 0x60, 0xf2, 0x34, /* l %r6, 0x234(%r15) */ 1079 1.1 christos 0x58, 0x70, 0xf2, 0x3c, /* l %r7, 0x23c(%r15) */ 1080 1.1 christos 0x58, 0x80, 0xf2, 0x44, /* l %r8, 0x244(%r15) */ 1081 1.1 christos 0x58, 0x90, 0xf2, 0x4c, /* l %r9, 0x24c(%r15) */ 1082 1.1 christos 0x58, 0xa0, 0xf2, 0x54, /* l %r10, 0x254(%r15) */ 1083 1.1 christos 0x58, 0xb0, 0xf2, 0x5c, /* l %r11, 0x25c(%r15) */ 1084 1.1 christos 0x58, 0xc0, 0xf2, 0x64, /* l %r12, 0x264(%r15) */ 1085 1.1 christos 0x58, 0xd0, 0xf2, 0x6c, /* l %r13, 0x26c(%r15) */ 1086 1.1 christos 0x58, 0xe0, 0xf2, 0x74, /* l %r14, 0x274(%r15) */ 1087 1.1 christos 0x58, 0xf0, 0xf2, 0x7c, /* l %r15, 0x27c(%r15) */ 1088 1.1 christos }; 1089 1.1 christos 1090 1.1 christos /* Code sequence restoring GPRs, for 64-bit targets and 31-bit targets 1091 1.1 christos with high GPRs. */ 1092 1.1 christos 1093 1.1 christos static const unsigned char s390_ft_exit_gpr_zarch[] = { 1094 1.1 christos 0xeb, 0x0f, 0xf2, 0x00, 0x00, 0x04, /* lmg %r0, %r15, 0x200(%r15) */ 1095 1.1 christos }; 1096 1.1 christos 1097 1.1 christos /* Writes instructions to target, updating the to pointer. */ 1098 1.1 christos 1099 1.1 christos static void 1100 1.1 christos append_insns (CORE_ADDR *to, size_t len, const unsigned char *buf) 1101 1.1 christos { 1102 1.1 christos target_write_memory (*to, buf, len); 1103 1.1 christos *to += len; 1104 1.1 christos } 1105 1.1 christos 1106 1.1 christos /* Relocates an instruction from oldloc to *to, updating to. */ 1107 1.1 christos 1108 1.1 christos static int 1109 1.1 christos s390_relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc, int is_64) 1110 1.1 christos { 1111 1.1 christos gdb_byte buf[6]; 1112 1.1 christos int ilen; 1113 1.1 christos int op2; 1114 1.1 christos /* 0: no fixup, 1: PC16DBL fixup, 2: PC32DBL fixup. */ 1115 1.1 christos int mode = 0; 1116 1.1 christos int is_bras = 0; 1117 1.1 christos read_inferior_memory (oldloc, buf, sizeof buf); 1118 1.1 christos if (buf[0] < 0x40) 1119 1.1 christos ilen = 2; 1120 1.1 christos else if (buf[0] < 0xc0) 1121 1.1 christos ilen = 4; 1122 1.1 christos else 1123 1.1 christos ilen = 6; 1124 1.1 christos switch (buf[0]) 1125 1.1 christos { 1126 1.1 christos case 0x05: /* BALR */ 1127 1.1 christos case 0x0c: /* BASSM */ 1128 1.1 christos case 0x0d: /* BASR */ 1129 1.1 christos case 0x45: /* BAL */ 1130 1.1 christos case 0x4d: /* BAS */ 1131 1.1 christos /* These save a return address and mess around with registers. 1132 1.1 christos We can't relocate them. */ 1133 1.1 christos return 1; 1134 1.1 christos case 0x84: /* BRXH */ 1135 1.1 christos case 0x85: /* BRXLE */ 1136 1.1 christos mode = 1; 1137 1.1 christos break; 1138 1.1 christos case 0xa7: 1139 1.1 christos op2 = buf[1] & 0xf; 1140 1.1 christos /* BRC, BRAS, BRCT, BRCTG */ 1141 1.1 christos if (op2 >= 4 && op2 <= 7) 1142 1.1 christos mode = 1; 1143 1.1 christos /* BRAS */ 1144 1.1 christos if (op2 == 5) 1145 1.1 christos is_bras = 1; 1146 1.1 christos break; 1147 1.1 christos case 0xc0: 1148 1.1 christos op2 = buf[1] & 0xf; 1149 1.1 christos /* LARL, BRCL, BRASL */ 1150 1.1 christos if (op2 == 0 || op2 == 4 || op2 == 5) 1151 1.1 christos mode = 2; 1152 1.1 christos /* BRASL */ 1153 1.1 christos if (op2 == 5) 1154 1.1 christos is_bras = 1; 1155 1.1 christos break; 1156 1.1 christos case 0xc4: 1157 1.1 christos case 0xc6: 1158 1.1 christos /* PC-relative addressing instructions. */ 1159 1.1 christos mode = 2; 1160 1.1 christos break; 1161 1.1 christos case 0xc5: /* BPRP */ 1162 1.1 christos case 0xc7: /* BPP */ 1163 1.1 christos /* Branch prediction - just skip it. */ 1164 1.1 christos return 0; 1165 1.1 christos case 0xcc: 1166 1.1 christos op2 = buf[1] & 0xf; 1167 1.1 christos /* BRCTH */ 1168 1.1 christos if (op2 == 6) 1169 1.1 christos mode = 2; 1170 1.1 christos break; 1171 1.1 christos case 0xec: 1172 1.1 christos op2 = buf[5]; 1173 1.1 christos switch (op2) 1174 1.1 christos { 1175 1.1 christos case 0x44: /* BRXHG */ 1176 1.1 christos case 0x45: /* BRXLG */ 1177 1.1 christos case 0x64: /* CGRJ */ 1178 1.1 christos case 0x65: /* CLGRJ */ 1179 1.1 christos case 0x76: /* CRJ */ 1180 1.1 christos case 0x77: /* CLRJ */ 1181 1.1 christos mode = 1; 1182 1.1 christos break; 1183 1.1 christos } 1184 1.1 christos break; 1185 1.1 christos } 1186 1.1 christos 1187 1.1 christos if (mode != 0) 1188 1.1 christos { 1189 1.1 christos /* We'll have to relocate an instruction with a PC-relative field. 1190 1.1 christos First, compute the target. */ 1191 1.1 christos int64_t loffset = 0; 1192 1.1 christos CORE_ADDR target; 1193 1.1 christos if (mode == 1) 1194 1.1 christos { 1195 1.1 christos int16_t soffset = 0; 1196 1.1 christos memcpy (&soffset, buf + 2, 2); 1197 1.1 christos loffset = soffset; 1198 1.1 christos } 1199 1.1 christos else if (mode == 2) 1200 1.1 christos { 1201 1.1 christos int32_t soffset = 0; 1202 1.1 christos memcpy (&soffset, buf + 2, 4); 1203 1.1 christos loffset = soffset; 1204 1.1 christos } 1205 1.1 christos target = oldloc + loffset * 2; 1206 1.1 christos if (!is_64) 1207 1.1 christos target &= 0x7fffffff; 1208 1.1 christos 1209 1.1 christos if (is_bras) 1210 1.1 christos { 1211 1.1 christos /* BRAS or BRASL was used. We cannot just relocate those, since 1212 1.1 christos they save the return address in a register. We can, however, 1213 1.1 christos replace them with a LARL+JG sequence. */ 1214 1.1 christos 1215 1.1 christos /* Make the LARL. */ 1216 1.1 christos int32_t soffset; 1217 1.1 christos buf[0] = 0xc0; 1218 1.1 christos buf[1] &= 0xf0; 1219 1.1 christos loffset = oldloc + ilen - *to; 1220 1.1 christos loffset >>= 1; 1221 1.1 christos soffset = loffset; 1222 1.1 christos if (soffset != loffset && is_64) 1223 1.1 christos return 1; 1224 1.1 christos memcpy (buf + 2, &soffset, 4); 1225 1.1 christos append_insns (to, 6, buf); 1226 1.1 christos 1227 1.1 christos /* Note: this is not fully correct. In 31-bit mode, LARL will write 1228 1.1 christos an address with the top bit 0, while BRAS/BRASL will write it 1229 1.1 christos with top bit 1. It should not matter much, since linux compilers 1230 1.1 christos use BR and not BSM to return from functions, but it could confuse 1231 1.1 christos some poor stack unwinder. */ 1232 1.1 christos 1233 1.1 christos /* We'll now be writing a JG. */ 1234 1.1 christos mode = 2; 1235 1.1 christos buf[0] = 0xc0; 1236 1.1 christos buf[1] = 0xf4; 1237 1.1 christos ilen = 6; 1238 1.1 christos } 1239 1.1 christos 1240 1.1 christos /* Compute the new offset and write it to the buffer. */ 1241 1.1 christos loffset = target - *to; 1242 1.1 christos loffset >>= 1; 1243 1.1 christos 1244 1.1 christos if (mode == 1) 1245 1.1 christos { 1246 1.1 christos int16_t soffset = loffset; 1247 1.1 christos if (soffset != loffset) 1248 1.1 christos return 1; 1249 1.1 christos memcpy (buf + 2, &soffset, 2); 1250 1.1 christos } 1251 1.1 christos else if (mode == 2) 1252 1.1 christos { 1253 1.1 christos int32_t soffset = loffset; 1254 1.1 christos if (soffset != loffset && is_64) 1255 1.1 christos return 1; 1256 1.1 christos memcpy (buf + 2, &soffset, 4); 1257 1.1 christos } 1258 1.1 christos } 1259 1.1 christos append_insns (to, ilen, buf); 1260 1.1 christos return 0; 1261 1.1 christos } 1262 1.1 christos 1263 1.1 christos bool 1264 1.1 christos s390_target::supports_fast_tracepoints () 1265 1.1 christos { 1266 1.1 christos return true; 1267 1.1 christos } 1268 1.1 christos 1269 1.1 christos /* Implementation of target ops method 1270 1.1 christos "install_fast_tracepoint_jump_pad". */ 1271 1.1 christos 1272 1.1 christos int 1273 1.1 christos s390_target::install_fast_tracepoint_jump_pad 1274 1.1 christos (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector, 1275 1.1 christos CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry, 1276 1.1 christos CORE_ADDR *trampoline, ULONGEST *trampoline_size, 1277 1.1 christos unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size, 1278 1.1 christos CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end, 1279 1.1 christos char *err) 1280 1.1 christos { 1281 1.1 christos int i; 1282 1.1 christos int64_t loffset; 1283 1.1 christos int32_t offset; 1284 1.1 christos unsigned char jbuf[6] = { 0xc0, 0xf4, 0, 0, 0, 0 }; /* jg ... */ 1285 1.1 christos CORE_ADDR buildaddr = *jump_entry; 1286 1.1 christos #ifdef __s390x__ 1287 1.1.1.4 christos int is_64 = register_size (current_process ()->tdesc, 0) == 8; 1288 1.1 christos int is_zarch = is_64 || have_hwcap_s390_high_gprs; 1289 1.1 christos int has_vx = have_hwcap_s390_vx; 1290 1.1 christos #else 1291 1.1 christos int is_64 = 0, is_zarch = 0, has_vx = 0; 1292 1.1 christos #endif 1293 1.1 christos CORE_ADDR literals[4] = { 1294 1.1 christos tpaddr, 1295 1.1 christos tpoint, 1296 1.1 christos collector, 1297 1.1 christos lockaddr, 1298 1.1 christos }; 1299 1.1 christos 1300 1.1 christos /* First, store the GPRs. */ 1301 1.1 christos if (is_zarch) 1302 1.1 christos append_insns (&buildaddr, sizeof s390_ft_entry_gpr_zarch, 1303 1.1 christos s390_ft_entry_gpr_zarch); 1304 1.1 christos else 1305 1.1 christos append_insns (&buildaddr, sizeof s390_ft_entry_gpr_esa, 1306 1.1 christos s390_ft_entry_gpr_esa); 1307 1.1 christos 1308 1.1 christos /* Second, misc registers (ARs, PSWM, FPC). PSWA will be stored below. */ 1309 1.1 christos append_insns (&buildaddr, sizeof s390_ft_entry_misc, s390_ft_entry_misc); 1310 1.1 christos 1311 1.1 christos /* Third, FRs or VRs. */ 1312 1.1 christos if (has_vx) 1313 1.1 christos append_insns (&buildaddr, sizeof s390_ft_entry_vr, s390_ft_entry_vr); 1314 1.1 christos else 1315 1.1 christos append_insns (&buildaddr, sizeof s390_ft_entry_fr, s390_ft_entry_fr); 1316 1.1 christos 1317 1.1 christos /* Now, the main part of code - store PSWA, take lock, call collector, 1318 1.1 christos leave lock. First, we'll need to fetch 4 literals. */ 1319 1.1 christos if (is_64) { 1320 1.1 christos unsigned char buf[] = { 1321 1.1 christos 0x07, 0x07, /* nopr %r7 */ 1322 1.1 christos 0x07, 0x07, /* nopr %r7 */ 1323 1.1 christos 0x07, 0x07, /* nopr %r7 */ 1324 1.1 christos 0xa7, 0x15, 0x00, 0x12, /* bras %r1, .Lend */ 1325 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, /* tpaddr */ 1326 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, /* tpoint */ 1327 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, /* collector */ 1328 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, /* lockaddr */ 1329 1.1 christos /* .Lend: */ 1330 1.1 christos }; 1331 1.1 christos /* Find the proper start place in buf, so that literals will be 1332 1.1 christos aligned. */ 1333 1.1 christos int bufpos = (buildaddr + 2) & 7; 1334 1.1 christos /* Stuff the literals into the buffer. */ 1335 1.1 christos for (i = 0; i < 4; i++) { 1336 1.1 christos uint64_t lit = literals[i]; 1337 1.1 christos memcpy (&buf[sizeof buf - 32 + i * 8], &lit, 8); 1338 1.1 christos } 1339 1.1 christos append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos); 1340 1.1 christos append_insns (&buildaddr, sizeof s390_ft_main_64, s390_ft_main_64); 1341 1.1 christos } else { 1342 1.1 christos unsigned char buf[] = { 1343 1.1 christos 0x07, 0x07, /* nopr %r7 */ 1344 1.1 christos 0xa7, 0x15, 0x00, 0x0a, /* bras %r1, .Lend */ 1345 1.1 christos 0, 0, 0, 0, /* tpaddr */ 1346 1.1 christos 0, 0, 0, 0, /* tpoint */ 1347 1.1 christos 0, 0, 0, 0, /* collector */ 1348 1.1 christos 0, 0, 0, 0, /* lockaddr */ 1349 1.1 christos /* .Lend: */ 1350 1.1 christos }; 1351 1.1 christos /* Find the proper start place in buf, so that literals will be 1352 1.1 christos aligned. */ 1353 1.1 christos int bufpos = (buildaddr + 2) & 3; 1354 1.1 christos /* First literal will be saved as the PSWA, make sure it has the high bit 1355 1.1 christos set. */ 1356 1.1 christos literals[0] |= 0x80000000; 1357 1.1 christos /* Stuff the literals into the buffer. */ 1358 1.1 christos for (i = 0; i < 4; i++) { 1359 1.1 christos uint32_t lit = literals[i]; 1360 1.1 christos memcpy (&buf[sizeof buf - 16 + i * 4], &lit, 4); 1361 1.1 christos } 1362 1.1 christos append_insns (&buildaddr, sizeof buf - bufpos, buf + bufpos); 1363 1.1 christos append_insns (&buildaddr, sizeof s390_ft_main_31, s390_ft_main_31); 1364 1.1 christos } 1365 1.1 christos 1366 1.1 christos /* Restore FRs or VRs. */ 1367 1.1 christos if (has_vx) 1368 1.1 christos append_insns (&buildaddr, sizeof s390_ft_exit_vr, s390_ft_exit_vr); 1369 1.1 christos else 1370 1.1 christos append_insns (&buildaddr, sizeof s390_ft_exit_fr, s390_ft_exit_fr); 1371 1.1 christos 1372 1.1 christos /* Restore misc registers. */ 1373 1.1 christos append_insns (&buildaddr, sizeof s390_ft_exit_misc, s390_ft_exit_misc); 1374 1.1 christos 1375 1.1 christos /* Restore the GPRs. */ 1376 1.1 christos if (is_zarch) 1377 1.1 christos append_insns (&buildaddr, sizeof s390_ft_exit_gpr_zarch, 1378 1.1 christos s390_ft_exit_gpr_zarch); 1379 1.1 christos else 1380 1.1 christos append_insns (&buildaddr, sizeof s390_ft_exit_gpr_esa, 1381 1.1 christos s390_ft_exit_gpr_esa); 1382 1.1 christos 1383 1.1 christos /* Now, adjust the original instruction to execute in the jump 1384 1.1 christos pad. */ 1385 1.1 christos *adjusted_insn_addr = buildaddr; 1386 1.1 christos if (s390_relocate_instruction (&buildaddr, tpaddr, is_64)) 1387 1.1 christos { 1388 1.1 christos sprintf (err, "E.Could not relocate instruction for tracepoint."); 1389 1.1 christos return 1; 1390 1.1 christos } 1391 1.1 christos *adjusted_insn_addr_end = buildaddr; 1392 1.1 christos 1393 1.1 christos /* Finally, write a jump back to the program. */ 1394 1.1 christos 1395 1.1 christos loffset = (tpaddr + orig_size) - buildaddr; 1396 1.1 christos loffset >>= 1; 1397 1.1 christos offset = loffset; 1398 1.1 christos if (is_64 && offset != loffset) 1399 1.1 christos { 1400 1.1 christos sprintf (err, 1401 1.1 christos "E.Jump back from jump pad too far from tracepoint " 1402 1.1 christos "(offset 0x%" PRIx64 " > int33).", loffset); 1403 1.1 christos return 1; 1404 1.1 christos } 1405 1.1 christos memcpy (jbuf + 2, &offset, 4); 1406 1.1 christos append_insns (&buildaddr, sizeof jbuf, jbuf); 1407 1.1 christos 1408 1.1 christos /* The jump pad is now built. Wire in a jump to our jump pad. This 1409 1.1 christos is always done last (by our caller actually), so that we can 1410 1.1 christos install fast tracepoints with threads running. This relies on 1411 1.1 christos the agent's atomic write support. */ 1412 1.1 christos loffset = *jump_entry - tpaddr; 1413 1.1 christos loffset >>= 1; 1414 1.1 christos offset = loffset; 1415 1.1 christos if (is_64 && offset != loffset) 1416 1.1 christos { 1417 1.1 christos sprintf (err, 1418 1.1 christos "E.Jump back from jump pad too far from tracepoint " 1419 1.1 christos "(offset 0x%" PRIx64 " > int33).", loffset); 1420 1.1 christos return 1; 1421 1.1 christos } 1422 1.1 christos memcpy (jbuf + 2, &offset, 4); 1423 1.1 christos memcpy (jjump_pad_insn, jbuf, sizeof jbuf); 1424 1.1 christos *jjump_pad_insn_size = sizeof jbuf; 1425 1.1 christos 1426 1.1 christos /* Return the end address of our pad. */ 1427 1.1 christos *jump_entry = buildaddr; 1428 1.1 christos 1429 1.1 christos return 0; 1430 1.1 christos } 1431 1.1 christos 1432 1.1 christos /* Implementation of target ops method 1433 1.1 christos "get_min_fast_tracepoint_insn_len". */ 1434 1.1 christos 1435 1.1 christos int 1436 1.1 christos s390_target::get_min_fast_tracepoint_insn_len () 1437 1.1 christos { 1438 1.1 christos /* We only support using 6-byte jumps to reach the tracepoint code. 1439 1.1 christos If the tracepoint buffer were allocated sufficiently close (64kiB) 1440 1.1 christos to the executable code, and the traced instruction itself was close 1441 1.1 christos enough to the beginning, we could use 4-byte jumps, but this doesn't 1442 1.1 christos seem to be worth the effort. */ 1443 1.1 christos return 6; 1444 1.1 christos } 1445 1.1 christos 1446 1.1 christos /* Implementation of target ops method "get_ipa_tdesc_idx". */ 1447 1.1 christos 1448 1.1 christos int 1449 1.1 christos s390_target::get_ipa_tdesc_idx () 1450 1.1 christos { 1451 1.1.1.4 christos const target_desc *tdesc = current_process ()->tdesc; 1452 1.1 christos 1453 1.1 christos #ifdef __s390x__ 1454 1.1 christos if (tdesc == tdesc_s390x_linux64) 1455 1.1 christos return S390_TDESC_64; 1456 1.1 christos if (tdesc == tdesc_s390x_linux64v1) 1457 1.1 christos return S390_TDESC_64V1; 1458 1.1 christos if (tdesc == tdesc_s390x_linux64v2) 1459 1.1 christos return S390_TDESC_64V2; 1460 1.1 christos if (tdesc == tdesc_s390x_te_linux64) 1461 1.1 christos return S390_TDESC_TE; 1462 1.1 christos if (tdesc == tdesc_s390x_vx_linux64) 1463 1.1 christos return S390_TDESC_VX; 1464 1.1 christos if (tdesc == tdesc_s390x_tevx_linux64) 1465 1.1 christos return S390_TDESC_TEVX; 1466 1.1 christos if (tdesc == tdesc_s390x_gs_linux64) 1467 1.1 christos return S390_TDESC_GS; 1468 1.1 christos #endif 1469 1.1 christos 1470 1.1 christos if (tdesc == tdesc_s390_linux32) 1471 1.1 christos return S390_TDESC_32; 1472 1.1 christos if (tdesc == tdesc_s390_linux32v1) 1473 1.1 christos return S390_TDESC_32V1; 1474 1.1 christos if (tdesc == tdesc_s390_linux32v2) 1475 1.1 christos return S390_TDESC_32V2; 1476 1.1 christos if (tdesc == tdesc_s390_linux64) 1477 1.1 christos return S390_TDESC_64; 1478 1.1 christos if (tdesc == tdesc_s390_linux64v1) 1479 1.1 christos return S390_TDESC_64V1; 1480 1.1 christos if (tdesc == tdesc_s390_linux64v2) 1481 1.1 christos return S390_TDESC_64V2; 1482 1.1 christos if (tdesc == tdesc_s390_te_linux64) 1483 1.1 christos return S390_TDESC_TE; 1484 1.1 christos if (tdesc == tdesc_s390_vx_linux64) 1485 1.1 christos return S390_TDESC_VX; 1486 1.1 christos if (tdesc == tdesc_s390_tevx_linux64) 1487 1.1 christos return S390_TDESC_TEVX; 1488 1.1 christos if (tdesc == tdesc_s390_gs_linux64) 1489 1.1 christos return S390_TDESC_GS; 1490 1.1 christos 1491 1.1 christos return 0; 1492 1.1 christos } 1493 1.1 christos 1494 1.1 christos /* Appends given buffer to current_insn_ptr in the target. */ 1495 1.1 christos 1496 1.1 christos static void 1497 1.1 christos add_insns (const unsigned char *start, int len) 1498 1.1 christos { 1499 1.1 christos CORE_ADDR buildaddr = current_insn_ptr; 1500 1.1 christos 1501 1.1.1.2 christos threads_debug_printf ("Adding %d bytes of insn at %s", 1502 1.1.1.2 christos len, paddress (buildaddr)); 1503 1.1 christos 1504 1.1 christos append_insns (&buildaddr, len, start); 1505 1.1 christos current_insn_ptr = buildaddr; 1506 1.1 christos } 1507 1.1 christos 1508 1.1 christos /* Register usage in emit: 1509 1.1 christos 1510 1.1 christos - %r0, %r1: temp 1511 1.1 christos - %r2: top of stack (high word for 31-bit) 1512 1.1 christos - %r3: low word of top of stack (for 31-bit) 1513 1.1 christos - %r4, %r5: temp 1514 1.1 christos - %r6, %r7, %r8: don't use 1515 1.1 christos - %r9: saved arg1 1516 1.1 christos - %r10: saved arg2 1517 1.1 christos - %r11: frame pointer 1518 1.1 christos - %r12: saved top of stack for void_call_2 (high word for 31-bit) 1519 1.1 christos - %r13: low word of saved top of stack (for 31-bit) 1520 1.1 christos - %r14: return address for calls 1521 1.1 christos - %r15: stack pointer 1522 1.1 christos 1523 1.1 christos */ 1524 1.1 christos 1525 1.1 christos /* The "emit_prologue" emit_ops method for s390. */ 1526 1.1 christos 1527 1.1 christos static void 1528 1.1 christos s390_emit_prologue (void) 1529 1.1 christos { 1530 1.1 christos static const unsigned char buf[] = { 1531 1.1 christos 0x90, 0x9f, 0xf0, 0x24, /* stm %r9, %r15, 0x24(%r15) */ 1532 1.1 christos 0x18, 0x92, /* lr %r9, %r2 */ 1533 1.1 christos 0x18, 0xa3, /* lr %r10, %r3 */ 1534 1.1 christos 0x18, 0xbf, /* lr %r11, %r15 */ 1535 1.1 christos }; 1536 1.1 christos add_insns (buf, sizeof buf); 1537 1.1 christos } 1538 1.1 christos 1539 1.1 christos /* The "emit_epilogue" emit_ops method for s390. */ 1540 1.1 christos 1541 1.1 christos static void 1542 1.1 christos s390_emit_epilogue (void) 1543 1.1 christos { 1544 1.1 christos static const unsigned char buf[] = { 1545 1.1 christos 0x90, 0x23, 0xa0, 0x00, /* stm %r2, %r3, 0(%r10) */ 1546 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1547 1.1 christos 0x98, 0x9f, 0xb0, 0x24, /* lm %r9, %r15, 0x24(%r11) */ 1548 1.1 christos 0x07, 0xfe, /* br %r14 */ 1549 1.1 christos }; 1550 1.1 christos add_insns (buf, sizeof buf); 1551 1.1 christos } 1552 1.1 christos 1553 1.1 christos /* The "emit_add" emit_ops method for s390. */ 1554 1.1 christos 1555 1.1 christos static void 1556 1.1 christos s390_emit_add (void) 1557 1.1 christos { 1558 1.1 christos static const unsigned char buf[] = { 1559 1.1 christos 0x5e, 0x30, 0xf0, 0x04, /* al %r3, 4(%r15) */ 1560 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x98, /* al %r2, 0(%r15) */ 1561 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1562 1.1 christos }; 1563 1.1 christos add_insns (buf, sizeof buf); 1564 1.1 christos } 1565 1.1 christos 1566 1.1 christos /* The "emit_sub" emit_ops method for s390. */ 1567 1.1 christos 1568 1.1 christos static void 1569 1.1 christos s390_emit_sub (void) 1570 1.1 christos { 1571 1.1 christos static const unsigned char buf[] = { 1572 1.1 christos 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */ 1573 1.1 christos 0x1f, 0x53, /* slr %r5, %r3 */ 1574 1.1 christos 0xb9, 0x99, 0x00, 0x42, /* slbr %r4, %r2 */ 1575 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1576 1.1 christos 0x18, 0x35, /* lr %r3, %r5 */ 1577 1.1 christos 0x18, 0x24, /* lr %r2, %r4 */ 1578 1.1 christos }; 1579 1.1 christos add_insns (buf, sizeof buf); 1580 1.1 christos } 1581 1.1 christos 1582 1.1 christos /* The "emit_mul" emit_ops method for s390. */ 1583 1.1 christos 1584 1.1 christos static void 1585 1.1 christos s390_emit_mul (void) 1586 1.1 christos { 1587 1.1 christos emit_error = 1; 1588 1.1 christos } 1589 1.1 christos 1590 1.1 christos /* The "emit_lsh" emit_ops method for s390. */ 1591 1.1 christos 1592 1.1 christos static void 1593 1.1 christos s390_emit_lsh (void) 1594 1.1 christos { 1595 1.1 christos static const unsigned char buf[] = { 1596 1.1 christos 0x18, 0x43, /* lr %r4, %r3 */ 1597 1.1 christos 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */ 1598 1.1 christos 0x8d, 0x20, 0x40, 0x00, /* sldl %r2, 0(%r4) */ 1599 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1600 1.1 christos }; 1601 1.1 christos add_insns (buf, sizeof buf); 1602 1.1 christos } 1603 1.1 christos 1604 1.1 christos /* The "emit_rsh_signed" emit_ops method for s390. */ 1605 1.1 christos 1606 1.1 christos static void 1607 1.1 christos s390_emit_rsh_signed (void) 1608 1.1 christos { 1609 1.1 christos static const unsigned char buf[] = { 1610 1.1 christos 0x18, 0x43, /* lr %r4, %r3 */ 1611 1.1 christos 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */ 1612 1.1 christos 0x8e, 0x20, 0x40, 0x00, /* srda %r2, 0(%r4) */ 1613 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1614 1.1 christos }; 1615 1.1 christos add_insns (buf, sizeof buf); 1616 1.1 christos } 1617 1.1 christos 1618 1.1 christos /* The "emit_rsh_unsigned" emit_ops method for s390. */ 1619 1.1 christos 1620 1.1 christos static void 1621 1.1 christos s390_emit_rsh_unsigned (void) 1622 1.1 christos { 1623 1.1 christos static const unsigned char buf[] = { 1624 1.1 christos 0x18, 0x43, /* lr %r4, %r3 */ 1625 1.1 christos 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */ 1626 1.1 christos 0x8c, 0x20, 0x40, 0x00, /* srdl %r2, 0(%r4) */ 1627 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1628 1.1 christos }; 1629 1.1 christos add_insns (buf, sizeof buf); 1630 1.1 christos } 1631 1.1 christos 1632 1.1 christos /* The "emit_ext" emit_ops method for s390. */ 1633 1.1 christos 1634 1.1 christos static void 1635 1.1 christos s390_emit_ext (int arg) 1636 1.1 christos { 1637 1.1 christos unsigned char buf[] = { 1638 1.1 christos 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */ 1639 1.1 christos 0x8e, 0x20, 0x00, (unsigned char) (64 - arg), /* srda %r2, <64-arg> */ 1640 1.1 christos }; 1641 1.1 christos add_insns (buf, sizeof buf); 1642 1.1 christos } 1643 1.1 christos 1644 1.1 christos /* The "emit_log_not" emit_ops method for s390. */ 1645 1.1 christos 1646 1.1 christos static void 1647 1.1 christos s390_emit_log_not (void) 1648 1.1 christos { 1649 1.1 christos static const unsigned char buf[] = { 1650 1.1 christos 0x16, 0x23, /* or %r2, %r3 */ 1651 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1652 1.1 christos 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */ 1653 1.1 christos 0xa7, 0x74, 0x00, 0x04, /* jne .Lskip */ 1654 1.1 christos 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */ 1655 1.1 christos /* .Lskip: */ 1656 1.1 christos }; 1657 1.1 christos add_insns (buf, sizeof buf); 1658 1.1 christos } 1659 1.1 christos 1660 1.1 christos /* The "emit_bit_and" emit_ops method for s390. */ 1661 1.1 christos 1662 1.1 christos static void 1663 1.1 christos s390_emit_bit_and (void) 1664 1.1 christos { 1665 1.1 christos static const unsigned char buf[] = { 1666 1.1 christos 0x54, 0x20, 0xf0, 0x00, /* n %r2, 0(%r15) */ 1667 1.1 christos 0x54, 0x30, 0xf0, 0x04, /* n %r3, 4(%r15) */ 1668 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1669 1.1 christos }; 1670 1.1 christos add_insns (buf, sizeof buf); 1671 1.1 christos } 1672 1.1 christos 1673 1.1 christos /* The "emit_bit_or" emit_ops method for s390. */ 1674 1.1 christos 1675 1.1 christos static void 1676 1.1 christos s390_emit_bit_or (void) 1677 1.1 christos { 1678 1.1 christos static const unsigned char buf[] = { 1679 1.1 christos 0x56, 0x20, 0xf0, 0x00, /* o %r2, 0(%r15) */ 1680 1.1 christos 0x56, 0x30, 0xf0, 0x04, /* o %r3, 4(%r15) */ 1681 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1682 1.1 christos }; 1683 1.1 christos add_insns (buf, sizeof buf); 1684 1.1 christos } 1685 1.1 christos 1686 1.1 christos /* The "emit_bit_xor" emit_ops method for s390. */ 1687 1.1 christos 1688 1.1 christos static void 1689 1.1 christos s390_emit_bit_xor (void) 1690 1.1 christos { 1691 1.1 christos static const unsigned char buf[] = { 1692 1.1 christos 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */ 1693 1.1 christos 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */ 1694 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1695 1.1 christos }; 1696 1.1 christos add_insns (buf, sizeof buf); 1697 1.1 christos } 1698 1.1 christos 1699 1.1 christos /* The "emit_bit_not" emit_ops method for s390. */ 1700 1.1 christos 1701 1.1 christos static void 1702 1.1 christos s390_emit_bit_not (void) 1703 1.1 christos { 1704 1.1 christos static const unsigned char buf[] = { 1705 1.1 christos 0xa7, 0x48, 0xff, 0xff, /* lhi %r4, -1 */ 1706 1.1 christos 0x17, 0x24, /* xr %r2, %r4 */ 1707 1.1 christos 0x17, 0x34, /* xr %r3, %r4 */ 1708 1.1 christos }; 1709 1.1 christos add_insns (buf, sizeof buf); 1710 1.1 christos } 1711 1.1 christos 1712 1.1 christos /* The "emit_equal" emit_ops method for s390. */ 1713 1.1 christos 1714 1.1 christos static void 1715 1.1 christos s390_emit_equal (void) 1716 1.1 christos { 1717 1.1 christos s390_emit_bit_xor (); 1718 1.1 christos s390_emit_log_not (); 1719 1.1 christos } 1720 1.1 christos 1721 1.1 christos /* The "emit_less_signed" emit_ops method for s390. */ 1722 1.1 christos 1723 1.1 christos static void 1724 1.1 christos s390_emit_less_signed (void) 1725 1.1 christos { 1726 1.1 christos static const unsigned char buf[] = { 1727 1.1 christos 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */ 1728 1.1 christos 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */ 1729 1.1 christos 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */ 1730 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 1731 1.1 christos 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */ 1732 1.1 christos /* .Lhigh: */ 1733 1.1 christos 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */ 1734 1.1 christos 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */ 1735 1.1 christos /* .Lless: */ 1736 1.1 christos 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */ 1737 1.1 christos /* .Lend: */ 1738 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1739 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1740 1.1 christos }; 1741 1.1 christos add_insns (buf, sizeof buf); 1742 1.1 christos } 1743 1.1 christos 1744 1.1 christos /* The "emit_less_unsigned" emit_ops method for s390. */ 1745 1.1 christos 1746 1.1 christos static void 1747 1.1 christos s390_emit_less_unsigned (void) 1748 1.1 christos { 1749 1.1 christos static const unsigned char buf[] = { 1750 1.1 christos 0x55, 0x20, 0xf0, 0x00, /* cl %r2, 0(%r15) */ 1751 1.1 christos 0xa7, 0x24, 0x00, 0x0c, /* jh .Lless */ 1752 1.1 christos 0xa7, 0x44, 0x00, 0x06, /* jl .Lhigh */ 1753 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 1754 1.1 christos 0xa7, 0x24, 0x00, 0x06, /* jh .Lless */ 1755 1.1 christos /* .Lhigh: */ 1756 1.1 christos 0xa7, 0x38, 0x00, 0x00, /* lhi %r3, 0 */ 1757 1.1 christos 0xa7, 0xf4, 0x00, 0x04, /* j .Lend */ 1758 1.1 christos /* .Lless: */ 1759 1.1 christos 0xa7, 0x38, 0x00, 0x01, /* lhi %r3, 1 */ 1760 1.1 christos /* .Lend: */ 1761 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1762 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1763 1.1 christos }; 1764 1.1 christos add_insns (buf, sizeof buf); 1765 1.1 christos } 1766 1.1 christos 1767 1.1 christos /* The "emit_ref" emit_ops method for s390. */ 1768 1.1 christos 1769 1.1 christos static void 1770 1.1 christos s390_emit_ref (int size) 1771 1.1 christos { 1772 1.1 christos static const unsigned char buf1[] = { 1773 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1774 1.1 christos 0x43, 0x30, 0x30, 0x00, /* ic %r3, 0(%r3) */ 1775 1.1 christos }; 1776 1.1 christos static const unsigned char buf2[] = { 1777 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1778 1.1 christos 0x48, 0x30, 0x30, 0x00, /* lh %r3, 0(%r3) */ 1779 1.1 christos }; 1780 1.1 christos static const unsigned char buf4[] = { 1781 1.1 christos 0xa7, 0x28, 0x00, 0x00, /* lhi %r2, 0 */ 1782 1.1 christos 0x58, 0x30, 0x30, 0x00, /* l %r3, 0(%r3) */ 1783 1.1 christos }; 1784 1.1 christos static const unsigned char buf8[] = { 1785 1.1 christos 0x98, 0x23, 0x30, 0x00, /* lm %r2, %r3, 0(%r3) */ 1786 1.1 christos }; 1787 1.1 christos switch (size) 1788 1.1 christos { 1789 1.1 christos case 1: 1790 1.1 christos add_insns (buf1, sizeof buf1); 1791 1.1 christos break; 1792 1.1 christos case 2: 1793 1.1 christos add_insns (buf2, sizeof buf2); 1794 1.1 christos break; 1795 1.1 christos case 4: 1796 1.1 christos add_insns (buf4, sizeof buf4); 1797 1.1 christos break; 1798 1.1 christos case 8: 1799 1.1 christos add_insns (buf8, sizeof buf8); 1800 1.1 christos break; 1801 1.1 christos default: 1802 1.1 christos emit_error = 1; 1803 1.1 christos } 1804 1.1 christos } 1805 1.1 christos 1806 1.1 christos /* The "emit_if_goto" emit_ops method for s390. */ 1807 1.1 christos 1808 1.1 christos static void 1809 1.1 christos s390_emit_if_goto (int *offset_p, int *size_p) 1810 1.1 christos { 1811 1.1 christos static const unsigned char buf[] = { 1812 1.1 christos 0x16, 0x23, /* or %r2, %r3 */ 1813 1.1 christos 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */ 1814 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1815 1.1 christos 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00 /* jgne <fillme> */ 1816 1.1 christos }; 1817 1.1 christos add_insns (buf, sizeof buf); 1818 1.1 christos if (offset_p) 1819 1.1 christos *offset_p = 12; 1820 1.1 christos if (size_p) 1821 1.1 christos *size_p = 4; 1822 1.1 christos } 1823 1.1 christos 1824 1.1 christos /* The "emit_goto" emit_ops method for s390 and s390x. */ 1825 1.1 christos 1826 1.1 christos static void 1827 1.1 christos s390_emit_goto (int *offset_p, int *size_p) 1828 1.1 christos { 1829 1.1 christos static const unsigned char buf[] = { 1830 1.1 christos 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */ 1831 1.1 christos }; 1832 1.1 christos add_insns (buf, sizeof buf); 1833 1.1 christos if (offset_p) 1834 1.1 christos *offset_p = 2; 1835 1.1 christos if (size_p) 1836 1.1 christos *size_p = 4; 1837 1.1 christos } 1838 1.1 christos 1839 1.1 christos /* The "write_goto_address" emit_ops method for s390 and s390x. */ 1840 1.1 christos 1841 1.1 christos static void 1842 1.1 christos s390_write_goto_address (CORE_ADDR from, CORE_ADDR to, int size) 1843 1.1 christos { 1844 1.1 christos long diff = ((long) (to - (from - 2))) / 2; 1845 1.1 christos int sdiff = diff; 1846 1.1 christos unsigned char buf[sizeof sdiff]; 1847 1.1 christos 1848 1.1 christos /* We're only doing 4-byte sizes at the moment. */ 1849 1.1 christos if (size != sizeof sdiff || sdiff != diff) 1850 1.1 christos { 1851 1.1 christos emit_error = 1; 1852 1.1 christos return; 1853 1.1 christos } 1854 1.1 christos 1855 1.1 christos memcpy (buf, &sdiff, sizeof sdiff); 1856 1.1 christos target_write_memory (from, buf, sizeof sdiff); 1857 1.1 christos } 1858 1.1 christos 1859 1.1 christos /* Preparation for emitting a literal pool of given size. Loads the address 1860 1.1 christos of the pool into %r1, and jumps over it. Called should emit the pool data 1861 1.1 christos immediately afterwards. Used for both s390 and s390x. */ 1862 1.1 christos 1863 1.1 christos static void 1864 1.1 christos s390_emit_litpool (int size) 1865 1.1 christos { 1866 1.1 christos static const unsigned char nop[] = { 1867 1.1 christos 0x07, 0x07, 1868 1.1 christos }; 1869 1.1 christos unsigned char buf[] = { 1870 1.1 christos 0xa7, 0x15, 0x00, 1871 1.1 christos (unsigned char) ((size + 4) / 2), /* bras %r1, .Lend+size */ 1872 1.1 christos /* .Lend: */ 1873 1.1 christos }; 1874 1.1 christos if (size == 4) 1875 1.1 christos { 1876 1.1 christos /* buf needs to start at even halfword for litpool to be aligned */ 1877 1.1 christos if (current_insn_ptr & 2) 1878 1.1 christos add_insns (nop, sizeof nop); 1879 1.1 christos } 1880 1.1 christos else 1881 1.1 christos { 1882 1.1 christos while ((current_insn_ptr & 6) != 4) 1883 1.1 christos add_insns (nop, sizeof nop); 1884 1.1 christos } 1885 1.1 christos add_insns (buf, sizeof buf); 1886 1.1 christos } 1887 1.1 christos 1888 1.1 christos /* The "emit_const" emit_ops method for s390. */ 1889 1.1 christos 1890 1.1 christos static void 1891 1.1 christos s390_emit_const (LONGEST num) 1892 1.1 christos { 1893 1.1 christos unsigned long long n = num; 1894 1.1 christos unsigned char buf_s[] = { 1895 1.1 christos /* lhi %r3, <num> */ 1896 1.1 christos 0xa7, 0x38, 1897 1.1 christos (unsigned char) (num >> 8), (unsigned char) num, 1898 1.1 christos /* xr %r2, %r2 */ 1899 1.1 christos 0x17, 0x22, 1900 1.1 christos }; 1901 1.1 christos static const unsigned char buf_l[] = { 1902 1.1 christos 0x98, 0x23, 0x10, 0x00, /* lm %r2, %r3, 0(%r1) */ 1903 1.1 christos }; 1904 1.1 christos if (num < 0x8000 && num >= 0) 1905 1.1 christos add_insns (buf_s, sizeof buf_s); 1906 1.1 christos else 1907 1.1.1.2 christos { 1908 1.1.1.2 christos s390_emit_litpool (8); 1909 1.1.1.2 christos add_insns ((unsigned char *) &n, sizeof n); 1910 1.1.1.2 christos add_insns (buf_l, sizeof buf_l); 1911 1.1.1.2 christos } 1912 1.1 christos } 1913 1.1 christos 1914 1.1 christos /* The "emit_call" emit_ops method for s390. */ 1915 1.1 christos 1916 1.1 christos static void 1917 1.1 christos s390_emit_call (CORE_ADDR fn) 1918 1.1 christos { 1919 1.1 christos unsigned int n = fn; 1920 1.1 christos static const unsigned char buf[] = { 1921 1.1 christos 0x58, 0x10, 0x10, 0x00, /* l %r1, 0(%r1) */ 1922 1.1 christos 0xa7, 0xfa, 0xff, 0xa0, /* ahi %r15, -0x60 */ 1923 1.1 christos 0x0d, 0xe1, /* basr %r14, %r1 */ 1924 1.1 christos 0xa7, 0xfa, 0x00, 0x60, /* ahi %r15, 0x60 */ 1925 1.1 christos }; 1926 1.1 christos s390_emit_litpool (4); 1927 1.1 christos add_insns ((unsigned char *) &n, sizeof n); 1928 1.1 christos add_insns (buf, sizeof buf); 1929 1.1 christos } 1930 1.1 christos 1931 1.1 christos /* The "emit_reg" emit_ops method for s390. */ 1932 1.1 christos 1933 1.1 christos static void 1934 1.1 christos s390_emit_reg (int reg) 1935 1.1 christos { 1936 1.1 christos unsigned char bufpre[] = { 1937 1.1 christos /* lr %r2, %r9 */ 1938 1.1 christos 0x18, 0x29, 1939 1.1 christos /* lhi %r3, <reg> */ 1940 1.1 christos 0xa7, 0x38, (unsigned char) (reg >> 8), (unsigned char) reg, 1941 1.1 christos }; 1942 1.1 christos add_insns (bufpre, sizeof bufpre); 1943 1.1 christos s390_emit_call (get_raw_reg_func_addr ()); 1944 1.1 christos } 1945 1.1 christos 1946 1.1 christos /* The "emit_pop" emit_ops method for s390. */ 1947 1.1 christos 1948 1.1 christos static void 1949 1.1 christos s390_emit_pop (void) 1950 1.1 christos { 1951 1.1 christos static const unsigned char buf[] = { 1952 1.1 christos 0x98, 0x23, 0xf0, 0x00, /* lm %r2, %r3, 0(%r15) */ 1953 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 1954 1.1 christos }; 1955 1.1 christos add_insns (buf, sizeof buf); 1956 1.1 christos } 1957 1.1 christos 1958 1.1 christos /* The "emit_stack_flush" emit_ops method for s390. */ 1959 1.1 christos 1960 1.1 christos static void 1961 1.1 christos s390_emit_stack_flush (void) 1962 1.1 christos { 1963 1.1 christos static const unsigned char buf[] = { 1964 1.1 christos 0xa7, 0xfa, 0xff, 0xf8, /* ahi %r15, -8 */ 1965 1.1 christos 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */ 1966 1.1 christos }; 1967 1.1 christos add_insns (buf, sizeof buf); 1968 1.1 christos } 1969 1.1 christos 1970 1.1 christos /* The "emit_zero_ext" emit_ops method for s390. */ 1971 1.1 christos 1972 1.1 christos static void 1973 1.1 christos s390_emit_zero_ext (int arg) 1974 1.1 christos { 1975 1.1 christos unsigned char buf[] = { 1976 1.1 christos 0x8d, 0x20, 0x00, (unsigned char) (64 - arg), /* sldl %r2, <64-arg> */ 1977 1.1 christos 0x8c, 0x20, 0x00, (unsigned char) (64 - arg), /* srdl %r2, <64-arg> */ 1978 1.1 christos }; 1979 1.1 christos add_insns (buf, sizeof buf); 1980 1.1 christos } 1981 1.1 christos 1982 1.1 christos /* The "emit_swap" emit_ops method for s390. */ 1983 1.1 christos 1984 1.1 christos static void 1985 1.1 christos s390_emit_swap (void) 1986 1.1 christos { 1987 1.1 christos static const unsigned char buf[] = { 1988 1.1 christos 0x98, 0x45, 0xf0, 0x00, /* lm %r4, %r5, 0(%r15) */ 1989 1.1 christos 0x90, 0x23, 0xf0, 0x00, /* stm %r2, %r3, 0(%r15) */ 1990 1.1 christos 0x18, 0x24, /* lr %r2, %r4 */ 1991 1.1 christos 0x18, 0x35, /* lr %r3, %r5 */ 1992 1.1 christos }; 1993 1.1 christos add_insns (buf, sizeof buf); 1994 1.1 christos } 1995 1.1 christos 1996 1.1 christos /* The "emit_stack_adjust" emit_ops method for s390. */ 1997 1.1 christos 1998 1.1 christos static void 1999 1.1 christos s390_emit_stack_adjust (int n) 2000 1.1 christos { 2001 1.1 christos unsigned char buf[] = { 2002 1.1 christos /* ahi %r15, 8*n */ 2003 1.1 christos 0xa7, 0xfa, 2004 1.1 christos (unsigned char ) (n * 8 >> 8), (unsigned char) (n * 8), 2005 1.1 christos }; 2006 1.1 christos add_insns (buf, sizeof buf); 2007 1.1 christos } 2008 1.1 christos 2009 1.1 christos /* Sets %r2 to a 32-bit constant. */ 2010 1.1 christos 2011 1.1 christos static void 2012 1.1 christos s390_emit_set_r2 (int arg1) 2013 1.1 christos { 2014 1.1 christos unsigned char buf_s[] = { 2015 1.1 christos /* lhi %r2, <arg1> */ 2016 1.1 christos 0xa7, 0x28, (unsigned char) (arg1 >> 8), (unsigned char) arg1, 2017 1.1 christos }; 2018 1.1 christos static const unsigned char buf_l[] = { 2019 1.1 christos 0x58, 0x20, 0x10, 0x00, /* l %r2, 0(%r1) */ 2020 1.1 christos }; 2021 1.1 christos if (arg1 < 0x8000 && arg1 >= -0x8000) 2022 1.1 christos add_insns (buf_s, sizeof buf_s); 2023 1.1 christos else 2024 1.1.1.2 christos { 2025 1.1.1.2 christos s390_emit_litpool (4); 2026 1.1.1.2 christos add_insns ((unsigned char *) &arg1, sizeof arg1); 2027 1.1.1.2 christos add_insns (buf_l, sizeof buf_l); 2028 1.1.1.2 christos } 2029 1.1 christos } 2030 1.1 christos 2031 1.1 christos /* The "emit_int_call_1" emit_ops method for s390. */ 2032 1.1 christos 2033 1.1 christos static void 2034 1.1 christos s390_emit_int_call_1 (CORE_ADDR fn, int arg1) 2035 1.1 christos { 2036 1.1 christos /* FN's prototype is `LONGEST(*fn)(int)'. */ 2037 1.1 christos s390_emit_set_r2 (arg1); 2038 1.1 christos s390_emit_call (fn); 2039 1.1 christos } 2040 1.1 christos 2041 1.1 christos /* The "emit_void_call_2" emit_ops method for s390. */ 2042 1.1 christos 2043 1.1 christos static void 2044 1.1 christos s390_emit_void_call_2 (CORE_ADDR fn, int arg1) 2045 1.1 christos { 2046 1.1 christos /* FN's prototype is `void(*fn)(int,LONGEST)'. */ 2047 1.1 christos static const unsigned char buf[] = { 2048 1.1 christos 0x18, 0xc2, /* lr %r12, %r2 */ 2049 1.1 christos 0x18, 0xd3, /* lr %r13, %r3 */ 2050 1.1 christos 0x18, 0x43, /* lr %r4, %r3 */ 2051 1.1 christos 0x18, 0x32, /* lr %r3, %r2 */ 2052 1.1 christos }; 2053 1.1 christos static const unsigned char buf2[] = { 2054 1.1 christos 0x18, 0x2c, /* lr %r2, %r12 */ 2055 1.1 christos 0x18, 0x3d, /* lr %r3, %r13 */ 2056 1.1 christos }; 2057 1.1 christos add_insns (buf, sizeof buf); 2058 1.1 christos s390_emit_set_r2 (arg1); 2059 1.1 christos s390_emit_call (fn); 2060 1.1 christos add_insns (buf2, sizeof buf2); 2061 1.1 christos } 2062 1.1 christos 2063 1.1 christos /* The "emit_eq_goto" emit_ops method for s390. */ 2064 1.1 christos 2065 1.1 christos static void 2066 1.1 christos s390_emit_eq_goto (int *offset_p, int *size_p) 2067 1.1 christos { 2068 1.1 christos static const unsigned char buf[] = { 2069 1.1 christos 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */ 2070 1.1 christos 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */ 2071 1.1 christos 0x16, 0x23, /* or %r2, %r3 */ 2072 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2073 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2074 1.1 christos 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */ 2075 1.1 christos }; 2076 1.1 christos add_insns (buf, sizeof buf); 2077 1.1 christos if (offset_p) 2078 1.1 christos *offset_p = 20; 2079 1.1 christos if (size_p) 2080 1.1 christos *size_p = 4; 2081 1.1 christos } 2082 1.1 christos 2083 1.1 christos /* The "emit_ne_goto" emit_ops method for s390. */ 2084 1.1 christos 2085 1.1 christos static void 2086 1.1 christos s390_emit_ne_goto (int *offset_p, int *size_p) 2087 1.1 christos { 2088 1.1 christos static const unsigned char buf[] = { 2089 1.1 christos 0x57, 0x20, 0xf0, 0x00, /* x %r2, 0(%r15) */ 2090 1.1 christos 0x57, 0x30, 0xf0, 0x04, /* x %r3, 4(%r15) */ 2091 1.1 christos 0x16, 0x23, /* or %r2, %r3 */ 2092 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2093 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2094 1.1 christos 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */ 2095 1.1 christos }; 2096 1.1 christos add_insns (buf, sizeof buf); 2097 1.1 christos if (offset_p) 2098 1.1 christos *offset_p = 20; 2099 1.1 christos if (size_p) 2100 1.1 christos *size_p = 4; 2101 1.1 christos } 2102 1.1 christos 2103 1.1 christos /* The "emit_lt_goto" emit_ops method for s390. */ 2104 1.1 christos 2105 1.1 christos static void 2106 1.1 christos s390_emit_lt_goto (int *offset_p, int *size_p) 2107 1.1 christos { 2108 1.1 christos static const unsigned char buf[] = { 2109 1.1 christos 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */ 2110 1.1 christos 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */ 2111 1.1 christos 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */ 2112 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 2113 1.1 christos 0xa7, 0x24, 0x00, 0x08, /* jh .Ltrue */ 2114 1.1 christos /* .Lfalse: */ 2115 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2116 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2117 1.1 christos 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */ 2118 1.1 christos /* .Ltrue: */ 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 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */ 2122 1.1 christos /* .Lend: */ 2123 1.1 christos }; 2124 1.1 christos add_insns (buf, sizeof buf); 2125 1.1 christos if (offset_p) 2126 1.1 christos *offset_p = 42; 2127 1.1 christos if (size_p) 2128 1.1 christos *size_p = 4; 2129 1.1 christos } 2130 1.1 christos 2131 1.1 christos /* The "emit_le_goto" emit_ops method for s390. */ 2132 1.1 christos 2133 1.1 christos static void 2134 1.1 christos s390_emit_le_goto (int *offset_p, int *size_p) 2135 1.1 christos { 2136 1.1 christos static const unsigned char buf[] = { 2137 1.1 christos 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */ 2138 1.1 christos 0xa7, 0x24, 0x00, 0x0e, /* jh .Ltrue */ 2139 1.1 christos 0xa7, 0x44, 0x00, 0x06, /* jl .Lfalse */ 2140 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 2141 1.1 christos 0xa7, 0xa4, 0x00, 0x08, /* jhe .Ltrue */ 2142 1.1 christos /* .Lfalse: */ 2143 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2144 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2145 1.1 christos 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */ 2146 1.1 christos /* .Ltrue: */ 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 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */ 2150 1.1 christos /* .Lend: */ 2151 1.1 christos }; 2152 1.1 christos add_insns (buf, sizeof buf); 2153 1.1 christos if (offset_p) 2154 1.1 christos *offset_p = 42; 2155 1.1 christos if (size_p) 2156 1.1 christos *size_p = 4; 2157 1.1 christos } 2158 1.1 christos 2159 1.1 christos /* The "emit_gt_goto" emit_ops method for s390. */ 2160 1.1 christos 2161 1.1 christos static void 2162 1.1 christos s390_emit_gt_goto (int *offset_p, int *size_p) 2163 1.1 christos { 2164 1.1 christos static const unsigned char buf[] = { 2165 1.1 christos 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */ 2166 1.1 christos 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */ 2167 1.1 christos 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */ 2168 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 2169 1.1 christos 0xa7, 0x44, 0x00, 0x08, /* jl .Ltrue */ 2170 1.1 christos /* .Lfalse: */ 2171 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2172 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2173 1.1 christos 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */ 2174 1.1 christos /* .Ltrue: */ 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 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */ 2178 1.1 christos /* .Lend: */ 2179 1.1 christos }; 2180 1.1 christos add_insns (buf, sizeof buf); 2181 1.1 christos if (offset_p) 2182 1.1 christos *offset_p = 42; 2183 1.1 christos if (size_p) 2184 1.1 christos *size_p = 4; 2185 1.1 christos } 2186 1.1 christos 2187 1.1 christos /* The "emit_ge_goto" emit_ops method for s390. */ 2188 1.1 christos 2189 1.1 christos static void 2190 1.1 christos s390_emit_ge_goto (int *offset_p, int *size_p) 2191 1.1 christos { 2192 1.1 christos static const unsigned char buf[] = { 2193 1.1 christos 0x59, 0x20, 0xf0, 0x00, /* c %r2, 0(%r15) */ 2194 1.1 christos 0xa7, 0x44, 0x00, 0x0e, /* jl .Ltrue */ 2195 1.1 christos 0xa7, 0x24, 0x00, 0x06, /* jh .Lfalse */ 2196 1.1 christos 0x55, 0x30, 0xf0, 0x04, /* cl %r3, 4(%r15) */ 2197 1.1 christos 0xa7, 0xc4, 0x00, 0x08, /* jle .Ltrue */ 2198 1.1 christos /* .Lfalse: */ 2199 1.1 christos 0x98, 0x23, 0xf0, 0x08, /* lm %r2, %r3, 8(%r15) */ 2200 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2201 1.1 christos 0xa7, 0xf4, 0x00, 0x09, /* j .Lend */ 2202 1.1 christos /* .Ltrue: */ 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 0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, /* jg <fillme> */ 2206 1.1 christos /* .Lend: */ 2207 1.1 christos }; 2208 1.1 christos add_insns (buf, sizeof buf); 2209 1.1 christos if (offset_p) 2210 1.1 christos *offset_p = 42; 2211 1.1 christos if (size_p) 2212 1.1 christos *size_p = 4; 2213 1.1 christos } 2214 1.1 christos 2215 1.1 christos /* The "emit_ops" structure for s390. Named _impl to avoid name 2216 1.1 christos collision with s390_emit_ops function. */ 2217 1.1 christos 2218 1.1 christos static struct emit_ops s390_emit_ops_impl = 2219 1.1 christos { 2220 1.1 christos s390_emit_prologue, 2221 1.1 christos s390_emit_epilogue, 2222 1.1 christos s390_emit_add, 2223 1.1 christos s390_emit_sub, 2224 1.1 christos s390_emit_mul, 2225 1.1 christos s390_emit_lsh, 2226 1.1 christos s390_emit_rsh_signed, 2227 1.1 christos s390_emit_rsh_unsigned, 2228 1.1 christos s390_emit_ext, 2229 1.1 christos s390_emit_log_not, 2230 1.1 christos s390_emit_bit_and, 2231 1.1 christos s390_emit_bit_or, 2232 1.1 christos s390_emit_bit_xor, 2233 1.1 christos s390_emit_bit_not, 2234 1.1 christos s390_emit_equal, 2235 1.1 christos s390_emit_less_signed, 2236 1.1 christos s390_emit_less_unsigned, 2237 1.1 christos s390_emit_ref, 2238 1.1 christos s390_emit_if_goto, 2239 1.1 christos s390_emit_goto, 2240 1.1 christos s390_write_goto_address, 2241 1.1 christos s390_emit_const, 2242 1.1 christos s390_emit_call, 2243 1.1 christos s390_emit_reg, 2244 1.1 christos s390_emit_pop, 2245 1.1 christos s390_emit_stack_flush, 2246 1.1 christos s390_emit_zero_ext, 2247 1.1 christos s390_emit_swap, 2248 1.1 christos s390_emit_stack_adjust, 2249 1.1 christos s390_emit_int_call_1, 2250 1.1 christos s390_emit_void_call_2, 2251 1.1 christos s390_emit_eq_goto, 2252 1.1 christos s390_emit_ne_goto, 2253 1.1 christos s390_emit_lt_goto, 2254 1.1 christos s390_emit_le_goto, 2255 1.1 christos s390_emit_gt_goto, 2256 1.1 christos s390_emit_ge_goto 2257 1.1 christos }; 2258 1.1 christos 2259 1.1 christos #ifdef __s390x__ 2260 1.1 christos 2261 1.1 christos /* The "emit_prologue" emit_ops method for s390x. */ 2262 1.1 christos 2263 1.1 christos static void 2264 1.1 christos s390x_emit_prologue (void) 2265 1.1 christos { 2266 1.1 christos static const unsigned char buf[] = { 2267 1.1 christos 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x24, /* stmg %r9, %r15, 0x48(%r15) */ 2268 1.1 christos 0xb9, 0x04, 0x00, 0x92, /* lgr %r9, %r2 */ 2269 1.1 christos 0xb9, 0x04, 0x00, 0xa3, /* lgr %r10, %r3 */ 2270 1.1 christos 0xb9, 0x04, 0x00, 0xbf, /* lgr %r11, %r15 */ 2271 1.1 christos }; 2272 1.1 christos add_insns (buf, sizeof buf); 2273 1.1 christos } 2274 1.1 christos 2275 1.1 christos /* The "emit_epilogue" emit_ops method for s390x. */ 2276 1.1 christos 2277 1.1 christos static void 2278 1.1 christos s390x_emit_epilogue (void) 2279 1.1 christos { 2280 1.1 christos static const unsigned char buf[] = { 2281 1.1 christos 0xe3, 0x20, 0xa0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r10) */ 2282 1.1 christos 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */ 2283 1.1 christos 0xeb, 0x9f, 0xf0, 0x48, 0x00, 0x04, /* lmg %r9, %r15, 0x48(%r15) */ 2284 1.1 christos 0x07, 0xfe, /* br %r14 */ 2285 1.1 christos }; 2286 1.1 christos add_insns (buf, sizeof buf); 2287 1.1 christos } 2288 1.1 christos 2289 1.1 christos /* The "emit_add" emit_ops method for s390x. */ 2290 1.1 christos 2291 1.1 christos static void 2292 1.1 christos s390x_emit_add (void) 2293 1.1 christos { 2294 1.1 christos static const unsigned char buf[] = { 2295 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x0a, /* alg %r2, 0(%r15) */ 2296 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2297 1.1 christos }; 2298 1.1 christos add_insns (buf, sizeof buf); 2299 1.1 christos } 2300 1.1 christos 2301 1.1 christos /* The "emit_sub" emit_ops method for s390x. */ 2302 1.1 christos 2303 1.1 christos static void 2304 1.1 christos s390x_emit_sub (void) 2305 1.1 christos { 2306 1.1 christos static const unsigned char buf[] = { 2307 1.1 christos 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */ 2308 1.1 christos 0xb9, 0x0b, 0x00, 0x32, /* slgr %r3, %r2 */ 2309 1.1 christos 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */ 2310 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2311 1.1 christos }; 2312 1.1 christos add_insns (buf, sizeof buf); 2313 1.1 christos } 2314 1.1 christos 2315 1.1 christos /* The "emit_mul" emit_ops method for s390x. */ 2316 1.1 christos 2317 1.1 christos static void 2318 1.1 christos s390x_emit_mul (void) 2319 1.1 christos { 2320 1.1 christos emit_error = 1; 2321 1.1 christos } 2322 1.1 christos 2323 1.1 christos /* The "emit_lsh" emit_ops method for s390x. */ 2324 1.1 christos 2325 1.1 christos static void 2326 1.1 christos s390x_emit_lsh (void) 2327 1.1 christos { 2328 1.1 christos static const unsigned char buf[] = { 2329 1.1 christos 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */ 2330 1.1 christos 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0d, /* sllg %r2, %r3, 0(%r2) */ 2331 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2332 1.1 christos }; 2333 1.1 christos add_insns (buf, sizeof buf); 2334 1.1 christos } 2335 1.1 christos 2336 1.1 christos /* The "emit_rsh_signed" emit_ops method for s390x. */ 2337 1.1 christos 2338 1.1 christos static void 2339 1.1 christos s390x_emit_rsh_signed (void) 2340 1.1 christos { 2341 1.1 christos static const unsigned char buf[] = { 2342 1.1 christos 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */ 2343 1.1 christos 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0a, /* srag %r2, %r3, 0(%r2) */ 2344 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2345 1.1 christos }; 2346 1.1 christos add_insns (buf, sizeof buf); 2347 1.1 christos } 2348 1.1 christos 2349 1.1 christos /* The "emit_rsh_unsigned" emit_ops method for s390x. */ 2350 1.1 christos 2351 1.1 christos static void 2352 1.1 christos s390x_emit_rsh_unsigned (void) 2353 1.1 christos { 2354 1.1 christos static const unsigned char buf[] = { 2355 1.1 christos 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */ 2356 1.1 christos 0xeb, 0x23, 0x20, 0x00, 0x00, 0x0c, /* srlg %r2, %r3, 0(%r2) */ 2357 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2358 1.1 christos }; 2359 1.1 christos add_insns (buf, sizeof buf); 2360 1.1 christos } 2361 1.1 christos 2362 1.1 christos /* The "emit_ext" emit_ops method for s390x. */ 2363 1.1 christos 2364 1.1 christos static void 2365 1.1 christos s390x_emit_ext (int arg) 2366 1.1 christos { 2367 1.1 christos unsigned char buf[] = { 2368 1.1 christos /* sllg %r2, %r2, <64-arg> */ 2369 1.1 christos 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d, 2370 1.1 christos /* srag %r2, %r2, <64-arg> */ 2371 1.1 christos 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0a, 2372 1.1 christos }; 2373 1.1 christos add_insns (buf, sizeof buf); 2374 1.1 christos } 2375 1.1 christos 2376 1.1 christos /* The "emit_log_not" emit_ops method for s390x. */ 2377 1.1 christos 2378 1.1 christos static void 2379 1.1 christos s390x_emit_log_not (void) 2380 1.1 christos { 2381 1.1 christos static const unsigned char buf[] = { 2382 1.1 christos 0xb9, 0x00, 0x00, 0x22, /* lpgr %r2, %r2 */ 2383 1.1 christos 0xa7, 0x2b, 0xff, 0xff, /* aghi %r2, -1 */ 2384 1.1 christos 0xeb, 0x22, 0x00, 0x3f, 0x00, 0x0c, /* srlg %r2, %r2, 63 */ 2385 1.1 christos }; 2386 1.1 christos add_insns (buf, sizeof buf); 2387 1.1 christos } 2388 1.1 christos 2389 1.1 christos /* The "emit_bit_and" emit_ops method for s390x. */ 2390 1.1 christos 2391 1.1 christos static void 2392 1.1 christos s390x_emit_bit_and (void) 2393 1.1 christos { 2394 1.1 christos static const unsigned char buf[] = { 2395 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x80, /* ng %r2, 0(%r15) */ 2396 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2397 1.1 christos }; 2398 1.1 christos add_insns (buf, sizeof buf); 2399 1.1 christos } 2400 1.1 christos 2401 1.1 christos /* The "emit_bit_or" emit_ops method for s390x. */ 2402 1.1 christos 2403 1.1 christos static void 2404 1.1 christos s390x_emit_bit_or (void) 2405 1.1 christos { 2406 1.1 christos static const unsigned char buf[] = { 2407 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x81, /* og %r2, 0(%r15) */ 2408 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2409 1.1 christos }; 2410 1.1 christos add_insns (buf, sizeof buf); 2411 1.1 christos } 2412 1.1 christos 2413 1.1 christos /* The "emit_bit_xor" emit_ops method for s390x. */ 2414 1.1 christos 2415 1.1 christos static void 2416 1.1 christos s390x_emit_bit_xor (void) 2417 1.1 christos { 2418 1.1 christos static const unsigned char buf[] = { 2419 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x82, /* xg %r2, 0(%r15) */ 2420 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2421 1.1 christos }; 2422 1.1 christos add_insns (buf, sizeof buf); 2423 1.1 christos } 2424 1.1 christos 2425 1.1 christos /* The "emit_bit_not" emit_ops method for s390x. */ 2426 1.1 christos 2427 1.1 christos static void 2428 1.1 christos s390x_emit_bit_not (void) 2429 1.1 christos { 2430 1.1 christos static const unsigned char buf[] = { 2431 1.1 christos 0xa7, 0x39, 0xff, 0xff, /* lghi %r3, -1 */ 2432 1.1 christos 0xb9, 0x82, 0x00, 0x23, /* xgr %r2, %r3 */ 2433 1.1 christos }; 2434 1.1 christos add_insns (buf, sizeof buf); 2435 1.1 christos } 2436 1.1 christos 2437 1.1 christos /* The "emit_equal" emit_ops method for s390x. */ 2438 1.1 christos 2439 1.1 christos static void 2440 1.1 christos s390x_emit_equal (void) 2441 1.1 christos { 2442 1.1 christos s390x_emit_bit_xor (); 2443 1.1 christos s390x_emit_log_not (); 2444 1.1 christos } 2445 1.1 christos 2446 1.1 christos /* The "emit_less_signed" emit_ops method for s390x. */ 2447 1.1 christos 2448 1.1 christos static void 2449 1.1 christos s390x_emit_less_signed (void) 2450 1.1 christos { 2451 1.1 christos static const unsigned char buf[] = { 2452 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2453 1.1 christos 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */ 2454 1.1 christos 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */ 2455 1.1 christos 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */ 2456 1.1 christos /* .Lend: */ 2457 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2458 1.1 christos }; 2459 1.1 christos add_insns (buf, sizeof buf); 2460 1.1 christos } 2461 1.1 christos 2462 1.1 christos /* The "emit_less_unsigned" emit_ops method for s390x. */ 2463 1.1 christos 2464 1.1 christos static void 2465 1.1 christos s390x_emit_less_unsigned (void) 2466 1.1 christos { 2467 1.1 christos static const unsigned char buf[] = { 2468 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x21, /* clg %r2, 0(%r15) */ 2469 1.1 christos 0xa7, 0x29, 0x00, 0x01, /* lghi %r2, 1 */ 2470 1.1 christos 0xa7, 0x24, 0x00, 0x04, /* jh .Lend */ 2471 1.1 christos 0xa7, 0x29, 0x00, 0x00, /* lghi %r2, 0 */ 2472 1.1 christos /* .Lend: */ 2473 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2474 1.1 christos }; 2475 1.1 christos add_insns (buf, sizeof buf); 2476 1.1 christos } 2477 1.1 christos 2478 1.1 christos /* The "emit_ref" emit_ops method for s390x. */ 2479 1.1 christos 2480 1.1 christos static void 2481 1.1 christos s390x_emit_ref (int size) 2482 1.1 christos { 2483 1.1 christos static const unsigned char buf1[] = { 2484 1.1 christos 0xe3, 0x20, 0x20, 0x00, 0x00, 0x90, /* llgc %r2, 0(%r2) */ 2485 1.1 christos }; 2486 1.1 christos static const unsigned char buf2[] = { 2487 1.1 christos 0xe3, 0x20, 0x20, 0x00, 0x00, 0x91 /* llgh %r2, 0(%r2) */ 2488 1.1 christos }; 2489 1.1 christos static const unsigned char buf4[] = { 2490 1.1 christos 0xe3, 0x20, 0x20, 0x00, 0x00, 0x16, /* llgf %r2, 0(%r2) */ 2491 1.1 christos }; 2492 1.1 christos static const unsigned char buf8[] = { 2493 1.1 christos 0xe3, 0x20, 0x20, 0x00, 0x00, 0x04, /* lg %r2, 0(%r2) */ 2494 1.1 christos }; 2495 1.1 christos switch (size) 2496 1.1 christos { 2497 1.1 christos case 1: 2498 1.1 christos add_insns (buf1, sizeof buf1); 2499 1.1 christos break; 2500 1.1 christos case 2: 2501 1.1 christos add_insns (buf2, sizeof buf2); 2502 1.1 christos break; 2503 1.1 christos case 4: 2504 1.1 christos add_insns (buf4, sizeof buf4); 2505 1.1 christos break; 2506 1.1 christos case 8: 2507 1.1 christos add_insns (buf8, sizeof buf8); 2508 1.1 christos break; 2509 1.1 christos default: 2510 1.1 christos emit_error = 1; 2511 1.1 christos } 2512 1.1 christos } 2513 1.1 christos 2514 1.1 christos /* The "emit_if_goto" emit_ops method for s390x. */ 2515 1.1 christos 2516 1.1 christos static void 2517 1.1 christos s390x_emit_if_goto (int *offset_p, int *size_p) 2518 1.1 christos { 2519 1.1 christos static const unsigned char buf[] = { 2520 1.1 christos 0xb9, 0x02, 0x00, 0x22, /* ltgr %r2, %r2 */ 2521 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */ 2522 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2523 1.1 christos 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */ 2524 1.1 christos }; 2525 1.1 christos add_insns (buf, sizeof buf); 2526 1.1 christos if (offset_p) 2527 1.1 christos *offset_p = 16; 2528 1.1 christos if (size_p) 2529 1.1 christos *size_p = 4; 2530 1.1 christos } 2531 1.1 christos 2532 1.1 christos /* The "emit_const" emit_ops method for s390x. */ 2533 1.1 christos 2534 1.1 christos static void 2535 1.1 christos s390x_emit_const (LONGEST num) 2536 1.1 christos { 2537 1.1 christos unsigned long long n = num; 2538 1.1 christos unsigned char buf_s[] = { 2539 1.1 christos /* lghi %r2, <num> */ 2540 1.1 christos 0xa7, 0x29, (unsigned char) (num >> 8), (unsigned char) num, 2541 1.1 christos }; 2542 1.1 christos static const unsigned char buf_l[] = { 2543 1.1 christos 0xe3, 0x20, 0x10, 0x00, 0x00, 0x04, /* lg %r2, 0(%r1) */ 2544 1.1 christos }; 2545 1.1 christos if (num < 0x8000 && num >= -0x8000) 2546 1.1 christos add_insns (buf_s, sizeof buf_s); 2547 1.1 christos else 2548 1.1.1.2 christos { 2549 1.1.1.2 christos s390_emit_litpool (8); 2550 1.1.1.2 christos add_insns ((unsigned char *) &n, sizeof n); 2551 1.1.1.2 christos add_insns (buf_l, sizeof buf_l); 2552 1.1.1.2 christos } 2553 1.1 christos } 2554 1.1 christos 2555 1.1 christos /* The "emit_call" emit_ops method for s390x. */ 2556 1.1 christos 2557 1.1 christos static void 2558 1.1 christos s390x_emit_call (CORE_ADDR fn) 2559 1.1 christos { 2560 1.1 christos unsigned long n = fn; 2561 1.1 christos static const unsigned char buf[] = { 2562 1.1 christos 0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, /* lg %r1, 0(%r1) */ 2563 1.1 christos 0xa7, 0xfb, 0xff, 0x60, /* aghi %r15, -0xa0 */ 2564 1.1 christos 0x0d, 0xe1, /* basr %r14, %r1 */ 2565 1.1 christos 0xa7, 0xfb, 0x00, 0xa0, /* aghi %r15, 0xa0 */ 2566 1.1 christos }; 2567 1.1 christos s390_emit_litpool (8); 2568 1.1 christos add_insns ((unsigned char *) &n, sizeof n); 2569 1.1 christos add_insns (buf, sizeof buf); 2570 1.1 christos } 2571 1.1 christos 2572 1.1 christos /* The "emit_reg" emit_ops method for s390x. */ 2573 1.1 christos 2574 1.1 christos static void 2575 1.1 christos s390x_emit_reg (int reg) 2576 1.1 christos { 2577 1.1 christos unsigned char buf[] = { 2578 1.1 christos /* lgr %r2, %r9 */ 2579 1.1 christos 0xb9, 0x04, 0x00, 0x29, 2580 1.1 christos /* lghi %r3, <reg> */ 2581 1.1 christos 0xa7, 0x39, (unsigned char) (reg >> 8), (unsigned char) reg, 2582 1.1 christos }; 2583 1.1 christos add_insns (buf, sizeof buf); 2584 1.1 christos s390x_emit_call (get_raw_reg_func_addr ()); 2585 1.1 christos } 2586 1.1 christos 2587 1.1 christos /* The "emit_pop" emit_ops method for s390x. */ 2588 1.1 christos 2589 1.1 christos static void 2590 1.1 christos s390x_emit_pop (void) 2591 1.1 christos { 2592 1.1 christos static const unsigned char buf[] = { 2593 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x04, /* lg %r2, 0(%r15) */ 2594 1.1 christos 0x41, 0xf0, 0xf0, 0x08, /* la %r15, 8(%r15) */ 2595 1.1 christos }; 2596 1.1 christos add_insns (buf, sizeof buf); 2597 1.1 christos } 2598 1.1 christos 2599 1.1 christos /* The "emit_stack_flush" emit_ops method for s390x. */ 2600 1.1 christos 2601 1.1 christos static void 2602 1.1 christos s390x_emit_stack_flush (void) 2603 1.1 christos { 2604 1.1 christos static const unsigned char buf[] = { 2605 1.1 christos 0xa7, 0xfb, 0xff, 0xf8, /* aghi %r15, -8 */ 2606 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */ 2607 1.1 christos }; 2608 1.1 christos add_insns (buf, sizeof buf); 2609 1.1 christos } 2610 1.1 christos 2611 1.1 christos /* The "emit_zero_ext" emit_ops method for s390x. */ 2612 1.1 christos 2613 1.1 christos static void 2614 1.1 christos s390x_emit_zero_ext (int arg) 2615 1.1 christos { 2616 1.1 christos unsigned char buf[] = { 2617 1.1 christos /* sllg %r2, %r2, <64-arg> */ 2618 1.1 christos 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0d, 2619 1.1 christos /* srlg %r2, %r2, <64-arg> */ 2620 1.1 christos 0xeb, 0x22, 0x00, (unsigned char) (64 - arg), 0x00, 0x0c, 2621 1.1 christos }; 2622 1.1 christos add_insns (buf, sizeof buf); 2623 1.1 christos } 2624 1.1 christos 2625 1.1 christos /* The "emit_swap" emit_ops method for s390x. */ 2626 1.1 christos 2627 1.1 christos static void 2628 1.1 christos s390x_emit_swap (void) 2629 1.1 christos { 2630 1.1 christos static const unsigned char buf[] = { 2631 1.1 christos 0xe3, 0x30, 0xf0, 0x00, 0x00, 0x04, /* lg %r3, 0(%r15) */ 2632 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x24, /* stg %r2, 0(%r15) */ 2633 1.1 christos 0xb9, 0x04, 0x00, 0x23, /* lgr %r2, %r3 */ 2634 1.1 christos }; 2635 1.1 christos add_insns (buf, sizeof buf); 2636 1.1 christos } 2637 1.1 christos 2638 1.1 christos /* The "emit_stack_adjust" emit_ops method for s390x. */ 2639 1.1 christos 2640 1.1 christos static void 2641 1.1 christos s390x_emit_stack_adjust (int n) 2642 1.1 christos { 2643 1.1 christos unsigned char buf[] = { 2644 1.1 christos /* aghi %r15, 8*n */ 2645 1.1 christos 0xa7, 0xfb, 2646 1.1 christos (unsigned char) (n * 8 >> 8), (unsigned char) (n * 8), 2647 1.1 christos }; 2648 1.1 christos add_insns (buf, sizeof buf); 2649 1.1 christos } 2650 1.1 christos 2651 1.1 christos /* The "emit_int_call_1" emit_ops method for s390x. */ 2652 1.1 christos 2653 1.1 christos static void 2654 1.1 christos s390x_emit_int_call_1 (CORE_ADDR fn, int arg1) 2655 1.1 christos { 2656 1.1 christos /* FN's prototype is `LONGEST(*fn)(int)'. */ 2657 1.1 christos s390x_emit_const (arg1); 2658 1.1 christos s390x_emit_call (fn); 2659 1.1 christos } 2660 1.1 christos 2661 1.1 christos /* The "emit_void_call_2" emit_ops method for s390x. */ 2662 1.1 christos 2663 1.1 christos static void 2664 1.1 christos s390x_emit_void_call_2 (CORE_ADDR fn, int arg1) 2665 1.1 christos { 2666 1.1 christos /* FN's prototype is `void(*fn)(int,LONGEST)'. */ 2667 1.1 christos static const unsigned char buf[] = { 2668 1.1 christos 0xb9, 0x04, 0x00, 0x32, /* lgr %r3, %r2 */ 2669 1.1 christos 0xb9, 0x04, 0x00, 0xc2, /* lgr %r12, %r2 */ 2670 1.1 christos }; 2671 1.1 christos static const unsigned char buf2[] = { 2672 1.1 christos 0xb9, 0x04, 0x00, 0x2c, /* lgr %r2, %r12 */ 2673 1.1 christos }; 2674 1.1 christos add_insns (buf, sizeof buf); 2675 1.1 christos s390x_emit_const (arg1); 2676 1.1 christos s390x_emit_call (fn); 2677 1.1 christos add_insns (buf2, sizeof buf2); 2678 1.1 christos } 2679 1.1 christos 2680 1.1 christos /* The "emit_eq_goto" emit_ops method for s390x. */ 2681 1.1 christos 2682 1.1 christos static void 2683 1.1 christos s390x_emit_eq_goto (int *offset_p, int *size_p) 2684 1.1 christos { 2685 1.1 christos static const unsigned char buf[] = { 2686 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2687 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2688 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2689 1.1 christos 0xc0, 0x84, 0x00, 0x00, 0x00, 0x00, /* jge <fillme> */ 2690 1.1 christos }; 2691 1.1 christos add_insns (buf, sizeof buf); 2692 1.1 christos if (offset_p) 2693 1.1 christos *offset_p = 18; 2694 1.1 christos if (size_p) 2695 1.1 christos *size_p = 4; 2696 1.1 christos } 2697 1.1 christos 2698 1.1 christos /* The "emit_ne_goto" emit_ops method for s390x. */ 2699 1.1 christos 2700 1.1 christos static void 2701 1.1 christos s390x_emit_ne_goto (int *offset_p, int *size_p) 2702 1.1 christos { 2703 1.1 christos static const unsigned char buf[] = { 2704 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2705 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2706 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2707 1.1 christos 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, /* jgne <fillme> */ 2708 1.1 christos }; 2709 1.1 christos add_insns (buf, sizeof buf); 2710 1.1 christos if (offset_p) 2711 1.1 christos *offset_p = 18; 2712 1.1 christos if (size_p) 2713 1.1 christos *size_p = 4; 2714 1.1 christos } 2715 1.1 christos 2716 1.1 christos /* The "emit_lt_goto" emit_ops method for s390x. */ 2717 1.1 christos 2718 1.1 christos static void 2719 1.1 christos s390x_emit_lt_goto (int *offset_p, int *size_p) 2720 1.1 christos { 2721 1.1 christos static const unsigned char buf[] = { 2722 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2723 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2724 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2725 1.1 christos 0xc0, 0x24, 0x00, 0x00, 0x00, 0x00, /* jgh <fillme> */ 2726 1.1 christos }; 2727 1.1 christos add_insns (buf, sizeof buf); 2728 1.1 christos if (offset_p) 2729 1.1 christos *offset_p = 18; 2730 1.1 christos if (size_p) 2731 1.1 christos *size_p = 4; 2732 1.1 christos } 2733 1.1 christos 2734 1.1 christos /* The "emit_le_goto" emit_ops method for s390x. */ 2735 1.1 christos 2736 1.1 christos static void 2737 1.1 christos s390x_emit_le_goto (int *offset_p, int *size_p) 2738 1.1 christos { 2739 1.1 christos static const unsigned char buf[] = { 2740 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2741 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2742 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2743 1.1 christos 0xc0, 0xa4, 0x00, 0x00, 0x00, 0x00, /* jghe <fillme> */ 2744 1.1 christos }; 2745 1.1 christos add_insns (buf, sizeof buf); 2746 1.1 christos if (offset_p) 2747 1.1 christos *offset_p = 18; 2748 1.1 christos if (size_p) 2749 1.1 christos *size_p = 4; 2750 1.1 christos } 2751 1.1 christos 2752 1.1 christos /* The "emit_gt_goto" emit_ops method for s390x. */ 2753 1.1 christos 2754 1.1 christos static void 2755 1.1 christos s390x_emit_gt_goto (int *offset_p, int *size_p) 2756 1.1 christos { 2757 1.1 christos static const unsigned char buf[] = { 2758 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2759 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2760 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2761 1.1 christos 0xc0, 0x44, 0x00, 0x00, 0x00, 0x00, /* jgl <fillme> */ 2762 1.1 christos }; 2763 1.1 christos add_insns (buf, sizeof buf); 2764 1.1 christos if (offset_p) 2765 1.1 christos *offset_p = 18; 2766 1.1 christos if (size_p) 2767 1.1 christos *size_p = 4; 2768 1.1 christos } 2769 1.1 christos 2770 1.1 christos /* The "emit_ge_goto" emit_ops method for s390x. */ 2771 1.1 christos 2772 1.1 christos static void 2773 1.1 christos s390x_emit_ge_goto (int *offset_p, int *size_p) 2774 1.1 christos { 2775 1.1 christos static const unsigned char buf[] = { 2776 1.1 christos 0xe3, 0x20, 0xf0, 0x00, 0x00, 0x20, /* cg %r2, 0(%r15) */ 2777 1.1 christos 0xe3, 0x20, 0xf0, 0x08, 0x00, 0x04, /* lg %r2, 8(%r15) */ 2778 1.1 christos 0x41, 0xf0, 0xf0, 0x10, /* la %r15, 16(%r15) */ 2779 1.1 christos 0xc0, 0xc4, 0x00, 0x00, 0x00, 0x00, /* jgle <fillme> */ 2780 1.1 christos }; 2781 1.1 christos add_insns (buf, sizeof buf); 2782 1.1 christos if (offset_p) 2783 1.1 christos *offset_p = 18; 2784 1.1 christos if (size_p) 2785 1.1 christos *size_p = 4; 2786 1.1 christos } 2787 1.1 christos 2788 1.1 christos /* The "emit_ops" structure for s390x. */ 2789 1.1 christos 2790 1.1 christos static struct emit_ops s390x_emit_ops = 2791 1.1 christos { 2792 1.1 christos s390x_emit_prologue, 2793 1.1 christos s390x_emit_epilogue, 2794 1.1 christos s390x_emit_add, 2795 1.1 christos s390x_emit_sub, 2796 1.1 christos s390x_emit_mul, 2797 1.1 christos s390x_emit_lsh, 2798 1.1 christos s390x_emit_rsh_signed, 2799 1.1 christos s390x_emit_rsh_unsigned, 2800 1.1 christos s390x_emit_ext, 2801 1.1 christos s390x_emit_log_not, 2802 1.1 christos s390x_emit_bit_and, 2803 1.1 christos s390x_emit_bit_or, 2804 1.1 christos s390x_emit_bit_xor, 2805 1.1 christos s390x_emit_bit_not, 2806 1.1 christos s390x_emit_equal, 2807 1.1 christos s390x_emit_less_signed, 2808 1.1 christos s390x_emit_less_unsigned, 2809 1.1 christos s390x_emit_ref, 2810 1.1 christos s390x_emit_if_goto, 2811 1.1 christos s390_emit_goto, 2812 1.1 christos s390_write_goto_address, 2813 1.1 christos s390x_emit_const, 2814 1.1 christos s390x_emit_call, 2815 1.1 christos s390x_emit_reg, 2816 1.1 christos s390x_emit_pop, 2817 1.1 christos s390x_emit_stack_flush, 2818 1.1 christos s390x_emit_zero_ext, 2819 1.1 christos s390x_emit_swap, 2820 1.1 christos s390x_emit_stack_adjust, 2821 1.1 christos s390x_emit_int_call_1, 2822 1.1 christos s390x_emit_void_call_2, 2823 1.1 christos s390x_emit_eq_goto, 2824 1.1 christos s390x_emit_ne_goto, 2825 1.1 christos s390x_emit_lt_goto, 2826 1.1 christos s390x_emit_le_goto, 2827 1.1 christos s390x_emit_gt_goto, 2828 1.1 christos s390x_emit_ge_goto 2829 1.1 christos }; 2830 1.1 christos #endif 2831 1.1 christos 2832 1.1 christos /* The "emit_ops" target ops method. */ 2833 1.1 christos 2834 1.1 christos emit_ops * 2835 1.1 christos s390_target::emit_ops () 2836 1.1 christos { 2837 1.1 christos #ifdef __s390x__ 2838 1.1.1.4 christos if (register_size (current_process ()->tdesc, 0) == 8) 2839 1.1 christos return &s390x_emit_ops; 2840 1.1 christos else 2841 1.1 christos #endif 2842 1.1 christos return &s390_emit_ops_impl; 2843 1.1 christos } 2844 1.1 christos 2845 1.1 christos /* The linux target ops object. */ 2846 1.1 christos 2847 1.1 christos linux_process_target *the_linux_target = &the_s390_target; 2848 1.1 christos 2849 1.1 christos void 2850 1.1 christos initialize_low_arch (void) 2851 1.1 christos { 2852 1.1 christos /* Initialize the Linux target descriptions. */ 2853 1.1 christos 2854 1.1 christos init_registers_s390_linux32 (); 2855 1.1 christos init_registers_s390_linux32v1 (); 2856 1.1 christos init_registers_s390_linux32v2 (); 2857 1.1 christos init_registers_s390_linux64 (); 2858 1.1 christos init_registers_s390_linux64v1 (); 2859 1.1 christos init_registers_s390_linux64v2 (); 2860 1.1 christos init_registers_s390_te_linux64 (); 2861 1.1 christos init_registers_s390_vx_linux64 (); 2862 1.1 christos init_registers_s390_tevx_linux64 (); 2863 1.1 christos init_registers_s390_gs_linux64 (); 2864 1.1 christos #ifdef __s390x__ 2865 1.1 christos init_registers_s390x_linux64 (); 2866 1.1 christos init_registers_s390x_linux64v1 (); 2867 1.1 christos init_registers_s390x_linux64v2 (); 2868 1.1 christos init_registers_s390x_te_linux64 (); 2869 1.1 christos init_registers_s390x_vx_linux64 (); 2870 1.1 christos init_registers_s390x_tevx_linux64 (); 2871 1.1 christos init_registers_s390x_gs_linux64 (); 2872 1.1 christos #endif 2873 1.1 christos 2874 1.1 christos initialize_regsets_info (&s390_regsets_info); 2875 1.1 christos initialize_regsets_info (&s390_regsets_info_3264); 2876 1.1 christos } 2877