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