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 HOST_CHARSET == HC_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 HOST_CHARSET == HC_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) && HOST_CHARSET == HC_ASCII
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 ASCII */
234 #if !defined(TARGET_EBCDIC) && HOST_CHARSET == HC_EBCDIC
235 /* EBCDIC to ASCII conversion table. */
236 static const unsigned char ebcasc
[256] =
238 /*00 NU SH SX EX PF HT LC DL */
239 0x00, 0x01, 0x02, 0x03, 0x00, 0x09, 0x00, 0x7F,
240 /*08 SM VT FF CR SO SI */
241 0x00, 0x00, 0x00, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
242 /*10 DE D1 D2 TM RS NL BS IL */
243 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x08, 0x00,
244 /*18 CN EM CC C1 FS GS RS US */
245 0x18, 0x19, 0x00, 0x00, 0x1C, 0x1D, 0x1E, 0x1F,
246 /*20 DS SS FS BP LF EB EC */
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x17, 0x1B,
248 /*28 SM C2 EQ AK BL */
249 0x00, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x00,
250 /*30 SY PN RS UC ET */
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
253 0x00, 0x00, 0x00, 0x00, 0x14, 0x15, 0x00, 0x1A,
255 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
259 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
263 0x2D, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 /*78 ` : # @ ' = " */
269 0x00, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
270 /*80 a b c d e f g */
271 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
273 0x68, 0x69, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x00,
274 /*90 j k l m n o p */
275 0x00, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
277 0x71, 0x72, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00,
278 /*A0 ~ s t u v w x */
279 0x00, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
281 0x79, 0x7A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00,
286 /*C0 { A B C D E F G */
287 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
289 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 /*D0 } J K L M N O P */
291 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
293 0x51, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 /*E0 \ S T U V W X */
295 0x5C, 0x00, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
297 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 /*F0 0 1 2 3 4 5 6 7 */
299 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
301 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
303 #endif /* target ASCII, host EBCDIC */
305 /* Initialize the GCC target structure. */
307 #undef TARGET_ASM_BYTE_OP
308 #define TARGET_ASM_BYTE_OP NULL
309 #undef TARGET_ASM_ALIGNED_HI_OP
310 #define TARGET_ASM_ALIGNED_HI_OP NULL
311 #undef TARGET_ASM_ALIGNED_SI_OP
312 #define TARGET_ASM_ALIGNED_SI_OP NULL
313 #undef TARGET_ASM_INTEGER
314 #define TARGET_ASM_INTEGER i370_hlasm_assemble_integer
315 #undef TARGET_ASM_GLOBALIZE_LABEL
316 #define TARGET_ASM_GLOBALIZE_LABEL i370_globalize_label
319 #undef TARGET_ASM_FUNCTION_PROLOGUE
320 #define TARGET_ASM_FUNCTION_PROLOGUE i370_output_function_prologue
321 #undef TARGET_ASM_FUNCTION_EPILOGUE
322 #define TARGET_ASM_FUNCTION_EPILOGUE i370_output_function_epilogue
323 #undef TARGET_ASM_FILE_START
324 #define TARGET_ASM_FILE_START i370_file_start
325 #undef TARGET_ASM_FILE_END
326 #define TARGET_ASM_FILE_END i370_file_end
327 #undef TARGET_ASM_INTERNAL_LABEL
328 #define TARGET_ASM_INTERNAL_LABEL i370_internal_label
329 #undef TARGET_RTX_COSTS
330 #define TARGET_RTX_COSTS i370_rtx_costs
332 struct gcc_target targetm
= TARGET_INITIALIZER
;
334 /* Set global variables as needed for the options enabled. */
339 /* We're 370 floating point, not IEEE floating point. */
340 memset (real_format_for_mode
, 0, sizeof real_format_for_mode
);
341 real_format_for_mode
[SFmode
- QFmode
] = &i370_single_format
;
342 real_format_for_mode
[DFmode
- QFmode
] = &i370_double_format
;
346 /* Map characters from one character set to another.
347 C is the character to be translated. */
353 #if defined(TARGET_EBCDIC) && HOST_CHARSET == HC_ASCII
354 fprintf (stderr
, "mvs_map_char: TE & !HE: c = %02x\n", c
);
357 #if !defined(TARGET_EBCDIC) && HOST_CHARSET == HC_EBCDIC
358 fprintf (stderr
, "mvs_map_char: !TE & HE: c = %02x\n", c
);
361 fprintf (stderr
, "mvs_map_char: !TE & !HE: c = %02x\n", c
);
367 /* ===================================================== */
368 /* The following three routines are used to determine whther
369 forward branch is on this page, or is a far jump. We use
370 the "length" attr on an insn [(set_atter "length" "4")]
371 to store the largest possible code length that insn
372 could have. This gives us a hint of the address of a
373 branch destination, and from that, we can work out
374 the length of the jump, and whether its on page or not.
377 /* Return the destination address of a branch. */
380 i370_branch_dest (branch
)
383 rtx dest
= SET_SRC (PATTERN (branch
));
387 /* first, compute the estimated address of the branch target */
388 if (GET_CODE (dest
) == IF_THEN_ELSE
)
389 dest
= XEXP (dest
, 1);
390 dest
= XEXP (dest
, 0);
391 dest_uid
= INSN_UID (dest
);
392 dest_addr
= INSN_ADDRESSES (dest_uid
);
394 /* next, record the address of this insn as the true addr of first ref */
397 rtx label
= JUMP_LABEL (branch
);
398 int labelno
= CODE_LABEL_NUMBER (label
);
400 if (!label
|| CODE_LABEL
!= GET_CODE (label
)) abort ();
402 lp
= mvs_get_label (labelno
);
403 if (-1 == lp
-> first_ref_page
) lp
->first_ref_page
= mvs_page_num
;
409 i370_branch_length (insn
)
413 here
= INSN_ADDRESSES (INSN_UID (insn
));
414 there
= i370_branch_dest (insn
);
415 return (there
- here
);
420 i370_short_branch (insn
)
425 base_offset
= i370_branch_length(insn
);
428 base_offset
+= mvs_page_code
;
432 /* avoid bumping into lit pool; use 2x to estimate max possible lits */
434 base_offset
+= mvs_page_code
+ mvs_page_lit
;
437 /* make a conservative estimate of room left on page */
438 if ((4060 >base_offset
) && ( 0 < base_offset
)) return 1;
442 /* The i370_label_scan() routine is supposed to loop over
443 all labels and label references in a compilation unit,
444 and determine whether all label refs appear on the same
445 code page as the label. If they do, then we can avoid
446 a reload of the base register for that label.
448 Note that the instruction addresses used here are only
449 approximate, and make the sizes of the jumps appear
450 farther apart then they will actually be. This makes
451 this code far more conservative than it needs to be.
454 #define I370_RECORD_LABEL_REF(label,addr) { \
456 int labelno = CODE_LABEL_NUMBER (label); \
457 lp = mvs_get_label (labelno); \
458 if (addr < lp -> label_first_ref) lp->label_first_ref = addr; \
459 if (addr > lp -> label_last_ref) lp->label_last_ref = addr; \
467 int tablejump_offset
= 0;
469 for (insn
= get_insns(); insn
; insn
= NEXT_INSN(insn
))
471 int here
= INSN_ADDRESSES (INSN_UID (insn
));
472 enum rtx_code code
= GET_CODE(insn
);
474 /* ??? adjust for tables embedded in the .text section that
475 * the compiler didn't take into account */
476 here
+= tablejump_offset
;
477 INSN_ADDRESSES (INSN_UID (insn
)) = here
;
479 /* check to see if this insn is a label ... */
480 if (CODE_LABEL
== code
)
482 int labelno
= CODE_LABEL_NUMBER (insn
);
484 lp
= mvs_get_label (labelno
);
485 lp
-> label_addr
= here
;
487 /* Supposedly, labels are supposed to have circular
488 lists of label-refs that reference them,
489 setup in flow.c, but this does not appear to be the case. */
490 rtx labelref
= LABEL_REFS (insn
);
494 rtx linsn
= CONTAINING_INSN(ref
);
495 ref
= LABEL_NEXTREF(ref
);
496 } while (ref
&& (ref
!= labelref
));
500 if (JUMP_INSN
== code
)
502 rtx label
= JUMP_LABEL (insn
);
504 /* If there is no label for this jump, then this
505 had better be a ADDR_VEC or an ADDR_DIFF_VEC
506 and there had better be a vector of labels. */
510 rtx body
= PATTERN (insn
);
511 if (ADDR_VEC
== GET_CODE(body
))
513 for (j
=0; j
< XVECLEN (body
, 0); j
++)
515 rtx lref
= XVECEXP (body
, 0, j
);
516 if (LABEL_REF
!= GET_CODE (lref
)) abort ();
517 label
= XEXP (lref
,0);
518 if (CODE_LABEL
!= GET_CODE (label
)) abort ();
519 tablejump_offset
+= 4;
521 I370_RECORD_LABEL_REF(label
,here
);
523 /* finished with the vector go do next insn */
527 if (ADDR_DIFF_VEC
== GET_CODE(body
))
530 Right now, we leave this as a no-op, but strictly speaking,
531 this is incorrect. It is possible that a table-jump
532 driven off of a relative address could take us off-page,
533 to a place where we need to reload the base reg. So really,
534 we need to examing both labels, and compare thier values
535 to the current basereg value.
537 More generally, this brings up a troubling issue overall:
538 what happens if a tablejump is split across two pages? I do
539 not beleive that this case is handled correctly at all, and
540 can only lead to horrible results if this were to occur.
542 However, the current situation is not any worse than it was
543 last week, and so we punt for now. */
546 for (j
=0; j
< XVECLEN (body
, 0); j
++)
549 /* finished with the vector go do next insn */
555 Compiling the exception handling (L_eh) in libgcc2.a will trip
556 up right here, with something that looks like
557 (set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
559 I'm not sure of what leads up to this, but it looks like
560 the makings of a long jump which will surely get us into trouble
561 because the base & page registers don't get reloaded. For now
562 I'm not sure of what to do ... again we punt ... we are not worse
563 off than yesterday. */
565 /* print_rtl_single (stdout, insn); */
573 /* At this point, this jump_insn had better be a plain-old
574 ordinary one, grap the label id and go */
575 if (CODE_LABEL
!= GET_CODE (label
)) abort ();
576 I370_RECORD_LABEL_REF(label
,here
);
580 /* Sometimes, we take addresses of labels and use them
581 as instruction operands ... these show up as REG_NOTES */
585 if ('i' == GET_RTX_CLASS (code
))
588 for (note
= REG_NOTES (insn
); note
; note
= XEXP(note
,1))
590 if (REG_LABEL
== REG_NOTE_KIND(note
))
592 rtx label
= XEXP (note
,0);
593 if (!label
|| CODE_LABEL
!= GET_CODE (label
)) abort ();
595 I370_RECORD_LABEL_REF(label
,here
);
603 /* ===================================================== */
605 /* Emit reload of base register if indicated. This is to eliminate multiple
606 reloads when several labels are generated pointing to the same place
609 The page table is written at the end of the function.
610 The entries in the page table look like
611 .LPGT0: // PGT0 EQU *
612 .long .LPG0 // DC A(PG0)
613 .long .LPG1 // DC A(PG1)
614 while the prologue generates
617 Note that this paging scheme breaks down if a single subroutine
618 has more than about 10MB of code in it ... as long as humans write
619 code, this shouldn't be a problem ...
625 if (mvs_need_base_reload
)
627 mvs_need_base_reload
= 0;
630 fprintf (assembler_source
, "\tL\t%d,%d(,%d)\n",
631 BASE_REGISTER
, (mvs_page_num
- function_base_page
) * 4,
636 /* Add the label to the current page label list. If a free element is available
637 it will be used for the new label. Otherwise, a label element will be
638 allocated from memory.
639 ID is the label number of the label being added to the list. */
641 static label_node_t
*
647 /* first, lets see if we already go one, if so, use that. */
648 for (lp
= label_anchor
; lp
; lp
= lp
->label_next
)
650 if (lp
->label_id
== id
) return lp
;
653 /* not found, get a new one */
657 free_anchor
= lp
->label_next
;
661 lp
= (label_node_t
*) xmalloc (sizeof (label_node_t
));
664 /* initialize for new label */
667 lp
->label_next
= label_anchor
;
668 lp
->label_first_ref
= 2000123123;
669 lp
->label_last_ref
= -1;
671 lp
->first_ref_page
= -1;
684 lp
= mvs_get_label (id
);
685 lp
->label_page
= mvs_page_num
;
687 /* OK, we just saw the label. Determine if this label
688 * needs a reload of the base register */
689 if ((-1 != lp
->first_ref_page
) &&
690 (lp
->first_ref_page
!= mvs_page_num
))
692 /* Yep; the first label_ref was on a different page. */
693 mvs_need_base_reload
++;
697 /* Hmm. Try to see if the estimated address of the last
698 label_ref is on the current page. If it is, then we
699 don't need a base reg reload. Note that this estimate
700 is very conservatively handled; we'll tend to have
701 a good bit more reloads than actually needed. Someday,
702 we should tighten the estimates (which are driven by
703 the (set_att "length") insn attibute.
705 Currently, we estimate that number of page literals
706 same as number of insns, which is a vast overestimate,
707 esp that the estimate of each insn size is its max size. */
709 /* if latest ref comes before label, we are clear */
710 if (lp
->label_last_ref
< lp
->label_addr
) return;
712 fwd_distance
= lp
->label_last_ref
- lp
->label_addr
;
714 if (mvs_page_code
+ 2 * fwd_distance
+ mvs_page_lit
< 4060) return;
716 mvs_need_base_reload
++;
719 /* Check to see if the label is in the list and in the current
720 page. If not found, we have to make worst case assumption
721 that label will be on a different page, and thus will have to
722 generate a load and branch on register. This is rather
723 ugly for forward-jumps, but what can we do? For backward
724 jumps on the same page we can branch directly to address.
725 ID is the label number of the label being checked. */
733 for (lp
= label_anchor
; lp
; lp
= lp
->label_next
)
735 if (lp
->label_id
== id
)
737 if (lp
->label_page
== mvs_page_num
)
750 /* Get the page on which the label sits. This will be used to
751 determine is a register reload is really needed. */
755 mvs_get_label_page(int id
)
759 for (lp
= label_anchor
; lp
; lp
= lp
->label_next
)
761 if (lp
->label_id
== id
)
762 return lp
->label_page
;
768 /* The label list for the current page freed by linking the list onto the free
769 label element chain. */
772 mvs_free_label_list ()
777 label_node_t
*last_lp
= label_anchor
;
778 while (last_lp
->label_next
) last_lp
= last_lp
->label_next
;
779 last_lp
->label_next
= free_anchor
;
780 free_anchor
= label_anchor
;
785 /* ====================================================================== */
786 /* If the page size limit is reached a new code page is started, and the base
787 register is set to it. This page break point is counted conservatively,
788 most literals that have the same value are collapsed by the assembler.
789 True is returned when a new page is started.
790 FILE is the assembler output file descriptor.
791 CODE is the length, in bytes, of the instruction to be emitted.
792 LIT is the length of the literal to be emitted. */
796 mvs_check_page (file
, code
, lit
)
801 assembler_source
= file
;
803 if (mvs_page_code
+ code
+ mvs_page_lit
+ lit
> MAX_MVS_PAGE_LENGTH
)
805 fprintf (assembler_source
, "\tB\tPGE%d\n", mvs_page_num
);
806 fprintf (assembler_source
, "\tDS\t0F\n");
807 fprintf (assembler_source
, "\tLTORG\n");
808 fprintf (assembler_source
, "\tDS\t0F\n");
809 fprintf (assembler_source
, "PGE%d\tEQU\t*\n", mvs_page_num
);
810 fprintf (assembler_source
, "\tDROP\t%d\n", BASE_REGISTER
);
812 /* Safe to use BASR not BALR, since we are
813 * not switching addressing mode here ... */
814 fprintf (assembler_source
, "\tBASR\t%d,0\n", BASE_REGISTER
);
815 fprintf (assembler_source
, "PG%d\tEQU\t*\n", mvs_page_num
);
816 fprintf (assembler_source
, "\tUSING\t*,%d\n", BASE_REGISTER
);
817 mvs_page_code
= code
;
821 mvs_page_code
+= code
;
825 #endif /* TARGET_HLASM */
828 #ifdef TARGET_ELF_ABI
830 mvs_check_page (file
, code
, lit
)
835 assembler_source
= file
;
837 if (mvs_page_code
+ code
+ mvs_page_lit
+ lit
> MAX_MVS_PAGE_LENGTH
)
839 /* hop past the literal pool */
840 fprintf (assembler_source
, "\tB\t.LPGE%d\n", mvs_page_num
);
842 /* dump the literal pool. The .baligns are optional, since
843 * ltorg will align to the size of the largest literal
844 * (which is possibly 8 bytes) */
845 fprintf (assembler_source
, "\t.balign\t4\n");
846 fprintf (assembler_source
, "\t.LTORG\n");
847 fprintf (assembler_source
, "\t.balign\t4\n");
849 /* we continue execution here ... */
850 fprintf (assembler_source
, ".LPGE%d:\n", mvs_page_num
);
851 fprintf (assembler_source
, "\t.DROP\t%d\n", BASE_REGISTER
);
854 /* BASR puts the contents of the PSW into r3
855 * that is, r3 will be loaded with the address of "." */
856 fprintf (assembler_source
, "\tBASR\tr%d,0\n", BASE_REGISTER
);
857 fprintf (assembler_source
, ".LPG%d:\n", mvs_page_num
);
858 fprintf (assembler_source
, "\t.USING\t.,r%d\n", BASE_REGISTER
);
859 mvs_page_code
= code
;
863 mvs_page_code
+= code
;
867 #endif /* TARGET_ELF_ABI */
869 /* ===================================================== */
870 /* defines and functions specific to the HLASM assembler */
873 /* Check for C/370 runtime function, they don't use standard calling
874 conventions. True is returned if the function is in the table.
875 NAME is the name of the current function. */
878 mvs_function_check (name
)
881 int lower
, middle
, upper
;
885 upper
= MVS_FUNCTION_TABLE_LENGTH
- 1;
886 while (lower
<= upper
)
888 middle
= (lower
+ upper
) / 2;
889 i
= strcmp (name
, mvs_function_table
[middle
]);
900 /* Generate a hash for a given key. */
909 int l
= strlen (key
);
912 for (i
= 1; i
< l
; i
++)
913 h
= ((h
* MVS_SET_SIZE
) + key
[i
]) % MVS_HASH_PRIME
;
918 /* Add the alias to the current alias list. */
921 mvs_add_alias (realname
, aliasname
, emitted
)
922 const char *realname
;
923 const char *aliasname
;
928 ap
= (alias_node_t
*) xmalloc (sizeof (alias_node_t
));
929 if (strlen (realname
) > MAX_LONG_LABEL_SIZE
)
931 warning ("real name is too long - alias ignored");
934 if (strlen (aliasname
) > MAX_MVS_LABEL_SIZE
)
936 warning ("alias name is too long - alias ignored");
940 strcpy (ap
->real_name
, realname
);
941 strcpy (ap
->alias_name
, aliasname
);
942 ap
->alias_emitted
= emitted
;
943 ap
->alias_next
= alias_anchor
;
947 /* Check to see if the name needs aliasing. ie. the name is either:
948 1. Longer than 8 characters
949 2. Contains an underscore
953 mvs_need_alias (realname
)
954 const char *realname
;
956 int i
, j
= strlen (realname
);
958 if (mvs_function_check (realname
))
961 if (!strcmp (realname
, "gccmain"))
963 if (!strcmp (realname
, "main"))
966 if (j
> MAX_MVS_LABEL_SIZE
)
968 if (strchr (realname
, '_') != 0)
970 if (ISUPPER (realname
[0]))
972 for (i
= 1; i
< j
; i
++)
974 if (ISLOWER (realname
[i
]))
980 for (i
= 1; i
< j
; i
++)
982 if (ISUPPER (realname
[i
]))
990 /* Get the alias from the list.
991 If 1 is returned then it's in the alias list, 0 if it was not */
994 mvs_get_alias (realname
, aliasname
)
995 const char *realname
;
1001 for (ap
= alias_anchor
; ap
; ap
= ap
->alias_next
)
1003 if (!strcmp (ap
->real_name
, realname
))
1005 strcpy (aliasname
, ap
->alias_name
);
1009 if (mvs_need_alias (realname
))
1015 if (ISLOWER (c1
)) c1
= TOUPPER (c1
);
1016 else if (c1
== '_') c1
= 'A';
1017 if (ISLOWER (c2
)) c2
= TOUPPER (c2
);
1018 else if (c2
== '_' || c2
== '\0') c2
= '#';
1020 sprintf (aliasname
, "%c%c%06d", c1
, c2
, mvs_hash_alias (realname
));
1021 mvs_add_alias (realname
, aliasname
, 0);
1025 if (strlen (realname
) > MAX_MVS_LABEL_SIZE
)
1027 strncpy (aliasname
, realname
, MAX_MVS_LABEL_SIZE
);
1028 aliasname
[MAX_MVS_LABEL_SIZE
] = '\0';
1035 /* Check to see if the alias is in the list.
1036 If 1 is returned then it's in the alias list, 2 it was emitted */
1039 mvs_check_alias (realname
, aliasname
)
1040 const char *realname
;
1046 for (ap
= alias_anchor
; ap
; ap
= ap
->alias_next
)
1048 if (!strcmp (ap
->real_name
, realname
))
1050 int rc
= (ap
->alias_emitted
== 1) ? 1 : 2;
1051 strcpy (aliasname
, ap
->alias_name
);
1052 ap
->alias_emitted
= 1;
1056 if (mvs_need_alias (realname
))
1062 if (ISLOWER (c1
)) c1
= TOUPPER (c1
);
1063 else if (c1
== '_') c1
= 'A';
1064 if (ISLOWER (c2
)) c2
= TOUPPER (c2
);
1065 else if (c2
== '_' || c2
== '\0') c2
= '#';
1067 sprintf (aliasname
, "%c%c%06d", c1
, c2
, mvs_hash_alias (realname
));
1068 mvs_add_alias (realname
, aliasname
, 0);
1069 alias_anchor
->alias_emitted
= 1;
1073 if (strlen (realname
) > MAX_MVS_LABEL_SIZE
)
1075 strncpy (aliasname
, realname
, MAX_MVS_LABEL_SIZE
);
1076 aliasname
[MAX_MVS_LABEL_SIZE
] = '\0';
1083 /* defines and functions specific to the HLASM assembler */
1084 #endif /* TARGET_HLASM */
1085 /* ===================================================== */
1086 /* ===================================================== */
1087 /* defines and functions specific to the gas assembler */
1088 #ifdef TARGET_ELF_ABI
1090 /* Check for C/370 runtime function, they don't use standard calling
1091 conventions. True is returned if the function is in the table.
1092 NAME is the name of the current function. */
1093 /* no special calling conventions (yet ??) */
1096 mvs_function_check (name
)
1097 const char *name ATTRIBUTE_UNUSED
;
1102 #endif /* TARGET_ELF_ABI */
1103 /* ===================================================== */
1106 /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.
1107 OP is the current operation.
1108 MODE is the current operation mode. */
1111 s_operand (op
, mode
)
1113 enum machine_mode mode
;
1115 extern int volatile_ok
;
1116 register enum rtx_code code
= GET_CODE (op
);
1118 if (CONSTANT_ADDRESS_P (op
))
1120 if (mode
== VOIDmode
|| GET_MODE (op
) != mode
)
1124 register rtx x
= XEXP (op
, 0);
1126 if (!volatile_ok
&& op
->volatil
)
1128 if (REG_P (x
) && REG_OK_FOR_BASE_P (x
))
1130 if (GET_CODE (x
) == PLUS
1131 && REG_P (XEXP (x
, 0)) && REG_OK_FOR_BASE_P (XEXP (x
, 0))
1132 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1133 && (unsigned) INTVAL (XEXP (x
, 1)) < 4096)
1140 /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
1142 OP is the current operation.
1143 MODE is the current operation mode. */
1146 r_or_s_operand (op
, mode
)
1148 enum machine_mode mode
;
1150 extern int volatile_ok
;
1151 register enum rtx_code code
= GET_CODE (op
);
1153 if (CONSTANT_ADDRESS_P (op
))
1155 if (mode
== VOIDmode
|| GET_MODE (op
) != mode
)
1159 else if (code
== MEM
)
1161 register rtx x
= XEXP (op
, 0);
1163 if (!volatile_ok
&& op
->volatil
)
1165 if (REG_P (x
) && REG_OK_FOR_BASE_P (x
))
1167 if (GET_CODE (x
) == PLUS
1168 && REG_P (XEXP (x
, 0)) && REG_OK_FOR_BASE_P (XEXP (x
, 0))
1169 && GET_CODE (XEXP (x
, 1)) == CONST_INT
1170 && (unsigned) INTVAL (XEXP (x
, 1)) < 4096)
1177 /* Some remarks about unsigned_jump_follows_p():
1178 gcc is built around the assumption that branches are signed
1179 or unsigned, whereas the 370 doesn't care; its the compares that
1180 are signed or unsigned. Thus, we need to somehow know if we
1181 need to do a signed or an unsigned compare, and we do this by
1182 looking ahead in the instruction sequence until we find a jump.
1183 We then note whether this jump is signed or unsigned, and do the
1184 compare appropriately. Note that we have to scan ahead indefinitley,
1185 as the gcc optimizer may insert any number of instructions between
1186 the compare and the jump.
1188 Note that using conditional branch expanders seems to be be a more
1189 elegant/correct way of doing this. See, for instance, the Alpha
1190 cmpdi and bgt patterns. Note also that for the i370, various
1191 arithmetic insn's set the condition code as well.
1193 The unsigned_jump_follows_p() routine returns a 1 if the next jump
1194 is unsigned. INSN is the current instruction. */
1197 unsigned_jump_follows_p (insn
)
1200 rtx orig_insn
= insn
;
1203 register rtx tmp_insn
;
1206 insn
= NEXT_INSN (insn
);
1207 if (!insn
) fatal_insn ("internal error--no jump follows compare:", orig_insn
);
1209 if (GET_CODE (insn
) != JUMP_INSN
) continue;
1211 tmp_insn
= XEXP (insn
, 3);
1212 if (GET_CODE (tmp_insn
) != SET
) continue;
1214 if (GET_CODE (XEXP (tmp_insn
, 0)) != PC
) continue;
1216 tmp_insn
= XEXP (tmp_insn
, 1);
1217 if (GET_CODE (tmp_insn
) != IF_THEN_ELSE
) continue;
1219 /* if we got to here, this instruction is a jump. Is it signed? */
1220 tmp_insn
= XEXP (tmp_insn
, 0);
1221 coda
= GET_CODE (tmp_insn
);
1223 return coda
!= GE
&& coda
!= GT
&& coda
!= LE
&& coda
!= LT
;
1229 /* Target hook for assembling integer objects. This version handles all
1230 objects when TARGET_HLASM is defined. */
1233 i370_hlasm_assemble_integer (x
, size
, aligned_p
)
1238 const char *int_format
= NULL
;
1244 int_format
= "\tDC\tX'%02X'\n";
1248 int_format
= "\tDC\tX'%04X'\n";
1252 if (GET_CODE (x
) == CONST_INT
)
1254 fputs ("\tDC\tF'", asm_out_file
);
1255 output_addr_const (asm_out_file
, x
);
1256 fputs ("'\n", asm_out_file
);
1260 fputs ("\tDC\tA(", asm_out_file
);
1261 output_addr_const (asm_out_file
, x
);
1262 fputs (")\n", asm_out_file
);
1267 if (int_format
&& GET_CODE (x
) == CONST_INT
)
1269 fprintf (asm_out_file
, int_format
, INTVAL (x
));
1272 return default_assemble_integer (x
, size
, aligned_p
);
1275 /* Generate the assembly code for function entry. FILE is a stdio
1276 stream to output the code to. SIZE is an int: how many units of
1277 temporary storage to allocate.
1279 Refer to the array `regs_ever_live' to determine which registers to
1280 save; `regs_ever_live[I]' is nonzero if register number I is ever
1281 used in the function. This function is responsible for knowing
1282 which registers should not be saved even if used. */
1285 i370_output_function_prologue (f
, l
)
1289 #if MACROPROLOGUE == 1
1290 fprintf (f
, "* Function %s prologue\n", mvs_function_name
);
1291 fprintf (f
, "\tEDCPRLG USRDSAL=%d,BASEREG=%d\n",
1292 STACK_POINTER_OFFSET
+ l
- 120 +
1293 current_function_outgoing_args_size
, BASE_REGISTER
);
1294 #else /* MACROPROLOGUE != 1 */
1295 static int function_label_index
= 1;
1296 static int function_first
= 0;
1297 static int function_year
, function_month
, function_day
;
1298 static int function_hour
, function_minute
, function_second
;
1300 if (!function_first
)
1302 struct tm
*function_time
;
1305 function_time
= localtime (&lcltime
);
1306 function_year
= function_time
->tm_year
+ 1900;
1307 function_month
= function_time
->tm_mon
+ 1;
1308 function_day
= function_time
->tm_mday
;
1309 function_hour
= function_time
->tm_hour
;
1310 function_minute
= function_time
->tm_min
;
1311 function_second
= function_time
->tm_sec
;
1313 fprintf (f
, "* Function %s prologue\n", mvs_function_name
);
1314 fprintf (f
, "FDSE%03d\tDSECT\n", function_label_index
);
1315 fprintf (f
, "\tDS\tD\n");
1316 fprintf (f
, "\tDS\tCL(" HOST_WIDE_INT_PRINT_DEC
")\n",
1317 STACK_POINTER_OFFSET
+ l
1318 + current_function_outgoing_args_size
);
1319 fprintf (f
, "\tORG\tFDSE%03d\n", function_label_index
);
1320 fprintf (f
, "\tDS\tCL(120+8)\n");
1321 fprintf (f
, "\tORG\n");
1322 fprintf (f
, "\tDS\t0D\n");
1323 fprintf (f
, "FDSL%03d\tEQU\t*-FDSE%03d-8\n", function_label_index
,
1324 function_label_index
);
1325 fprintf (f
, "\tDS\t0H\n");
1326 assemble_name (f
, mvs_function_name
);
1327 fprintf (f
, "\tCSECT\n");
1328 fprintf (f
, "\tUSING\t*,15\n");
1329 fprintf (f
, "\tB\tFENT%03d\n", function_label_index
);
1330 fprintf (f
, "\tDC\tAL1(FNAM%03d+4-*)\n", function_label_index
);
1331 fprintf (f
, "\tDC\tX'CE',X'A0',AL1(16)\n");
1332 fprintf (f
, "\tDC\tAL4(FPPA%03d)\n", function_label_index
);
1333 fprintf (f
, "\tDC\tAL4(0)\n");
1334 fprintf (f
, "\tDC\tAL4(FDSL%03d)\n", function_label_index
);
1335 fprintf (f
, "FNAM%03d\tEQU\t*\n", function_label_index
);
1336 fprintf (f
, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name
),
1338 fprintf (f
, "FPPA%03d\tDS\t0F\n", function_label_index
);
1339 fprintf (f
, "\tDC\tX'03',X'00',X'33',X'00'\n");
1340 fprintf (f
, "\tDC\tV(CEESTART)\n");
1341 fprintf (f
, "\tDC\tAL4(0)\n");
1342 fprintf (f
, "\tDC\tAL4(FTIM%03d)\n", function_label_index
);
1343 fprintf (f
, "FTIM%03d\tDS\t0F\n", function_label_index
);
1344 fprintf (f
, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1345 function_year
, function_month
, function_day
,
1346 function_hour
, function_minute
);
1347 fprintf (f
, "\tDC\tCL2'01',CL4'0100'\n");
1348 fprintf (f
, "FENT%03d\tDS\t0H\n", function_label_index
);
1349 fprintf (f
, "\tSTM\t14,12,12(13)\n");
1350 fprintf (f
, "\tL\t2,76(,13)\n");
1351 fprintf (f
, "\tL\t0,16(,15)\n");
1352 fprintf (f
, "\tALR\t0,2\n");
1353 fprintf (f
, "\tCL\t0,12(,12)\n");
1354 fprintf (f
, "\tBNH\t*+10\n");
1355 fprintf (f
, "\tL\t15,116(,12)\n");
1356 fprintf (f
, "\tBALR\t14,15\n");
1357 fprintf (f
, "\tL\t15,72(,13)\n");
1358 fprintf (f
, "\tSTM\t15,0,72(2)\n");
1359 fprintf (f
, "\tMVI\t0(2),X'10'\n");
1360 fprintf (f
, "\tST\t2,8(,13)\n ");
1361 fprintf (f
, "\tST\t13,4(,2)\n ");
1362 fprintf (f
, "\tLR\t13,2\n");
1363 fprintf (f
, "\tDROP\t15\n");
1364 fprintf (f
, "\tBALR\t%d,0\n", BASE_REGISTER
);
1365 fprintf (f
, "\tUSING\t*,%d\n", BASE_REGISTER
);
1367 function_label_index
++;
1369 if (!function_first
)
1371 struct tm
*function_time
;
1374 function_time
= localtime (&lcltime
);
1375 function_year
= function_time
->tm_year
+ 1900;
1376 function_month
= function_time
->tm_mon
+ 1;
1377 function_day
= function_time
->tm_mday
;
1378 function_hour
= function_time
->tm_hour
;
1379 function_minute
= function_time
->tm_min
;
1380 function_second
= function_time
->tm_sec
;
1381 fprintf (f
, "PPA2\tDS\t0F\n");
1382 fprintf (f
, "\tDC\tX'03',X'00',X'33',X'00'\n");
1383 fprintf (f
, "\tDC\tV(CEESTART),A(0)\n");
1384 fprintf (f
, "\tDC\tA(CEETIMES)\n");
1385 fprintf (f
, "CEETIMES\tDS\t0F\n");
1386 fprintf (f
, "\tDC\tCL4'%d',CL4'%02d%02d',CL6'%02d%02d00'\n",
1387 function_year
, function_month
, function_day
,
1388 function_hour
, function_minute
, function_second
);
1389 fprintf (f
, "\tDC\tCL2'01',CL4'0100'\n");
1391 fprintf (f
, "* Function %s prologue\n", mvs_function_name
);
1392 fprintf (f
, "FDSD%03d\tDSECT\n", function_label_index
);
1393 fprintf (f
, "\tDS\tD\n");
1394 fprintf (f
, "\tDS\tCL(%d)\n", STACK_POINTER_OFFSET
+ l
1395 + current_function_outgoing_args_size
);
1396 fprintf (f
, "\tORG\tFDSD%03d\n", function_label_index
);
1397 fprintf (f
, "\tDS\tCL(120+8)\n");
1398 fprintf (f
, "\tORG\n");
1399 fprintf (f
, "\tDS\t0D\n");
1400 fprintf (f
, "FDSL%03d\tEQU\t*-FDSD%03d-8\n", function_label_index
,
1401 function_label_index
);
1402 fprintf (f
, "\tDS\t0H\n");
1403 assemble_name (f
, mvs_function_name
);
1404 fprintf (f
, "\tCSECT\n");
1405 fprintf (f
, "\tUSING\t*,15\n");
1406 fprintf (f
, "\tB\tFPL%03d\n", function_label_index
);
1407 fprintf (f
, "\tDC\tAL1(FPL%03d+4-*)\n", function_label_index
+ 1);
1408 fprintf (f
, "\tDC\tX'CE',X'A0',AL1(16)\n");
1409 fprintf (f
, "\tDC\tAL4(PPA2)\n");
1410 fprintf (f
, "\tDC\tAL4(0)\n");
1411 fprintf (f
, "\tDC\tAL4(FDSL%03d)\n", function_label_index
);
1412 fprintf (f
, "FPL%03d\tEQU\t*\n", function_label_index
+ 1);
1413 fprintf (f
, "\tDC\tAL2(%d),C'%s'\n", strlen (mvs_function_name
),
1415 fprintf (f
, "FPL%03d\tDS\t0H\n", function_label_index
);
1416 fprintf (f
, "\tSTM\t14,12,12(13)\n");
1417 fprintf (f
, "\tL\t2,76(,13)\n");
1418 fprintf (f
, "\tL\t0,16(,15)\n");
1419 fprintf (f
, "\tALR\t0,2\n");
1420 fprintf (f
, "\tCL\t0,12(,12)\n");
1421 fprintf (f
, "\tBNH\t*+10\n");
1422 fprintf (f
, "\tL\t15,116(,12)\n");
1423 fprintf (f
, "\tBALR\t14,15\n");
1424 fprintf (f
, "\tL\t15,72(,13)\n");
1425 fprintf (f
, "\tSTM\t15,0,72(2)\n");
1426 fprintf (f
, "\tMVI\t0(2),X'10'\n");
1427 fprintf (f
, "\tST\t2,8(,13)\n ");
1428 fprintf (f
, "\tST\t13,4(,2)\n ");
1429 fprintf (f
, "\tLR\t13,2\n");
1430 fprintf (f
, "\tDROP\t15\n");
1431 fprintf (f
, "\tBALR\t%d,0\n", BASE_REGISTER
);
1432 fprintf (f
, "\tUSING\t*,%d\n", BASE_REGISTER
);
1434 function_label_index
+= 2;
1436 #endif /* MACROPROLOGUE */
1437 fprintf (f
, "PG%d\tEQU\t*\n", mvs_page_num
);
1438 fprintf (f
, "\tLR\t11,1\n");
1439 fprintf (f
, "\tL\t%d,=A(PGT%d)\n", PAGE_REGISTER
, mvs_page_num
);
1440 fprintf (f
, "* Function %s code\n", mvs_function_name
);
1442 mvs_free_label_list ();
1445 mvs_check_page (f
, 0, 0);
1446 function_base_page
= mvs_page_num
;
1448 /* find all labels in this routine */
1453 i370_globalize_label (stream
, name
)
1457 char temp
[MAX_MVS_LABEL_SIZE
+ 1];
1458 if (mvs_check_alias (name
, temp
) == 2)
1459 fprintf (stream
, "%s\tALIAS\tC'%s'\n", temp
, name
);
1460 fputs ("\tENTRY\t", stream
);
1461 assemble_name (stream
, name
);
1462 putc ('\n', stream
);
1464 #endif /* TARGET_HLASM */
1467 #ifdef TARGET_ELF_ABI
1469 The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
1470 It implements a stack that grows downward.
1471 It performs the following steps:
1472 -- saves the callers non-volatile registers on the callers stack.
1473 -- subtracts stackframe size from the stack pointer.
1474 -- stores backpointer to old caller stack.
1476 XXX hack alert -- if the global var int leaf_function is nonzero,
1477 then this is a leaf, and it might be possible to optimize the prologue
1478 into doing even less, e.g. not grabbing a new stackframe or maybe just a
1479 partial stack frame.
1481 XXX hack alert -- the current stack frame is bloated into twice the
1482 needed size by unused entries. These entries make it marginally
1483 compatible with MVS/OE/USS C environment, but really they're not used
1484 and could probably chopped out. Modifications to i370.md would be needed
1485 also, to quite using addresses 136, 140, etc.
1489 i370_output_function_prologue (f
, frame_size
)
1491 HOST_WIDE_INT frame_size
;
1493 static int function_label_index
= 1;
1494 static int function_first
= 0;
1495 int stackframe_size
, aligned_size
;
1497 fprintf (f
, "# Function prologue\n");
1498 /* define the stack, put it into its own data segment
1499 FDSE == Function Stack Entry
1500 FDSL == Function Stack Length */
1502 STACK_POINTER_OFFSET
+ current_function_outgoing_args_size
+ frame_size
;
1503 aligned_size
= (stackframe_size
+ 7) >> 3;
1506 fprintf (f
, "# arg_size=0x%x frame_size=" HOST_WIDE_INT_PRINT_HEX
1507 " aligned size=0x%x\n",
1508 current_function_outgoing_args_size
, frame_size
, aligned_size
);
1510 fprintf (f
, "\t.using\t.,r15\n");
1512 /* Branch to exectuable part of prologue. */
1513 fprintf (f
, "\tB\t.LFENT%03d\n", function_label_index
);
1515 /* write the length of the stackframe */
1516 fprintf (f
, "\t.long\t%d\n", aligned_size
);
1518 /* FENT == function prologue entry */
1519 fprintf (f
, "\t.balign 2\n.LFENT%03d:\n",
1520 function_label_index
);
1522 /* store multiple registers 14,15,0,...12 at 12 bytes from sp */
1523 fprintf (f
, "\tSTM\tr14,r12,12(sp)\n");
1525 /* r3 == saved callee stack pointer */
1526 fprintf (f
, "\tLR\tr3,sp\n");
1528 /* 4(r15) == stackframe size */
1529 fprintf (f
, "\tSL\tsp,4(,r15)\n");
1531 /* r11 points to arg list in callers stackframe; was passed in r2 */
1532 fprintf (f
, "\tLR\tr11,r2\n");
1534 /* store callee stack pointer at 8(sp) */
1535 /* fprintf (f, "\tST\tsp,8(,r3)\n "); wasted cycles, no one uses this ... */
1537 /* backchain -- store caller sp at 4(callee_sp) */
1538 fprintf (f
, "\tST\tr3,4(,sp)\n ");
1540 fprintf (f
, "\t.drop\tr15\n");
1541 /* Place contents of the PSW into r3
1542 that is, place the address of "." into r3 */
1543 fprintf (f
, "\tBASR\tr%d,0\n", BASE_REGISTER
);
1544 fprintf (f
, "\t.using\t.,r%d\n", BASE_REGISTER
);
1546 function_label_index
++;
1548 fprintf (f
, ".LPG%d:\n", mvs_page_num
);
1549 fprintf (f
, "\tL\tr%d,=A(.LPGT%d)\n", PAGE_REGISTER
, mvs_page_num
);
1550 fprintf (f
, "# Function code\n");
1552 mvs_free_label_list ();
1555 mvs_check_page (f
, 0, 0);
1556 function_base_page
= mvs_page_num
;
1558 /* find all labels in this routine */
1561 #endif /* TARGET_ELF_ABI */
1563 /* This function generates the assembly code for function exit.
1564 Args are as for output_function_prologue ().
1566 The function epilogue should not depend on the current stack
1567 pointer! It should use the frame pointer only. This is mandatory
1568 because of alloca; we also take advantage of it to omit stack
1569 adjustments before returning. */
1572 i370_output_function_epilogue (file
, l
)
1574 HOST_WIDE_INT l ATTRIBUTE_UNUSED
;
1578 check_label_emit ();
1579 mvs_check_page (file
, 14, 0);
1580 fprintf (file
, "* Function %s epilogue\n", mvs_function_name
);
1583 #if MACROEPILOGUE == 1
1584 fprintf (file
, "\tEDCEPIL\n");
1585 #else /* MACROEPILOGUE != 1 */
1586 fprintf (file
, "\tL\t13,4(,13)\n");
1587 fprintf (file
, "\tL\t14,12(,13)\n");
1588 fprintf (file
, "\tLM\t2,12,28(13)\n");
1589 fprintf (file
, "\tBALR\t1,14\n");
1590 fprintf (file
, "\tDC\tA(");
1591 assemble_name (file
, mvs_function_name
);
1592 fprintf (file
, ")\n" );
1593 #endif /* MACROEPILOGUE */
1595 fprintf (file
, "* Function %s literal pool\n", mvs_function_name
);
1596 fprintf (file
, "\tDS\t0F\n" );
1597 fprintf (file
, "\tLTORG\n");
1598 fprintf (file
, "* Function %s page table\n", mvs_function_name
);
1599 fprintf (file
, "\tDS\t0F\n");
1600 fprintf (file
, "PGT%d\tEQU\t*\n", function_base_page
);
1602 mvs_free_label_list();
1603 for (i
= function_base_page
; i
< mvs_page_num
; i
++)
1604 fprintf (file
, "\tDC\tA(PG%d)\n", i
);
1610 fputs ("\tRMODE\tANY\n\tCSECT\n", asm_out_file
);
1616 fputs ("\tEND\n", asm_out_file
);
1620 i370_internal_label (stream
, prefix
, labelno
)
1623 unsigned long labelno
;
1625 if (!strcmp (prefix
, "L"))
1626 mvs_add_label(labelno
);
1628 default_internal_label (stream
, prefix
, labelno
);
1632 i370_rtx_costs (x
, code
, outer_code
, total
)
1635 int outer_code ATTRIBUTE_UNUSED
;
1641 if ((unsigned HOST_WIDE_INT
) INTVAL (x
) < 0xfff)