xref: /openbsd-src/gnu/usr.bin/gcc/gcc/config/i370/i370.c (revision c87b03e512fc05ed6e0222f6fb0ae86264b1d05b)
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 
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 
318 /* Set global variables as needed for the options enabled.  */
319 
320 void
override_options()321 override_options ()
322 {
323   /* We're 370 floating point, not IEEE floating point.  */
324   memset (real_format_for_mode, 0, sizeof real_format_for_mode);
325   real_format_for_mode[SFmode - QFmode] = &i370_single_format;
326   real_format_for_mode[DFmode - QFmode] = &i370_double_format;
327 }
328 
329 
330 /* Map characters from one character set to another.
331    C is the character to be translated.  */
332 
333 char
mvs_map_char(c)334 mvs_map_char (c)
335      int c;
336 {
337 #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
338   fprintf (stderr, "mvs_map_char: TE & !HE: c = %02x\n", c);
339   return ascebc[c];
340 #else
341 #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
342   fprintf (stderr, "mvs_map_char: !TE & HE: c = %02x\n", c);
343   return ebcasc[c];
344 #else
345   fprintf (stderr, "mvs_map_char: !TE & !HE: c = %02x\n", c);
346   return c;
347 #endif
348 #endif
349 }
350 
351 /* ===================================================== */
352 /* The following three routines are used to determine whther
353    forward branch is on this page, or is a far jump.  We use
354    the "length" attr on an insn [(set_atter "length" "4")]
355    to store the largest possible code length that insn
356    could have.  This gives us a hint of the address of a
357    branch destination, and from that, we can work out
358    the length of the jump, and whether its on page or not.
359  */
360 
361 /* Return the destination address of a branch.  */
362 
363 int
i370_branch_dest(branch)364 i370_branch_dest (branch)
365      rtx branch;
366 {
367   rtx dest = SET_SRC (PATTERN (branch));
368   int dest_uid;
369   int dest_addr;
370 
371   /* first, compute the estimated address of the branch target */
372   if (GET_CODE (dest) == IF_THEN_ELSE)
373     dest = XEXP (dest, 1);
374   dest = XEXP (dest, 0);
375   dest_uid = INSN_UID (dest);
376   dest_addr = INSN_ADDRESSES (dest_uid);
377 
378   /* next, record the address of this insn as the true addr of first ref */
379   {
380      label_node_t *lp;
381      rtx label = JUMP_LABEL (branch);
382      int labelno = CODE_LABEL_NUMBER (label);
383 
384      if (!label || CODE_LABEL != GET_CODE (label)) abort ();
385 
386      lp = mvs_get_label (labelno);
387      if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num;
388   }
389   return dest_addr;
390 }
391 
392 int
i370_branch_length(insn)393 i370_branch_length (insn)
394      rtx insn;
395 {
396   int here, there;
397   here = INSN_ADDRESSES (INSN_UID (insn));
398   there = i370_branch_dest (insn);
399   return (there - here);
400 }
401 
402 
403 int
i370_short_branch(insn)404 i370_short_branch (insn)
405      rtx insn;
406 {
407   int base_offset;
408 
409   base_offset = i370_branch_length(insn);
410   if (0 > base_offset)
411     {
412       base_offset += mvs_page_code;
413     }
414   else
415     {
416       /* avoid bumping into lit pool; use 2x to estimate max possible lits */
417       base_offset *= 2;
418       base_offset += mvs_page_code + mvs_page_lit;
419     }
420 
421   /* make a conservative estimate of room left on page */
422   if ((4060 >base_offset) && ( 0 < base_offset)) return 1;
423   return 0;
424 }
425 
426 /* The i370_label_scan() routine is supposed to loop over
427    all labels and label references in a compilation unit,
428    and determine whether all label refs appear on the same
429    code page as the label. If they do, then we can avoid
430    a reload of the base register for that label.
431 
432    Note that the instruction addresses used here are only
433    approximate, and make the sizes of the jumps appear
434    farther apart then they will actually be.  This makes
435    this code far more conservative than it needs to be.
436  */
437 
438 #define I370_RECORD_LABEL_REF(label,addr) {				\
439 	label_node_t *lp;						\
440 	int labelno = CODE_LABEL_NUMBER (label);			\
441 	lp = mvs_get_label (labelno);					\
442 	if (addr < lp -> label_first_ref) lp->label_first_ref = addr;	\
443 	if (addr > lp -> label_last_ref) lp->label_last_ref = addr;	\
444 }
445 
446 static void
i370_label_scan()447 i370_label_scan ()
448 {
449    rtx insn;
450    label_node_t *lp;
451    int tablejump_offset = 0;
452 
453    for (insn = get_insns(); insn; insn = NEXT_INSN(insn))
454      {
455        int here = INSN_ADDRESSES (INSN_UID (insn));
456        enum rtx_code code = GET_CODE(insn);
457 
458        /* ??? adjust for tables embedded in the .text section that
459         * the compiler didn't take into account */
460        here += tablejump_offset;
461        INSN_ADDRESSES (INSN_UID (insn)) = here;
462 
463        /* check to see if this insn is a label ...  */
464        if (CODE_LABEL == code)
465          {
466            int labelno = CODE_LABEL_NUMBER (insn);
467 
468            lp = mvs_get_label (labelno);
469            lp -> label_addr = here;
470 #if 0
471            /* Supposedly, labels are supposed to have circular
472               lists of label-refs that reference them,
473               setup in flow.c, but this does not appear to be the case.  */
474            rtx labelref = LABEL_REFS (insn);
475            rtx ref = labelref;
476            do
477              {
478                rtx linsn = CONTAINING_INSN(ref);
479                ref =  LABEL_NEXTREF(ref);
480              } while (ref && (ref != labelref));
481 #endif
482          }
483        else
484        if (JUMP_INSN == code)
485          {
486            rtx label = JUMP_LABEL (insn);
487 
488            /* If there is no label for this jump, then this
489               had better be a ADDR_VEC or an ADDR_DIFF_VEC
490               and there had better be a vector of labels.  */
491            if (!label)
492              {
493                int j;
494                rtx body = PATTERN (insn);
495                if (ADDR_VEC == GET_CODE(body))
496                  {
497                     for (j=0; j < XVECLEN (body, 0); j++)
498                       {
499                          rtx lref = XVECEXP (body, 0, j);
500                          if (LABEL_REF != GET_CODE (lref)) abort ();
501                          label = XEXP (lref,0);
502                          if (CODE_LABEL != GET_CODE (label)) abort ();
503                          tablejump_offset += 4;
504                          here += 4;
505                          I370_RECORD_LABEL_REF(label,here);
506                       }
507                     /* finished with the vector go do next insn */
508                     continue;
509                  }
510                else
511                if (ADDR_DIFF_VEC == GET_CODE(body))
512                  {
513 /* XXX hack alert.
514    Right now, we leave this as a no-op, but strictly speaking,
515    this is incorrect.  It is possible that a table-jump
516    driven off of a relative address could take us off-page,
517    to a place where we need to reload the base reg.  So really,
518    we need to examing both labels, and compare thier values
519    to the current basereg value.
520 
521    More generally, this brings up a troubling issue overall:
522    what happens if a tablejump is split across two pages? I do
523    not beleive that this case is handled correctly at all, and
524    can only lead to horrible results if this were to occur.
525 
526    However, the current situation is not any worse than it was
527    last week, and so we punt for now.  */
528 
529                     debug_rtx (insn);
530                     for (j=0; j < XVECLEN (body, 0); j++)
531                       {
532                       }
533                     /* finished with the vector go do next insn */
534                     continue;
535                  }
536                else
537                  {
538 /* XXX hack alert.
539    Compiling the exception handling (L_eh) in libgcc2.a will trip
540    up right here, with something that looks like
541    (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
542       {indirect_jump}
543    I'm not sure of what leads up to this, but it looks like
544    the makings of a long jump which will surely get us into trouble
545    because the base & page registers don't get reloaded.  For now
546    I'm not sure of what to do ... again we punt ... we are not worse
547    off than yesterday.  */
548 
549                     /* print_rtl_single (stdout, insn); */
550                     debug_rtx (insn);
551                     /* abort(); */
552                     continue;
553                  }
554             }
555           else
556             {
557               /* At this point, this jump_insn had better be a plain-old
558                  ordinary one, grap the label id and go */
559               if (CODE_LABEL != GET_CODE (label)) abort ();
560               I370_RECORD_LABEL_REF(label,here);
561             }
562         }
563 
564       /* Sometimes, we take addresses of labels and use them
565          as instruction operands ... these show up as REG_NOTES */
566       else
567       if (INSN == code)
568        {
569          if ('i' == GET_RTX_CLASS (code))
570            {
571               rtx note;
572               for (note = REG_NOTES (insn); note;  note = XEXP(note,1))
573                 {
574                    if (REG_LABEL == REG_NOTE_KIND(note))
575                      {
576                         rtx label = XEXP (note,0);
577                         if (!label || CODE_LABEL != GET_CODE (label)) abort ();
578 
579                         I370_RECORD_LABEL_REF(label,here);
580                      }
581                 }
582            }
583        }
584    }
585 }
586 
587 /* ===================================================== */
588 
589 /* Emit reload of base register if indicated.  This is to eliminate multiple
590    reloads when several labels are generated pointing to the same place
591    in the code.
592 
593    The page table is written at the end of the function.
594    The entries in the page table look like
595      .LPGT0:          // PGT0 EQU *
596      .long .LPG0      // DC A(PG0)
597      .long .LPG1      // DC A(PG1)
598   while the prologue generates
599       L       r4,=A(.LPGT0)
600 
601   Note that this paging scheme breaks down if a single subroutine
602   has more than about 10MB of code in it ... as long as humans write
603   code, this shouldn't be a problem ...
604  */
605 
606 void
check_label_emit()607 check_label_emit ()
608 {
609   if (mvs_need_base_reload)
610     {
611       mvs_need_base_reload = 0;
612 
613       mvs_page_code += 4;
614       fprintf (assembler_source, "\tL\t%d,%d(,%d)\n",
615 	  BASE_REGISTER, (mvs_page_num - function_base_page) * 4,
616 	  PAGE_REGISTER);
617     }
618 }
619 
620 /* Add the label to the current page label list.  If a free element is available
621    it will be used for the new label.  Otherwise, a label element will be
622    allocated from memory.
623    ID is the label number of the label being added to the list.  */
624 
625 static label_node_t *
mvs_get_label(id)626 mvs_get_label (id)
627      int id;
628 {
629   label_node_t *lp;
630 
631   /* first, lets see if we already go one, if so, use that.  */
632   for (lp = label_anchor; lp; lp = lp->label_next)
633     {
634       if (lp->label_id == id) return lp;
635     }
636 
637   /* not found, get a new one */
638   if (free_anchor)
639     {
640       lp = free_anchor;
641       free_anchor = lp->label_next;
642     }
643   else
644     {
645       lp = (label_node_t *) xmalloc (sizeof (label_node_t));
646     }
647 
648   /* initialize for new label */
649   lp->label_id = id;
650   lp->label_page = -1;
651   lp->label_next = label_anchor;
652   lp->label_first_ref = 2000123123;
653   lp->label_last_ref = -1;
654   lp->label_addr = -1;
655   lp->first_ref_page = -1;
656   label_anchor = lp;
657 
658   return lp;
659 }
660 
661 void
mvs_add_label(id)662 mvs_add_label (id)
663      int id;
664 {
665   label_node_t *lp;
666   int fwd_distance;
667 
668   lp = mvs_get_label (id);
669   lp->label_page = mvs_page_num;
670 
671   /* OK, we just saw the label.  Determine if this label
672    * needs a reload of the base register */
673   if ((-1 != lp->first_ref_page) &&
674       (lp->first_ref_page != mvs_page_num))
675     {
676       /* Yep; the first label_ref was on a different page.  */
677       mvs_need_base_reload ++;
678       return;
679     }
680 
681   /* Hmm.  Try to see if the estimated address of the last
682      label_ref is on the current page.  If it is, then we
683      don't need a base reg reload.  Note that this estimate
684      is very conservatively handled; we'll tend to have
685      a good bit more reloads than actually needed.  Someday,
686      we should tighten the estimates (which are driven by
687      the (set_att "length") insn attibute.
688 
689      Currently, we estimate that number of page literals
690      same as number of insns, which is a vast overestimate,
691      esp that the estimate of each insn size is its max size.  */
692 
693   /* if latest ref comes before label, we are clear */
694   if (lp->label_last_ref < lp->label_addr) return;
695 
696   fwd_distance = lp->label_last_ref - lp->label_addr;
697 
698   if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return;
699 
700   mvs_need_base_reload ++;
701 }
702 
703 /* Check to see if the label is in the list and in the current
704    page.  If not found, we have to make worst case assumption
705    that label will be on a different page, and thus will have to
706    generate a load and branch on register.  This is rather
707    ugly for forward-jumps, but what can we do? For backward
708    jumps on the same page we can branch directly to address.
709    ID is the label number of the label being checked.  */
710 
711 int
mvs_check_label(id)712 mvs_check_label (id)
713      int id;
714 {
715   label_node_t *lp;
716 
717   for (lp = label_anchor; lp; lp = lp->label_next)
718     {
719       if (lp->label_id == id)
720         {
721           if (lp->label_page == mvs_page_num)
722             {
723                return 1;
724             }
725           else
726             {
727 	       return 0;
728             }
729         }
730     }
731   return 0;
732 }
733 
734 /* Get the page on which the label sits.  This will be used to
735    determine is a register reload is really needed.  */
736 
737 #if 0
738 int
739 mvs_get_label_page(int id)
740 {
741   label_node_t *lp;
742 
743   for (lp = label_anchor; lp; lp = lp->label_next)
744     {
745       if (lp->label_id == id)
746 	return lp->label_page;
747     }
748   return -1;
749 }
750 #endif
751 
752 /* The label list for the current page freed by linking the list onto the free
753    label element chain.  */
754 
755 void
mvs_free_label_list()756 mvs_free_label_list ()
757 {
758 
759   if (label_anchor)
760     {
761       label_node_t *last_lp = label_anchor;
762       while (last_lp->label_next) last_lp = last_lp->label_next;
763       last_lp->label_next = free_anchor;
764       free_anchor = label_anchor;
765     }
766   label_anchor = 0;
767 }
768 
769 /* ====================================================================== */
770 /* If the page size limit is reached a new code page is started, and the base
771    register is set to it.  This page break point is counted conservatively,
772    most literals that have the same value are collapsed by the assembler.
773    True is returned when a new page is started.
774    FILE is the assembler output file descriptor.
775    CODE is the length, in bytes, of the instruction to be emitted.
776    LIT is the length of the literal to be emitted.  */
777 
778 #ifdef TARGET_HLASM
779 int
mvs_check_page(file,code,lit)780 mvs_check_page (file, code, lit)
781      FILE *file;
782      int code, lit;
783 {
784   if (file)
785     assembler_source = file;
786 
787   if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
788     {
789       fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num);
790       fprintf (assembler_source, "\tDS\t0F\n");
791       fprintf (assembler_source, "\tLTORG\n");
792       fprintf (assembler_source, "\tDS\t0F\n");
793       fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num);
794       fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER);
795       mvs_page_num++;
796       /* Safe to use BASR not BALR, since we are
797        * not switching addressing mode here ...  */
798       fprintf (assembler_source, "\tBASR\t%d,0\n", BASE_REGISTER);
799       fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num);
800       fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER);
801       mvs_page_code = code;
802       mvs_page_lit = lit;
803       return 1;
804     }
805   mvs_page_code += code;
806   mvs_page_lit += lit;
807   return 0;
808 }
809 #endif /* TARGET_HLASM */
810 
811 
812 #ifdef TARGET_ELF_ABI
813 int
mvs_check_page(file,code,lit)814 mvs_check_page (file, code, lit)
815      FILE *file;
816      int code, lit;
817 {
818   if (file)
819     assembler_source = file;
820 
821   if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
822     {
823       /* hop past the literal pool */
824       fprintf (assembler_source, "\tB\t.LPGE%d\n", mvs_page_num);
825 
826       /* dump the literal pool. The .baligns are optional, since
827        * ltorg will align to the size of the largest literal
828        * (which is possibly 8 bytes) */
829       fprintf (assembler_source, "\t.balign\t4\n");
830       fprintf (assembler_source, "\t.LTORG\n");
831       fprintf (assembler_source, "\t.balign\t4\n");
832 
833       /* we continue execution here ...  */
834       fprintf (assembler_source, ".LPGE%d:\n", mvs_page_num);
835       fprintf (assembler_source, "\t.DROP\t%d\n", BASE_REGISTER);
836       mvs_page_num++;
837 
838       /* BASR puts the contents of the PSW into r3
839        * that is, r3 will be loaded with the address of "." */
840       fprintf (assembler_source, "\tBASR\tr%d,0\n", BASE_REGISTER);
841       fprintf (assembler_source, ".LPG%d:\n", mvs_page_num);
842       fprintf (assembler_source, "\t.USING\t.,r%d\n", BASE_REGISTER);
843       mvs_page_code = code;
844       mvs_page_lit = lit;
845       return 1;
846     }
847   mvs_page_code += code;
848   mvs_page_lit += lit;
849   return 0;
850 }
851 #endif /* TARGET_ELF_ABI */
852 
853 /* ===================================================== */
854 /* defines and functions specific to the HLASM assembler */
855 #ifdef TARGET_HLASM
856 
857 /* Check for C/370 runtime function, they don't use standard calling
858    conventions.  True is returned if the function is in the table.
859    NAME is the name of the current function.  */
860 
861 int
mvs_function_check(name)862 mvs_function_check (name)
863      const char *name;
864 {
865   int lower, middle, upper;
866   int i;
867 
868   lower = 0;
869   upper = MVS_FUNCTION_TABLE_LENGTH - 1;
870   while (lower <= upper)
871     {
872       middle = (lower + upper) / 2;
873       i = strcmp (name, mvs_function_table[middle]);
874       if (i == 0)
875 	return 1;
876       if (i < 0)
877 	upper = middle - 1;
878       else
879 	lower = middle + 1;
880     }
881   return 0;
882 }
883 
884 /* Generate a hash for a given key.  */
885 
886 #ifdef LONGEXTERNAL
887 static int
mvs_hash_alias(key)888 mvs_hash_alias (key)
889      const char *key;
890 {
891   int h;
892   int i;
893   int l = strlen (key);
894 
895   h = key[0];
896   for (i = 1; i < l; i++)
897     h = ((h * MVS_SET_SIZE) + key[i]) % MVS_HASH_PRIME;
898   return (h);
899 }
900 #endif
901 
902 /* Add the alias to the current alias list.  */
903 
904 void
mvs_add_alias(realname,aliasname,emitted)905 mvs_add_alias (realname, aliasname, emitted)
906      const char *realname;
907      const char *aliasname;
908      int   emitted;
909 {
910   alias_node_t *ap;
911 
912   ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
913   if (strlen (realname) > MAX_LONG_LABEL_SIZE)
914     {
915       warning ("real name is too long - alias ignored");
916       return;
917     }
918   if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
919     {
920       warning ("alias name is too long - alias ignored");
921       return;
922     }
923 
924   strcpy (ap->real_name, realname);
925   strcpy (ap->alias_name, aliasname);
926   ap->alias_emitted = emitted;
927   ap->alias_next = alias_anchor;
928   alias_anchor = ap;
929 }
930 
931 /* Check to see if the name needs aliasing. ie. the name is either:
932      1. Longer than 8 characters
933      2. Contains an underscore
934      3. Is mixed case */
935 
936 int
mvs_need_alias(realname)937 mvs_need_alias (realname)
938       const char *realname;
939 {
940    int i, j = strlen (realname);
941 
942    if (mvs_function_check (realname))
943      return 0;
944 #if 0
945    if (!strcmp (realname, "gccmain"))
946      return 0;
947    if (!strcmp (realname, "main"))
948      return 0;
949 #endif
950    if (j > MAX_MVS_LABEL_SIZE)
951      return 1;
952    if (strchr (realname, '_') != 0)
953      return 1;
954    if (ISUPPER (realname[0]))
955      {
956        for (i = 1; i < j; i++)
957 	 {
958 	   if (ISLOWER (realname[i]))
959 	     return 1;
960 	 }
961      }
962    else
963      {
964        for (i = 1; i < j; i++)
965          {
966 	   if (ISUPPER (realname[i]))
967 	     return 1;
968 	 }
969      }
970 
971    return 0;
972 }
973 
974 /* Get the alias from the list.
975    If 1 is returned then it's in the alias list, 0 if it was not */
976 
977 int
mvs_get_alias(realname,aliasname)978 mvs_get_alias (realname, aliasname)
979      const char *realname;
980      char *aliasname;
981 {
982 #ifdef LONGEXTERNAL
983   alias_node_t *ap;
984 
985   for (ap = alias_anchor; ap; ap = ap->alias_next)
986     {
987       if (!strcmp (ap->real_name, realname))
988 	{
989 	  strcpy (aliasname, ap->alias_name);
990 	  return 1;
991 	}
992     }
993   if (mvs_need_alias (realname))
994     {
995       char c1, c2;
996 
997       c1 = realname[0];
998       c2 = realname[1];
999       if (ISLOWER (c1)) c1 = TOUPPER (c1);
1000       else if (c1 == '_') c1 = 'A';
1001       if (ISLOWER (c2)) c2 = TOUPPER (c2);
1002       else if (c2 == '_' || c2 == '\0') c2 = '#';
1003 
1004       sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
1005       mvs_add_alias (realname, aliasname, 0);
1006       return 1;
1007     }
1008 #else
1009   if (strlen (realname) > MAX_MVS_LABEL_SIZE)
1010     {
1011       strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1012       aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1013       return 1;
1014     }
1015 #endif
1016   return 0;
1017 }
1018 
1019 /* Check to see if the alias is in the list.
1020    If 1 is returned then it's in the alias list, 2 it was emitted  */
1021 
1022 int
mvs_check_alias(realname,aliasname)1023 mvs_check_alias (realname, aliasname)
1024      const char *realname;
1025      char *aliasname;
1026 {
1027 #ifdef LONGEXTERNAL
1028   alias_node_t *ap;
1029 
1030   for (ap = alias_anchor; ap; ap = ap->alias_next)
1031     {
1032       if (!strcmp (ap->real_name, realname))
1033 	{
1034 	  int rc = (ap->alias_emitted == 1) ? 1 : 2;
1035 	  strcpy (aliasname, ap->alias_name);
1036 	  ap->alias_emitted = 1;
1037 	  return rc;
1038 	}
1039     }
1040   if (mvs_need_alias (realname))
1041     {
1042       char c1, c2;
1043 
1044       c1 = realname[0];
1045       c2 = realname[1];
1046       if (ISLOWER (c1)) c1 = TOUPPER (c1);
1047       else if (c1 == '_') c1 = 'A';
1048       if (ISLOWER (c2)) c2 = TOUPPER (c2);
1049       else if (c2 == '_' || c2 == '\0') c2 = '#';
1050 
1051       sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
1052       mvs_add_alias (realname, aliasname, 0);
1053       alias_anchor->alias_emitted = 1;
1054       return 2;
1055     }
1056 #else
1057   if (strlen (realname) > MAX_MVS_LABEL_SIZE)
1058     {
1059       strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1060       aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1061       return 1;
1062     }
1063 #endif
1064   return 0;
1065 }
1066 
1067 /* defines and functions specific to the HLASM assembler */
1068 #endif /* TARGET_HLASM */
1069 /* ===================================================== */
1070 /* ===================================================== */
1071 /* defines and functions specific to the gas assembler */
1072 #ifdef TARGET_ELF_ABI
1073 
1074 /* Check for C/370 runtime function, they don't use standard calling
1075    conventions.  True is returned if the function is in the table.
1076    NAME is the name of the current function.  */
1077 /* no special calling conventions (yet ??) */
1078 
1079 int
mvs_function_check(name)1080 mvs_function_check (name)
1081      const char *name ATTRIBUTE_UNUSED;
1082 {
1083    return 0;
1084 }
1085 
1086 #endif /* TARGET_ELF_ABI */
1087 /* ===================================================== */
1088 
1089 
1090 /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
1091    OP is the current operation.
1092    MODE is the current operation mode.  */
1093 
1094 int
s_operand(op,mode)1095 s_operand (op, mode)
1096      register rtx op;
1097      enum machine_mode mode;
1098 {
1099   extern int volatile_ok;
1100   register enum rtx_code code = GET_CODE (op);
1101 
1102   if (CONSTANT_ADDRESS_P (op))
1103     return 1;
1104   if (mode == VOIDmode || GET_MODE (op) != mode)
1105     return 0;
1106   if (code == MEM)
1107     {
1108       register rtx x = XEXP (op, 0);
1109 
1110       if (!volatile_ok && op->volatil)
1111 	return 0;
1112       if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1113 	return 1;
1114       if (GET_CODE (x) == PLUS
1115 	  && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1116 	  && GET_CODE (XEXP (x, 1)) == CONST_INT
1117 	  && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1118 	return 1;
1119     }
1120   return 0;
1121 }
1122 
1123 
1124 /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
1125    instruction.
1126    OP is the current operation.
1127    MODE is the current operation mode.  */
1128 
1129 int
r_or_s_operand(op,mode)1130 r_or_s_operand (op, mode)
1131      register rtx op;
1132      enum machine_mode mode;
1133 {
1134   extern int volatile_ok;
1135   register enum rtx_code code = GET_CODE (op);
1136 
1137   if (CONSTANT_ADDRESS_P (op))
1138     return 1;
1139   if (mode == VOIDmode || GET_MODE (op) != mode)
1140     return 0;
1141   if (code == REG)
1142     return 1;
1143   else if (code == MEM)
1144     {
1145       register rtx x = XEXP (op, 0);
1146 
1147       if (!volatile_ok && op->volatil)
1148 	return 0;
1149       if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1150 	return 1;
1151       if (GET_CODE (x) == PLUS
1152 	  && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1153 	  && GET_CODE (XEXP (x, 1)) == CONST_INT
1154 	  && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1155 	return 1;
1156     }
1157   return 0;
1158 }
1159 
1160 
1161 /* Some remarks about unsigned_jump_follows_p():
1162    gcc is built around the assumption that branches are signed
1163    or unsigned, whereas the 370 doesn't care; its the compares that
1164    are signed or unsigned.  Thus, we need to somehow know if we
1165    need to do a signed or an unsigned compare, and we do this by
1166    looking ahead in the instruction sequence until we find a jump.
1167    We then note whether this jump is signed or unsigned, and do the
1168    compare appropriately.  Note that we have to scan ahead indefinitley,
1169    as the gcc optimizer may insert any number of instructions between
1170    the compare and the jump.
1171 
1172    Note that using conditional branch expanders seems to be be a more
1173    elegant/correct way of doing this.   See, for instance, the Alpha
1174    cmpdi and bgt patterns.  Note also that for the i370, various
1175    arithmetic insn's set the condition code as well.
1176 
1177    The unsigned_jump_follows_p() routine  returns a 1 if the next jump
1178    is unsigned.  INSN is the current instruction.  */
1179 
1180 int
unsigned_jump_follows_p(insn)1181 unsigned_jump_follows_p (insn)
1182      register rtx insn;
1183 {
1184   rtx orig_insn = insn;
1185   while (1)
1186     {
1187       register rtx tmp_insn;
1188       enum rtx_code coda;
1189 
1190       insn = NEXT_INSN (insn);
1191       if (!insn) fatal_insn ("internal error--no jump follows compare:", orig_insn);
1192 
1193       if (GET_CODE (insn) != JUMP_INSN) continue;
1194 
1195       tmp_insn = XEXP (insn, 3);
1196       if (GET_CODE (tmp_insn) != SET) continue;
1197 
1198       if (GET_CODE (XEXP (tmp_insn, 0)) != PC) continue;
1199 
1200       tmp_insn = XEXP (tmp_insn, 1);
1201       if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue;
1202 
1203       /* if we got to here, this instruction is a jump.  Is it signed? */
1204       tmp_insn = XEXP (tmp_insn, 0);
1205       coda = GET_CODE (tmp_insn);
1206 
1207       return coda != GE && coda != GT && coda != LE && coda != LT;
1208     }
1209 }
1210 
1211 #ifdef TARGET_HLASM
1212 
1213 /* Target hook for assembling integer objects.  This version handles all
1214    objects when TARGET_HLASM is defined.  */
1215 
1216 static bool
i370_hlasm_assemble_integer(x,size,aligned_p)1217 i370_hlasm_assemble_integer (x, size, aligned_p)
1218      rtx x;
1219      unsigned int size;
1220      int aligned_p;
1221 {
1222   const char *int_format = NULL;
1223 
1224   if (aligned_p)
1225     switch (size)
1226       {
1227       case 1:
1228 	int_format = "\tDC\tX'%02X'\n";
1229 	break;
1230 
1231       case 2:
1232 	int_format = "\tDC\tX'%04X'\n";
1233 	break;
1234 
1235       case 4:
1236 	if (GET_CODE (x) == CONST_INT)
1237 	  {
1238 	    fputs ("\tDC\tF'", asm_out_file);
1239 	    output_addr_const (asm_out_file, x);
1240 	    fputs ("'\n", asm_out_file);
1241 	  }
1242 	else
1243 	  {
1244 	    fputs ("\tDC\tA(", asm_out_file);
1245 	    output_addr_const (asm_out_file, x);
1246 	    fputs (")\n", asm_out_file);
1247 	  }
1248 	return true;
1249       }
1250 
1251   if (int_format && GET_CODE (x) == CONST_INT)
1252     {
1253       fprintf (asm_out_file, int_format, INTVAL (x));
1254       return true;
1255     }
1256   return default_assemble_integer (x, size, aligned_p);
1257 }
1258 
1259 /* Generate the assembly code for function entry.  FILE is a stdio
1260    stream to output the code to.  SIZE is an int: how many units of
1261    temporary storage to allocate.
1262 
1263    Refer to the array `regs_ever_live' to determine which registers to
1264    save; `regs_ever_live[I]' is nonzero if register number I is ever
1265    used in the function.  This function is responsible for knowing
1266    which registers should not be saved even if used.  */
1267 
1268 static void
i370_output_function_prologue(f,l)1269 i370_output_function_prologue (f, l)
1270      FILE *f;
1271      HOST_WIDE_INT l;
1272 {
1273 #if MACROPROLOGUE == 1
1274   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1275   fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
1276 	   STACK_POINTER_OFFSET + l - 120 +
1277 	   current_function_outgoing_args_size, BASE_REGISTER);
1278 #else /* MACROPROLOGUE != 1 */
1279   static int function_label_index = 1;
1280   static int function_first = 0;
1281   static int function_year, function_month, function_day;
1282   static int function_hour, function_minute, function_second;
1283 #if defined(LE370)
1284   if (!function_first)
1285     {
1286       struct tm *function_time;
1287       time_t lcltime;
1288       time (&lcltime);
1289       function_time = localtime (&lcltime);
1290       function_year = function_time->tm_year + 1900;
1291       function_month = function_time->tm_mon + 1;
1292       function_day = function_time->tm_mday;
1293       function_hour = function_time->tm_hour;
1294       function_minute = function_time->tm_min;
1295       function_second = function_time->tm_sec;
1296     }
1297   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1298   fprintf (f, "FDSE%03d\tDSECT\n", function_label_index);
1299   fprintf (f, "\tDS\tD\n");
1300   fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
1301 			+ current_function_outgoing_args_size);
1302   fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
1303   fprintf (f, "\tDS\tCL(120+8)\n");
1304   fprintf (f, "\tORG\n");
1305   fprintf (f, "\tDS\t0D\n");
1306   fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index,
1307 	   function_label_index);
1308   fprintf (f, "\tDS\t0H\n");
1309   assemble_name (f, mvs_function_name);
1310   fprintf (f, "\tCSECT\n");
1311   fprintf (f, "\tUSING\t*,15\n");
1312   fprintf (f, "\tB\tFENT%03d\n", function_label_index);
1313   fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index);
1314   fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1315   fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index);
1316   fprintf (f, "\tDC\tAL4(0)\n");
1317   fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1318   fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index);
1319   fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1320 	mvs_function_name);
1321   fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index);
1322   fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1323   fprintf (f, "\tDC\tV(CEESTART)\n");
1324   fprintf (f, "\tDC\tAL4(0)\n");
1325   fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index);
1326   fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index);
1327   fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1328   		 function_year, function_month, function_day,
1329     		 function_hour, function_minute);
1330   fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1331   fprintf (f, "FENT%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 ++;
1351 #else /* !LE370 */
1352   if (!function_first)
1353     {
1354       struct tm *function_time;
1355       time_t lcltime;
1356       time (&lcltime);
1357       function_time = localtime (&lcltime);
1358       function_year = function_time->tm_year + 1900;
1359       function_month = function_time->tm_mon + 1;
1360       function_day = function_time->tm_mday;
1361       function_hour = function_time->tm_hour;
1362       function_minute = function_time->tm_min;
1363       function_second = function_time->tm_sec;
1364       fprintf (f, "PPA2\tDS\t0F\n");
1365       fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1366       fprintf (f, "\tDC\tV(CEESTART),A(0)\n");
1367       fprintf (f, "\tDC\tA(CEETIMES)\n");
1368       fprintf (f, "CEETIMES\tDS\t0F\n");
1369       fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1370     		 function_year, function_month, function_day,
1371     		 function_hour, function_minute, function_second);
1372       fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1373     }
1374   fprintf (f, "* Function %s prologue\n", mvs_function_name);
1375   fprintf (f, "FDSD%03d\tDSECT\n", function_label_index);
1376   fprintf (f, "\tDS\tD\n");
1377   fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
1378 			+ current_function_outgoing_args_size);
1379   fprintf (f, "\tORG\tFDSD%03d\n", function_label_index);
1380   fprintf (f, "\tDS\tCL(120+8)\n");
1381   fprintf (f, "\tORG\n");
1382   fprintf (f, "\tDS\t0D\n");
1383   fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index,
1384 	   function_label_index);
1385   fprintf (f, "\tDS\t0H\n");
1386   assemble_name (f, mvs_function_name);
1387   fprintf (f, "\tCSECT\n");
1388   fprintf (f, "\tUSING\t*,15\n");
1389   fprintf (f, "\tB\tFPL%03d\n", function_label_index);
1390   fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);
1391   fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1392   fprintf (f, "\tDC\tAL4(PPA2)\n");
1393   fprintf (f, "\tDC\tAL4(0)\n");
1394   fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1395   fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1);
1396   fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1397 	mvs_function_name);
1398   fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index);
1399   fprintf (f, "\tSTM\t14,12,12(13)\n");
1400   fprintf (f, "\tL\t2,76(,13)\n");
1401   fprintf (f, "\tL\t0,16(,15)\n");
1402   fprintf (f, "\tALR\t0,2\n");
1403   fprintf (f, "\tCL\t0,12(,12)\n");
1404   fprintf (f, "\tBNH\t*+10\n");
1405   fprintf (f, "\tL\t15,116(,12)\n");
1406   fprintf (f, "\tBALR\t14,15\n");
1407   fprintf (f, "\tL\t15,72(,13)\n");
1408   fprintf (f, "\tSTM\t15,0,72(2)\n");
1409   fprintf (f, "\tMVI\t0(2),X'10'\n");
1410   fprintf (f, "\tST\t2,8(,13)\n ");
1411   fprintf (f, "\tST\t13,4(,2)\n ");
1412   fprintf (f, "\tLR\t13,2\n");
1413   fprintf (f, "\tDROP\t15\n");
1414   fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
1415   fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
1416   function_first = 1;
1417   function_label_index += 2;
1418 #endif /* !LE370 */
1419 #endif /* MACROPROLOGUE */
1420   fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
1421   fprintf (f, "\tLR\t11,1\n");
1422   fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
1423   fprintf (f, "* Function %s code\n", mvs_function_name);
1424 
1425   mvs_free_label_list ();
1426   mvs_page_code = 6;
1427   mvs_page_lit = 4;
1428   mvs_check_page (f, 0, 0);
1429   function_base_page = mvs_page_num;
1430 
1431   /* find all labels in this routine */
1432   i370_label_scan ();
1433 }
1434 
1435 static void
i370_globalize_label(stream,name)1436 i370_globalize_label (stream, name)
1437      FILE *stream;
1438      const char *name;
1439 {
1440   char temp[MAX_MVS_LABEL_SIZE + 1];
1441   if (mvs_check_alias (name, temp) == 2)
1442     fprintf (stream, "%s\tALIAS\tC'%s'\n", temp, name);
1443   fputs ("\tENTRY\t", stream);
1444   assemble_name (stream, name);
1445   putc ('\n', stream);
1446 }
1447 #endif /* TARGET_HLASM */
1448 
1449 
1450 #ifdef TARGET_ELF_ABI
1451 /*
1452    The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
1453    It implements a stack that grows downward.
1454    It performs the following steps:
1455    -- saves the callers non-volatile registers on the callers stack.
1456    -- subtracts stackframe size from the stack pointer.
1457    -- stores backpointer to old caller stack.
1458 
1459    XXX hack alert -- if the global var int leaf_function is nonzero,
1460    then this is a leaf, and it might be possible to optimize the prologue
1461    into doing even less, e.g. not grabbing a new stackframe or maybe just a
1462    partial stack frame.
1463 
1464    XXX hack alert -- the current stack frame is bloated into twice the
1465    needed size by unused entries. These entries make it marginally
1466    compatible with MVS/OE/USS C environment, but really they're not used
1467    and could probably chopped out. Modifications to i370.md would be needed
1468    also, to quite using addresses 136, 140, etc.
1469  */
1470 
1471 static void
i370_output_function_prologue(f,frame_size)1472 i370_output_function_prologue (f, frame_size)
1473      FILE *f;
1474      HOST_WIDE_INT frame_size;
1475 {
1476   static int function_label_index = 1;
1477   static int function_first = 0;
1478   int stackframe_size, aligned_size;
1479 
1480   fprintf (f, "# Function prologue\n");
1481   /* define the stack, put it into its own data segment
1482      FDSE == Function Stack Entry
1483      FDSL == Function Stack Length */
1484   stackframe_size =
1485      STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size;
1486   aligned_size = (stackframe_size + 7) >> 3;
1487   aligned_size <<= 3;
1488 
1489   fprintf (f, "# arg_size=0x%x frame_size=0x%x aligned size=0x%x\n",
1490      current_function_outgoing_args_size, frame_size, aligned_size);
1491 
1492   fprintf (f, "\t.using\t.,r15\n");
1493 
1494   /* Branch to exectuable part of prologue.  */
1495   fprintf (f, "\tB\t.LFENT%03d\n", function_label_index);
1496 
1497   /* write the length of the stackframe */
1498   fprintf (f, "\t.long\t%d\n", aligned_size);
1499 
1500   /* FENT == function prologue entry */
1501   fprintf (f, "\t.balign 2\n.LFENT%03d:\n",
1502               function_label_index);
1503 
1504   /* store multiple registers 14,15,0,...12 at 12 bytes from sp */
1505   fprintf (f, "\tSTM\tr14,r12,12(sp)\n");
1506 
1507   /* r3 == saved callee stack pointer */
1508   fprintf (f, "\tLR\tr3,sp\n");
1509 
1510   /* 4(r15) == stackframe size */
1511   fprintf (f, "\tSL\tsp,4(,r15)\n");
1512 
1513   /* r11 points to arg list in callers stackframe; was passed in r2 */
1514   fprintf (f, "\tLR\tr11,r2\n");
1515 
1516   /* store callee stack pointer at 8(sp) */
1517   /* fprintf (f, "\tST\tsp,8(,r3)\n ");  wasted cycles, no one uses this ...  */
1518 
1519   /* backchain -- store caller sp at 4(callee_sp)  */
1520   fprintf (f, "\tST\tr3,4(,sp)\n ");
1521 
1522   fprintf (f, "\t.drop\tr15\n");
1523   /* Place contents of the PSW into r3
1524      that is, place the address of "." into r3 */
1525   fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER);
1526   fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER);
1527   function_first = 1;
1528   function_label_index ++;
1529 
1530   fprintf (f, ".LPG%d:\n", mvs_page_num  );
1531   fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num);
1532   fprintf (f, "# Function code\n");
1533 
1534   mvs_free_label_list ();
1535   mvs_page_code = 6;
1536   mvs_page_lit = 4;
1537   mvs_check_page (f, 0, 0);
1538   function_base_page = mvs_page_num;
1539 
1540   /* find all labels in this routine */
1541   i370_label_scan ();
1542 }
1543 #endif /* TARGET_ELF_ABI */
1544 
1545 /* This function generates the assembly code for function exit.
1546    Args are as for output_function_prologue ().
1547 
1548    The function epilogue should not depend on the current stack
1549    pointer!  It should use the frame pointer only.  This is mandatory
1550    because of alloca; we also take advantage of it to omit stack
1551    adjustments before returning.  */
1552 
1553 static void
i370_output_function_epilogue(file,l)1554 i370_output_function_epilogue (file, l)
1555      FILE *file;
1556      HOST_WIDE_INT l ATTRIBUTE_UNUSED;
1557 {
1558   int i;
1559 
1560   check_label_emit ();
1561   mvs_check_page (file, 14, 0);
1562   fprintf (file, "* Function %s epilogue\n", mvs_function_name);
1563   mvs_page_num++;
1564 
1565 #if MACROEPILOGUE == 1
1566   fprintf (file, "\tEDCEPIL\n");
1567 #else /* MACROEPILOGUE != 1 */
1568   fprintf (file, "\tL\t13,4(,13)\n");
1569   fprintf (file, "\tL\t14,12(,13)\n");
1570   fprintf (file, "\tLM\t2,12,28(13)\n");
1571   fprintf (file, "\tBALR\t1,14\n");
1572   fprintf (file, "\tDC\tA(");
1573   assemble_name (file, mvs_function_name);
1574   fprintf (file, ")\n" );
1575 #endif /* MACROEPILOGUE */
1576 
1577   fprintf (file, "* Function %s literal pool\n", mvs_function_name);
1578   fprintf (file, "\tDS\t0F\n" );
1579   fprintf (file, "\tLTORG\n");
1580   fprintf (file, "* Function %s page table\n", mvs_function_name);
1581   fprintf (file, "\tDS\t0F\n");
1582   fprintf (file, "PGT%d\tEQU\t*\n", function_base_page);
1583 
1584   mvs_free_label_list();
1585   for (i = function_base_page; i < mvs_page_num; i++)
1586     fprintf (file, "\tDC\tA(PG%d)\n", i);
1587 }
1588 
1589 /* Mark external references.  */
1590 
1591 static void
i370_encode_section_info(decl,first)1592 i370_encode_section_info (decl, first)
1593      tree decl;
1594      int first ATTRIBUTE_UNUSED;
1595 {
1596   if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
1597     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
1598 }
1599 
1600