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