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)
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. */
27 #include "coretypes.h"
32 #include "hard-reg-set.h"
34 #include "insn-config.h"
35 #include "conditions.h"
37 #include "insn-attr.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;
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. */
81 /* Length of the current page literals. */
84 /* Current function name. */
85 char *mvs_function_name = 0;
87 /* Current function name length. */
88 size_t mvs_function_name_length = 0;
90 /* Page number for multi-page functions. */
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));
105 static bool i370_hlasm_assemble_integer PARAMS ((rtx, unsigned int, int));
106 static void i370_globalize_label PARAMS ((FILE *, const char *));
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 static void i370_file_start PARAMS ((void));
111 static void i370_file_end PARAMS ((void));
114 static int mvs_hash_alias PARAMS ((const char *));
116 static void i370_internal_label PARAMS ((FILE *, const char *, unsigned long));
117 static bool i370_rtx_costs PARAMS ((rtx, int, int, int *));
119 /* ===================================================== */
120 /* defines and functions specific to the HLASM assembler */
123 #define MVS_HASH_PRIME 999983
124 #if defined(HOST_EBCDIC)
125 #define MVS_SET_SIZE 256
127 #define MVS_SET_SIZE 128
130 #ifndef MAX_MVS_LABEL_SIZE
131 #define MAX_MVS_LABEL_SIZE 8
134 #define MAX_LONG_LABEL_SIZE 255
136 /* Alias node, this structure is used to keep track of aliases to external
137 variables. The IBM assembler allows an alias to an external name
138 that is longer that 8 characters; but only once per assembly.
139 Also, this structure stores the #pragma map info. */
140 typedef struct alias_node
142 struct alias_node *alias_next;
144 char alias_name [MAX_MVS_LABEL_SIZE + 1];
145 char real_name [MAX_LONG_LABEL_SIZE + 1];
149 /* Alias node list anchor. */
150 static alias_node_t *alias_anchor = 0;
152 /* Define the length of the internal MVS function table. */
153 #define MVS_FUNCTION_TABLE_LENGTH 32
155 /* C/370 internal function table. These functions use non-standard linkage
156 and must handled in a special manner. */
157 static const char *const mvs_function_table[MVS_FUNCTION_TABLE_LENGTH] =
159 #if defined(HOST_EBCDIC) /* Changed for EBCDIC collating sequence */
160 "ceil", "edc_acos", "edc_asin", "edc_atan", "edc_ata2", "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", "jn",
164 "j0", "j1", "ldexp", "modf", "pow", "yn",
167 "ceil", "edc_acos", "edc_asin", "edc_ata2", "edc_atan", "edc_cos",
168 "edc_cosh", "edc_erf", "edc_erfc", "edc_exp", "edc_gamm", "edc_lg10",
169 "edc_log", "edc_sin", "edc_sinh", "edc_sqrt", "edc_tan", "edc_tanh",
170 "fabs", "floor", "fmod", "frexp", "hypot", "j0",
171 "j1", "jn", "ldexp", "modf", "pow", "y0",
176 #endif /* TARGET_HLASM */
177 /* ===================================================== */
179 #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
180 /* ASCII to EBCDIC conversion table. */
181 static const unsigned char ascebc[256] =
183 /*00 NL SH SX EX ET NQ AK BL */
184 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
185 /*08 BS HT LF VT FF CR SO SI */
186 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
187 /*10 DL D1 D2 D3 D4 NK SN EB */
188 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
189 /*18 CN EM SB EC FS GS RS US */
190 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
191 /*20 SP ! " # $ % & ' */
192 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
193 /*28 ( ) * + , - . / */
194 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
195 /*30 0 1 2 3 4 5 6 7 */
196 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
197 /*38 8 9 : ; < = > ? */
198 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
199 /*40 @ A B C D E F G */
200 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
201 /*48 H I J K L M N O */
202 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
203 /*50 P Q R S T U V W */
204 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
205 /*58 X Y Z [ \ ] ^ _ */
206 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
207 /*60 ` a b c d e f g */
208 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
209 /*68 h i j k l m n o */
210 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
211 /*70 p q r s t u v w */
212 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
213 /*78 x y z { | } ~ DL */
214 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
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, 0x3F,
228 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
229 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
230 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
232 #endif /* TARGET_EBCDIC && ! HOST_EBCDIC */
235 #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
236 /* EBCDIC to ASCII conversion table. */
237 static const unsigned char ebcasc[256] =
239 /*00 NU SH SX EX PF HT LC DL */
240 0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
241 /*08 SM VT FF CR SO SI */
242 0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
243 /*10 DE D1 D2 TM RS NL BS IL */
244 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
245 /*18 CN EM CC C1 FS GS RS US */
246 0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
247 /*20 DS SS FS BP LF EB EC */
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
249 /*28 SM C2 EQ AK BL */
250 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
251 /*30 SY PN RS UC ET */
252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
254 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
256 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
260 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
264 0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 /*78 ` : # @ ' = " */
270 0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
271 /*80 a b c d e f g */
272 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
274 0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
275 /*90 j k l m n o p */
276 0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
278 0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
279 /*A0 ~ s t u v w x */
280 0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
282 0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
287 /*C0 { A B C D E F G */
288 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
290 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 /*D0 } J K L M N O P */
292 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
294 0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 /*E0 \ S T U V W X */
296 0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
298 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 /*F0 0 1 2 3 4 5 6 7 */
300 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
302 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
304 #endif /* HOST_EBCDIC && ! TARGET_EBCDIC */
306 /* Initialize the GCC target structure. */
308 #undef TARGET_ASM_BYTE_OP
309 #define TARGET_ASM_BYTE_OP NULL
310 #undef TARGET_ASM_ALIGNED_HI_OP
311 #define TARGET_ASM_ALIGNED_HI_OP NULL
312 #undef TARGET_ASM_ALIGNED_SI_OP
313 #define TARGET_ASM_ALIGNED_SI_OP NULL
314 #undef TARGET_ASM_INTEGER
315 #define TARGET_ASM_INTEGER i370_hlasm_assemble_integer
316 #undef TARGET_ASM_GLOBALIZE_LABEL
317 #define TARGET_ASM_GLOBALIZE_LABEL i370_globalize_label
320 #undef TARGET_ASM_FUNCTION_PROLOGUE
321 #define TARGET_ASM_FUNCTION_PROLOGUE i370_output_function_prologue
322 #undef TARGET_ASM_FUNCTION_EPILOGUE
323 #define TARGET_ASM_FUNCTION_EPILOGUE i370_output_function_epilogue
324 #undef TARGET_ASM_FILE_START
325 #define TARGET_ASM_FILE_START i370_file_start
326 #undef TARGET_ASM_FILE_END
327 #define TARGET_ASM_FILE_END i370_file_end
328 #undef TARGET_ASM_INTERNAL_LABEL
329 #define TARGET_ASM_INTERNAL_LABEL i370_internal_label
330 #undef TARGET_RTX_COSTS
331 #define TARGET_RTX_COSTS i370_rtx_costs
333 struct gcc_target targetm = TARGET_INITIALIZER;
335 /* Set global variables as needed for the options enabled. */
340 /* We're 370 floating point, not IEEE floating point. */
341 memset (real_format_for_mode, 0, sizeof real_format_for_mode);
342 real_format_for_mode[SFmode - QFmode] = &i370_single_format;
343 real_format_for_mode[DFmode - QFmode] = &i370_double_format;
347 /* Map characters from one character set to another.
348 C is the character to be translated. */
354 #if defined(TARGET_EBCDIC) && !defined(HOST_EBCDIC)
355 fprintf (stderr, "mvs_map_char: TE & !HE: c = %02x\n", c);
358 #if defined(HOST_EBCDIC) && !defined(TARGET_EBCDIC)
359 fprintf (stderr, "mvs_map_char: !TE & HE: c = %02x\n", c);
362 fprintf (stderr, "mvs_map_char: !TE & !HE: c = %02x\n", c);
368 /* ===================================================== */
369 /* The following three routines are used to determine whther
370 forward branch is on this page, or is a far jump. We use
371 the "length" attr on an insn [(set_atter "length" "4")]
372 to store the largest possible code length that insn
373 could have. This gives us a hint of the address of a
374 branch destination, and from that, we can work out
375 the length of the jump, and whether its on page or not.
378 /* Return the destination address of a branch. */
381 i370_branch_dest (branch)
384 rtx dest = SET_SRC (PATTERN (branch));
388 /* first, compute the estimated address of the branch target */
389 if (GET_CODE (dest) == IF_THEN_ELSE)
390 dest = XEXP (dest, 1);
391 dest = XEXP (dest, 0);
392 dest_uid = INSN_UID (dest);
393 dest_addr = INSN_ADDRESSES (dest_uid);
395 /* next, record the address of this insn as the true addr of first ref */
398 rtx label = JUMP_LABEL (branch);
399 int labelno = CODE_LABEL_NUMBER (label);
401 if (!label || CODE_LABEL != GET_CODE (label)) abort ();
403 lp = mvs_get_label (labelno);
404 if (-1 == lp -> first_ref_page) lp->first_ref_page = mvs_page_num;
410 i370_branch_length (insn)
414 here = INSN_ADDRESSES (INSN_UID (insn));
415 there = i370_branch_dest (insn);
416 return (there - here);
421 i370_short_branch (insn)
426 base_offset = i370_branch_length(insn);
429 base_offset += mvs_page_code;
433 /* avoid bumping into lit pool; use 2x to estimate max possible lits */
435 base_offset += mvs_page_code + mvs_page_lit;
438 /* make a conservative estimate of room left on page */
439 if ((4060 >base_offset) && ( 0 < base_offset)) return 1;
443 /* The i370_label_scan() routine is supposed to loop over
444 all labels and label references in a compilation unit,
445 and determine whether all label refs appear on the same
446 code page as the label. If they do, then we can avoid
447 a reload of the base register for that label.
449 Note that the instruction addresses used here are only
450 approximate, and make the sizes of the jumps appear
451 farther apart then they will actually be. This makes
452 this code far more conservative than it needs to be.
455 #define I370_RECORD_LABEL_REF(label,addr) { \
457 int labelno = CODE_LABEL_NUMBER (label); \
458 lp = mvs_get_label (labelno); \
459 if (addr < lp -> label_first_ref) lp->label_first_ref = addr; \
460 if (addr > lp -> label_last_ref) lp->label_last_ref = addr; \
468 int tablejump_offset = 0;
470 for (insn = get_insns(); insn; insn = NEXT_INSN(insn))
472 int here = INSN_ADDRESSES (INSN_UID (insn));
473 enum rtx_code code = GET_CODE(insn);
475 /* ??? adjust for tables embedded in the .text section that
476 * the compiler didn't take into account */
477 here += tablejump_offset;
478 INSN_ADDRESSES (INSN_UID (insn)) = here;
480 /* check to see if this insn is a label ... */
481 if (CODE_LABEL == code)
483 int labelno = CODE_LABEL_NUMBER (insn);
485 lp = mvs_get_label (labelno);
486 lp -> label_addr = here;
488 /* Supposedly, labels are supposed to have circular
489 lists of label-refs that reference them,
490 setup in flow.c, but this does not appear to be the case. */
491 rtx labelref = LABEL_REFS (insn);
495 rtx linsn = CONTAINING_INSN(ref);
496 ref = LABEL_NEXTREF(ref);
497 } while (ref && (ref != labelref));
501 if (JUMP_INSN == code)
503 rtx label = JUMP_LABEL (insn);
505 /* If there is no label for this jump, then this
506 had better be a ADDR_VEC or an ADDR_DIFF_VEC
507 and there had better be a vector of labels. */
511 rtx body = PATTERN (insn);
512 if (ADDR_VEC == GET_CODE(body))
514 for (j=0; j < XVECLEN (body, 0); j++)
516 rtx lref = XVECEXP (body, 0, j);
517 if (LABEL_REF != GET_CODE (lref)) abort ();
518 label = XEXP (lref,0);
519 if (CODE_LABEL != GET_CODE (label)) abort ();
520 tablejump_offset += 4;
522 I370_RECORD_LABEL_REF(label,here);
524 /* finished with the vector go do next insn */
528 if (ADDR_DIFF_VEC == GET_CODE(body))
531 Right now, we leave this as a no-op, but strictly speaking,
532 this is incorrect. It is possible that a table-jump
533 driven off of a relative address could take us off-page,
534 to a place where we need to reload the base reg. So really,
535 we need to examing both labels, and compare thier values
536 to the current basereg value.
538 More generally, this brings up a troubling issue overall:
539 what happens if a tablejump is split across two pages? I do
540 not beleive that this case is handled correctly at all, and
541 can only lead to horrible results if this were to occur.
543 However, the current situation is not any worse than it was
544 last week, and so we punt for now. */
547 for (j=0; j < XVECLEN (body, 0); j++)
550 /* finished with the vector go do next insn */
556 Compiling the exception handling (L_eh) in libgcc2.a will trip
557 up right here, with something that looks like
558 (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
560 I'm not sure of what leads up to this, but it looks like
561 the makings of a long jump which will surely get us into trouble
562 because the base & page registers don't get reloaded. For now
563 I'm not sure of what to do ... again we punt ... we are not worse
564 off than yesterday. */
566 /* print_rtl_single (stdout, insn); */
574 /* At this point, this jump_insn had better be a plain-old
575 ordinary one, grap the label id and go */
576 if (CODE_LABEL != GET_CODE (label)) abort ();
577 I370_RECORD_LABEL_REF(label,here);
581 /* Sometimes, we take addresses of labels and use them
582 as instruction operands ... these show up as REG_NOTES */
586 if ('i' == GET_RTX_CLASS (code))
589 for (note = REG_NOTES (insn); note; note = XEXP(note,1))
591 if (REG_LABEL == REG_NOTE_KIND(note))
593 rtx label = XEXP (note,0);
594 if (!label || CODE_LABEL != GET_CODE (label)) abort ();
596 I370_RECORD_LABEL_REF(label,here);
604 /* ===================================================== */
606 /* Emit reload of base register if indicated. This is to eliminate multiple
607 reloads when several labels are generated pointing to the same place
610 The page table is written at the end of the function.
611 The entries in the page table look like
612 .LPGT0: // PGT0 EQU *
613 .long .LPG0 // DC A(PG0)
614 .long .LPG1 // DC A(PG1)
615 while the prologue generates
618 Note that this paging scheme breaks down if a single subroutine
619 has more than about 10MB of code in it ... as long as humans write
620 code, this shouldn't be a problem ...
626 if (mvs_need_base_reload)
628 mvs_need_base_reload = 0;
631 fprintf (assembler_source, "\tL\t%d,%d(,%d)\n",
632 BASE_REGISTER, (mvs_page_num - function_base_page) * 4,
637 /* Add the label to the current page label list. If a free element is available
638 it will be used for the new label. Otherwise, a label element will be
639 allocated from memory.
640 ID is the label number of the label being added to the list. */
642 static label_node_t *
648 /* first, lets see if we already go one, if so, use that. */
649 for (lp = label_anchor; lp; lp = lp->label_next)
651 if (lp->label_id == id) return lp;
654 /* not found, get a new one */
658 free_anchor = lp->label_next;
662 lp = (label_node_t *) xmalloc (sizeof (label_node_t));
665 /* initialize for new label */
668 lp->label_next = label_anchor;
669 lp->label_first_ref = 2000123123;
670 lp->label_last_ref = -1;
672 lp->first_ref_page = -1;
685 lp = mvs_get_label (id);
686 lp->label_page = mvs_page_num;
688 /* OK, we just saw the label. Determine if this label
689 * needs a reload of the base register */
690 if ((-1 != lp->first_ref_page) &&
691 (lp->first_ref_page != mvs_page_num))
693 /* Yep; the first label_ref was on a different page. */
694 mvs_need_base_reload ++;
698 /* Hmm. Try to see if the estimated address of the last
699 label_ref is on the current page. If it is, then we
700 don't need a base reg reload. Note that this estimate
701 is very conservatively handled; we'll tend to have
702 a good bit more reloads than actually needed. Someday,
703 we should tighten the estimates (which are driven by
704 the (set_att "length") insn attibute.
706 Currently, we estimate that number of page literals
707 same as number of insns, which is a vast overestimate,
708 esp that the estimate of each insn size is its max size. */
710 /* if latest ref comes before label, we are clear */
711 if (lp->label_last_ref < lp->label_addr) return;
713 fwd_distance = lp->label_last_ref - lp->label_addr;
715 if (mvs_page_code + 2 * fwd_distance + mvs_page_lit < 4060) return;
717 mvs_need_base_reload ++;
720 /* Check to see if the label is in the list and in the current
721 page. If not found, we have to make worst case assumption
722 that label will be on a different page, and thus will have to
723 generate a load and branch on register. This is rather
724 ugly for forward-jumps, but what can we do? For backward
725 jumps on the same page we can branch directly to address.
726 ID is the label number of the label being checked. */
734 for (lp = label_anchor; lp; lp = lp->label_next)
736 if (lp->label_id == id)
738 if (lp->label_page == mvs_page_num)
751 /* Get the page on which the label sits. This will be used to
752 determine is a register reload is really needed. */
756 mvs_get_label_page(int id)
760 for (lp = label_anchor; lp; lp = lp->label_next)
762 if (lp->label_id == id)
763 return lp->label_page;
769 /* The label list for the current page freed by linking the list onto the free
770 label element chain. */
773 mvs_free_label_list ()
778 label_node_t *last_lp = label_anchor;
779 while (last_lp->label_next) last_lp = last_lp->label_next;
780 last_lp->label_next = free_anchor;
781 free_anchor = label_anchor;
786 /* ====================================================================== */
787 /* If the page size limit is reached a new code page is started, and the base
788 register is set to it. This page break point is counted conservatively,
789 most literals that have the same value are collapsed by the assembler.
790 True is returned when a new page is started.
791 FILE is the assembler output file descriptor.
792 CODE is the length, in bytes, of the instruction to be emitted.
793 LIT is the length of the literal to be emitted. */
797 mvs_check_page (file, code, lit)
802 assembler_source = file;
804 if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
806 fprintf (assembler_source, "\tB\tPGE%d\n", mvs_page_num);
807 fprintf (assembler_source, "\tDS\t0F\n");
808 fprintf (assembler_source, "\tLTORG\n");
809 fprintf (assembler_source, "\tDS\t0F\n");
810 fprintf (assembler_source, "PGE%d\tEQU\t*\n", mvs_page_num);
811 fprintf (assembler_source, "\tDROP\t%d\n", BASE_REGISTER);
813 /* Safe to use BASR not BALR, since we are
814 * not switching addressing mode here ... */
815 fprintf (assembler_source, "\tBASR\t%d,0\n", BASE_REGISTER);
816 fprintf (assembler_source, "PG%d\tEQU\t*\n", mvs_page_num);
817 fprintf (assembler_source, "\tUSING\t*,%d\n", BASE_REGISTER);
818 mvs_page_code = code;
822 mvs_page_code += code;
826 #endif /* TARGET_HLASM */
829 #ifdef TARGET_ELF_ABI
831 mvs_check_page (file, code, lit)
836 assembler_source = file;
838 if (mvs_page_code + code + mvs_page_lit + lit > MAX_MVS_PAGE_LENGTH)
840 /* hop past the literal pool */
841 fprintf (assembler_source, "\tB\t.LPGE%d\n", mvs_page_num);
843 /* dump the literal pool. The .baligns are optional, since
844 * ltorg will align to the size of the largest literal
845 * (which is possibly 8 bytes) */
846 fprintf (assembler_source, "\t.balign\t4\n");
847 fprintf (assembler_source, "\t.LTORG\n");
848 fprintf (assembler_source, "\t.balign\t4\n");
850 /* we continue execution here ... */
851 fprintf (assembler_source, ".LPGE%d:\n", mvs_page_num);
852 fprintf (assembler_source, "\t.DROP\t%d\n", BASE_REGISTER);
855 /* BASR puts the contents of the PSW into r3
856 * that is, r3 will be loaded with the address of "." */
857 fprintf (assembler_source, "\tBASR\tr%d,0\n", BASE_REGISTER);
858 fprintf (assembler_source, ".LPG%d:\n", mvs_page_num);
859 fprintf (assembler_source, "\t.USING\t.,r%d\n", BASE_REGISTER);
860 mvs_page_code = code;
864 mvs_page_code += code;
868 #endif /* TARGET_ELF_ABI */
870 /* ===================================================== */
871 /* defines and functions specific to the HLASM assembler */
874 /* Check for C/370 runtime function, they don't use standard calling
875 conventions. True is returned if the function is in the table.
876 NAME is the name of the current function. */
879 mvs_function_check (name)
882 int lower, middle, upper;
886 upper = MVS_FUNCTION_TABLE_LENGTH - 1;
887 while (lower <= upper)
889 middle = (lower + upper) / 2;
890 i = strcmp (name, mvs_function_table[middle]);
901 /* Generate a hash for a given key. */
910 int l = strlen (key);
913 for (i = 1; i < l; i++)
914 h = ((h * MVS_SET_SIZE) + key[i]) % MVS_HASH_PRIME;
919 /* Add the alias to the current alias list. */
922 mvs_add_alias (realname, aliasname, emitted)
923 const char *realname;
924 const char *aliasname;
929 ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
930 if (strlen (realname) > MAX_LONG_LABEL_SIZE)
932 warning ("real name is too long - alias ignored");
935 if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
937 warning ("alias name is too long - alias ignored");
941 strcpy (ap->real_name, realname);
942 strcpy (ap->alias_name, aliasname);
943 ap->alias_emitted = emitted;
944 ap->alias_next = alias_anchor;
948 /* Check to see if the name needs aliasing. ie. the name is either:
949 1. Longer than 8 characters
950 2. Contains an underscore
954 mvs_need_alias (realname)
955 const char *realname;
957 int i, j = strlen (realname);
959 if (mvs_function_check (realname))
962 if (!strcmp (realname, "gccmain"))
964 if (!strcmp (realname, "main"))
967 if (j > MAX_MVS_LABEL_SIZE)
969 if (strchr (realname, '_') != 0)
971 if (ISUPPER (realname[0]))
973 for (i = 1; i < j; i++)
975 if (ISLOWER (realname[i]))
981 for (i = 1; i < j; i++)
983 if (ISUPPER (realname[i]))
991 /* Get the alias from the list.
992 If 1 is returned then it's in the alias list, 0 if it was not */
995 mvs_get_alias (realname, aliasname)
996 const char *realname;
1002 for (ap = alias_anchor; ap; ap = ap->alias_next)
1004 if (!strcmp (ap->real_name, realname))
1006 strcpy (aliasname, ap->alias_name);
1010 if (mvs_need_alias (realname))
1016 if (ISLOWER (c1)) c1 = TOUPPER (c1);
1017 else if (c1 == '_') c1 = 'A';
1018 if (ISLOWER (c2)) c2 = TOUPPER (c2);
1019 else if (c2 == '_' || c2 == '\0') c2 = '#';
1021 sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
1022 mvs_add_alias (realname, aliasname, 0);
1026 if (strlen (realname) > MAX_MVS_LABEL_SIZE)
1028 strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1029 aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1036 /* Check to see if the alias is in the list.
1037 If 1 is returned then it's in the alias list, 2 it was emitted */
1040 mvs_check_alias (realname, aliasname)
1041 const char *realname;
1047 for (ap = alias_anchor; ap; ap = ap->alias_next)
1049 if (!strcmp (ap->real_name, realname))
1051 int rc = (ap->alias_emitted == 1) ? 1 : 2;
1052 strcpy (aliasname, ap->alias_name);
1053 ap->alias_emitted = 1;
1057 if (mvs_need_alias (realname))
1063 if (ISLOWER (c1)) c1 = TOUPPER (c1);
1064 else if (c1 == '_') c1 = 'A';
1065 if (ISLOWER (c2)) c2 = TOUPPER (c2);
1066 else if (c2 == '_' || c2 == '\0') c2 = '#';
1068 sprintf (aliasname, "%c%c%06d", c1, c2, mvs_hash_alias (realname));
1069 mvs_add_alias (realname, aliasname, 0);
1070 alias_anchor->alias_emitted = 1;
1074 if (strlen (realname) > MAX_MVS_LABEL_SIZE)
1076 strncpy (aliasname, realname, MAX_MVS_LABEL_SIZE);
1077 aliasname[MAX_MVS_LABEL_SIZE] = '\0';
1084 /* defines and functions specific to the HLASM assembler */
1085 #endif /* TARGET_HLASM */
1086 /* ===================================================== */
1087 /* ===================================================== */
1088 /* defines and functions specific to the gas assembler */
1089 #ifdef TARGET_ELF_ABI
1091 /* Check for C/370 runtime function, they don't use standard calling
1092 conventions. True is returned if the function is in the table.
1093 NAME is the name of the current function. */
1094 /* no special calling conventions (yet ??) */
1097 mvs_function_check (name)
1098 const char *name ATTRIBUTE_UNUSED;
1103 #endif /* TARGET_ELF_ABI */
1104 /* ===================================================== */
1107 /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
1108 OP is the current operation.
1109 MODE is the current operation mode. */
1112 s_operand (op, mode)
1114 enum machine_mode mode;
1116 extern int volatile_ok;
1117 register enum rtx_code code = GET_CODE (op);
1119 if (CONSTANT_ADDRESS_P (op))
1121 if (mode == VOIDmode || GET_MODE (op) != mode)
1125 register rtx x = XEXP (op, 0);
1127 if (!volatile_ok && op->volatil)
1129 if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1131 if (GET_CODE (x) == PLUS
1132 && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1133 && GET_CODE (XEXP (x, 1)) == CONST_INT
1134 && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1141 /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
1143 OP is the current operation.
1144 MODE is the current operation mode. */
1147 r_or_s_operand (op, mode)
1149 enum machine_mode mode;
1151 extern int volatile_ok;
1152 register enum rtx_code code = GET_CODE (op);
1154 if (CONSTANT_ADDRESS_P (op))
1156 if (mode == VOIDmode || GET_MODE (op) != mode)
1160 else if (code == MEM)
1162 register rtx x = XEXP (op, 0);
1164 if (!volatile_ok && op->volatil)
1166 if (REG_P (x) && REG_OK_FOR_BASE_P (x))
1168 if (GET_CODE (x) == PLUS
1169 && REG_P (XEXP (x, 0)) && REG_OK_FOR_BASE_P (XEXP (x, 0))
1170 && GET_CODE (XEXP (x, 1)) == CONST_INT
1171 && (unsigned) INTVAL (XEXP (x, 1)) < 4096)
1178 /* Some remarks about unsigned_jump_follows_p():
1179 gcc is built around the assumption that branches are signed
1180 or unsigned, whereas the 370 doesn't care; its the compares that
1181 are signed or unsigned. Thus, we need to somehow know if we
1182 need to do a signed or an unsigned compare, and we do this by
1183 looking ahead in the instruction sequence until we find a jump.
1184 We then note whether this jump is signed or unsigned, and do the
1185 compare appropriately. Note that we have to scan ahead indefinitley,
1186 as the gcc optimizer may insert any number of instructions between
1187 the compare and the jump.
1189 Note that using conditional branch expanders seems to be be a more
1190 elegant/correct way of doing this. See, for instance, the Alpha
1191 cmpdi and bgt patterns. Note also that for the i370, various
1192 arithmetic insn's set the condition code as well.
1194 The unsigned_jump_follows_p() routine returns a 1 if the next jump
1195 is unsigned. INSN is the current instruction. */
1198 unsigned_jump_follows_p (insn)
1201 rtx orig_insn = insn;
1204 register rtx tmp_insn;
1207 insn = NEXT_INSN (insn);
1208 if (!insn) fatal_insn ("internal error--no jump follows compare:", orig_insn);
1210 if (GET_CODE (insn) != JUMP_INSN) continue;
1212 tmp_insn = XEXP (insn, 3);
1213 if (GET_CODE (tmp_insn) != SET) continue;
1215 if (GET_CODE (XEXP (tmp_insn, 0)) != PC) continue;
1217 tmp_insn = XEXP (tmp_insn, 1);
1218 if (GET_CODE (tmp_insn) != IF_THEN_ELSE) continue;
1220 /* if we got to here, this instruction is a jump. Is it signed? */
1221 tmp_insn = XEXP (tmp_insn, 0);
1222 coda = GET_CODE (tmp_insn);
1224 return coda != GE && coda != GT && coda != LE && coda != LT;
1230 /* Target hook for assembling integer objects. This version handles all
1231 objects when TARGET_HLASM is defined. */
1234 i370_hlasm_assemble_integer (x, size, aligned_p)
1239 const char *int_format = NULL;
1245 int_format = "\tDC\tX'%02X'\n";
1249 int_format = "\tDC\tX'%04X'\n";
1253 if (GET_CODE (x) == CONST_INT)
1255 fputs ("\tDC\tF'", asm_out_file);
1256 output_addr_const (asm_out_file, x);
1257 fputs ("'\n", asm_out_file);
1261 fputs ("\tDC\tA(", asm_out_file);
1262 output_addr_const (asm_out_file, x);
1263 fputs (")\n", asm_out_file);
1268 if (int_format && GET_CODE (x) == CONST_INT)
1270 fprintf (asm_out_file, int_format, INTVAL (x));
1273 return default_assemble_integer (x, size, aligned_p);
1276 /* Generate the assembly code for function entry. FILE is a stdio
1277 stream to output the code to. SIZE is an int: how many units of
1278 temporary storage to allocate.
1280 Refer to the array `regs_ever_live' to determine which registers to
1281 save; `regs_ever_live[I]' is nonzero if register number I is ever
1282 used in the function. This function is responsible for knowing
1283 which registers should not be saved even if used. */
1286 i370_output_function_prologue (f, l)
1290 #if MACROPROLOGUE == 1
1291 fprintf (f, "* Function %s prologue\n", mvs_function_name);
1292 fprintf (f, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
1293 STACK_POINTER_OFFSET + l - 120 +
1294 current_function_outgoing_args_size, BASE_REGISTER);
1295 #else /* MACROPROLOGUE != 1 */
1296 static int function_label_index = 1;
1297 static int function_first = 0;
1298 static int function_year, function_month, function_day;
1299 static int function_hour, function_minute, function_second;
1301 if (!function_first)
1303 struct tm *function_time;
1306 function_time = localtime (&lcltime);
1307 function_year = function_time->tm_year + 1900;
1308 function_month = function_time->tm_mon + 1;
1309 function_day = function_time->tm_mday;
1310 function_hour = function_time->tm_hour;
1311 function_minute = function_time->tm_min;
1312 function_second = function_time->tm_sec;
1314 fprintf (f, "* Function %s prologue\n", mvs_function_name);
1315 fprintf (f, "FDSE%03d\tDSECT\n", function_label_index);
1316 fprintf (f, "\tDS\tD\n");
1317 fprintf (f, "\tDS\tCL(" HOST_WIDE_INT_PRINT_DEC ")\n",
1318 STACK_POINTER_OFFSET + l
1319 + current_function_outgoing_args_size);
1320 fprintf (f, "\tORG\tFDSE%03d\n", function_label_index);
1321 fprintf (f, "\tDS\tCL(120+8)\n");
1322 fprintf (f, "\tORG\n");
1323 fprintf (f, "\tDS\t0D\n");
1324 fprintf (f, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index,
1325 function_label_index);
1326 fprintf (f, "\tDS\t0H\n");
1327 assemble_name (f, mvs_function_name);
1328 fprintf (f, "\tCSECT\n");
1329 fprintf (f, "\tUSING\t*,15\n");
1330 fprintf (f, "\tB\tFENT%03d\n", function_label_index);
1331 fprintf (f, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index);
1332 fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1333 fprintf (f, "\tDC\tAL4(FPPA%03d)\n", function_label_index);
1334 fprintf (f, "\tDC\tAL4(0)\n");
1335 fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1336 fprintf (f, "FNAM%03d\tEQU\t*\n", function_label_index);
1337 fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1339 fprintf (f, "FPPA%03d\tDS\t0F\n", function_label_index);
1340 fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1341 fprintf (f, "\tDC\tV(CEESTART)\n");
1342 fprintf (f, "\tDC\tAL4(0)\n");
1343 fprintf (f, "\tDC\tAL4(FTIM%03d)\n", function_label_index);
1344 fprintf (f, "FTIM%03d\tDS\t0F\n", function_label_index);
1345 fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1346 function_year, function_month, function_day,
1347 function_hour, function_minute);
1348 fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1349 fprintf (f, "FENT%03d\tDS\t0H\n", function_label_index);
1350 fprintf (f, "\tSTM\t14,12,12(13)\n");
1351 fprintf (f, "\tL\t2,76(,13)\n");
1352 fprintf (f, "\tL\t0,16(,15)\n");
1353 fprintf (f, "\tALR\t0,2\n");
1354 fprintf (f, "\tCL\t0,12(,12)\n");
1355 fprintf (f, "\tBNH\t*+10\n");
1356 fprintf (f, "\tL\t15,116(,12)\n");
1357 fprintf (f, "\tBALR\t14,15\n");
1358 fprintf (f, "\tL\t15,72(,13)\n");
1359 fprintf (f, "\tSTM\t15,0,72(2)\n");
1360 fprintf (f, "\tMVI\t0(2),X'10'\n");
1361 fprintf (f, "\tST\t2,8(,13)\n ");
1362 fprintf (f, "\tST\t13,4(,2)\n ");
1363 fprintf (f, "\tLR\t13,2\n");
1364 fprintf (f, "\tDROP\t15\n");
1365 fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
1366 fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
1368 function_label_index ++;
1370 if (!function_first)
1372 struct tm *function_time;
1375 function_time = localtime (&lcltime);
1376 function_year = function_time->tm_year + 1900;
1377 function_month = function_time->tm_mon + 1;
1378 function_day = function_time->tm_mday;
1379 function_hour = function_time->tm_hour;
1380 function_minute = function_time->tm_min;
1381 function_second = function_time->tm_sec;
1382 fprintf (f, "PPA2\tDS\t0F\n");
1383 fprintf (f, "\tDC\tX'03',X'00',X'33',X'00'\n");
1384 fprintf (f, "\tDC\tV(CEESTART),A(0)\n");
1385 fprintf (f, "\tDC\tA(CEETIMES)\n");
1386 fprintf (f, "CEETIMES\tDS\t0F\n");
1387 fprintf (f, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1388 function_year, function_month, function_day,
1389 function_hour, function_minute, function_second);
1390 fprintf (f, "\tDC\tCL2'01',CL4'0100'\n");
1392 fprintf (f, "* Function %s prologue\n", mvs_function_name);
1393 fprintf (f, "FDSD%03d\tDSECT\n", function_label_index);
1394 fprintf (f, "\tDS\tD\n");
1395 fprintf (f, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET + l
1396 + current_function_outgoing_args_size);
1397 fprintf (f, "\tORG\tFDSD%03d\n", function_label_index);
1398 fprintf (f, "\tDS\tCL(120+8)\n");
1399 fprintf (f, "\tORG\n");
1400 fprintf (f, "\tDS\t0D\n");
1401 fprintf (f, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index,
1402 function_label_index);
1403 fprintf (f, "\tDS\t0H\n");
1404 assemble_name (f, mvs_function_name);
1405 fprintf (f, "\tCSECT\n");
1406 fprintf (f, "\tUSING\t*,15\n");
1407 fprintf (f, "\tB\tFPL%03d\n", function_label_index);
1408 fprintf (f, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index + 1);
1409 fprintf (f, "\tDC\tX'CE',X'A0',AL1(16)\n");
1410 fprintf (f, "\tDC\tAL4(PPA2)\n");
1411 fprintf (f, "\tDC\tAL4(0)\n");
1412 fprintf (f, "\tDC\tAL4(FDSL%03d)\n", function_label_index);
1413 fprintf (f, "FPL%03d\tEQU\t*\n", function_label_index + 1);
1414 fprintf (f, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name),
1416 fprintf (f, "FPL%03d\tDS\t0H\n", function_label_index);
1417 fprintf (f, "\tSTM\t14,12,12(13)\n");
1418 fprintf (f, "\tL\t2,76(,13)\n");
1419 fprintf (f, "\tL\t0,16(,15)\n");
1420 fprintf (f, "\tALR\t0,2\n");
1421 fprintf (f, "\tCL\t0,12(,12)\n");
1422 fprintf (f, "\tBNH\t*+10\n");
1423 fprintf (f, "\tL\t15,116(,12)\n");
1424 fprintf (f, "\tBALR\t14,15\n");
1425 fprintf (f, "\tL\t15,72(,13)\n");
1426 fprintf (f, "\tSTM\t15,0,72(2)\n");
1427 fprintf (f, "\tMVI\t0(2),X'10'\n");
1428 fprintf (f, "\tST\t2,8(,13)\n ");
1429 fprintf (f, "\tST\t13,4(,2)\n ");
1430 fprintf (f, "\tLR\t13,2\n");
1431 fprintf (f, "\tDROP\t15\n");
1432 fprintf (f, "\tBALR\t%d,0\n", BASE_REGISTER);
1433 fprintf (f, "\tUSING\t*,%d\n", BASE_REGISTER);
1435 function_label_index += 2;
1437 #endif /* MACROPROLOGUE */
1438 fprintf (f, "PG%d\tEQU\t*\n", mvs_page_num );
1439 fprintf (f, "\tLR\t11,1\n");
1440 fprintf (f, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER, mvs_page_num);
1441 fprintf (f, "* Function %s code\n", mvs_function_name);
1443 mvs_free_label_list ();
1446 mvs_check_page (f, 0, 0);
1447 function_base_page = mvs_page_num;
1449 /* find all labels in this routine */
1454 i370_globalize_label (stream, name)
1458 char temp[MAX_MVS_LABEL_SIZE + 1];
1459 if (mvs_check_alias (name, temp) == 2)
1460 fprintf (stream, "%s\tALIAS\tC'%s'\n", temp, name);
1461 fputs ("\tENTRY\t", stream);
1462 assemble_name (stream, name);
1463 putc ('\n', stream);
1465 #endif /* TARGET_HLASM */
1468 #ifdef TARGET_ELF_ABI
1470 The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
1471 It implements a stack that grows downward.
1472 It performs the following steps:
1473 -- saves the callers non-volatile registers on the callers stack.
1474 -- subtracts stackframe size from the stack pointer.
1475 -- stores backpointer to old caller stack.
1477 XXX hack alert -- if the global var int leaf_function is nonzero,
1478 then this is a leaf, and it might be possible to optimize the prologue
1479 into doing even less, e.g. not grabbing a new stackframe or maybe just a
1480 partial stack frame.
1482 XXX hack alert -- the current stack frame is bloated into twice the
1483 needed size by unused entries. These entries make it marginally
1484 compatible with MVS/OE/USS C environment, but really they're not used
1485 and could probably chopped out. Modifications to i370.md would be needed
1486 also, to quite using addresses 136, 140, etc.
1490 i370_output_function_prologue (f, frame_size)
1492 HOST_WIDE_INT frame_size;
1494 static int function_label_index = 1;
1495 static int function_first = 0;
1496 int stackframe_size, aligned_size;
1498 fprintf (f, "# Function prologue\n");
1499 /* define the stack, put it into its own data segment
1500 FDSE == Function Stack Entry
1501 FDSL == Function Stack Length */
1503 STACK_POINTER_OFFSET + current_function_outgoing_args_size + frame_size;
1504 aligned_size = (stackframe_size + 7) >> 3;
1507 fprintf (f, "# arg_size=0x%x frame_size=" HOST_WIDE_INT_PRINT_HEX
1508 " aligned size=0x%x\n",
1509 current_function_outgoing_args_size, frame_size, aligned_size);
1511 fprintf (f, "\t.using\t.,r15\n");
1513 /* Branch to exectuable part of prologue. */
1514 fprintf (f, "\tB\t.LFENT%03d\n", function_label_index);
1516 /* write the length of the stackframe */
1517 fprintf (f, "\t.long\t%d\n", aligned_size);
1519 /* FENT == function prologue entry */
1520 fprintf (f, "\t.balign 2\n.LFENT%03d:\n",
1521 function_label_index);
1523 /* store multiple registers 14,15,0,...12 at 12 bytes from sp */
1524 fprintf (f, "\tSTM\tr14,r12,12(sp)\n");
1526 /* r3 == saved callee stack pointer */
1527 fprintf (f, "\tLR\tr3,sp\n");
1529 /* 4(r15) == stackframe size */
1530 fprintf (f, "\tSL\tsp,4(,r15)\n");
1532 /* r11 points to arg list in callers stackframe; was passed in r2 */
1533 fprintf (f, "\tLR\tr11,r2\n");
1535 /* store callee stack pointer at 8(sp) */
1536 /* fprintf (f, "\tST\tsp,8(,r3)\n "); wasted cycles, no one uses this ... */
1538 /* backchain -- store caller sp at 4(callee_sp) */
1539 fprintf (f, "\tST\tr3,4(,sp)\n ");
1541 fprintf (f, "\t.drop\tr15\n");
1542 /* Place contents of the PSW into r3
1543 that is, place the address of "." into r3 */
1544 fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER);
1545 fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER);
1547 function_label_index ++;
1549 fprintf (f, ".LPG%d:\n", mvs_page_num );
1550 fprintf (f, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER, mvs_page_num);
1551 fprintf (f, "# Function code\n");
1553 mvs_free_label_list ();
1556 mvs_check_page (f, 0, 0);
1557 function_base_page = mvs_page_num;
1559 /* find all labels in this routine */
1562 #endif /* TARGET_ELF_ABI */
1564 /* This function generates the assembly code for function exit.
1565 Args are as for output_function_prologue ().
1567 The function epilogue should not depend on the current stack
1568 pointer! It should use the frame pointer only. This is mandatory
1569 because of alloca; we also take advantage of it to omit stack
1570 adjustments before returning. */
1573 i370_output_function_epilogue (file, l)
1575 HOST_WIDE_INT l ATTRIBUTE_UNUSED;
1579 check_label_emit ();
1580 mvs_check_page (file, 14, 0);
1581 fprintf (file, "* Function %s epilogue\n", mvs_function_name);
1584 #if MACROEPILOGUE == 1
1585 fprintf (file, "\tEDCEPIL\n");
1586 #else /* MACROEPILOGUE != 1 */
1587 fprintf (file, "\tL\t13,4(,13)\n");
1588 fprintf (file, "\tL\t14,12(,13)\n");
1589 fprintf (file, "\tLM\t2,12,28(13)\n");
1590 fprintf (file, "\tBALR\t1,14\n");
1591 fprintf (file, "\tDC\tA(");
1592 assemble_name (file, mvs_function_name);
1593 fprintf (file, ")\n" );
1594 #endif /* MACROEPILOGUE */
1596 fprintf (file, "* Function %s literal pool\n", mvs_function_name);
1597 fprintf (file, "\tDS\t0F\n" );
1598 fprintf (file, "\tLTORG\n");
1599 fprintf (file, "* Function %s page table\n", mvs_function_name);
1600 fprintf (file, "\tDS\t0F\n");
1601 fprintf (file, "PGT%d\tEQU\t*\n", function_base_page);
1603 mvs_free_label_list();
1604 for (i = function_base_page; i < mvs_page_num; i++)
1605 fprintf (file, "\tDC\tA(PG%d)\n", i);
1611 fputs ("\tRMODE\tANY\n\tCSECT\n", asm_out_file);
1617 fputs ("\tEND\n", asm_out_file);
1621 i370_internal_label (stream, prefix, labelno)
1624 unsigned long labelno;
1626 if (!strcmp (prefix, "L"))
1627 mvs_add_label(labelno);
1629 default_internal_label (stream, prefix, labelno);
1633 i370_rtx_costs (x, code, outer_code, total)
1636 int outer_code ATTRIBUTE_UNUSED;
1642 if ((unsigned HOST_WIDE_INT) INTVAL (x) < 0xfff)