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