OSDN Git Service

* config/s390/s390.c: Follow spelling convention.
[pf3gnuchains/gcc-fork.git] / gcc / config / vax / vax.c
1 /* Subroutines for insn-output.c for VAX.
2    Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "function.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "recog.h"
35 #include "expr.h"
36 #include "flags.h"
37 #include "tm_p.h"
38 #include "target.h"
39 #include "target-def.h"
40
41 static int follows_p PARAMS ((rtx, rtx));
42 static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
43 #if VMS_TARGET
44 static void vms_asm_out_constructor PARAMS ((rtx, int));
45 static void vms_asm_out_destructor PARAMS ((rtx, int));
46 static void vms_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT));
47 static void vms_encode_section_info PARAMS ((tree, int));
48 static void vms_globalize_label PARAMS ((FILE *, const char *));
49 #endif
50 \f
51 /* Initialize the GCC target structure.  */
52 #undef TARGET_ASM_ALIGNED_HI_OP
53 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
54
55 #undef TARGET_ASM_FUNCTION_PROLOGUE
56 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
57
58 #if VMS_TARGET
59 #undef TARGET_ASM_SELECT_SECTION
60 #define TARGET_ASM_SELECT_SECTION vms_select_section
61 #undef TARGET_ENCODE_SECTION_INFO
62 #define TARGET_ENCODE_SECTION_INFO vms_encode_section_info
63 #undef TARGET_ASM_GLOBALIZE_LABEL
64 #define TARGET_ASM_GLOBALIZE_LABEL vms_globalize_label
65 #endif
66
67 struct gcc_target targetm = TARGET_INITIALIZER;
68 \f
69 /* Generate the assembly code for function entry.  FILE is a stdio
70    stream to output the code to.  SIZE is an int: how many units of
71    temporary storage to allocate.
72
73    Refer to the array `regs_ever_live' to determine which registers to
74    save; `regs_ever_live[I]' is nonzero if register number I is ever
75    used in the function.  This function is responsible for knowing
76    which registers should not be saved even if used.  */
77
78 static void
79 vax_output_function_prologue (file, size)
80      FILE * file;
81      HOST_WIDE_INT size;
82 {
83   register int regno;
84   register int mask = 0;
85
86   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
87     if (regs_ever_live[regno] && !call_used_regs[regno])
88       mask |= 1 << regno;
89
90   fprintf (file, "\t.word 0x%x\n", mask);
91
92   if (VMS_TARGET)
93     {
94       /*
95        * This works for both gcc and g++.  It first checks to see if
96        * the current routine is "main", which will only happen for
97        * GCC, and add the jsb if it is.  If is not the case then try
98        * and see if __MAIN_NAME is part of current_function_name,
99        * which will only happen if we are running g++, and add the jsb
100        * if it is.  In gcc there should never be a paren in the
101        * function name, and in g++ there is always a "(" in the
102        * function name, thus there should never be any confusion.
103        *
104        * Adjusting the stack pointer by 4 before calling C$MAIN_ARGS
105        * is required when linking with the VMS POSIX version of the C
106        * run-time library; using `subl2 $4,r0' is adequate but we use
107        * `clrl -(sp)' instead.  The extra 4 bytes could be removed
108        * after the call because STARTING_FRAME_OFFSET's setting of -4
109        * will end up adding them right back again, but don't bother.
110        */
111
112       const char *p = current_function_name;
113       int is_main = strcmp ("main", p) == 0;
114 #     define __MAIN_NAME " main("
115
116       while (!is_main && *p != '\0')
117         {
118           if (*p == *__MAIN_NAME
119               && strncmp (p, __MAIN_NAME, sizeof __MAIN_NAME - sizeof "") == 0)
120             is_main = 1;
121           else
122             p++;
123         }
124
125       if (is_main)
126         fprintf (file, "\tclrl -(%ssp)\n\tjsb _C$MAIN_ARGS\n",
127                  REGISTER_PREFIX);
128     }
129
130   size -= STARTING_FRAME_OFFSET;
131   if (size >= 64)
132     fprintf (file, "\tmovab %d(%ssp),%ssp\n", -size, REGISTER_PREFIX,
133              REGISTER_PREFIX);
134   else if (size)
135     fprintf (file, "\tsubl2 $%d,%ssp\n", size, REGISTER_PREFIX);
136 }
137
138 /* This is like nonimmediate_operand with a restriction on the type of MEM.  */
139
140 void
141 split_quadword_operands (operands, low, n)
142      rtx *operands, *low;
143      int n ATTRIBUTE_UNUSED;
144 {
145   int i;
146   /* Split operands.  */
147
148   low[0] = low[1] = low[2] = 0;
149   for (i = 0; i < 3; i++)
150     {
151       if (low[i])
152         /* it's already been figured out */;
153       else if (GET_CODE (operands[i]) == MEM
154                && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
155         {
156           rtx addr = XEXP (operands[i], 0);
157           operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
158           if (which_alternative == 0 && i == 0)
159             {
160               addr = XEXP (operands[i], 0);
161               operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
162             }
163         }
164       else
165         {
166           low[i] = operand_subword (operands[i], 0, 0, DImode);
167           operands[i] = operand_subword (operands[i], 1, 0, DImode);
168         }
169     }
170 }
171 \f
172 void
173 print_operand_address (file, addr)
174      FILE *file;
175      register rtx addr;
176 {
177   register rtx reg1, breg, ireg;
178   rtx offset;
179
180  retry:
181   switch (GET_CODE (addr))
182     {
183     case MEM:
184       fprintf (file, "*");
185       addr = XEXP (addr, 0);
186       goto retry;
187
188     case REG:
189       fprintf (file, "(%s)", reg_names[REGNO (addr)]);
190       break;
191
192     case PRE_DEC:
193       fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
194       break;
195
196     case POST_INC:
197       fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
198       break;
199
200     case PLUS:
201       /* There can be either two or three things added here.  One must be a
202          REG.  One can be either a REG or a MULT of a REG and an appropriate
203          constant, and the third can only be a constant or a MEM.
204
205          We get these two or three things and put the constant or MEM in
206          OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
207          a register and can't tell yet if it is a base or index register,
208          put it into REG1.  */
209
210       reg1 = 0; ireg = 0; breg = 0; offset = 0;
211
212       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
213           || GET_CODE (XEXP (addr, 0)) == MEM)
214         {
215           offset = XEXP (addr, 0);
216           addr = XEXP (addr, 1);
217         }
218       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
219                || GET_CODE (XEXP (addr, 1)) == MEM)
220         {
221           offset = XEXP (addr, 1);
222           addr = XEXP (addr, 0);
223         }
224       else if (GET_CODE (XEXP (addr, 1)) == MULT)
225         {
226           ireg = XEXP (addr, 1);
227           addr = XEXP (addr, 0);
228         }
229       else if (GET_CODE (XEXP (addr, 0)) == MULT)
230         {
231           ireg = XEXP (addr, 0);
232           addr = XEXP (addr, 1);
233         }
234       else if (GET_CODE (XEXP (addr, 1)) == REG)
235         {
236           reg1 = XEXP (addr, 1);
237           addr = XEXP (addr, 0);
238         }
239       else if (GET_CODE (XEXP (addr, 0)) == REG)
240         {
241           reg1 = XEXP (addr, 0);
242           addr = XEXP (addr, 1);
243         }
244       else
245         abort ();
246
247       if (GET_CODE (addr) == REG)
248         {
249           if (reg1)
250             ireg = addr;
251           else
252             reg1 = addr;
253         }
254       else if (GET_CODE (addr) == MULT)
255         ireg = addr;
256       else if (GET_CODE (addr) == PLUS)
257         {
258           if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
259               || GET_CODE (XEXP (addr, 0)) == MEM)
260             {
261               if (offset)
262                 {
263                   if (GET_CODE (offset) == CONST_INT)
264                     offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
265                   else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
266                     offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
267                   else
268                     abort ();
269                 }
270               offset = XEXP (addr, 0);
271             }
272           else if (GET_CODE (XEXP (addr, 0)) == REG)
273             {
274               if (reg1)
275                 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
276               else
277                 reg1 = XEXP (addr, 0);
278             }
279           else if (GET_CODE (XEXP (addr, 0)) == MULT)
280             {
281               if (ireg)
282                 abort ();
283               ireg = XEXP (addr, 0);
284             }
285           else
286             abort ();
287
288           if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
289               || GET_CODE (XEXP (addr, 1)) == MEM)
290             {
291               if (offset)
292                 {
293                   if (GET_CODE (offset) == CONST_INT)
294                     offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
295                   else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
296                     offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
297                   else
298                     abort ();
299                 }
300               offset = XEXP (addr, 1);
301             }
302           else if (GET_CODE (XEXP (addr, 1)) == REG)
303             {
304               if (reg1)
305                 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
306               else
307                 reg1 = XEXP (addr, 1);
308             }
309           else if (GET_CODE (XEXP (addr, 1)) == MULT)
310             {
311               if (ireg)
312                 abort ();
313               ireg = XEXP (addr, 1);
314             }
315           else
316             abort ();
317         }
318       else
319         abort ();
320
321       /* If REG1 is nonzero, figure out if it is a base or index register.  */
322       if (reg1)
323         {
324           if (breg != 0 || (offset && GET_CODE (offset) == MEM))
325             {
326               if (ireg)
327                 abort ();
328               ireg = reg1;
329             }
330           else
331             breg = reg1;
332         }
333
334       if (offset != 0)
335         output_address (offset);
336
337       if (breg != 0)
338         fprintf (file, "(%s)", reg_names[REGNO (breg)]);
339
340       if (ireg != 0)
341         {
342           if (GET_CODE (ireg) == MULT)
343             ireg = XEXP (ireg, 0);
344           if (GET_CODE (ireg) != REG)
345             abort ();
346           fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
347         }
348       break;
349
350     default:
351       output_addr_const (file, addr);
352     }
353 }
354 \f
355 const char *
356 rev_cond_name (op)
357      rtx op;
358 {
359   switch (GET_CODE (op))
360     {
361     case EQ:
362       return "neq";
363     case NE:
364       return "eql";
365     case LT:
366       return "geq";
367     case LE:
368       return "gtr";
369     case GT:
370       return "leq";
371     case GE:
372       return "lss";
373     case LTU:
374       return "gequ";
375     case LEU:
376       return "gtru";
377     case GTU:
378       return "lequ";
379     case GEU:
380       return "lssu";
381
382     default:
383       abort ();
384     }
385 }
386
387 int
388 vax_float_literal(c)
389     register rtx c;
390 {
391   register enum machine_mode mode;
392   REAL_VALUE_TYPE r, s;
393   int i;
394
395   if (GET_CODE (c) != CONST_DOUBLE)
396     return 0;
397
398   mode = GET_MODE (c);
399
400   if (c == const_tiny_rtx[(int) mode][0]
401       || c == const_tiny_rtx[(int) mode][1]
402       || c == const_tiny_rtx[(int) mode][2])
403     return 1;
404
405   REAL_VALUE_FROM_CONST_DOUBLE (r, c);
406
407   for (i = 0; i < 7; i++)
408     {
409       int x = 1 << i;
410       REAL_VALUE_FROM_INT (s, x, 0, mode);
411
412       if (REAL_VALUES_EQUAL (r, s))
413         return 1;
414       if (!exact_real_inverse (mode, &s))
415         abort ();
416       if (REAL_VALUES_EQUAL (r, s))
417         return 1;
418     }
419   return 0;
420 }
421
422
423 /* Return the cost in cycles of a memory address, relative to register
424    indirect.
425
426    Each of the following adds the indicated number of cycles:
427
428    1 - symbolic address
429    1 - pre-decrement
430    1 - indexing and/or offset(register)
431    2 - indirect */
432
433
434 int
435 vax_address_cost (addr)
436     register rtx addr;
437 {
438   int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
439   rtx plus_op0 = 0, plus_op1 = 0;
440  restart:
441   switch (GET_CODE (addr))
442     {
443     case PRE_DEC:
444       predec = 1;
445     case REG:
446     case SUBREG:
447     case POST_INC:
448       reg = 1;
449       break;
450     case MULT:
451       indexed = 1;      /* 2 on VAX 2 */
452       break;
453     case CONST_INT:
454       /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
455       if (offset == 0)
456         offset = (unsigned)(INTVAL(addr)+128) > 256;
457       break;
458     case CONST:
459     case SYMBOL_REF:
460       offset = 1;       /* 2 on VAX 2 */
461       break;
462     case LABEL_REF:     /* this is probably a byte offset from the pc */
463       if (offset == 0)
464         offset = 1;
465       break;
466     case PLUS:
467       if (plus_op0)
468         plus_op1 = XEXP (addr, 0);
469       else
470         plus_op0 = XEXP (addr, 0);
471       addr = XEXP (addr, 1);
472       goto restart;
473     case MEM:
474       indir = 2;        /* 3 on VAX 2 */
475       addr = XEXP (addr, 0);
476       goto restart;
477     default:
478       break;
479     }
480
481   /* Up to 3 things can be added in an address.  They are stored in
482      plus_op0, plus_op1, and addr.  */
483
484   if (plus_op0)
485     {
486       addr = plus_op0;
487       plus_op0 = 0;
488       goto restart;
489     }
490   if (plus_op1)
491     {
492       addr = plus_op1;
493       plus_op1 = 0;
494       goto restart;
495     }
496   /* Indexing and register+offset can both be used (except on a VAX 2)
497      without increasing execution time over either one alone.  */
498   if (reg && indexed && offset)
499     return reg + indir + offset + predec;
500   return reg + indexed + indir + offset + predec;
501 }
502
503
504 /* Cost of an expression on a VAX.  This version has costs tuned for the
505    CVAX chip (found in the VAX 3 series) with comments for variations on
506    other models.  */
507
508 int
509 vax_rtx_cost (x)
510     register rtx x;
511 {
512   register enum rtx_code code = GET_CODE (x);
513   enum machine_mode mode = GET_MODE (x);
514   register int c;
515   int i = 0;                            /* may be modified in switch */
516   const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
517
518   switch (code)
519     {
520     case POST_INC:
521       return 2;
522     case PRE_DEC:
523       return 3;
524     case MULT:
525       switch (mode)
526         {
527         case DFmode:
528           c = 16;               /* 4 on VAX 9000 */
529           break;
530         case SFmode:
531           c = 9;                /* 4 on VAX 9000, 12 on VAX 2 */
532           break;
533         case DImode:
534           c = 16;               /* 6 on VAX 9000, 28 on VAX 2 */
535           break;
536         case SImode:
537         case HImode:
538         case QImode:
539           c = 10;               /* 3-4 on VAX 9000, 20-28 on VAX 2 */
540           break;
541         default:
542           return MAX_COST;      /* Mode is not supported.  */
543         }
544       break;
545     case UDIV:
546       if (mode != SImode)
547         return MAX_COST;        /* Mode is not supported.  */
548       c = 17;
549       break;
550     case DIV:
551       if (mode == DImode)
552         c = 30; /* highly variable */
553       else if (mode == DFmode)
554         /* divide takes 28 cycles if the result is not zero, 13 otherwise */
555         c = 24;
556       else
557         c = 11;                 /* 25 on VAX 2 */
558       break;
559     case MOD:
560       c = 23;
561       break;
562     case UMOD:
563       if (mode != SImode)
564         return MAX_COST;        /* Mode is not supported.  */
565       c = 29;
566       break;
567     case FLOAT:
568       c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
569       /* 4 on VAX 9000 */
570       break;
571     case FIX:
572       c = 7;                    /* 17 on VAX 2 */
573       break;
574     case ASHIFT:
575     case LSHIFTRT:
576     case ASHIFTRT:
577       if (mode == DImode)
578         c = 12;
579       else
580         c = 10;                 /* 6 on VAX 9000 */
581       break;
582     case ROTATE:
583     case ROTATERT:
584       c = 6;                    /* 5 on VAX 2, 4 on VAX 9000 */
585       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
586         fmt = "e";      /* all constant rotate counts are short */
587       break;
588     case PLUS:
589       /* Check for small negative integer operand: subl2 can be used with
590          a short positive constant instead.  */
591       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
592         if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
593           fmt = "e";
594     case MINUS:
595       c = (mode == DFmode) ? 13 : 8;    /* 6/8 on VAX 9000, 16/15 on VAX 2 */
596     case IOR:
597     case XOR:
598       c = 3;
599       break;
600     case AND:
601       /* AND is special because the first operand is complemented.  */
602       c = 3;
603       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
604         {
605           if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
606             c = 4;
607           fmt = "e";
608           i = 1;
609         }
610       break;
611     case NEG:
612       if (mode == DFmode)
613         return 9;
614       else if (mode == SFmode)
615         return 6;
616       else if (mode == DImode)
617         return 4;
618     case NOT:
619       return 2;
620     case ZERO_EXTRACT:
621     case SIGN_EXTRACT:
622       c = 15;
623       break;
624     case MEM:
625       if (mode == DImode || mode == DFmode)
626         c = 5;                          /* 7 on VAX 2 */
627       else
628         c = 3;                          /* 4 on VAX 2 */
629       x = XEXP (x, 0);
630       if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
631         return c;
632       return c + vax_address_cost (x);
633     default:
634       c = 3;
635       break;
636     }
637
638
639   /* Now look inside the expression.  Operands which are not registers or
640      short constants add to the cost.
641
642      FMT and I may have been adjusted in the switch above for instructions
643      which require special handling */
644
645   while (*fmt++ == 'e')
646     {
647       register rtx op = XEXP (x, i++);
648       code = GET_CODE (op);
649
650       /* A NOT is likely to be found as the first operand of an AND
651          (in which case the relevant cost is of the operand inside
652          the not) and not likely to be found anywhere else.  */
653       if (code == NOT)
654         op = XEXP (op, 0), code = GET_CODE (op);
655
656       switch (code)
657         {
658         case CONST_INT:
659           if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
660             c += 1;             /* 2 on VAX 2 */
661           break;
662         case CONST:
663         case LABEL_REF:
664         case SYMBOL_REF:
665           c += 1;               /* 2 on VAX 2 */
666           break;
667         case CONST_DOUBLE:
668           if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
669             {
670               /* Registers are faster than floating point constants -- even
671                  those constants which can be encoded in a single byte.  */
672               if (vax_float_literal (op))
673                 c++;
674               else
675                 c += (GET_MODE (x) == DFmode) ? 3 : 2;
676             }
677           else
678             {
679               if (CONST_DOUBLE_HIGH (op) != 0
680                   || (unsigned)CONST_DOUBLE_LOW (op) > 63)
681                 c += 2;
682             }
683           break;
684         case MEM:
685           c += 1;               /* 2 on VAX 2 */
686           if (GET_CODE (XEXP (op, 0)) != REG)
687             c += vax_address_cost (XEXP (op, 0));
688           break;
689         case REG:
690         case SUBREG:
691           break;
692         default:
693           c += 1;
694           break;
695         }
696     }
697   return c;
698 }
699 \f
700 #if VMS_TARGET
701 /* Additional support code for VMS target.  */
702
703 /* Linked list of all externals that are to be emitted when optimizing
704    for the global pointer if they haven't been declared by the end of
705    the program with an appropriate .comm or initialization.  */
706
707 static
708 struct extern_list {
709   struct extern_list *next;     /* next external */
710   const char *name;             /* name of the external */
711   int size;                     /* external's actual size */
712   int in_const;                 /* section type flag */
713 } *extern_head = 0, *pending_head = 0;
714
715 /* Check whether NAME is already on the external definition list.  If not,
716    add it to either that list or the pending definition list.  */
717
718 void
719 vms_check_external (decl, name, pending)
720      tree decl;
721      const char *name;
722      int pending;
723 {
724   register struct extern_list *p, *p0;
725
726   for (p = extern_head; p; p = p->next)
727     if (!strcmp (p->name, name))
728       return;
729
730   for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)
731     if (!strcmp (p->name, name))
732       {
733         if (pending)
734           return;
735
736         /* Was pending, but has now been defined; move it to other list.  */
737         if (p == pending_head)
738           pending_head = p->next;
739         else
740           p0->next = p->next;
741         p->next = extern_head;
742         extern_head = p;
743         return;
744       }
745
746   /* Not previously seen; create a new list entry.  */
747   p = (struct extern_list *) xmalloc (sizeof (struct extern_list));
748   p->name = name;
749
750   if (pending)
751     {
752       /* Save the size and section type and link to `pending' list.  */
753       p->size = (DECL_SIZE (decl) == 0) ? 0 :
754         TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
755                                       size_int (BITS_PER_UNIT)));
756       p->in_const = (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl));
757
758       p->next = pending_head;
759       pending_head = p;
760     }
761   else
762     {
763       /* Size and section type don't matter; link to `declared' list.  */
764       p->size = p->in_const = 0;        /* arbitrary init */
765
766       p->next = extern_head;
767       extern_head = p;
768     }
769   return;
770 }
771
772 void
773 vms_flush_pending_externals (file)
774      FILE *file;
775 {
776   register struct extern_list *p;
777
778   while (pending_head)
779     {
780       /* Move next pending declaration to the "done" list.  */
781       p = pending_head;
782       pending_head = p->next;
783       p->next = extern_head;
784       extern_head = p;
785
786       /* Now output the actual declaration.  */
787       if (p->in_const)
788         const_section ();
789       else
790         data_section ();
791       fputs (".comm ", file);
792       assemble_name (file, p->name);
793       fprintf (file, ",%d\n", p->size);
794     }
795 }
796
797 static void
798 vms_asm_out_constructor (symbol, priority)
799      rtx symbol;
800      int priority ATTRIBUTE_UNUSED;
801 {
802   fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
803   data_section();
804   fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_init_1:\n\t.long\t");
805   assemble_name (asm_out_file, XSTR (symbol, 0));
806   fputc ('\n', asm_out_file);
807 }
808
809 static void
810 vms_asm_out_destructor (symbol, priority)
811      rtx symbol;
812      int priority ATTRIBUTE_UNUSED;
813 {
814   fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
815   data_section();
816   fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_clean_1:\n\t.long\t");
817   assemble_name (asm_out_file, XSTR (symbol, 0));
818   fputc ('\n', asm_out_file);
819 }
820
821 static void
822 vms_select_section (exp, reloc, align)
823      tree exp;
824      int reloc ATTRIBUTE_UNUSED;
825      unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
826 {
827   if (TREE_CODE (exp) == VAR_DECL)
828     {
829       if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)
830           && DECL_INITIAL (exp)
831           && (DECL_INITIAL (exp) == error_mark_node
832               || TREE_CONSTANT (DECL_INITIAL (exp))))
833         {
834           if (TREE_PUBLIC (exp))
835             const_section ();
836           else
837             text_section ();
838         }
839       else
840         data_section ();
841     }
842   if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
843     {
844       if (TREE_CODE (exp) == STRING_CST && flag_writable_strings)
845         data_section ();
846       else
847         text_section ();
848     }
849 }
850
851 /* Make sure that external variables are correctly addressed.  Under VMS
852    there is some brain damage in the linker that requires us to do this.  */
853
854 static void
855 vms_encode_section_info (decl, first)
856      tree decl;
857      int first ATTRIBUTE_UNUSED;
858 {
859   if (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
860     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
861 }
862
863 /* This is how to output a command to make the user-level label named NAME
864    defined for reference from other files.  */
865 static void
866 vms_globalize_label (stream, name)
867      FILE *stream;
868      const char *name;
869 {
870   default_globalize_label (stream, name);
871   vms_check_external (NULL_TREE, name, 0);
872 }
873 #endif /* VMS_TARGET */
874 \f
875 /* Additional support code for VMS host.  */
876 /* ??? This should really be in libiberty; vax.c is a target file.  */
877 #ifdef QSORT_WORKAROUND
878   /*
879         Do not use VAXCRTL's qsort() due to a severe bug:  once you've
880         sorted something which has a size that's an exact multiple of 4
881         and is longword aligned, you cannot safely sort anything which
882         is either not a multiple of 4 in size or not longword aligned.
883         A static "move-by-longword" optimization flag inside qsort() is
884         never reset.  This is known to affect VMS V4.6 through VMS V5.5-1,
885         and was finally fixed in VMS V5.5-2.
886
887         In this work-around an insertion sort is used for simplicity.
888         The qsort code from glibc should probably be used instead.
889    */
890 void
891 not_qsort (array, count, size, compare)
892      void *array;
893      unsigned count, size;
894      int (*compare)();
895 {
896
897   if (size == sizeof (short))
898     {
899       register int i;
900       register short *next, *prev;
901       short tmp, *base = array;
902
903       for (next = base, i = count - 1; i > 0; i--)
904         {
905           prev = next++;
906           if ((*compare)(next, prev) < 0)
907             {
908               tmp = *next;
909               do  *(prev + 1) = *prev;
910                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
911               *(prev + 1) = tmp;
912             }
913         }
914     }
915   else if (size == sizeof (long))
916     {
917       register int i;
918       register long *next, *prev;
919       long tmp, *base = array;
920
921       for (next = base, i = count - 1; i > 0; i--)
922         {
923           prev = next++;
924           if ((*compare)(next, prev) < 0)
925             {
926               tmp = *next;
927               do  *(prev + 1) = *prev;
928                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
929               *(prev + 1) = tmp;
930             }
931         }
932     }
933   else  /* arbitrary size */
934     {
935       register int i;
936       register char *next, *prev, *tmp = alloca (size), *base = array;
937
938       for (next = base, i = count - 1; i > 0; i--)
939         {   /* count-1 forward iterations */
940           prev = next,  next += size;           /* increment front pointer */
941           if ((*compare)(next, prev) < 0)
942             {   /* found element out of order; move others up then re-insert */
943               memcpy (tmp, next, size);         /* save smaller element */
944               do { memcpy (prev + size, prev, size); /* move larger elem. up */
945                    prev -= size;                /* decrement back pointer */
946                  } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);
947               memcpy (prev + size, tmp, size);  /* restore small element */
948             }
949         }
950 #ifdef USE_C_ALLOCA
951       alloca (0);
952 #endif
953     }
954
955   return;
956 }
957 #endif /* QSORT_WORKAROUND */
958
959 /* Return 1 if insn A follows B.  */
960
961 static int
962 follows_p (a, b)
963      rtx a, b;
964 {
965   register rtx p;
966
967   for (p = a; p != b; p = NEXT_INSN (p))
968     if (! p)
969       return 1;
970
971   return 0;
972 }
973
974 /* Returns 1 if we know operand OP was 0 before INSN.  */
975
976 int
977 reg_was_0_p (insn, op)
978      rtx insn, op;
979 {
980   rtx link;
981
982   return ((link = find_reg_note (insn, REG_WAS_0, 0))
983           /* Make sure the insn that stored the 0 is still present
984              and doesn't follow INSN in the insn sequence.  */
985           && ! INSN_DELETED_P (XEXP (link, 0))
986           && GET_CODE (XEXP (link, 0)) != NOTE
987           && ! follows_p (XEXP (link, 0), insn)
988           /* Make sure cross jumping didn't happen here.  */
989           && no_labels_between_p (XEXP (link, 0), insn)
990           /* Make sure the reg hasn't been clobbered.  */
991           && ! reg_set_between_p (op, XEXP (link, 0), insn));
992 }