OSDN Git Service

* real.h: Don't define REAL_INFINITY or REAL_IS_NOT_DOUBLE.
[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 "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   REAL_VALUE_TYPE r, s;
378   int i;
379
380   if (GET_CODE (c) != CONST_DOUBLE)
381     return 0;
382
383   mode = GET_MODE (c);
384
385   if (c == const_tiny_rtx[(int) mode][0]
386       || c == const_tiny_rtx[(int) mode][1]
387       || c == const_tiny_rtx[(int) mode][2])
388     return 1;
389
390   REAL_VALUE_FROM_CONST_DOUBLE (r, c);
391
392   for (i = 0; i < 7; i++)
393     {
394       int x = 1 << i;
395       REAL_VALUE_FROM_INT (s, x, 0, mode);
396
397       if (REAL_VALUES_EQUAL (r, s))
398         return 1;
399       if (!exact_real_inverse (mode, &s))
400         abort ();
401       if (REAL_VALUES_EQUAL (r, s))
402         return 1;
403     }
404   return 0;
405 }
406
407
408 /* Return the cost in cycles of a memory address, relative to register
409    indirect.
410
411    Each of the following adds the indicated number of cycles:
412
413    1 - symbolic address
414    1 - pre-decrement
415    1 - indexing and/or offset(register)
416    2 - indirect */
417
418
419 int
420 vax_address_cost (addr)
421     register rtx addr;
422 {
423   int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
424   rtx plus_op0 = 0, plus_op1 = 0;
425  restart:
426   switch (GET_CODE (addr))
427     {
428     case PRE_DEC:
429       predec = 1;
430     case REG:
431     case SUBREG:
432     case POST_INC:
433       reg = 1;
434       break;
435     case MULT:
436       indexed = 1;      /* 2 on VAX 2 */
437       break;
438     case CONST_INT:
439       /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
440       if (offset == 0)
441         offset = (unsigned)(INTVAL(addr)+128) > 256;
442       break;
443     case CONST:
444     case SYMBOL_REF:
445       offset = 1;       /* 2 on VAX 2 */
446       break;
447     case LABEL_REF:     /* this is probably a byte offset from the pc */
448       if (offset == 0)
449         offset = 1;
450       break;
451     case PLUS:
452       if (plus_op0)
453         plus_op1 = XEXP (addr, 0);
454       else
455         plus_op0 = XEXP (addr, 0);
456       addr = XEXP (addr, 1);
457       goto restart;
458     case MEM:
459       indir = 2;        /* 3 on VAX 2 */
460       addr = XEXP (addr, 0);
461       goto restart;
462     default:
463       break;
464     }
465
466   /* Up to 3 things can be added in an address.  They are stored in
467      plus_op0, plus_op1, and addr.  */
468
469   if (plus_op0)
470     {
471       addr = plus_op0;
472       plus_op0 = 0;
473       goto restart;
474     }
475   if (plus_op1)
476     {
477       addr = plus_op1;
478       plus_op1 = 0;
479       goto restart;
480     }
481   /* Indexing and register+offset can both be used (except on a VAX 2)
482      without increasing execution time over either one alone.  */
483   if (reg && indexed && offset)
484     return reg + indir + offset + predec;
485   return reg + indexed + indir + offset + predec;
486 }
487
488
489 /* Cost of an expression on a VAX.  This version has costs tuned for the
490    CVAX chip (found in the VAX 3 series) with comments for variations on
491    other models.  */
492
493 int
494 vax_rtx_cost (x)
495     register rtx x;
496 {
497   register enum rtx_code code = GET_CODE (x);
498   enum machine_mode mode = GET_MODE (x);
499   register int c;
500   int i = 0;                            /* may be modified in switch */
501   const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
502
503   switch (code)
504     {
505     case POST_INC:
506       return 2;
507     case PRE_DEC:
508       return 3;
509     case MULT:
510       switch (mode)
511         {
512         case DFmode:
513           c = 16;               /* 4 on VAX 9000 */
514           break;
515         case SFmode:
516           c = 9;                /* 4 on VAX 9000, 12 on VAX 2 */
517           break;
518         case DImode:
519           c = 16;               /* 6 on VAX 9000, 28 on VAX 2 */
520           break;
521         case SImode:
522         case HImode:
523         case QImode:
524           c = 10;               /* 3-4 on VAX 9000, 20-28 on VAX 2 */
525           break;
526         default:
527           return MAX_COST;      /* Mode is not supported.  */
528         }
529       break;
530     case UDIV:
531       if (mode != SImode)
532         return MAX_COST;        /* Mode is not supported.  */
533       c = 17;
534       break;
535     case DIV:
536       if (mode == DImode)
537         c = 30; /* highly variable */
538       else if (mode == DFmode)
539         /* divide takes 28 cycles if the result is not zero, 13 otherwise */
540         c = 24;
541       else
542         c = 11;                 /* 25 on VAX 2 */
543       break;
544     case MOD:
545       c = 23;
546       break;
547     case UMOD:
548       if (mode != SImode)
549         return MAX_COST;        /* Mode is not supported.  */
550       c = 29;
551       break;
552     case FLOAT:
553       c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
554       /* 4 on VAX 9000 */
555       break;
556     case FIX:
557       c = 7;                    /* 17 on VAX 2 */
558       break;
559     case ASHIFT:
560     case LSHIFTRT:
561     case ASHIFTRT:
562       if (mode == DImode)
563         c = 12;
564       else
565         c = 10;                 /* 6 on VAX 9000 */
566       break;
567     case ROTATE:
568     case ROTATERT:
569       c = 6;                    /* 5 on VAX 2, 4 on VAX 9000 */
570       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
571         fmt = "e";      /* all constant rotate counts are short */
572       break;
573     case PLUS:
574       /* Check for small negative integer operand: subl2 can be used with
575          a short positive constant instead.  */
576       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
577         if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
578           fmt = "e";
579     case MINUS:
580       c = (mode == DFmode) ? 13 : 8;    /* 6/8 on VAX 9000, 16/15 on VAX 2 */
581     case IOR:
582     case XOR:
583       c = 3;
584       break;
585     case AND:
586       /* AND is special because the first operand is complemented.  */
587       c = 3;
588       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
589         {
590           if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
591             c = 4;
592           fmt = "e";
593           i = 1;
594         }
595       break;
596     case NEG:
597       if (mode == DFmode)
598         return 9;
599       else if (mode == SFmode)
600         return 6;
601       else if (mode == DImode)
602         return 4;
603     case NOT:
604       return 2;
605     case ZERO_EXTRACT:
606     case SIGN_EXTRACT:
607       c = 15;
608       break;
609     case MEM:
610       if (mode == DImode || mode == DFmode)
611         c = 5;                          /* 7 on VAX 2 */
612       else
613         c = 3;                          /* 4 on VAX 2 */
614       x = XEXP (x, 0);
615       if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
616         return c;
617       return c + vax_address_cost (x);
618     default:
619       c = 3;
620       break;
621     }
622
623
624   /* Now look inside the expression.  Operands which are not registers or
625      short constants add to the cost.
626
627      FMT and I may have been adjusted in the switch above for instructions
628      which require special handling */
629
630   while (*fmt++ == 'e')
631     {
632       register rtx op = XEXP (x, i++);
633       code = GET_CODE (op);
634
635       /* A NOT is likely to be found as the first operand of an AND
636          (in which case the relevant cost is of the operand inside
637          the not) and not likely to be found anywhere else.  */
638       if (code == NOT)
639         op = XEXP (op, 0), code = GET_CODE (op);
640
641       switch (code)
642         {
643         case CONST_INT:
644           if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
645             c += 1;             /* 2 on VAX 2 */
646           break;
647         case CONST:
648         case LABEL_REF:
649         case SYMBOL_REF:
650           c += 1;               /* 2 on VAX 2 */
651           break;
652         case CONST_DOUBLE:
653           if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
654             {
655               /* Registers are faster than floating point constants -- even
656                  those constants which can be encoded in a single byte.  */
657               if (vax_float_literal (op))
658                 c++;
659               else
660                 c += (GET_MODE (x) == DFmode) ? 3 : 2;
661             }
662           else
663             {
664               if (CONST_DOUBLE_HIGH (op) != 0
665                   || (unsigned)CONST_DOUBLE_LOW (op) > 63)
666                 c += 2;
667             }
668           break;
669         case MEM:
670           c += 1;               /* 2 on VAX 2 */
671           if (GET_CODE (XEXP (op, 0)) != REG)
672             c += vax_address_cost (XEXP (op, 0));
673           break;
674         case REG:
675         case SUBREG:
676           break;
677         default:
678           c += 1;
679           break;
680         }
681     }
682   return c;
683 }
684
685 /* Check a `double' value for validity for a particular machine mode.  */
686
687 static const char *const float_strings[] =
688 {
689    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
690   "-1.70141173319264430e+38",
691    "2.93873587705571877e-39", /* 2^-128 */
692   "-2.93873587705571877e-39"
693 };
694
695 static REAL_VALUE_TYPE float_values[4];
696
697 static int inited_float_values = 0;
698
699
700 int
701 check_float_value (mode, d, overflow)
702      enum machine_mode mode;
703      REAL_VALUE_TYPE *d;
704      int overflow;
705 {
706   if (inited_float_values == 0)
707     {
708       int i;
709       for (i = 0; i < 4; i++)
710         {
711           float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
712         }
713
714       inited_float_values = 1;
715     }
716
717   if (overflow)
718     {
719       memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
720       return 1;
721     }
722
723   if ((mode) == SFmode)
724     {
725       REAL_VALUE_TYPE r;
726       memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
727       if (REAL_VALUES_LESS (float_values[0], r))
728         {
729           memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
730           return 1;
731         }
732       else if (REAL_VALUES_LESS (r, float_values[1]))
733         {
734           memcpy (d, &float_values[1], sizeof (REAL_VALUE_TYPE));
735           return 1;
736         }
737       else if (REAL_VALUES_LESS (dconst0, r)
738                 && REAL_VALUES_LESS (r, float_values[2]))
739         {
740           memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
741           return 1;
742         }
743       else if (REAL_VALUES_LESS (r, dconst0)
744                 && REAL_VALUES_LESS (float_values[3], r))
745         {
746           memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
747           return 1;
748         }
749     }
750
751   return 0;
752 }
753 \f
754 #if VMS_TARGET
755 /* Additional support code for VMS target.  */
756
757 /* Linked list of all externals that are to be emitted when optimizing
758    for the global pointer if they haven't been declared by the end of
759    the program with an appropriate .comm or initialization.  */
760
761 static
762 struct extern_list {
763   struct extern_list *next;     /* next external */
764   const char *name;             /* name of the external */
765   int size;                     /* external's actual size */
766   int in_const;                 /* section type flag */
767 } *extern_head = 0, *pending_head = 0;
768
769 /* Check whether NAME is already on the external definition list.  If not,
770    add it to either that list or the pending definition list.  */
771
772 void
773 vms_check_external (decl, name, pending)
774      tree decl;
775      const char *name;
776      int pending;
777 {
778   register struct extern_list *p, *p0;
779
780   for (p = extern_head; p; p = p->next)
781     if (!strcmp (p->name, name))
782       return;
783
784   for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)
785     if (!strcmp (p->name, name))
786       {
787         if (pending)
788           return;
789
790         /* Was pending, but has now been defined; move it to other list.  */
791         if (p == pending_head)
792           pending_head = p->next;
793         else
794           p0->next = p->next;
795         p->next = extern_head;
796         extern_head = p;
797         return;
798       }
799
800   /* Not previously seen; create a new list entry.  */
801   p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
802   p->name = name;
803
804   if (pending)
805     {
806       /* Save the size and section type and link to `pending' list.  */
807       p->size = (DECL_SIZE (decl) == 0) ? 0 :
808         TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
809                                       size_int (BITS_PER_UNIT)));
810       p->in_const = (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl));
811
812       p->next = pending_head;
813       pending_head = p;
814     }
815   else
816     {
817       /* Size and section type don't matter; link to `declared' list.  */
818       p->size = p->in_const = 0;        /* arbitrary init */
819
820       p->next = extern_head;
821       extern_head = p;
822     }
823   return;
824 }
825
826 void
827 vms_flush_pending_externals (file)
828      FILE *file;
829 {
830   register struct extern_list *p;
831
832   while (pending_head)
833     {
834       /* Move next pending declaration to the "done" list.  */
835       p = pending_head;
836       pending_head = p->next;
837       p->next = extern_head;
838       extern_head = p;
839
840       /* Now output the actual declaration.  */
841       if (p->in_const)
842         const_section ();
843       else
844         data_section ();
845       fputs (".comm ", file);
846       assemble_name (file, p->name);
847       fprintf (file, ",%d\n", p->size);
848     }
849 }
850
851 static void
852 vms_asm_out_constructor (symbol, priority)
853      rtx symbol;
854      int priority ATTRIBUTE_UNUSED;
855 {
856   fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
857   data_section();
858   fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_init_1:\n\t.long\t");
859   assemble_name (asm_out_file, XSTR (symbol, 0));
860   fputc ('\n', asm_out_file);
861 }
862
863 static void
864 vms_asm_out_destructor (symbol, priority)
865      rtx symbol;
866      int priority ATTRIBUTE_UNUSED;
867 {
868   fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
869   data_section();
870   fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_clean_1:\n\t.long\t");
871   assemble_name (asm_out_file, XSTR (symbol, 0));
872   fputc ('\n', asm_out_file);
873 }
874 #endif /* VMS_TARGET */
875 \f
876 /* Additional support code for VMS host.  */
877 /* ??? This should really be in libiberty; vax.c is a target file.  */
878 #ifdef QSORT_WORKAROUND
879   /*
880         Do not use VAXCRTL's qsort() due to a severe bug:  once you've
881         sorted something which has a size that's an exact multiple of 4
882         and is longword aligned, you cannot safely sort anything which
883         is either not a multiple of 4 in size or not longword aligned.
884         A static "move-by-longword" optimization flag inside qsort() is
885         never reset.  This is known to affect VMS V4.6 through VMS V5.5-1,
886         and was finally fixed in VMS V5.5-2.
887
888         In this work-around an insertion sort is used for simplicity.
889         The qsort code from glibc should probably be used instead.
890    */
891 void
892 not_qsort (array, count, size, compare)
893      void *array;
894      unsigned count, size;
895      int (*compare)();
896 {
897
898   if (size == sizeof (short))
899     {
900       register int i;
901       register short *next, *prev;
902       short tmp, *base = array;
903
904       for (next = base, i = count - 1; i > 0; i--)
905         {
906           prev = next++;
907           if ((*compare)(next, prev) < 0)
908             {
909               tmp = *next;
910               do  *(prev + 1) = *prev;
911                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
912               *(prev + 1) = tmp;
913             }
914         }
915     }
916   else if (size == sizeof (long))
917     {
918       register int i;
919       register long *next, *prev;
920       long tmp, *base = array;
921
922       for (next = base, i = count - 1; i > 0; i--)
923         {
924           prev = next++;
925           if ((*compare)(next, prev) < 0)
926             {
927               tmp = *next;
928               do  *(prev + 1) = *prev;
929                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
930               *(prev + 1) = tmp;
931             }
932         }
933     }
934   else  /* arbitrary size */
935     {
936       register int i;
937       register char *next, *prev, *tmp = alloca (size), *base = array;
938
939       for (next = base, i = count - 1; i > 0; i--)
940         {   /* count-1 forward iterations */
941           prev = next,  next += size;           /* increment front pointer */
942           if ((*compare)(next, prev) < 0)
943             {   /* found element out of order; move others up then re-insert */
944               memcpy (tmp, next, size);         /* save smaller element */
945               do { memcpy (prev + size, prev, size); /* move larger elem. up */
946                    prev -= size;                /* decrement back pointer */
947                  } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);
948               memcpy (prev + size, tmp, size);  /* restore small element */
949             }
950         }
951 #ifdef USE_C_ALLOCA
952       alloca (0);
953 #endif
954     }
955
956   return;
957 }
958 #endif /* QSORT_WORKAROUND */
959
960 /* Return 1 if insn A follows B.  */
961
962 static int
963 follows_p (a, b)
964      rtx a, b;
965 {
966   register rtx p;
967
968   for (p = a; p != b; p = NEXT_INSN (p))
969     if (! p)
970       return 1;
971
972   return 0;
973 }
974
975 /* Returns 1 if we know operand OP was 0 before INSN.  */
976
977 int
978 reg_was_0_p (insn, op)
979      rtx insn, op;
980 {
981   rtx link;
982
983   return ((link = find_reg_note (insn, REG_WAS_0, 0))
984           /* Make sure the insn that stored the 0 is still present
985              and doesn't follow INSN in the insn sequence.  */
986           && ! INSN_DELETED_P (XEXP (link, 0))
987           && GET_CODE (XEXP (link, 0)) != NOTE
988           && ! follows_p (XEXP (link, 0), insn)
989           /* Make sure cross jumping didn't happen here.  */
990           && no_labels_between_p (XEXP (link, 0), insn)
991           /* Make sure the reg hasn't been clobbered.  */
992           && ! reg_set_between_p (op, XEXP (link, 0), insn));
993 }