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