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