OSDN Git Service

92d2795691ecb10067cdc46ffda936aa3cb9015f
[pf3gnuchains/gcc-fork.git] / gcc / config / i370 / i370.c
1 /* Subroutines for insn-output.c for System/370.
2    Copyright (C) 1989, 1993, 1995, 1997, 1998, 1999, 2000, 2002
3    Free Software Foundation, Inc.
4    Contributed by Jan Stein (jan@cd.chalmers.se).
5    Modified for OS/390 LanguageEnvironment C by Dave Pitts (dpitts@cozx.com)
6    Hacked for Linux-ELF/390 by Linas Vepstas (linas@linas.org) 
7
8 This file is part of GNU CC.
9
10 GNU CC is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 GNU CC is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GNU CC; see the file COPYING.  If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "real.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "flags.h"
39 #include "recog.h"
40 #include "toplev.h"
41 #include "cpplib.h"
42 #include "tm_p.h"
43 #include "target.h"
44 #include "target-def.h"
45
46 extern FILE *asm_out_file;
47
48 /* Label node.  This structure is used to keep track of labels 
49       on the various pages in the current routine.
50    The label_id is the numeric ID of the label,
51    The label_page is the page on which it actually appears,
52    The first_ref_page is the page on which the true first ref appears.
53    The label_addr is an estimate of its location in the current routine,
54    The label_first & last_ref are estimates of where the earliest and
55       latest references to this label occur.  */
56
57 typedef struct label_node
58   {
59     struct label_node *label_next;
60     int label_id;
61     int label_page;
62     int first_ref_page;
63
64     int label_addr;
65     int label_first_ref;
66     int label_last_ref;
67   }
68 label_node_t;
69
70 /* Is 1 when a label has been generated and the base register must be reloaded.  */
71 int mvs_need_base_reload = 0;
72
73 /* Current function starting base page.  */
74 int function_base_page;
75
76 /* Length of the current page code.  */
77 int mvs_page_code;
78
79 /* Length of the current page literals.  */
80 int mvs_page_lit;
81
82 /* Current function name.  */
83 char *mvs_function_name = 0;
84
85 /* Current function name length.  */
86 int mvs_function_name_length = 0;
87
88 /* Page number for multi-page functions.  */
89 int mvs_page_num = 0;
90
91 /* Label node list anchor.  */
92 static label_node_t *label_anchor = 0;
93
94 /* Label node free list anchor.  */
95 static label_node_t *free_anchor = 0;
96
97 /* Assembler source file descriptor.  */
98 static FILE *assembler_source = 0;
99
100 static label_node_t * mvs_get_label PARAMS ((int));
101 static void i370_label_scan PARAMS ((void));
102 #ifdef TARGET_HLASM
103 static bool i370_hlasm_assemble_integer PARAMS ((rtx, unsigned int, int));
104 static void i370_globalize_label PARAMS ((FILE *, const char *));
105 #endif
106 static void i370_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
107 static void i370_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
108 #ifdef LONGEXTERNAL
109 static int mvs_hash_alias PARAMS ((const char *));
110 #endif
111 static void i370_encode_section_info PARAMS ((tree, int));
112
113 /* ===================================================== */
114 /* defines and functions specific to the HLASM assembler */
115 #ifdef TARGET_HLASM
116
117 #define MVS_HASH_PRIME 999983
118 #if defined(HOST_EBCDIC)
119 #define MVS_SET_SIZE 256
120 #else
121 #define MVS_SET_SIZE 128
122 #endif
123
124 #ifndef MAX_MVS_LABEL_SIZE
125 #define MAX_MVS_LABEL_SIZE 8
126 #endif
127
128 #define MAX_LONG_LABEL_SIZE 255
129
130 /* Alias node, this structure is used to keep track of aliases to external
131    variables. The IBM assembler allows an alias to an external name 
132    that is longer that 8 characters; but only once per assembly.
133    Also, this structure stores the #pragma map info.  */
134 typedef struct alias_node
135   {
136     struct alias_node *alias_next;
137     int  alias_emitted;
138     char alias_name [MAX_MVS_LABEL_SIZE + 1];
139     char real_name [MAX_LONG_LABEL_SIZE + 1];
140   }
141 alias_node_t;
142
143 /* Alias node list anchor.  */
144 static alias_node_t *alias_anchor = 0;
145
146 /* Define the length of the internal MVS function table.  */
147 #define MVS_FUNCTION_TABLE_LENGTH 32
148
149 /* C/370 internal function table.  These functions use non-standard linkage
150    and must handled in a special manner.  */
151 static const char *const mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] =
152 {
153 #if defined(HOST_EBCDIC) /* Changed for EBCDIC collating sequence */
154    "ceil",     "edc_acos", "edc_asin", "edc_atan", "edc_ata2", "edc_cos",
155    "edc_cosh", "edc_erf",  "edc_erfc", "edc_exp",  "edc_gamm", "edc_lg10",
156    "edc_log",  "edc_sin",  "edc_sinh", "edc_sqrt", "edc_tan",  "edc_tanh",
157    "fabs",     "floor",    "fmod",     "frexp",    "hypot",    "jn",
158    "j0",       "j1",       "ldexp",    "modf",     "pow",      "yn",
159    "y0",       "y1"
160 #else
161    "ceil",     "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos",
162    "edc_cosh", "edc_erf",  "edc_erfc", "edc_exp",  "edc_gamm", "edc_lg10",
163    "edc_log",  "edc_sin",  "edc_sinh", "edc_sqrt", "edc_tan",  "edc_tanh",
164    "fabs",     "floor",    "fmod",     "frexp",    "hypot",    "j0",
165    "j1",       "jn",       "ldexp",    "modf",     "pow",      "y0",
166    "y1",       "yn"
167 #endif
168 };
169
170 #endif /* TARGET_HLASM */
171 /* ===================================================== */
172
173 /* ASCII to EBCDIC conversion table.  */
174 static const unsigned char ascebc[256] =
175 {
176  /*00  NL    SH    SX    EX    ET    NQ    AK    BL */
177      0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
178  /*08  BS    HT    LF    VT    FF    CR    SO    SI */
179      0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
180  /*10  DL    D1    D2    D3    D4    NK    SN    EB */
181      0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
182  /*18  CN    EM    SB    EC    FS    GS    RS    US */
183      0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
184  /*20  SP     !     "     #     $     %     &     ' */
185      0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
186  /*28   (     )     *     +     ,     -    .      / */
187      0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
188  /*30   0     1     2     3     4     5     6     7 */
189      0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
190  /*38   8     9     :     ;     <     =     >     ? */
191      0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
192  /*40   @     A     B     C     D     E     F     G */
193      0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
194  /*48   H     I     J     K     L     M     N     O */
195      0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
196  /*50   P     Q     R     S     T     U     V     W */
197      0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
198  /*58   X     Y     Z     [     \     ]     ^     _ */
199      0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
200  /*60   `     a     b     c     d     e     f     g */
201      0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
202  /*68   h     i     j     k     l     m     n     o */
203      0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
204  /*70   p     q     r     s     t     u     v     w */
205      0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
206  /*78   x     y     z     {     |     }     ~    DL */
207      0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
208      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
209      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
210      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
211      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
212      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
213      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
214      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
215      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
216      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
217      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
218      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
219      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
220      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
221      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
222      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
223      0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
224 };
225
226 /* EBCDIC to ASCII conversion table.  */
227 static const unsigned char ebcasc[256] =
228 {
229  /*00  NU    SH    SX    EX    PF    HT    LC    DL */
230      0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
231  /*08              SM    VT    FF    CR    SO    SI */
232      0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
233  /*10  DE    D1    D2    TM    RS    NL    BS    IL */
234      0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
235  /*18  CN    EM    CC    C1    FS    GS    RS    US */
236      0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
237  /*20  DS    SS    FS          BP    LF    EB    EC */
238      0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
239  /*28              SM    C2    EQ    AK    BL       */
240      0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
241  /*30              SY          PN    RS    UC    ET */
242      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
243  /*38                    C3    D4    NK          SU */
244      0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
245  /*40  SP                                           */
246      0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247  /*48                     .     <     (     +     | */
248      0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
249  /*50   &                                           */
250      0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251  /*58               !     $     *     )     ;     ^ */
252      0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
253  /*60   -     /                                     */
254      0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255  /*68                     ,     %     _     >     ? */
256      0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
257  /*70                                               */
258      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259  /*78         `     :     #     @     '     =     " */
260      0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
261  /*80         a     b     c     d     e     f     g */
262      0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
263  /*88   h     i           {                         */
264      0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
265  /*90         j     k     l     m     n     o     p */
266      0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
267  /*98   q     r           }                         */
268      0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
269  /*A0         ~     s     t     u     v     w     x */
270      0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
271  /*A8   y     z                       [             */
272      0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
273  /*B0                                               */
274      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275  /*B8                                 ]             */
276      0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
277  /*C0   {     A     B     C     D     E     F     G */
278      0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
279  /*C8   H     I                                     */
280      0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281  /*D0   }     J     K     L     M     N     O     P */
282      0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
283  /*D8   Q     R                                     */
284      0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285  /*E0   \           S     T     U     V     W     X */
286      0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
287  /*E8   Y     Z                                     */
288      0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289  /*F0   0     1     2     3     4     5     6     7 */
290      0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
291  /*F8   8     9                                     */
292      0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
293 };
294 \f
295 /* Initialize the GCC target structure.  */
296 #ifdef TARGET_HLASM
297 #undef TARGET_ASM_BYTE_OP
298 #define TARGET_ASM_BYTE_OP NULL
299 #undef TARGET_ASM_ALIGNED_HI_OP
300 #define TARGET_ASM_ALIGNED_HI_OP NULL
301 #undef TARGET_ASM_ALIGNED_SI_OP
302 #define TARGET_ASM_ALIGNED_SI_OP NULL
303 #undef TARGET_ASM_INTEGER
304 #define TARGET_ASM_INTEGER i370_hlasm_assemble_integer
305 #undef TARGET_ASM_GLOBALIZE_LABEL
306 #define TARGET_ASM_GLOBALIZE_LABEL i370_globalize_label
307 #endif
308
309 #undef TARGET_ASM_FUNCTION_PROLOGUE
310 #define TARGET_ASM_FUNCTION_PROLOGUE i370_output_function_prologue
311 #undef TARGET_ASM_FUNCTION_EPILOGUE
312 #define TARGET_ASM_FUNCTION_EPILOGUE i370_output_function_epilogue
313 #undef TARGET_ENCODE_SECTION_INFO
314 #define TARGET_ENCODE_SECTION_INFO i370_encode_section_info
315
316 struct gcc_target targetm = TARGET_INITIALIZER;
317 \f
318 /* Map characters from one character set to another.
319    C is the character to be translated.  */
320
321 char
322 mvs_map_char (c)
323      int c;
324 {
325 #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
326   fprintf (stderr, "mvs_map_char: TE & !HE: c = %02x\n", c);
327   return ascebc[c];
328 #else
329 #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
330   fprintf (stderr, "mvs_map_char: !TE & HE: c = %02x\n", c);
331   return ebcasc[c];
332 #else
333   fprintf (stderr, "mvs_map_char: !TE & !HE: c = %02x\n", c);
334   return c;
335 #endif
336 #endif
337 }
338
339 /* ===================================================== */
340 /* The following three routines are used to determine whther 
341    forward branch is on this page, or is a far jump.  We use
342    the "length" attr on an insn [(set_atter "length" "4")]
343    to store the largest possible code length that insn
344    could have.  This gives us a hint of the address of a
345    branch destination, and from that, we can work out 
346    the length of the jump, and whether its on page or not. 
347  */
348
349 /* Return the destination address of a branch.  */
350
351 int
352 i370_branch_dest (branch)
353      rtx branch;
354 {
355   rtx dest = SET_SRC (PATTERN (branch));
356   int dest_uid;
357   int dest_addr;
358
359   /* first, compute the estimated address of the branch target */
360   if (GET_CODE (dest) == IF_THEN_ELSE)
361     dest = XEXP (dest, 1);
362   dest = XEXP (dest, 0);
363   dest_uid = INSN_UID (dest);
364   dest_addr = INSN_ADDRESSES (dest_uid);
365
366   /* next, record the address of this insn as the true addr of first ref */
367   {
368      label_node_t *lp;
369      rtx label = JUMP_LABEL (branch);
370      int labelno = CODE_LABEL_NUMBER (label);
371
372      if (!label || CODE_LABEL != GET_CODE (label)) abort ();
373
374      lp = mvs_get_label (labelno);
375      if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num;
376   }
377   return dest_addr;
378 }
379
380 int
381 i370_branch_length (insn)
382      rtx insn;
383 {
384   int here, there;
385   here = INSN_ADDRESSES (INSN_UID (insn));
386   there = i370_branch_dest (insn);
387   return (there - here);
388 }
389
390
391 int
392 i370_short_branch (insn)
393      rtx insn;
394 {
395   int base_offset;
396
397   base_offset = i370_branch_length(insn);
398   if (0 > base_offset) 
399     {
400       base_offset += mvs_page_code;
401     } 
402   else 
403     {
404       /* avoid bumping into lit pool; use 2x to estimate max possible lits */
405       base_offset *= 2;
406       base_offset += mvs_page_code + mvs_page_lit;
407     }
408   
409   /* make a conservative estimate of room left on page */
410   if ((4060 >base_offset) && ( 0 < base_offset)) return 1;
411   return 0;
412 }
413
414 /* The i370_label_scan() routine is supposed to loop over
415    all labels and label references in a compilation unit,
416    and determine whether all label refs appear on the same 
417    code page as the label. If they do, then we can avoid 
418    a reload of the base register for that label.
419   
420    Note that the instruction addresses used here are only 
421    approximate, and make the sizes of the jumps appear
422    farther apart then they will actually be.  This makes 
423    this code far more conservative than it needs to be.
424  */
425
426 #define I370_RECORD_LABEL_REF(label,addr) {                             \
427         label_node_t *lp;                                               \
428         int labelno = CODE_LABEL_NUMBER (label);                        \
429         lp = mvs_get_label (labelno);                                   \
430         if (addr < lp -> label_first_ref) lp->label_first_ref = addr;   \
431         if (addr > lp -> label_last_ref) lp->label_last_ref = addr;     \
432 }
433
434 static void 
435 i370_label_scan () 
436 {
437    rtx insn;
438    label_node_t *lp;
439    int tablejump_offset = 0;
440
441    for (insn = get_insns(); insn; insn = NEXT_INSN(insn))
442      {
443        int here = INSN_ADDRESSES (INSN_UID (insn));
444        enum rtx_code code = GET_CODE(insn);
445
446        /* ??? adjust for tables embedded in the .text section that
447         * the compiler didn't take into account */
448        here += tablejump_offset;
449        INSN_ADDRESSES (INSN_UID (insn)) = here;
450
451        /* check to see if this insn is a label ...  */
452        if (CODE_LABEL == code)
453          {
454            int labelno = CODE_LABEL_NUMBER (insn);
455
456            lp = mvs_get_label (labelno);
457            lp -> label_addr = here;
458 #if 0
459            /* Supposedly, labels are supposed to have circular
460               lists of label-refs that reference them, 
461               setup in flow.c, but this does not appear to be the case.  */
462            rtx labelref = LABEL_REFS (insn);
463            rtx ref = labelref;
464            do 
465              {
466                rtx linsn = CONTAINING_INSN(ref);
467                ref =  LABEL_NEXTREF(ref);
468              } while (ref && (ref != labelref));
469 #endif
470          }
471        else
472        if (JUMP_INSN == code)
473          {
474            rtx label = JUMP_LABEL (insn);
475
476            /* If there is no label for this jump, then this
477               had better be a ADDR_VEC or an ADDR_DIFF_VEC
478               and there had better be a vector of labels.  */
479            if (!label) 
480              {
481                int j;
482                rtx body = PATTERN (insn);
483                if (ADDR_VEC == GET_CODE(body)) 
484                  {
485                     for (j=0; j < XVECLEN (body, 0); j++)
486                       {
487                          rtx lref = XVECEXP (body, 0, j);
488                          if (LABEL_REF != GET_CODE (lref)) abort ();
489                          label = XEXP (lref,0);
490                          if (CODE_LABEL != GET_CODE (label)) abort ();
491                          tablejump_offset += 4;
492                          here += 4;
493                          I370_RECORD_LABEL_REF(label,here);
494                       }
495                     /* finished with the vector go do next insn */
496                     continue;
497                  }
498                else
499                if (ADDR_DIFF_VEC == GET_CODE(body))
500                  {
501 /* XXX hack alert.
502    Right now, we leave this as a no-op, but strictly speaking,
503    this is incorrect.  It is possible that a table-jump
504    driven off of a relative address could take us off-page,
505    to a place where we need to reload the base reg.  So really,
506    we need to examing both labels, and compare thier values
507    to the current basereg value.
508   
509    More generally, this brings up a troubling issue overall:
510    what happens if a tablejump is split across two pages? I do 
511    not beleive that this case is handled correctly at all, and
512    can only lead to horrible results if this were to occur.
513   
514    However, the current situation is not any worse than it was 
515    last week, and so we punt for now.  */
516
517                     debug_rtx (insn);
518                     for (j=0; j < XVECLEN (body, 0); j++)
519                       {
520                       }
521                     /* finished with the vector go do next insn */
522                     continue;
523                  }
524                else 
525                  {
526 /* XXX hack alert.
527    Compiling the exception handling (L_eh) in libgcc2.a will trip
528    up right here, with something that looks like
529    (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
530       {indirect_jump} 
531    I'm not sure of what leads up to this, but it looks like
532    the makings of a long jump which will surely get us into trouble
533    because the base & page registers don't get reloaded.  For now
534    I'm not sure of what to do ... again we punt ... we are not worse
535    off than yesterday.  */
536
537                     /* print_rtl_single (stdout, insn); */
538                     debug_rtx (insn);
539                     /* abort(); */
540                     continue;
541                  }
542             }
543           else
544             {
545               /* At this point, this jump_insn had better be a plain-old
546                  ordinary one, grap the label id and go */
547               if (CODE_LABEL != GET_CODE (label)) abort ();
548               I370_RECORD_LABEL_REF(label,here);
549             }
550         }
551
552       /* Sometimes, we take addresses of labels and use them
553          as instruction operands ... these show up as REG_NOTES */
554       else
555       if (INSN == code)
556        {
557          if ('i' == GET_RTX_CLASS (code)) 
558            {
559               rtx note;
560               for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
561                 {
562                    if (REG_LABEL == REG_NOTE_KIND(note))
563                      {
564                         rtx label = XEXP (note,0);
565                         if (!label || CODE_LABEL != GET_CODE (label)) abort ();
566
567                         I370_RECORD_LABEL_REF(label,here);
568                      }
569                 }
570            }
571        }
572    }
573 }
574
575 /* ===================================================== */
576
577 /* Emit reload of base register if indicated.  This is to eliminate multiple
578    reloads when several labels are generated pointing to the same place
579    in the code.  
580
581    The page table is written at the end of the function. 
582    The entries in the page table look like
583      .LPGT0:          // PGT0 EQU *
584      .long .LPG0      // DC A(PG0)
585      .long .LPG1      // DC A(PG1)
586   while the prologue generates
587       L       r4,=A(.LPGT0)
588
589   Note that this paging scheme breaks down if a single subroutine 
590   has more than about 10MB of code in it ... as long as humans write
591   code, this shouldn't be a problem ...
592  */
593
594 void
595 check_label_emit ()
596 {
597   if (mvs_need_base_reload)
598     {
599       mvs_need_base_reload = 0;
600
601       mvs_page_code += 4;
602       fprintf (assembler_source, "\tL\t%d,%d(,%d)\n",
603           BASE_REGISTER, (mvs_page_num - function_base_page) * 4,
604           PAGE_REGISTER);
605     }
606 }
607
608 /* Add the label to the current page label list.  If a free element is available
609    it will be used for the new label.  Otherwise, a label element will be
610    allocated from memory.
611    ID is the label number of the label being added to the list.  */
612
613 static label_node_t *
614 mvs_get_label (id)
615      int id;
616 {
617   label_node_t *lp;
618
619   /* first, lets see if we already go one, if so, use that.  */
620   for (lp = label_anchor; lp; lp = lp->label_next)
621     {
622       if (lp->label_id == id) return lp;
623     }
624
625   /* not found, get a new one */
626   if (free_anchor)
627     {
628       lp = free_anchor;
629       free_anchor = lp->label_next;
630     }
631   else
632     {
633       lp = (label_node_t *) xmalloc (sizeof (label_node_t));
634     }
635
636   /* initialize for new label */
637   lp->label_id = id;
638   lp->label_page = -1;
639   lp->label_next = label_anchor;
640   lp->label_first_ref = 2000123123;
641   lp->label_last_ref = -1;
642   lp->label_addr = -1;
643   lp->first_ref_page = -1;
644   label_anchor = lp;
645
646   return lp;
647 }
648
649 void
650 mvs_add_label (id)
651      int id;
652 {
653   label_node_t *lp;
654   int fwd_distance;
655
656   lp = mvs_get_label (id);
657   lp->label_page = mvs_page_num;
658
659   /* OK, we just saw the label.  Determine if this label
660    * needs a reload of the base register */
661   if ((-1 != lp->first_ref_page) && 
662       (lp->first_ref_page != mvs_page_num)) 
663     {
664       /* Yep; the first label_ref was on a different page.  */
665       mvs_need_base_reload ++;
666       return;
667     }
668
669   /* Hmm.  Try to see if the estimated address of the last
670      label_ref is on the current page.  If it is, then we
671      don't need a base reg reload.  Note that this estimate
672      is very conservatively handled; we'll tend to have 
673      a good bit more reloads than actually needed.  Someday,
674      we should tighten the estimates (which are driven by
675      the (set_att "length") insn attibute.
676     
677      Currently, we estimate that number of page literals 
678      same as number of insns, which is a vast overestimate,
679      esp that the estimate of each insn size is its max size.  */
680
681   /* if latest ref comes before label, we are clear */
682   if (lp->label_last_ref < lp->label_addr) return;
683
684   fwd_distance = lp->label_last_ref - lp->label_addr;
685
686   if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return;
687
688   mvs_need_base_reload ++;
689 }
690
691 /* Check to see if the label is in the list and in the current
692    page.  If not found, we have to make worst case assumption 
693    that label will be on a different page, and thus will have to
694    generate a load and branch on register.  This is rather
695    ugly for forward-jumps, but what can we do? For backward
696    jumps on the same page we can branch directly to address.
697    ID is the label number of the label being checked.  */
698
699 int
700 mvs_check_label (id)
701      int id;
702 {
703   label_node_t *lp;
704
705   for (lp = label_anchor; lp; lp = lp->label_next)
706     {
707       if (lp->label_id == id) 
708         {
709           if (lp->label_page == mvs_page_num) 
710             {
711                return 1;
712             } 
713           else 
714             {
715                return 0;
716             } 
717         }
718     }
719   return 0;
720 }
721
722 /* Get the page on which the label sits.  This will be used to 
723    determine is a register reload is really needed.  */
724
725 #if 0
726 int
727 mvs_get_label_page(int id)
728 {
729   label_node_t *lp;
730
731   for (lp = label_anchor; lp; lp = lp->label_next)
732     {
733       if (lp->label_id == id)
734         return lp->label_page;
735     }
736   return -1;
737 }
738 #endif
739
740 /* The label list for the current page freed by linking the list onto the free
741    label element chain.  */
742
743 void
744 mvs_free_label_list ()
745 {
746
747   if (label_anchor)
748     {
749       label_node_t *last_lp = label_anchor;
750       while (last_lp->label_next) last_lp = last_lp->label_next;
751       last_lp->label_next = free_anchor;
752       free_anchor = label_anchor;
753     }
754   label_anchor = 0;
755 }
756
757 /* ====================================================================== */
758 /* If the page size limit is reached a new code page is started, and the base
759    register is set to it.  This page break point is counted conservatively,
760    most literals that have the same value are collapsed by the assembler.
761    True is returned when a new page is started.
762    FILE is the assembler output file descriptor.
763    CODE is the length, in bytes, of the instruction to be emitted.
764    LIT is the length of the literal to be emitted.  */
765
766 #ifdef TARGET_HLASM
767 int
768 mvs_check_page (file, code, lit)
769      FILE *file;
770      int code, lit;
771 {
772   if (file)
773     assembler_source = file;
774
775   if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
776     {
777       fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num);
778       fprintf (assembler_source, "\tDS\t0F\n");
779       fprintf (assembler_source, "\tLTORG\n");
780       fprintf (assembler_source, "\tDS\t0F\n");
781       fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num);
782       fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER);
783       mvs_page_num++;
784       /* Safe to use BASR not BALR, since we are
785        * not switching addressing mode here ...  */
786       fprintf (assembler_source, "\tBASR\t%d,0\n", BASE_REGISTER);
787       fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num);
788       fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER);
789       mvs_page_code = code;
790       mvs_page_lit = lit;
791       return 1;
792     }
793   mvs_page_code += code;
794   mvs_page_lit += lit;
795   return 0;
796 }
797 #endif /* TARGET_HLASM */
798
799
800 #ifdef TARGET_ELF_ABI
801 int
802 mvs_check_page (file, code, lit)
803      FILE *file;
804      int code, lit;
805 {
806   if (file)
807     assembler_source = file;
808
809   if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
810     {
811       /* hop past the literal pool */
812       fprintf (assembler_source, "\tB\t.LPGE%d\n", mvs_page_num);
813
814       /* dump the literal pool. The .baligns are optional, since 
815        * ltorg will align to the size of the largest literal 
816        * (which is possibly 8 bytes) */
817       fprintf (assembler_source, "\t.balign\t4\n");
818       fprintf (assembler_source, "\t.LTORG\n");
819       fprintf (assembler_source, "\t.balign\t4\n");
820
821       /* we continue execution here ...  */
822       fprintf (assembler_source, ".LPGE%d:\n", mvs_page_num);
823       fprintf (assembler_source, "\t.DROP\t%d\n", BASE_REGISTER);
824       mvs_page_num++;
825
826       /* BASR puts the contents of the PSW into r3
827        * that is, r3 will be loaded with the address of "." */
828       fprintf (assembler_source, "\tBASR\tr%d,0\n", BASE_REGISTER);
829       fprintf (assembler_source, ".LPG%d:\n", mvs_page_num);
830       fprintf (assembler_source, "\t.USING\t.,r%d\n", BASE_REGISTER);
831       mvs_page_code = code;
832       mvs_page_lit = lit;
833       return 1;
834     }
835   mvs_page_code += code;
836   mvs_page_lit += lit;
837   return 0;
838 }
839 #endif /* TARGET_ELF_ABI */
840
841 /* ===================================================== */
842 /* defines and functions specific to the HLASM assembler */
843 #ifdef TARGET_HLASM
844
845 /* Check for C/370 runtime function, they don't use standard calling
846    conventions.  True is returned if the function is in the table.
847    NAME is the name of the current function.  */
848
849 int
850 mvs_function_check (name)
851      const char *name;
852 {
853   int lower, middle, upper;
854   int i;
855
856   lower = 0;
857   upper = MVS_FUNCTION_TABLE_LENGTH - 1;
858   while (lower <= upper)
859     {
860       middle = (lower + upper) / 2;
861       i = strcmp (name, mvs_function_table[middle]);
862       if (i == 0)
863         return 1;
864       if (i < 0)
865         upper = middle - 1;
866       else
867         lower = middle + 1;
868     }
869   return 0;
870 }
871
872 /* Generate a hash for a given key.  */
873
874 #ifdef LONGEXTERNAL
875 static int
876 mvs_hash_alias (key)
877      const char *key;
878 {
879   int h;
880   int i;
881   int l = strlen (key);
882
883   h = key[0];
884   for (i = 1; i < l; i++)
885     h = ((h * MVS_SET_SIZE) + key[i]) % MVS_HASH_PRIME;
886   return (h);
887 }
888 #endif
889
890 /* Add the alias to the current alias list.  */
891
892 void
893 mvs_add_alias (realname, aliasname, emitted)
894      const char *realname;
895      const char *aliasname;
896      int   emitted;
897 {
898   alias_node_t *ap;
899
900   ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
901   if (strlen (realname) > MAX_LONG_LABEL_SIZE)
902     {
903       warning ("real name is too long - alias ignored");
904       return;
905     }
906   if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
907     {
908       warning ("alias name is too long - alias ignored");
909       return;
910     }
911       
912   strcpy (ap->real_name, realname);
913   strcpy (ap->alias_name, aliasname);
914   ap->alias_emitted = emitted;
915   ap->alias_next = alias_anchor;
916   alias_anchor = ap;
917 }
918
919 /* Check to see if the name needs aliasing. ie. the name is either:
920      1. Longer than 8 characters
921      2. Contains an underscore
922      3. Is mixed case */
923
924 int
925 mvs_need_alias (realname)
926       const char *realname;
927 {
928    int i, j = strlen (realname);
929
930    if (mvs_function_check (realname))
931      return 0;
932 #if 0
933    if (!strcmp (realname, "gccmain"))
934      return 0;
935    if (!strcmp (realname, "main"))
936      return 0;
937 #endif
938    if (j > MAX_MVS_LABEL_SIZE)
939      return 1;
940    if (strchr (realname, '_') != 0)
941      return 1;
942    if (ISUPPER (realname[0]))
943      {
944        for (i = 1; i < j; i++)
945          {
946            if (ISLOWER (realname[i]))
947              return 1;
948          }
949      }
950    else
951      {
952        for (i = 1; i < j; i++)
953          {
954            if (ISUPPER (realname[i]))
955              return 1;
956          }
957      }
958
959    return 0;
960 }
961
962 /* Get the alias from the list. 
963    If 1 is returned then it's in the alias list, 0 if it was not */
964
965 int
966 mvs_get_alias (realname, aliasname)
967      const char *realname;
968      char *aliasname;
969 {
970 #ifdef LONGEXTERNAL
971   alias_node_t *ap;
972
973   for (ap = alias_anchor; ap; ap = ap->alias_next)
974     {
975       if (!strcmp (ap->real_name, realname))
976         {
977           strcpy (aliasname, ap->alias_name);
978           return 1;
979         }
980     }
981   if (mvs_need_alias (realname))
982     {
983       char c1, c2;
984
985       c1 = realname[0];
986       c2 = realname[1];
987       if (ISLOWER (c1)) c1 = TOUPPER (c1);
988       else if (c1 == '_') c1 = 'A';
989       if (ISLOWER (c2)) c2 = TOUPPER (c2);
990       else if (c2 == '_' || c2 == '\0') c2 = '#';
991
992       sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
993       mvs_add_alias (realname, aliasname, 0);
994       return 1;
995     }
996 #else
997   if (strlen (realname) > MAX_MVS_LABEL_SIZE)
998     {
999       strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1000       aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1001       return 1;
1002     }
1003 #endif
1004   return 0;
1005 }
1006
1007 /* Check to see if the alias is in the list. 
1008    If 1 is returned then it's in the alias list, 2 it was emitted  */
1009
1010 int
1011 mvs_check_alias (realname, aliasname)
1012      const char *realname;
1013      char *aliasname;
1014 {
1015 #ifdef LONGEXTERNAL
1016   alias_node_t *ap;
1017
1018   for (ap = alias_anchor; ap; ap = ap->alias_next)
1019     {
1020       if (!strcmp (ap->real_name, realname))
1021         {
1022           int rc = (ap->alias_emitted == 1) ? 1 : 2; 
1023           strcpy (aliasname, ap->alias_name);
1024           ap->alias_emitted = 1; 
1025           return rc;
1026         }
1027     }
1028   if (mvs_need_alias (realname))
1029     {
1030       char c1, c2;
1031
1032       c1 = realname[0];
1033       c2 = realname[1];
1034       if (ISLOWER (c1)) c1 = TOUPPER (c1);
1035       else if (c1 == '_') c1 = 'A';
1036       if (ISLOWER (c2)) c2 = TOUPPER (c2);
1037       else if (c2 == '_' || c2 == '\0') c2 = '#';
1038
1039       sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
1040       mvs_add_alias (realname, aliasname, 0);
1041       alias_anchor->alias_emitted = 1;
1042       return 2;
1043     }
1044 #else
1045   if (strlen (realname) > MAX_MVS_LABEL_SIZE)
1046     {
1047       strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1048       aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1049       return 1;
1050     }
1051 #endif
1052   return 0;
1053 }
1054
1055 /* defines and functions specific to the HLASM assembler */
1056 #endif /* TARGET_HLASM */
1057 /* ===================================================== */
1058 /* ===================================================== */
1059 /* defines and functions specific to the gas assembler */
1060 #ifdef TARGET_ELF_ABI
1061
1062 /* Check for C/370 runtime function, they don't use standard calling
1063    conventions.  True is returned if the function is in the table.
1064    NAME is the name of the current function.  */
1065 /* no special calling conventions (yet ??) */
1066
1067 int
1068 mvs_function_check (name)
1069      const char *name ATTRIBUTE_UNUSED;
1070 {
1071    return 0;
1072 }
1073
1074 #endif /* TARGET_ELF_ABI */
1075 /* ===================================================== */
1076
1077
1078 /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
1079    OP is the current operation.
1080    MODE is the current operation mode.  */
1081
1082 int
1083 s_operand (op, mode)
1084      register rtx op;
1085      enum machine_mode mode;
1086 {
1087   extern int volatile_ok;
1088   register enum rtx_code code = GET_CODE (op);
1089
1090   if (CONSTANT_ADDRESS_P (op))
1091     return 1;
1092   if (mode == VOIDmode || GET_MODE (op) != mode)
1093     return 0;
1094   if (code == MEM)
1095     {
1096       register rtx x = XEXP (op, 0);
1097
1098       if (!volatile_ok && op->volatil)
1099         return 0;
1100       if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1101         return 1;
1102       if (GET_CODE (x) == PLUS
1103           && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1104           && GET_CODE (XEXP (x, 1)) == CONST_INT
1105           && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1106         return 1;
1107     }
1108   return 0;
1109 }
1110
1111
1112 /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
1113    instruction.
1114    OP is the current operation.
1115    MODE is the current operation mode.  */
1116
1117 int
1118 r_or_s_operand (op, mode)
1119      register rtx op;
1120      enum machine_mode mode;
1121 {
1122   extern int volatile_ok;
1123   register enum rtx_code code = GET_CODE (op);
1124
1125   if (CONSTANT_ADDRESS_P (op))
1126     return 1;
1127   if (mode == VOIDmode || GET_MODE (op) != mode)
1128     return 0;
1129   if (code == REG)
1130     return 1;
1131   else if (code == MEM)
1132     {
1133       register rtx x = XEXP (op, 0);
1134
1135       if (!volatile_ok && op->volatil)
1136         return 0;
1137       if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1138         return 1;
1139       if (GET_CODE (x) == PLUS
1140           && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1141           && GET_CODE (XEXP (x, 1)) == CONST_INT
1142           && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1143         return 1;
1144     }
1145   return 0;
1146 }
1147
1148
1149 /* Some remarks about unsigned_jump_follows_p():
1150    gcc is built around the assumption that branches are signed
1151    or unsigned, whereas the 370 doesn't care; its the compares that
1152    are signed or unsigned.  Thus, we need to somehow know if we
1153    need to do a signed or an unsigned compare, and we do this by 
1154    looking ahead in the instruction sequence until we find a jump.
1155    We then note whether this jump is signed or unsigned, and do the 
1156    compare appropriately.  Note that we have to scan ahead indefinitley,
1157    as the gcc optimizer may insert any number of instructions between 
1158    the compare and the jump.
1159   
1160    Note that using conditional branch expanders seems to be be a more 
1161    elegant/correct way of doing this.   See, for instance, the Alpha 
1162    cmpdi and bgt patterns.  Note also that for the i370, various
1163    arithmetic insn's set the condition code as well.
1164
1165    The unsigned_jump_follows_p() routine  returns a 1 if the next jump 
1166    is unsigned.  INSN is the current instruction.  */
1167
1168 int
1169 unsigned_jump_follows_p (insn)
1170      register rtx insn;
1171 {
1172   rtx orig_insn = insn;
1173   while (1) 
1174     {
1175       register rtx tmp_insn;
1176       enum rtx_code coda;
1177   
1178       insn = NEXT_INSN (insn);
1179       if (!insn) fatal_insn ("internal error--no jump follows compare:", orig_insn);
1180   
1181       if (GET_CODE (insn) != JUMP_INSN) continue;
1182     
1183       tmp_insn = XEXP (insn, 3);
1184       if (GET_CODE (tmp_insn) != SET) continue;
1185     
1186       if (GET_CODE (XEXP (tmp_insn, 0)) != PC) continue;
1187     
1188       tmp_insn = XEXP (tmp_insn, 1);
1189       if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue;
1190     
1191       /* if we got to here, this instruction is a jump.  Is it signed? */
1192       tmp_insn = XEXP (tmp_insn, 0);
1193       coda = GET_CODE (tmp_insn);
1194   
1195       return coda != GE && coda != GT && coda != LE && coda != LT;
1196     }
1197 }
1198
1199 #ifdef TARGET_HLASM
1200
1201 /* Target hook for assembling integer objects.  This version handles all
1202    objects when TARGET_HLASM is defined.  */
1203
1204 static bool
1205 i370_hlasm_assemble_integer (x, size, aligned_p)
1206      rtx x;
1207      unsigned int size;
1208      int aligned_p;
1209 {
1210   const char *int_format = NULL;
1211
1212   if (aligned_p)
1213     switch (size)
1214       {
1215       case 1:
1216         int_format = "\tDC\tX'%02X'\n";
1217         break;
1218
1219       case 2:
1220         int_format = "\tDC\tX'%04X'\n";
1221         break;
1222
1223       case 4:
1224         if (GET_CODE (x) == CONST_INT)
1225           {
1226             fputs ("\tDC\tF'", asm_out_file);
1227             output_addr_const (asm_out_file, x);
1228             fputs ("'\n", asm_out_file);
1229           }
1230         else
1231           {
1232             fputs ("\tDC\tA(", asm_out_file);
1233             output_addr_const (asm_out_file, x);
1234             fputs (")\n", asm_out_file);
1235           }
1236         return true;
1237       }
1238
1239   if (int_format && GET_CODE (x) == CONST_INT)
1240     {
1241       fprintf (asm_out_file, int_format, INTVAL (x));
1242       return true;
1243     }
1244   return default_assemble_integer (x, size, aligned_p);
1245 }
1246
1247 /* Generate the assembly code for function entry.  FILE is a stdio
1248    stream to output the code to.  SIZE is an int: how many units of
1249    temporary storage to allocate.
1250
1251    Refer to the array `regs_ever_live' to determine which registers to
1252    save; `regs_ever_live[I]' is nonzero if register number I is ever
1253    used in the function.  This function is responsible for knowing
1254    which registers should not be saved even if used.  */
1255
1256 static void
1257 i370_output_function_prologue (f, l)
1258      FILE *f;
1259      HOST_WIDE_INT l;
1260 {
1261 #if MACROPROLOGUE == 1
1262   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1263   fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
1264            STACK_POINTER_OFFSET + l - 120 +
1265            current_function_outgoing_args_size, BASE_REGISTER);
1266 #else /* MACROPROLOGUE != 1 */
1267   static int function_label_index = 1;
1268   static int function_first = 0;
1269   static int function_year, function_month, function_day;
1270   static int function_hour, function_minute, function_second;
1271 #if defined(LE370)
1272   if (!function_first)
1273     {
1274       struct tm *function_time;
1275       time_t lcltime;
1276       time (&lcltime);
1277       function_time = localtime (&lcltime);
1278       function_year = function_time->tm_year + 1900;
1279       function_month = function_time->tm_mon + 1;
1280       function_day = function_time->tm_mday;
1281       function_hour = function_time->tm_hour;
1282       function_minute = function_time->tm_min;
1283       function_second = function_time->tm_sec;
1284     }
1285   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1286   fprintf (f, "FDSE%03d\tDSECT\n", function_label_index);
1287   fprintf (f, "\tDS\tD\n");
1288   fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
1289                         + current_function_outgoing_args_size);
1290   fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
1291   fprintf (f, "\tDS\tCL(120+8)\n");
1292   fprintf (f, "\tORG\n");
1293   fprintf (f, "\tDS\t0D\n");
1294   fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index,
1295            function_label_index);
1296   fprintf (f, "\tDS\t0H\n");
1297   assemble_name (f, mvs_function_name);
1298   fprintf (f, "\tCSECT\n");
1299   fprintf (f, "\tUSING\t*,15\n");
1300   fprintf (f, "\tB\tFENT%03d\n", function_label_index);
1301   fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index);
1302   fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1303   fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index);
1304   fprintf (f, "\tDC\tAL4(0)\n");
1305   fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1306   fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index);
1307   fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1308         mvs_function_name);
1309   fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index);
1310   fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1311   fprintf (f, "\tDC\tV(CEESTART)\n");
1312   fprintf (f, "\tDC\tAL4(0)\n");
1313   fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index);
1314   fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index);
1315   fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1316                  function_year, function_month, function_day,
1317                  function_hour, function_minute);
1318   fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1319   fprintf (f, "FENT%03d\tDS\t0H\n", function_label_index);
1320   fprintf (f, "\tSTM\t14,12,12(13)\n");
1321   fprintf (f, "\tL\t2,76(,13)\n");
1322   fprintf (f, "\tL\t0,16(,15)\n");
1323   fprintf (f, "\tALR\t0,2\n");
1324   fprintf (f, "\tCL\t0,12(,12)\n");
1325   fprintf (f, "\tBNH\t*+10\n");
1326   fprintf (f, "\tL\t15,116(,12)\n");
1327   fprintf (f, "\tBALR\t14,15\n");
1328   fprintf (f, "\tL\t15,72(,13)\n");
1329   fprintf (f, "\tSTM\t15,0,72(2)\n");
1330   fprintf (f, "\tMVI\t0(2),X'10'\n");
1331   fprintf (f, "\tST\t2,8(,13)\n ");
1332   fprintf (f, "\tST\t13,4(,2)\n ");
1333   fprintf (f, "\tLR\t13,2\n");
1334   fprintf (f, "\tDROP\t15\n");
1335   fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
1336   fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
1337   function_first = 1;
1338   function_label_index ++;
1339 #else /* !LE370 */
1340   if (!function_first)
1341     {
1342       struct tm *function_time;
1343       time_t lcltime;
1344       time (&lcltime);
1345       function_time = localtime (&lcltime);
1346       function_year = function_time->tm_year + 1900;
1347       function_month = function_time->tm_mon + 1;
1348       function_day = function_time->tm_mday;
1349       function_hour = function_time->tm_hour;
1350       function_minute = function_time->tm_min;
1351       function_second = function_time->tm_sec;
1352       fprintf (f, "PPA2\tDS\t0F\n");
1353       fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1354       fprintf (f, "\tDC\tV(CEESTART),A(0)\n");
1355       fprintf (f, "\tDC\tA(CEETIMES)\n");
1356       fprintf (f, "CEETIMES\tDS\t0F\n");
1357       fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1358                  function_year, function_month, function_day,
1359                  function_hour, function_minute, function_second);
1360       fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1361     }
1362   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1363   fprintf (f, "FDSD%03d\tDSECT\n", function_label_index);
1364   fprintf (f, "\tDS\tD\n");
1365   fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
1366                         + current_function_outgoing_args_size);
1367   fprintf (f, "\tORG\tFDSD%03d\n", function_label_index);
1368   fprintf (f, "\tDS\tCL(120+8)\n");
1369   fprintf (f, "\tORG\n");
1370   fprintf (f, "\tDS\t0D\n");
1371   fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index,
1372            function_label_index);
1373   fprintf (f, "\tDS\t0H\n");
1374   assemble_name (f, mvs_function_name);
1375   fprintf (f, "\tCSECT\n");
1376   fprintf (f, "\tUSING\t*,15\n");
1377   fprintf (f, "\tB\tFPL%03d\n", function_label_index);
1378   fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);
1379   fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1380   fprintf (f, "\tDC\tAL4(PPA2)\n");
1381   fprintf (f, "\tDC\tAL4(0)\n");
1382   fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1383   fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1);
1384   fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1385         mvs_function_name);
1386   fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index);
1387   fprintf (f, "\tSTM\t14,12,12(13)\n");
1388   fprintf (f, "\tL\t2,76(,13)\n");
1389   fprintf (f, "\tL\t0,16(,15)\n");
1390   fprintf (f, "\tALR\t0,2\n");
1391   fprintf (f, "\tCL\t0,12(,12)\n");
1392   fprintf (f, "\tBNH\t*+10\n");
1393   fprintf (f, "\tL\t15,116(,12)\n");
1394   fprintf (f, "\tBALR\t14,15\n");
1395   fprintf (f, "\tL\t15,72(,13)\n");
1396   fprintf (f, "\tSTM\t15,0,72(2)\n");
1397   fprintf (f, "\tMVI\t0(2),X'10'\n");
1398   fprintf (f, "\tST\t2,8(,13)\n ");
1399   fprintf (f, "\tST\t13,4(,2)\n ");
1400   fprintf (f, "\tLR\t13,2\n");
1401   fprintf (f, "\tDROP\t15\n");
1402   fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
1403   fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
1404   function_first = 1;
1405   function_label_index += 2;
1406 #endif /* !LE370 */
1407 #endif /* MACROPROLOGUE */
1408   fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
1409   fprintf (f, "\tLR\t11,1\n"); 
1410   fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
1411   fprintf (f, "* Function %s code\n", mvs_function_name);
1412
1413   mvs_free_label_list ();
1414   mvs_page_code = 6;
1415   mvs_page_lit = 4;
1416   mvs_check_page (f, 0, 0);
1417   function_base_page = mvs_page_num;
1418
1419   /* find all labels in this routine */
1420   i370_label_scan ();
1421 }
1422
1423 static void
1424 i370_globalize_label (stream, name)
1425      FILE *stream;
1426      const char *name;
1427 {
1428   char temp[MAX_MVS_LABEL_SIZE + 1];
1429   if (mvs_check_alias (name, temp) == 2)
1430     fprintf (stream, "%s\tALIAS\tC'%s'\n", temp, name);
1431   fputs ("\tENTRY\t", stream);
1432   assemble_name (stream, name);
1433   putc ('\n', stream);
1434 }
1435 #endif /* TARGET_HLASM */
1436
1437
1438 #ifdef TARGET_ELF_ABI
1439 /*
1440    The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
1441    It implements a stack that grows downward. 
1442    It performs the following steps:
1443    -- saves the callers non-volatile registers on the callers stack.
1444    -- subtracts stackframe size from the stack pointer.
1445    -- stores backpointer to old caller stack.
1446   
1447    XXX hack alert -- if the global var int leaf_function is nonzero, 
1448    then this is a leaf, and it might be possible to optimize the prologue
1449    into doing even less, e.g. not grabbing a new stackframe or maybe just a
1450    partial stack frame.
1451   
1452    XXX hack alert -- the current stack frame is bloated into twice the 
1453    needed size by unused entries. These entries make it marginally 
1454    compatible with MVS/OE/USS C environment, but really they're not used
1455    and could probably chopped out. Modifications to i370.md would be needed
1456    also, to quite using addresses 136, 140, etc.
1457  */
1458
1459 static void
1460 i370_output_function_prologue (f, frame_size)
1461      FILE *f;
1462      HOST_WIDE_INT frame_size;
1463 {
1464   static int function_label_index = 1;
1465   static int function_first = 0;
1466   int stackframe_size, aligned_size;
1467
1468   fprintf (f, "# Function prologue\n");
1469   /* define the stack, put it into its own data segment
1470      FDSE == Function Stack Entry
1471      FDSL == Function Stack Length */
1472   stackframe_size = 
1473      STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size;
1474   aligned_size = (stackframe_size + 7) >> 3;
1475   aligned_size <<= 3;
1476   
1477   fprintf (f, "# arg_size=0x%x frame_size=0x%x aligned size=0x%x\n", 
1478      current_function_outgoing_args_size, frame_size, aligned_size);
1479
1480   fprintf (f, "\t.using\t.,r15\n");
1481
1482   /* Branch to exectuable part of prologue.  */
1483   fprintf (f, "\tB\t.LFENT%03d\n", function_label_index);
1484
1485   /* write the length of the stackframe */
1486   fprintf (f, "\t.long\t%d\n", aligned_size);
1487
1488   /* FENT == function prologue entry */
1489   fprintf (f, "\t.balign 2\n.LFENT%03d:\n",
1490               function_label_index);
1491
1492   /* store multiple registers 14,15,0,...12 at 12 bytes from sp */
1493   fprintf (f, "\tSTM\tr14,r12,12(sp)\n");
1494
1495   /* r3 == saved callee stack pointer */
1496   fprintf (f, "\tLR\tr3,sp\n");
1497
1498   /* 4(r15) == stackframe size */
1499   fprintf (f, "\tSL\tsp,4(,r15)\n");
1500
1501   /* r11 points to arg list in callers stackframe; was passed in r2 */
1502   fprintf (f, "\tLR\tr11,r2\n");
1503
1504   /* store callee stack pointer at 8(sp) */
1505   /* fprintf (f, "\tST\tsp,8(,r3)\n ");  wasted cycles, no one uses this ...  */
1506
1507   /* backchain -- store caller sp at 4(callee_sp)  */
1508   fprintf (f, "\tST\tr3,4(,sp)\n ");
1509
1510   fprintf (f, "\t.drop\tr15\n");
1511   /* Place contents of the PSW into r3
1512      that is, place the address of "." into r3 */
1513   fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER);
1514   fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER);
1515   function_first = 1;
1516   function_label_index ++;
1517
1518   fprintf (f, ".LPG%d:\n", mvs_page_num  );
1519   fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num);
1520   fprintf (f, "# Function code\n");
1521
1522   mvs_free_label_list ();
1523   mvs_page_code = 6;
1524   mvs_page_lit = 4;
1525   mvs_check_page (f, 0, 0);
1526   function_base_page = mvs_page_num;
1527
1528   /* find all labels in this routine */
1529   i370_label_scan ();
1530 }
1531 #endif /* TARGET_ELF_ABI */
1532
1533 /* This function generates the assembly code for function exit.
1534    Args are as for output_function_prologue ().
1535
1536    The function epilogue should not depend on the current stack
1537    pointer!  It should use the frame pointer only.  This is mandatory
1538    because of alloca; we also take advantage of it to omit stack
1539    adjustments before returning.  */
1540
1541 static void
1542 i370_output_function_epilogue (file, l)
1543      FILE *file;
1544      HOST_WIDE_INT l ATTRIBUTE_UNUSED;
1545 {
1546   int i;
1547
1548   check_label_emit ();
1549   mvs_check_page (file, 14, 0);
1550   fprintf (file, "* Function %s epilogue\n", mvs_function_name);
1551   mvs_page_num++;
1552
1553 #if MACROEPILOGUE == 1
1554   fprintf (file, "\tEDCEPIL\n");
1555 #else /* MACROEPILOGUE != 1 */
1556   fprintf (file, "\tL\t13,4(,13)\n");
1557   fprintf (file, "\tL\t14,12(,13)\n");
1558   fprintf (file, "\tLM\t2,12,28(13)\n");
1559   fprintf (file, "\tBALR\t1,14\n");
1560   fprintf (file, "\tDC\tA(");
1561   assemble_name (file, mvs_function_name);
1562   fprintf (file, ")\n" );
1563 #endif /* MACROEPILOGUE */
1564
1565   fprintf (file, "* Function %s literal pool\n", mvs_function_name);
1566   fprintf (file, "\tDS\t0F\n" );
1567   fprintf (file, "\tLTORG\n");
1568   fprintf (file, "* Function %s page table\n", mvs_function_name);
1569   fprintf (file, "\tDS\t0F\n");
1570   fprintf (file, "PGT%d\tEQU\t*\n", function_base_page);
1571
1572   mvs_free_label_list();
1573   for (i = function_base_page; i < mvs_page_num; i++)
1574     fprintf (file, "\tDC\tA(PG%d)\n", i);
1575 }
1576
1577 /* Mark external references.  */
1578
1579 static void
1580 i370_encode_section_info (decl, first)
1581      tree decl;
1582      int first ATTRIBUTE_UNUSED;
1583 {
1584   if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
1585     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
1586 }
1587