OSDN Git Service

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