OSDN Git Service

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