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