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