]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/i370/i370.c
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / i370 / i370.c
diff --git a/gcc/config/i370/i370.c b/gcc/config/i370/i370.c
deleted file mode 100644 (file)
index 5ee6b23..0000000
+++ /dev/null
@@ -1,1556 +0,0 @@
-/* Subroutines for insn-output.c for System/370.
-   Copyright (C) 1989, 1993, 1995, 1997, 1998, 1999, 2000, 2002
-   Free Software Foundation, Inc.
-   Contributed by Jan Stein (jan@cd.chalmers.se).
-   Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com)
-   Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) 
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "rtl.h"
-#include "tree.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "real.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "output.h"
-#include "insn-attr.h"
-#include "function.h"
-#include "expr.h"
-#include "flags.h"
-#include "recog.h"
-#include "toplev.h"
-#include "cpplib.h"
-#include "tm_p.h"
-#include "target.h"
-#include "target-def.h"
-
-extern FILE *asm_out_file;
-
-/* Label node.  This structure is used to keep track of labels 
-      on the various pages in the current routine.
-   The label_id is the numeric ID of the label,
-   The label_page is the page on which it actually appears,
-   The first_ref_page is the page on which the true first ref appears.
-   The label_addr is an estimate of its location in the current routine,
-   The label_first & last_ref are estimates of where the earliest and
-      latest references to this label occur.  */
-
-typedef struct label_node
-  {
-    struct label_node *label_next;
-    int label_id;
-    int label_page;
-    int first_ref_page;
-
-    int label_addr;
-    int label_first_ref;
-    int label_last_ref;
-  }
-label_node_t;
-
-/* Is 1 when a label has been generated and the base register must be reloaded.  */
-int mvs_need_base_reload = 0;
-
-/* Current function starting base page.  */
-int function_base_page;
-
-/* Length of the current page code.  */
-int mvs_page_code;
-
-/* Length of the current page literals.  */
-int mvs_page_lit;
-
-/* Current function name.  */
-char *mvs_function_name = 0;
-
-/* Current function name length.  */
-int mvs_function_name_length = 0;
-
-/* Page number for multi-page functions.  */
-int mvs_page_num = 0;
-
-/* Label node list anchor.  */
-static label_node_t *label_anchor = 0;
-
-/* Label node free list anchor.  */
-static label_node_t *free_anchor = 0;
-
-/* Assembler source file descriptor.  */
-static FILE *assembler_source = 0;
-
-static label_node_t * mvs_get_label PARAMS ((int));
-static void i370_label_scan PARAMS ((void));
-#ifdef TARGET_HLASM
-static bool i370_hlasm_assemble_integer PARAMS ((rtx, unsigned int, int));
-#endif
-static void i370_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void i370_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-#ifdef LONGEXTERNAL
-static int mvs_hash_alias PARAMS ((const char *));
-#endif
-
-/* ===================================================== */
-/* defines and functions specific to the HLASM assembler */
-#ifdef TARGET_HLASM
-
-#define MVS_HASH_PRIME 999983
-#if defined(HOST_EBCDIC)
-#define MVS_SET_SIZE 256
-#else
-#define MVS_SET_SIZE 128
-#endif
-
-#ifndef MAX_MVS_LABEL_SIZE
-#define MAX_MVS_LABEL_SIZE 8
-#endif
-
-#define MAX_LONG_LABEL_SIZE 255
-
-/* Alias node, this structure is used to keep track of aliases to external
-   variables. The IBM assembler allows an alias to an external name 
-   that is longer that 8 characters; but only once per assembly.
-   Also, this structure stores the #pragma map info.  */
-typedef struct alias_node
-  {
-    struct alias_node *alias_next;
-    int  alias_emitted;
-    char alias_name [MAX_MVS_LABEL_SIZE + 1];
-    char real_name [MAX_LONG_LABEL_SIZE + 1];
-  }
-alias_node_t;
-
-/* Alias node list anchor.  */
-static alias_node_t *alias_anchor = 0;
-
-/* Define the length of the internal MVS function table.  */
-#define MVS_FUNCTION_TABLE_LENGTH 32
-
-/* C/370 internal function table.  These functions use non-standard linkage
-   and must handled in a special manner.  */
-static const char *const mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] =
-{
-#if defined(HOST_EBCDIC) /* Changed for EBCDIC collating sequence */
-   "ceil",     "edc_acos", "edc_asin", "edc_atan", "edc_ata2", "edc_cos",
-   "edc_cosh", "edc_erf",  "edc_erfc", "edc_exp",  "edc_gamm", "edc_lg10",
-   "edc_log",  "edc_sin",  "edc_sinh", "edc_sqrt", "edc_tan",  "edc_tanh",
-   "fabs",     "floor",    "fmod",     "frexp",    "hypot",    "jn",
-   "j0",       "j1",       "ldexp",    "modf",     "pow",      "yn",
-   "y0",       "y1"
-#else
-   "ceil",     "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos",
-   "edc_cosh", "edc_erf",  "edc_erfc", "edc_exp",  "edc_gamm", "edc_lg10",
-   "edc_log",  "edc_sin",  "edc_sinh", "edc_sqrt", "edc_tan",  "edc_tanh",
-   "fabs",     "floor",    "fmod",     "frexp",    "hypot",    "j0",
-   "j1",       "jn",       "ldexp",    "modf",     "pow",      "y0",
-   "y1",       "yn"
-#endif
-};
-
-#endif /* TARGET_HLASM */
-/* ===================================================== */
-
-/* ASCII to EBCDIC conversion table.  */
-static const unsigned char ascebc[256] =
-{
- /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
-     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08  BS    HT    LF    VT    FF    CR    SO    SI */
-     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10  DL    D1    D2    D3    D4    NK    SN    EB */
-     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
- /*18  CN    EM    SB    EC    FS    GS    RS    US */
-     0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20  SP     !     "     #     $     %     &     ' */
-     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28   (     )     *     +     ,     -    .      / */
-     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30   0     1     2     3     4     5     6     7 */
-     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38   8     9     :     ;     <     =     >     ? */
-     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40   @     A     B     C     D     E     F     G */
-     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48   H     I     J     K     L     M     N     O */
-     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50   P     Q     R     S     T     U     V     W */
-     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58   X     Y     Z     [     \     ]     ^     _ */
-     0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60   `     a     b     c     d     e     f     g */
-     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68   h     i     j     k     l     m     n     o */
-     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70   p     q     r     s     t     u     v     w */
-     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78   x     y     z     {     |     }     ~    DL */
-     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/* EBCDIC to ASCII conversion table.  */
-static const unsigned char ebcasc[256] =
-{
- /*00  NU    SH    SX    EX    PF    HT    LC    DL */
-     0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
- /*08              SM    VT    FF    CR    SO    SI */
-     0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10  DE    D1    D2    TM    RS    NL    BS    IL */
-     0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
- /*18  CN    EM    CC    C1    FS    GS    RS    US */
-     0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20  DS    SS    FS          BP    LF    EB    EC */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
- /*28              SM    C2    EQ    AK    BL       */
-     0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
- /*30              SY          PN    RS    UC    ET */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
- /*38                    C3    D4    NK          SU */
-     0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
- /*40  SP                                           */
-     0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*48                     .     <     (     +     | */
-     0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /*50   &                                           */
-     0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*58               !     $     *     )     ;     ^ */
-     0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
- /*60   -     /                                     */
-     0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*68                     ,     %     _     >     ? */
-     0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /*70                                               */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*78         `     :     #     @     '     =     " */
-     0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /*80         a     b     c     d     e     f     g */
-     0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /*88   h     i           {                         */
-     0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
- /*90         j     k     l     m     n     o     p */
-     0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /*98   q     r           }                         */
-     0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
- /*A0         ~     s     t     u     v     w     x */
-     0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /*A8   y     z                       [             */
-     0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
- /*B0                                               */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*B8                                 ]             */
-     0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
- /*C0   {     A     B     C     D     E     F     G */
-     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /*C8   H     I                                     */
-     0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*D0   }     J     K     L     M     N     O     P */
-     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /*D8   Q     R                                     */
-     0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*E0   \           S     T     U     V     W     X */
-     0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /*E8   Y     Z                                     */
-     0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- /*F0   0     1     2     3     4     5     6     7 */
-     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /*F8   8     9                                     */
-     0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
-};
-\f
-/* Initialize the GCC target structure.  */
-#ifdef TARGET_HLASM
-#undef TARGET_ASM_BYTE_OP
-#define TARGET_ASM_BYTE_OP NULL
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP NULL
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP NULL
-#undef TARGET_ASM_INTEGER
-#define TARGET_ASM_INTEGER i370_hlasm_assemble_integer
-#endif
-
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE i370_output_function_prologue
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE i370_output_function_epilogue
-
-struct gcc_target targetm = TARGET_INITIALIZER;
-\f
-/* Map characters from one character set to another.
-   C is the character to be translated.  */
-
-char
-mvs_map_char (c)
-     int c;
-{
-#if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
-  fprintf (stderr, "mvs_map_char: TE & !HE: c = %02x\n", c);
-  return ascebc[c];
-#else
-#if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
-  fprintf (stderr, "mvs_map_char: !TE & HE: c = %02x\n", c);
-  return ebcasc[c];
-#else
-  fprintf (stderr, "mvs_map_char: !TE & !HE: c = %02x\n", c);
-  return c;
-#endif
-#endif
-}
-
-/* ===================================================== */
-/* The following three routines are used to determine whther 
-   forward branch is on this page, or is a far jump.  We use
-   the "length" attr on an insn [(set_atter "length" "4")]
-   to store the largest possible code length that insn
-   could have.  This gives us a hint of the address of a
-   branch destination, and from that, we can work out 
-   the length of the jump, and whether its on page or not. 
- */
-
-/* Return the destination address of a branch.  */
-
-int
-i370_branch_dest (branch)
-     rtx branch;
-{
-  rtx dest = SET_SRC (PATTERN (branch));
-  int dest_uid;
-  int dest_addr;
-
-  /* first, compute the estimated address of the branch target */
-  if (GET_CODE (dest) == IF_THEN_ELSE)
-    dest = XEXP (dest, 1);
-  dest = XEXP (dest, 0);
-  dest_uid = INSN_UID (dest);
-  dest_addr = INSN_ADDRESSES (dest_uid);
-
-  /* next, record the address of this insn as the true addr of first ref */
-  {
-     label_node_t *lp;
-     rtx label = JUMP_LABEL (branch);
-     int labelno = CODE_LABEL_NUMBER (label);
-
-     if (!label || CODE_LABEL != GET_CODE (label)) abort ();
-
-     lp = mvs_get_label (labelno);
-     if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num;
-  }
-  return dest_addr;
-}
-
-int
-i370_branch_length (insn)
-     rtx insn;
-{
-  int here, there;
-  here = INSN_ADDRESSES (INSN_UID (insn));
-  there = i370_branch_dest (insn);
-  return (there - here);
-}
-
-
-int
-i370_short_branch (insn)
-     rtx insn;
-{
-  int base_offset;
-
-  base_offset = i370_branch_length(insn);
-  if (0 > base_offset) 
-    {
-      base_offset += mvs_page_code;
-    } 
-  else 
-    {
-      /* avoid bumping into lit pool; use 2x to estimate max possible lits */
-      base_offset *= 2;
-      base_offset += mvs_page_code + mvs_page_lit;
-    }
-  
-  /* make a conservative estimate of room left on page */
-  if ((4060 >base_offset) && ( 0 < base_offset)) return 1;
-  return 0;
-}
-
-/* The i370_label_scan() routine is supposed to loop over
-   all labels and label references in a compilation unit,
-   and determine whether all label refs appear on the same 
-   code page as the label. If they do, then we can avoid 
-   a reload of the base register for that label.
-  
-   Note that the instruction addresses used here are only 
-   approximate, and make the sizes of the jumps appear
-   farther apart then they will actually be.  This makes 
-   this code far more conservative than it needs to be.
- */
-
-#define I370_RECORD_LABEL_REF(label,addr) {                            \
-       label_node_t *lp;                                               \
-       int labelno = CODE_LABEL_NUMBER (label);                        \
-       lp = mvs_get_label (labelno);                                   \
-       if (addr < lp -> label_first_ref) lp->label_first_ref = addr;   \
-       if (addr > lp -> label_last_ref) lp->label_last_ref = addr;     \
-}
-
-static void 
-i370_label_scan () 
-{
-   rtx insn;
-   label_node_t *lp;
-   int tablejump_offset = 0;
-
-   for (insn = get_insns(); insn; insn = NEXT_INSN(insn))
-     {
-       int here = INSN_ADDRESSES (INSN_UID (insn));
-       enum rtx_code code = GET_CODE(insn);
-
-       /* ??? adjust for tables embedded in the .text section that
-        * the compiler didn't take into account */
-       here += tablejump_offset;
-       INSN_ADDRESSES (INSN_UID (insn)) = here;
-
-       /* check to see if this insn is a label ...  */
-       if (CODE_LABEL == code)
-         {
-           int labelno = CODE_LABEL_NUMBER (insn);
-
-           lp = mvs_get_label (labelno);
-           lp -> label_addr = here;
-#if 0
-           /* Supposedly, labels are supposed to have circular
-              lists of label-refs that reference them, 
-              setup in flow.c, but this does not appear to be the case.  */
-           rtx labelref = LABEL_REFS (insn);
-           rtx ref = labelref;
-           do 
-             {
-               rtx linsn = CONTAINING_INSN(ref);
-               ref =  LABEL_NEXTREF(ref);
-             } while (ref && (ref != labelref));
-#endif
-         }
-       else
-       if (JUMP_INSN == code)
-         {
-           rtx label = JUMP_LABEL (insn);
-
-           /* If there is no label for this jump, then this
-              had better be a ADDR_VEC or an ADDR_DIFF_VEC
-              and there had better be a vector of labels.  */
-           if (!label) 
-             {
-               int j;
-               rtx body = PATTERN (insn);
-               if (ADDR_VEC == GET_CODE(body)) 
-                 {
-                    for (j=0; j < XVECLEN (body, 0); j++)
-                      {
-                         rtx lref = XVECEXP (body, 0, j);
-                         if (LABEL_REF != GET_CODE (lref)) abort ();
-                         label = XEXP (lref,0);
-                         if (CODE_LABEL != GET_CODE (label)) abort ();
-                         tablejump_offset += 4;
-                         here += 4;
-                         I370_RECORD_LABEL_REF(label,here);
-                      }
-                    /* finished with the vector go do next insn */
-                    continue;
-                 }
-               else
-               if (ADDR_DIFF_VEC == GET_CODE(body))
-                 {
-/* XXX hack alert.
-   Right now, we leave this as a no-op, but strictly speaking,
-   this is incorrect.  It is possible that a table-jump
-   driven off of a relative address could take us off-page,
-   to a place where we need to reload the base reg.  So really,
-   we need to examing both labels, and compare thier values
-   to the current basereg value.
-  
-   More generally, this brings up a troubling issue overall:
-   what happens if a tablejump is split across two pages? I do 
-   not beleive that this case is handled correctly at all, and
-   can only lead to horrible results if this were to occur.
-  
-   However, the current situation is not any worse than it was 
-   last week, and so we punt for now.  */
-
-                    debug_rtx (insn);
-                    for (j=0; j < XVECLEN (body, 0); j++)
-                      {
-                      }
-                    /* finished with the vector go do next insn */
-                    continue;
-                 }
-               else 
-                 {
-/* XXX hack alert.
-   Compiling the exception handling (L_eh) in libgcc2.a will trip
-   up right here, with something that looks like
-   (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
-      {indirect_jump} 
-   I'm not sure of what leads up to this, but it looks like
-   the makings of a long jump which will surely get us into trouble
-   because the base & page registers don't get reloaded.  For now
-   I'm not sure of what to do ... again we punt ... we are not worse
-   off than yesterday.  */
-
-                    /* print_rtl_single (stdout, insn); */
-                    debug_rtx (insn);
-                    /* abort(); */
-                    continue;
-                 }
-            }
-          else
-            {
-              /* At this point, this jump_insn had better be a plain-old
-                 ordinary one, grap the label id and go */
-              if (CODE_LABEL != GET_CODE (label)) abort ();
-              I370_RECORD_LABEL_REF(label,here);
-            }
-        }
-
-      /* Sometimes, we take addresses of labels and use them
-         as instruction operands ... these show up as REG_NOTES */
-      else
-      if (INSN == code)
-       {
-         if ('i' == GET_RTX_CLASS (code)) 
-           {
-              rtx note;
-              for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
-                {
-                   if (REG_LABEL == REG_NOTE_KIND(note))
-                     {
-                        rtx label = XEXP (note,0);
-                        if (!label || CODE_LABEL != GET_CODE (label)) abort ();
-
-                        I370_RECORD_LABEL_REF(label,here);
-                     }
-                }
-           }
-       }
-   }
-}
-
-/* ===================================================== */
-
-/* Emit reload of base register if indicated.  This is to eliminate multiple
-   reloads when several labels are generated pointing to the same place
-   in the code.  
-
-   The page table is written at the end of the function. 
-   The entries in the page table look like
-     .LPGT0:          // PGT0 EQU *
-     .long .LPG0      // DC A(PG0)
-     .long .LPG1      // DC A(PG1)
-  while the prologue generates
-      L       r4,=A(.LPGT0)
-
-  Note that this paging scheme breaks down if a single subroutine 
-  has more than about 10MB of code in it ... as long as humans write
-  code, this shouldn't be a problem ...
- */
-
-void
-check_label_emit ()
-{
-  if (mvs_need_base_reload)
-    {
-      mvs_need_base_reload = 0;
-
-      mvs_page_code += 4;
-      fprintf (assembler_source, "\tL\t%d,%d(,%d)\n",
-         BASE_REGISTER, (mvs_page_num - function_base_page) * 4,
-         PAGE_REGISTER);
-    }
-}
-
-/* Add the label to the current page label list.  If a free element is available
-   it will be used for the new label.  Otherwise, a label element will be
-   allocated from memory.
-   ID is the label number of the label being added to the list.  */
-
-static label_node_t *
-mvs_get_label (id)
-     int id;
-{
-  label_node_t *lp;
-
-  /* first, lets see if we already go one, if so, use that.  */
-  for (lp = label_anchor; lp; lp = lp->label_next)
-    {
-      if (lp->label_id == id) return lp;
-    }
-
-  /* not found, get a new one */
-  if (free_anchor)
-    {
-      lp = free_anchor;
-      free_anchor = lp->label_next;
-    }
-  else
-    {
-      lp = (label_node_t *) xmalloc (sizeof (label_node_t));
-    }
-
-  /* initialize for new label */
-  lp->label_id = id;
-  lp->label_page = -1;
-  lp->label_next = label_anchor;
-  lp->label_first_ref = 2000123123;
-  lp->label_last_ref = -1;
-  lp->label_addr = -1;
-  lp->first_ref_page = -1;
-  label_anchor = lp;
-
-  return lp;
-}
-
-void
-mvs_add_label (id)
-     int id;
-{
-  label_node_t *lp;
-  int fwd_distance;
-
-  lp = mvs_get_label (id);
-  lp->label_page = mvs_page_num;
-
-  /* OK, we just saw the label.  Determine if this label
-   * needs a reload of the base register */
-  if ((-1 != lp->first_ref_page) && 
-      (lp->first_ref_page != mvs_page_num)) 
-    {
-      /* Yep; the first label_ref was on a different page.  */
-      mvs_need_base_reload ++;
-      return;
-    }
-
-  /* Hmm.  Try to see if the estimated address of the last
-     label_ref is on the current page.  If it is, then we
-     don't need a base reg reload.  Note that this estimate
-     is very conservatively handled; we'll tend to have 
-     a good bit more reloads than actually needed.  Someday,
-     we should tighten the estimates (which are driven by
-     the (set_att "length") insn attibute.
-    
-     Currently, we estimate that number of page literals 
-     same as number of insns, which is a vast overestimate,
-     esp that the estimate of each insn size is its max size.  */
-
-  /* if latest ref comes before label, we are clear */
-  if (lp->label_last_ref < lp->label_addr) return;
-
-  fwd_distance = lp->label_last_ref - lp->label_addr;
-
-  if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return;
-
-  mvs_need_base_reload ++;
-}
-
-/* Check to see if the label is in the list and in the current
-   page.  If not found, we have to make worst case assumption 
-   that label will be on a different page, and thus will have to
-   generate a load and branch on register.  This is rather
-   ugly for forward-jumps, but what can we do? For backward
-   jumps on the same page we can branch directly to address.
-   ID is the label number of the label being checked.  */
-
-int
-mvs_check_label (id)
-     int id;
-{
-  label_node_t *lp;
-
-  for (lp = label_anchor; lp; lp = lp->label_next)
-    {
-      if (lp->label_id == id) 
-        {
-          if (lp->label_page == mvs_page_num) 
-            {
-               return 1;
-            } 
-          else 
-            {
-              return 0;
-            } 
-        }
-    }
-  return 0;
-}
-
-/* Get the page on which the label sits.  This will be used to 
-   determine is a register reload is really needed.  */
-
-#if 0
-int
-mvs_get_label_page(int id)
-{
-  label_node_t *lp;
-
-  for (lp = label_anchor; lp; lp = lp->label_next)
-    {
-      if (lp->label_id == id)
-       return lp->label_page;
-    }
-  return -1;
-}
-#endif
-
-/* The label list for the current page freed by linking the list onto the free
-   label element chain.  */
-
-void
-mvs_free_label_list ()
-{
-
-  if (label_anchor)
-    {
-      label_node_t *last_lp = label_anchor;
-      while (last_lp->label_next) last_lp = last_lp->label_next;
-      last_lp->label_next = free_anchor;
-      free_anchor = label_anchor;
-    }
-  label_anchor = 0;
-}
-
-/* ====================================================================== */
-/* If the page size limit is reached a new code page is started, and the base
-   register is set to it.  This page break point is counted conservatively,
-   most literals that have the same value are collapsed by the assembler.
-   True is returned when a new page is started.
-   FILE is the assembler output file descriptor.
-   CODE is the length, in bytes, of the instruction to be emitted.
-   LIT is the length of the literal to be emitted.  */
-
-#ifdef TARGET_HLASM
-int
-mvs_check_page (file, code, lit)
-     FILE *file;
-     int code, lit;
-{
-  if (file)
-    assembler_source = file;
-
-  if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
-    {
-      fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num);
-      fprintf (assembler_source, "\tDS\t0F\n");
-      fprintf (assembler_source, "\tLTORG\n");
-      fprintf (assembler_source, "\tDS\t0F\n");
-      fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num);
-      fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER);
-      mvs_page_num++;
-      /* Safe to use BASR not BALR, since we are
-       * not switching addressing mode here ...  */
-      fprintf (assembler_source, "\tBASR\t%d,0\n", BASE_REGISTER);
-      fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num);
-      fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER);
-      mvs_page_code = code;
-      mvs_page_lit = lit;
-      return 1;
-    }
-  mvs_page_code += code;
-  mvs_page_lit += lit;
-  return 0;
-}
-#endif /* TARGET_HLASM */
-
-
-#ifdef TARGET_ELF_ABI
-int
-mvs_check_page (file, code, lit)
-     FILE *file;
-     int code, lit;
-{
-  if (file)
-    assembler_source = file;
-
-  if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
-    {
-      /* hop past the literal pool */
-      fprintf (assembler_source, "\tB\t.LPGE%d\n", mvs_page_num);
-
-      /* dump the literal pool. The .baligns are optional, since 
-       * ltorg will align to the size of the largest literal 
-       * (which is possibly 8 bytes) */
-      fprintf (assembler_source, "\t.balign\t4\n");
-      fprintf (assembler_source, "\t.LTORG\n");
-      fprintf (assembler_source, "\t.balign\t4\n");
-
-      /* we continue execution here ...  */
-      fprintf (assembler_source, ".LPGE%d:\n", mvs_page_num);
-      fprintf (assembler_source, "\t.DROP\t%d\n", BASE_REGISTER);
-      mvs_page_num++;
-
-      /* BASR puts the contents of the PSW into r3
-       * that is, r3 will be loaded with the address of "." */
-      fprintf (assembler_source, "\tBASR\tr%d,0\n", BASE_REGISTER);
-      fprintf (assembler_source, ".LPG%d:\n", mvs_page_num);
-      fprintf (assembler_source, "\t.USING\t.,r%d\n", BASE_REGISTER);
-      mvs_page_code = code;
-      mvs_page_lit = lit;
-      return 1;
-    }
-  mvs_page_code += code;
-  mvs_page_lit += lit;
-  return 0;
-}
-#endif /* TARGET_ELF_ABI */
-
-/* ===================================================== */
-/* defines and functions specific to the HLASM assembler */
-#ifdef TARGET_HLASM
-
-/* Check for C/370 runtime function, they don't use standard calling
-   conventions.  True is returned if the function is in the table.
-   NAME is the name of the current function.  */
-
-int
-mvs_function_check (name)
-     const char *name;
-{
-  int lower, middle, upper;
-  int i;
-
-  lower = 0;
-  upper = MVS_FUNCTION_TABLE_LENGTH - 1;
-  while (lower <= upper)
-    {
-      middle = (lower + upper) / 2;
-      i = strcmp (name, mvs_function_table[middle]);
-      if (i == 0)
-       return 1;
-      if (i < 0)
-       upper = middle - 1;
-      else
-       lower = middle + 1;
-    }
-  return 0;
-}
-
-/* Generate a hash for a given key.  */
-
-#ifdef LONGEXTERNAL
-static int
-mvs_hash_alias (key)
-     const char *key;
-{
-  int h;
-  int i;
-  int l = strlen (key);
-
-  h = key[0];
-  for (i = 1; i < l; i++)
-    h = ((h * MVS_SET_SIZE) + key[i]) % MVS_HASH_PRIME;
-  return (h);
-}
-#endif
-
-/* Add the alias to the current alias list.  */
-
-void
-mvs_add_alias (realname, aliasname, emitted)
-     const char *realname;
-     const char *aliasname;
-     int   emitted;
-{
-  alias_node_t *ap;
-
-  ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
-  if (strlen (realname) > MAX_LONG_LABEL_SIZE)
-    {
-      warning ("real name is too long - alias ignored");
-      return;
-    }
-  if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
-    {
-      warning ("alias name is too long - alias ignored");
-      return;
-    }
-      
-  strcpy (ap->real_name, realname);
-  strcpy (ap->alias_name, aliasname);
-  ap->alias_emitted = emitted;
-  ap->alias_next = alias_anchor;
-  alias_anchor = ap;
-}
-
-/* Check to see if the name needs aliasing. ie. the name is either:
-     1. Longer than 8 characters
-     2. Contains an underscore
-     3. Is mixed case */
-
-int
-mvs_need_alias (realname)
-      const char *realname;
-{
-   int i, j = strlen (realname);
-
-   if (mvs_function_check (realname))
-     return 0;
-#if 0
-   if (!strcmp (realname, "gccmain"))
-     return 0;
-   if (!strcmp (realname, "main"))
-     return 0;
-#endif
-   if (j > MAX_MVS_LABEL_SIZE)
-     return 1;
-   if (strchr (realname, '_') != 0)
-     return 1;
-   if (ISUPPER (realname[0]))
-     {
-       for (i = 1; i < j; i++)
-        {
-          if (ISLOWER (realname[i]))
-            return 1;
-        }
-     }
-   else
-     {
-       for (i = 1; i < j; i++)
-         {
-          if (ISUPPER (realname[i]))
-            return 1;
-        }
-     }
-
-   return 0;
-}
-
-/* Get the alias from the list. 
-   If 1 is returned then it's in the alias list, 0 if it was not */
-
-int
-mvs_get_alias (realname, aliasname)
-     const char *realname;
-     char *aliasname;
-{
-#ifdef LONGEXTERNAL
-  alias_node_t *ap;
-
-  for (ap = alias_anchor; ap; ap = ap->alias_next)
-    {
-      if (!strcmp (ap->real_name, realname))
-       {
-         strcpy (aliasname, ap->alias_name);
-         return 1;
-       }
-    }
-  if (mvs_need_alias (realname))
-    {
-      char c1, c2;
-
-      c1 = realname[0];
-      c2 = realname[1];
-      if (ISLOWER (c1)) c1 = TOUPPER (c1);
-      else if (c1 == '_') c1 = 'A';
-      if (ISLOWER (c2)) c2 = TOUPPER (c2);
-      else if (c2 == '_' || c2 == '\0') c2 = '#';
-
-      sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
-      mvs_add_alias (realname, aliasname, 0);
-      return 1;
-    }
-#else
-  if (strlen (realname) > MAX_MVS_LABEL_SIZE)
-    {
-      strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
-      aliasname[MAX_MVS_LABEL_SIZE] = '\0';
-      return 1;
-    }
-#endif
-  return 0;
-}
-
-/* Check to see if the alias is in the list. 
-   If 1 is returned then it's in the alias list, 2 it was emitted  */
-
-int
-mvs_check_alias (realname, aliasname)
-     const char *realname;
-     char *aliasname;
-{
-#ifdef LONGEXTERNAL
-  alias_node_t *ap;
-
-  for (ap = alias_anchor; ap; ap = ap->alias_next)
-    {
-      if (!strcmp (ap->real_name, realname))
-       {
-         int rc = (ap->alias_emitted == 1) ? 1 : 2; 
-         strcpy (aliasname, ap->alias_name);
-         ap->alias_emitted = 1; 
-         return rc;
-       }
-    }
-  if (mvs_need_alias (realname))
-    {
-      char c1, c2;
-
-      c1 = realname[0];
-      c2 = realname[1];
-      if (ISLOWER (c1)) c1 = TOUPPER (c1);
-      else if (c1 == '_') c1 = 'A';
-      if (ISLOWER (c2)) c2 = TOUPPER (c2);
-      else if (c2 == '_' || c2 == '\0') c2 = '#';
-
-      sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
-      mvs_add_alias (realname, aliasname, 0);
-      alias_anchor->alias_emitted = 1;
-      return 2;
-    }
-#else
-  if (strlen (realname) > MAX_MVS_LABEL_SIZE)
-    {
-      strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
-      aliasname[MAX_MVS_LABEL_SIZE] = '\0';
-      return 1;
-    }
-#endif
-  return 0;
-}
-
-/* defines and functions specific to the HLASM assembler */
-#endif /* TARGET_HLASM */
-/* ===================================================== */
-/* ===================================================== */
-/* defines and functions specific to the gas assembler */
-#ifdef TARGET_ELF_ABI
-
-/* Check for C/370 runtime function, they don't use standard calling
-   conventions.  True is returned if the function is in the table.
-   NAME is the name of the current function.  */
-/* no special calling conventions (yet ??) */
-
-int
-mvs_function_check (name)
-     const char *name ATTRIBUTE_UNUSED;
-{
-   return 0;
-}
-
-#endif /* TARGET_ELF_ABI */
-/* ===================================================== */
-
-
-/* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
-   OP is the current operation.
-   MODE is the current operation mode.  */
-
-int
-s_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode;
-{
-  extern int volatile_ok;
-  register enum rtx_code code = GET_CODE (op);
-
-  if (CONSTANT_ADDRESS_P (op))
-    return 1;
-  if (mode == VOIDmode || GET_MODE (op) != mode)
-    return 0;
-  if (code == MEM)
-    {
-      register rtx x = XEXP (op, 0);
-
-      if (!volatile_ok && op->volatil)
-       return 0;
-      if (REG_P (x) && REG_OK_FOR_BASE_P (x))
-       return 1;
-      if (GET_CODE (x) == PLUS
-         && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
-         && GET_CODE (XEXP (x, 1)) == CONST_INT
-         && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
-       return 1;
-    }
-  return 0;
-}
-
-
-/* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
-   instruction.
-   OP is the current operation.
-   MODE is the current operation mode.  */
-
-int
-r_or_s_operand (op, mode)
-     register rtx op;
-     enum machine_mode mode;
-{
-  extern int volatile_ok;
-  register enum rtx_code code = GET_CODE (op);
-
-  if (CONSTANT_ADDRESS_P (op))
-    return 1;
-  if (mode == VOIDmode || GET_MODE (op) != mode)
-    return 0;
-  if (code == REG)
-    return 1;
-  else if (code == MEM)
-    {
-      register rtx x = XEXP (op, 0);
-
-      if (!volatile_ok && op->volatil)
-       return 0;
-      if (REG_P (x) && REG_OK_FOR_BASE_P (x))
-       return 1;
-      if (GET_CODE (x) == PLUS
-         && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
-         && GET_CODE (XEXP (x, 1)) == CONST_INT
-         && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
-       return 1;
-    }
-  return 0;
-}
-
-
-/* Some remarks about unsigned_jump_follows_p():
-   gcc is built around the assumption that branches are signed
-   or unsigned, whereas the 370 doesn't care; its the compares that
-   are signed or unsigned.  Thus, we need to somehow know if we
-   need to do a signed or an unsigned compare, and we do this by 
-   looking ahead in the instruction sequence until we find a jump.
-   We then note whether this jump is signed or unsigned, and do the 
-   compare appropriately.  Note that we have to scan ahead indefinitley,
-   as the gcc optimizer may insert any number of instructions between 
-   the compare and the jump.
-  
-   Note that using conditional branch expanders seems to be be a more 
-   elegant/correct way of doing this.   See, for instance, the Alpha 
-   cmpdi and bgt patterns.  Note also that for the i370, various
-   arithmetic insn's set the condition code as well.
-
-   The unsigned_jump_follows_p() routine  returns a 1 if the next jump 
-   is unsigned.  INSN is the current instruction.  */
-
-int
-unsigned_jump_follows_p (insn)
-     register rtx insn;
-{
-  rtx orig_insn = insn;
-  while (1) 
-    {
-      register rtx tmp_insn;
-      enum rtx_code coda;
-  
-      insn = NEXT_INSN (insn);
-      if (!insn) fatal_insn ("internal error--no jump follows compare:", orig_insn);
-  
-      if (GET_CODE (insn) != JUMP_INSN) continue;
-    
-      tmp_insn = XEXP (insn, 3);
-      if (GET_CODE (tmp_insn) != SET) continue;
-    
-      if (GET_CODE (XEXP (tmp_insn, 0)) != PC) continue;
-    
-      tmp_insn = XEXP (tmp_insn, 1);
-      if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue;
-    
-      /* if we got to here, this instruction is a jump.  Is it signed? */
-      tmp_insn = XEXP (tmp_insn, 0);
-      coda = GET_CODE (tmp_insn);
-  
-      return coda != GE && coda != GT && coda != LE && coda != LT;
-    }
-}
-
-#ifdef TARGET_HLASM
-
-/* Target hook for assembling integer objects.  This version handles all
-   objects when TARGET_HLASM is defined.  */
-
-static bool
-i370_hlasm_assemble_integer (x, size, aligned_p)
-     rtx x;
-     unsigned int size;
-     int aligned_p;
-{
-  const char *int_format = NULL;
-
-  if (aligned_p)
-    switch (size)
-      {
-      case 1:
-       int_format = "\tDC\tX'%02X'\n";
-       break;
-
-      case 2:
-       int_format = "\tDC\tX'%04X'\n";
-       break;
-
-      case 4:
-       if (GET_CODE (x) == CONST_INT)
-         {
-           fputs ("\tDC\tF'", asm_out_file);
-           output_addr_const (asm_out_file, x);
-           fputs ("'\n", asm_out_file);
-         }
-       else
-         {
-           fputs ("\tDC\tA(", asm_out_file);
-           output_addr_const (asm_out_file, x);
-           fputs (")\n", asm_out_file);
-         }
-       return true;
-      }
-
-  if (int_format && GET_CODE (x) == CONST_INT)
-    {
-      fprintf (asm_out_file, int_format, INTVAL (x));
-      return true;
-    }
-  return default_assemble_integer (x, size, aligned_p);
-}
-
-/* Generate the assembly code for function entry.  FILE is a stdio
-   stream to output the code to.  SIZE is an int: how many units of
-   temporary storage to allocate.
-
-   Refer to the array `regs_ever_live' to determine which registers to
-   save; `regs_ever_live[I]' is nonzero if register number I is ever
-   used in the function.  This function is responsible for knowing
-   which registers should not be saved even if used.  */
-
-static void
-i370_output_function_prologue (f, l)
-     FILE *f;
-     HOST_WIDE_INT l;
-{
-#if MACROPROLOGUE == 1
-  fprintf (f, "* Function %s prologue\n", mvs_function_name);
-  fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
-          STACK_POINTER_OFFSET + l - 120 +
-          current_function_outgoing_args_size, BASE_REGISTER);
-#else /* MACROPROLOGUE != 1 */
-  static int function_label_index = 1;
-  static int function_first = 0;
-  static int function_year, function_month, function_day;
-  static int function_hour, function_minute, function_second;
-#if defined(LE370)
-  if (!function_first)
-    {
-      struct tm *function_time;
-      time_t lcltime;
-      time (&lcltime);
-      function_time = localtime (&lcltime);
-      function_year = function_time->tm_year + 1900;
-      function_month = function_time->tm_mon + 1;
-      function_day = function_time->tm_mday;
-      function_hour = function_time->tm_hour;
-      function_minute = function_time->tm_min;
-      function_second = function_time->tm_sec;
-    }
-  fprintf (f, "* Function %s prologue\n", mvs_function_name);
-  fprintf (f, "FDSE%03d\tDSECT\n", function_label_index);
-  fprintf (f, "\tDS\tD\n");
-  fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
-                       + current_function_outgoing_args_size);
-  fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
-  fprintf (f, "\tDS\tCL(120+8)\n");
-  fprintf (f, "\tORG\n");
-  fprintf (f, "\tDS\t0D\n");
-  fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index,
-          function_label_index);
-  fprintf (f, "\tDS\t0H\n");
-  assemble_name (f, mvs_function_name);
-  fprintf (f, "\tCSECT\n");
-  fprintf (f, "\tUSING\t*,15\n");
-  fprintf (f, "\tB\tFENT%03d\n", function_label_index);
-  fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index);
-  fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
-  fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index);
-  fprintf (f, "\tDC\tAL4(0)\n");
-  fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
-  fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index);
-  fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
-       mvs_function_name);
-  fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index);
-  fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
-  fprintf (f, "\tDC\tV(CEESTART)\n");
-  fprintf (f, "\tDC\tAL4(0)\n");
-  fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index);
-  fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index);
-  fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
-                function_year, function_month, function_day,
-                function_hour, function_minute);
-  fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
-  fprintf (f, "FENT%03d\tDS\t0H\n", function_label_index);
-  fprintf (f, "\tSTM\t14,12,12(13)\n");
-  fprintf (f, "\tL\t2,76(,13)\n");
-  fprintf (f, "\tL\t0,16(,15)\n");
-  fprintf (f, "\tALR\t0,2\n");
-  fprintf (f, "\tCL\t0,12(,12)\n");
-  fprintf (f, "\tBNH\t*+10\n");
-  fprintf (f, "\tL\t15,116(,12)\n");
-  fprintf (f, "\tBALR\t14,15\n");
-  fprintf (f, "\tL\t15,72(,13)\n");
-  fprintf (f, "\tSTM\t15,0,72(2)\n");
-  fprintf (f, "\tMVI\t0(2),X'10'\n");
-  fprintf (f, "\tST\t2,8(,13)\n ");
-  fprintf (f, "\tST\t13,4(,2)\n ");
-  fprintf (f, "\tLR\t13,2\n");
-  fprintf (f, "\tDROP\t15\n");
-  fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
-  fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
-  function_first = 1;
-  function_label_index ++;
-#else /* !LE370 */
-  if (!function_first)
-    {
-      struct tm *function_time;
-      time_t lcltime;
-      time (&lcltime);
-      function_time = localtime (&lcltime);
-      function_year = function_time->tm_year + 1900;
-      function_month = function_time->tm_mon + 1;
-      function_day = function_time->tm_mday;
-      function_hour = function_time->tm_hour;
-      function_minute = function_time->tm_min;
-      function_second = function_time->tm_sec;
-      fprintf (f, "PPA2\tDS\t0F\n");
-      fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
-      fprintf (f, "\tDC\tV(CEESTART),A(0)\n");
-      fprintf (f, "\tDC\tA(CEETIMES)\n");
-      fprintf (f, "CEETIMES\tDS\t0F\n");
-      fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
-                function_year, function_month, function_day,
-                function_hour, function_minute, function_second);
-      fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
-    }
-  fprintf (f, "* Function %s prologue\n", mvs_function_name);
-  fprintf (f, "FDSD%03d\tDSECT\n", function_label_index);
-  fprintf (f, "\tDS\tD\n");
-  fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
-                       + current_function_outgoing_args_size);
-  fprintf (f, "\tORG\tFDSD%03d\n", function_label_index);
-  fprintf (f, "\tDS\tCL(120+8)\n");
-  fprintf (f, "\tORG\n");
-  fprintf (f, "\tDS\t0D\n");
-  fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index,
-          function_label_index);
-  fprintf (f, "\tDS\t0H\n");
-  assemble_name (f, mvs_function_name);
-  fprintf (f, "\tCSECT\n");
-  fprintf (f, "\tUSING\t*,15\n");
-  fprintf (f, "\tB\tFPL%03d\n", function_label_index);
-  fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);
-  fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
-  fprintf (f, "\tDC\tAL4(PPA2)\n");
-  fprintf (f, "\tDC\tAL4(0)\n");
-  fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
-  fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1);
-  fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
-       mvs_function_name);
-  fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index);
-  fprintf (f, "\tSTM\t14,12,12(13)\n");
-  fprintf (f, "\tL\t2,76(,13)\n");
-  fprintf (f, "\tL\t0,16(,15)\n");
-  fprintf (f, "\tALR\t0,2\n");
-  fprintf (f, "\tCL\t0,12(,12)\n");
-  fprintf (f, "\tBNH\t*+10\n");
-  fprintf (f, "\tL\t15,116(,12)\n");
-  fprintf (f, "\tBALR\t14,15\n");
-  fprintf (f, "\tL\t15,72(,13)\n");
-  fprintf (f, "\tSTM\t15,0,72(2)\n");
-  fprintf (f, "\tMVI\t0(2),X'10'\n");
-  fprintf (f, "\tST\t2,8(,13)\n ");
-  fprintf (f, "\tST\t13,4(,2)\n ");
-  fprintf (f, "\tLR\t13,2\n");
-  fprintf (f, "\tDROP\t15\n");
-  fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
-  fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
-  function_first = 1;
-  function_label_index += 2;
-#endif /* !LE370 */
-#endif /* MACROPROLOGUE */
-  fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
-  fprintf (f, "\tLR\t11,1\n"); 
-  fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
-  fprintf (f, "* Function %s code\n", mvs_function_name);
-
-  mvs_free_label_list ();
-  mvs_page_code = 6;
-  mvs_page_lit = 4;
-  mvs_check_page (f, 0, 0);
-  function_base_page = mvs_page_num;
-
-  /* find all labels in this routine */
-  i370_label_scan ();
-}
-#endif /* TARGET_HLASM */
-
-
-#ifdef TARGET_ELF_ABI
-/*
-   The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
-   It implements a stack that grows downward. 
-   It performs the following steps:
-   -- saves the callers non-volatile registers on the callers stack.
-   -- subtracts stackframe size from the stack pointer.
-   -- stores backpointer to old caller stack.
-  
-   XXX hack alert -- if the global var int leaf_function is non-zero, 
-   then this is a leaf, and it might be possible to optimize the prologue
-   into doing even less, e.g. not grabbing a new stackframe or maybe just a
-   partial stack frame.
-  
-   XXX hack alert -- the current stack frame is bloated into twice the 
-   needed size by unused entries. These entries make it marginally 
-   compatible with MVS/OE/USS C environment, but really they're not used
-   and could probably chopped out. Modifications to i370.md would be needed
-   also, to quite using addresses 136, 140, etc.
- */
-
-static void
-i370_output_function_prologue (f, frame_size)
-     FILE *f;
-     HOST_WIDE_INT frame_size;
-{
-  static int function_label_index = 1;
-  static int function_first = 0;
-  int stackframe_size, aligned_size;
-
-  fprintf (f, "# Function prologue\n");
-  /* define the stack, put it into its own data segment
-     FDSE == Function Stack Entry
-     FDSL == Function Stack Length */
-  stackframe_size = 
-     STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size;
-  aligned_size = (stackframe_size + 7) >> 3;
-  aligned_size <<= 3;
-  
-  fprintf (f, "# arg_size=0x%x frame_size=0x%x aligned size=0x%x\n", 
-     current_function_outgoing_args_size, frame_size, aligned_size);
-
-  fprintf (f, "\t.using\t.,r15\n");
-
-  /* Branch to exectuable part of prologue.  */
-  fprintf (f, "\tB\t.LFENT%03d\n", function_label_index);
-
-  /* write the length of the stackframe */
-  fprintf (f, "\t.long\t%d\n", aligned_size);
-
-  /* FENT == function prologue entry */
-  fprintf (f, "\t.balign 2\n.LFENT%03d:\n",
-              function_label_index);
-
-  /* store multiple registers 14,15,0,...12 at 12 bytes from sp */
-  fprintf (f, "\tSTM\tr14,r12,12(sp)\n");
-
-  /* r3 == saved callee stack pointer */
-  fprintf (f, "\tLR\tr3,sp\n");
-
-  /* 4(r15) == stackframe size */
-  fprintf (f, "\tSL\tsp,4(,r15)\n");
-
-  /* r11 points to arg list in callers stackframe; was passed in r2 */
-  fprintf (f, "\tLR\tr11,r2\n");
-
-  /* store callee stack pointer at 8(sp) */
-  /* fprintf (f, "\tST\tsp,8(,r3)\n ");  wasted cycles, no one uses this ...  */
-
-  /* backchain -- store caller sp at 4(callee_sp)  */
-  fprintf (f, "\tST\tr3,4(,sp)\n ");
-
-  fprintf (f, "\t.drop\tr15\n");
-  /* Place contents of the PSW into r3
-     that is, place the address of "." into r3 */
-  fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER);
-  fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER);
-  function_first = 1;
-  function_label_index ++;
-
-  fprintf (f, ".LPG%d:\n", mvs_page_num  );
-  fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num);
-  fprintf (f, "# Function code\n");
-
-  mvs_free_label_list ();
-  mvs_page_code = 6;
-  mvs_page_lit = 4;
-  mvs_check_page (f, 0, 0);
-  function_base_page = mvs_page_num;
-
-  /* find all labels in this routine */
-  i370_label_scan ();
-}
-#endif /* TARGET_ELF_ABI */
-
-/* This function generates the assembly code for function exit.
-   Args are as for output_function_prologue ().
-
-   The function epilogue should not depend on the current stack
-   pointer!  It should use the frame pointer only.  This is mandatory
-   because of alloca; we also take advantage of it to omit stack
-   adjustments before returning.  */
-
-static void
-i370_output_function_epilogue (file, l)
-     FILE *file;
-     HOST_WIDE_INT l ATTRIBUTE_UNUSED;
-{
-  int i;
-
-  check_label_emit ();
-  mvs_check_page (file, 14, 0);
-  fprintf (file, "* Function %s epilogue\n", mvs_function_name);
-  mvs_page_num++;
-
-#if MACROEPILOGUE == 1
-  fprintf (file, "\tEDCEPIL\n");
-#else /* MACROEPILOGUE != 1 */
-  fprintf (file, "\tL\t13,4(,13)\n");
-  fprintf (file, "\tL\t14,12(,13)\n");
-  fprintf (file, "\tLM\t2,12,28(13)\n");
-  fprintf (file, "\tBALR\t1,14\n");
-  fprintf (file, "\tDC\tA(");
-  assemble_name (file, mvs_function_name);
-  fprintf (file, ")\n" );
-#endif /* MACROEPILOGUE */
-
-  fprintf (file, "* Function %s literal pool\n", mvs_function_name);
-  fprintf (file, "\tDS\t0F\n" );
-  fprintf (file, "\tLTORG\n");
-  fprintf (file, "* Function %s page table\n", mvs_function_name);
-  fprintf (file, "\tDS\t0F\n");
-  fprintf (file, "PGT%d\tEQU\t*\n", function_base_page);
-
-  mvs_free_label_list();
-  for (i = function_base_page; i < mvs_page_num; i++)
-    fprintf (file, "\tDC\tA(PG%d)\n", i);
-}