OSDN Git Service

(vax_rtx_cost): Remove LSHIFT case.
[pf3gnuchains/gcc-fork.git] / gcc / config / vax / vax.c
1 /* Subroutines for insn-output.c for Vax.
2    Copyright (C) 1987, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include <stdio.h>
21 #include "config.h"
22 #include "rtl.h"
23 #include "regs.h"
24 #include "hard-reg-set.h"
25 #include "real.h"
26 #include "insn-config.h"
27 #include "conditions.h"
28 #include "insn-flags.h"
29 #include "output.h"
30 #include "insn-attr.h"
31
32
33 /* This is like nonimmediate_operand with a restriction on the type of MEM.  */
34
35 void
36 split_quadword_operands (operands, low, n)
37      rtx *operands, *low;
38      int n;
39 {
40   int i;
41   /* Split operands.  */
42
43   low[0] = low[1] = low[2] = 0;
44   for (i = 0; i < 3; i++)
45     {
46       if (low[i])
47         /* it's already been figured out */;
48       else if (GET_CODE (operands[i]) == MEM
49                && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
50         {
51           rtx addr = XEXP (operands[i], 0);
52           operands[i] = low[i] = gen_rtx (MEM, SImode, addr);
53           if (which_alternative == 0 && i == 0)
54             {
55               addr = XEXP (operands[i], 0);
56               operands[i+1] = low[i+1] = gen_rtx (MEM, SImode, addr);
57             }
58         }
59       else
60         {
61           low[i] = operand_subword (operands[i], 0, 0, DImode);
62           operands[i] = operand_subword (operands[i], 1, 0, DImode);
63         }
64     }
65 }
66 \f
67 print_operand_address (file, addr)
68      FILE *file;
69      register rtx addr;
70 {
71   register rtx reg1, reg2, breg, ireg;
72   rtx offset;
73
74  retry:
75   switch (GET_CODE (addr))
76     {
77     case MEM:
78       fprintf (file, "*");
79       addr = XEXP (addr, 0);
80       goto retry;
81
82     case REG:
83       fprintf (file, "(%s)", reg_names[REGNO (addr)]);
84       break;
85
86     case PRE_DEC:
87       fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
88       break;
89
90     case POST_INC:
91       fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
92       break;
93
94     case PLUS:
95       /* There can be either two or three things added here.  One must be a
96          REG.  One can be either a REG or a MULT of a REG and an appropriate
97          constant, and the third can only be a constant or a MEM.
98
99          We get these two or three things and put the constant or MEM in
100          OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
101          a register and can't tell yet if it is a base or index register,
102          put it into REG1.  */
103
104       reg1 = 0; ireg = 0; breg = 0; offset = 0;
105
106       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
107           || GET_CODE (XEXP (addr, 0)) == MEM)
108         {
109           offset = XEXP (addr, 0);
110           addr = XEXP (addr, 1);
111         }
112       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
113                || GET_CODE (XEXP (addr, 1)) == MEM)
114         {
115           offset = XEXP (addr, 1);
116           addr = XEXP (addr, 0);
117         }
118       else if (GET_CODE (XEXP (addr, 1)) == MULT)
119         {
120           ireg = XEXP (addr, 1);
121           addr = XEXP (addr, 0);
122         }
123       else if (GET_CODE (XEXP (addr, 0)) == MULT)
124         {
125           ireg = XEXP (addr, 0);
126           addr = XEXP (addr, 1);
127         }
128       else if (GET_CODE (XEXP (addr, 1)) == REG)
129         {
130           reg1 = XEXP (addr, 1);
131           addr = XEXP (addr, 0);
132         }
133       else if (GET_CODE (XEXP (addr, 0)) == REG)
134         {
135           reg1 = XEXP (addr, 0);
136           addr = XEXP (addr, 1);
137         }
138       else
139         abort ();
140
141       if (GET_CODE (addr) == REG)
142         {
143           if (reg1)
144             ireg = addr;
145           else
146             reg1 = addr;
147         }
148       else if (GET_CODE (addr) == MULT)
149         ireg = addr;
150       else if (GET_CODE (addr) == PLUS)
151         {
152           if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
153               || GET_CODE (XEXP (addr, 0)) == MEM)
154             {
155               if (offset)
156                 {
157                   if (GET_CODE (offset) == CONST_INT)
158                     offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
159                   else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
160                     offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
161                   else
162                     abort ();
163                 }
164               offset = XEXP (addr, 0);
165             }
166           else if (GET_CODE (XEXP (addr, 0)) == REG)
167             {
168               if (reg1)
169                 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
170               else
171                 reg1 = XEXP (addr, 0);
172             }
173           else if (GET_CODE (XEXP (addr, 0)) == MULT)
174             {
175               if (ireg)
176                 abort ();
177               ireg = XEXP (addr, 0);
178             }
179           else
180             abort ();
181
182           if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
183               || GET_CODE (XEXP (addr, 1)) == MEM)
184             {
185               if (offset)
186                 {
187                   if (GET_CODE (offset) == CONST_INT)
188                     offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
189                   else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
190                     offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
191                   else
192                     abort ();
193                 }
194               offset = XEXP (addr, 1);
195             }
196           else if (GET_CODE (XEXP (addr, 1)) == REG)
197             {
198               if (reg1)
199                 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
200               else
201                 reg1 = XEXP (addr, 1);
202             }
203           else if (GET_CODE (XEXP (addr, 1)) == MULT)
204             {
205               if (ireg)
206                 abort ();
207               ireg = XEXP (addr, 1);
208             }
209           else
210             abort ();
211         }
212       else
213         abort ();
214
215       /* If REG1 is non-zero, figure out if it is a base or index register.  */
216       if (reg1)
217         {
218           if (breg != 0 || (offset && GET_CODE (offset) == MEM))
219             {
220               if (ireg)
221                 abort ();
222               ireg = reg1;
223             }
224           else
225             breg = reg1;
226         }
227
228       if (offset != 0)
229         output_address (offset);
230
231       if (breg != 0)
232         fprintf (file, "(%s)", reg_names[REGNO (breg)]);
233
234       if (ireg != 0)
235         {
236           if (GET_CODE (ireg) == MULT)
237             ireg = XEXP (ireg, 0);
238           if (GET_CODE (ireg) != REG)
239             abort ();
240           fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
241         }
242       break;
243
244     default:
245       output_addr_const (file, addr);
246     }
247 }
248 \f
249 char *
250 rev_cond_name (op)
251      rtx op;
252 {
253   switch (GET_CODE (op))
254     {
255     case EQ:
256       return "neq";
257     case NE:
258       return "eql";
259     case LT:
260       return "geq";
261     case LE:
262       return "gtr";
263     case GT:
264       return "leq";
265     case GE:
266       return "lss";
267     case LTU:
268       return "gequ";
269     case LEU:
270       return "gtru";
271     case GTU:
272       return "lequ";
273     case GEU:
274       return "lssu";
275
276     default:
277       abort ();
278     }
279 }
280
281 int
282 vax_float_literal(c)
283     register rtx c;
284 {
285   register enum machine_mode mode;
286   int i;
287   union {double d; int i[2];} val;
288
289   if (GET_CODE (c) != CONST_DOUBLE)
290     return 0;
291
292   mode = GET_MODE (c);
293
294   if (c == const_tiny_rtx[(int) mode][0]
295       || c == const_tiny_rtx[(int) mode][1]
296       || c == const_tiny_rtx[(int) mode][2])
297     return 1;
298
299 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
300
301   val.i[0] = CONST_DOUBLE_LOW (c);
302   val.i[1] = CONST_DOUBLE_HIGH (c);
303
304   for (i = 0; i < 7; i ++)
305     if (val.d == 1 << i || val.d == 1 / (1 << i))
306       return 1;
307 #endif
308   return 0;
309 }
310
311
312 /* Return the cost in cycles of a memory address, relative to register
313    indirect.
314
315    Each of the following adds the indicated number of cycles:
316
317    1 - symbolic address
318    1 - pre-decrement
319    1 - indexing and/or offset(register)
320    2 - indirect */
321
322
323 int vax_address_cost(addr)
324     register rtx addr;
325 {
326   int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
327   rtx plus_op0 = 0, plus_op1 = 0;
328  restart:
329   switch (GET_CODE (addr))
330     {
331     case PRE_DEC:
332       predec = 1;
333     case REG:
334     case SUBREG:
335     case POST_INC:
336       reg = 1;
337       break;
338     case MULT:
339       indexed = 1;      /* 2 on VAX 2 */
340       break;
341     case CONST_INT:
342       /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
343       if (offset == 0)
344         offset = (unsigned)(INTVAL(addr)+128) > 256;
345       break;
346     case CONST:
347     case SYMBOL_REF:
348       offset = 1;       /* 2 on VAX 2 */
349       break;
350     case LABEL_REF:     /* this is probably a byte offset from the pc */
351       if (offset == 0)
352         offset = 1;
353       break;
354     case PLUS:
355       if (plus_op0)
356         plus_op1 = XEXP (addr, 0);
357       else
358         plus_op0 = XEXP (addr, 0);
359       addr = XEXP (addr, 1);
360       goto restart;
361     case MEM:
362       indir = 2;        /* 3 on VAX 2 */
363       addr = XEXP (addr, 0);
364       goto restart;
365     }
366
367   /* Up to 3 things can be added in an address.  They are stored in
368      plus_op0, plus_op1, and addr.  */
369
370   if (plus_op0)
371     {
372       addr = plus_op0;
373       plus_op0 = 0;
374       goto restart;
375     }
376   if (plus_op1)
377     {
378       addr = plus_op1;
379       plus_op1 = 0;
380       goto restart;
381     }
382   /* Indexing and register+offset can both be used (except on a VAX 2)
383      without increasing execution time over either one alone. */
384   if (reg && indexed && offset)
385     return reg + indir + offset + predec;
386   return reg + indexed + indir + offset + predec;
387 }
388
389
390 /* Cost of an expression on a VAX.  This version has costs tuned for the
391    CVAX chip (found in the VAX 3 series) with comments for variations on
392    other models.  */
393
394 int
395 vax_rtx_cost (x)
396     register rtx x;
397 {
398   register enum rtx_code code = GET_CODE (x);
399   enum machine_mode mode = GET_MODE (x);
400   register int c;
401   int i = 0;                            /* may be modified in switch */
402   char *fmt = GET_RTX_FORMAT (code);    /* may be modified in switch */
403
404   switch (code)
405     {
406     case POST_INC:
407       return 2;
408     case PRE_DEC:
409       return 3;
410     case MULT:
411       switch (mode)
412         {
413         case DFmode:
414           c = 16;               /* 4 on VAX 9000 */
415           break;
416         case SFmode:
417           c = 9;                /* 4 on VAX 9000, 12 on VAX 2 */
418           break;
419         case DImode:
420           c = 16;               /* 6 on VAX 9000, 28 on VAX 2 */
421           break;
422         case SImode:
423         case HImode:
424         case QImode:
425           c = 10;               /* 3-4 on VAX 9000, 20-28 on VAX 2 */
426           break;
427         }
428       break;
429     case UDIV:
430       c = 17;
431       break;
432     case DIV:
433       if (mode == DImode)
434         c = 30; /* highly variable */
435       else if (mode == DFmode)
436         /* divide takes 28 cycles if the result is not zero, 13 otherwise */
437         c = 24;
438       else
439         c = 11;                 /* 25 on VAX 2 */
440       break;
441     case MOD:
442       c = 23;
443       break;
444     case UMOD:
445       c = 29;
446       break;
447     case FLOAT:
448       c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
449       /* 4 on VAX 9000 */
450       break;
451     case FIX:
452       c = 7;                    /* 17 on VAX 2 */
453       break;
454     case ASHIFT:
455     case LSHIFTRT:
456     case ASHIFTRT:
457       if (mode == DImode)
458         c = 12;
459       else
460         c = 10;                 /* 6 on VAX 9000 */
461       break;
462     case ROTATE:
463     case ROTATERT:
464       c = 6;                    /* 5 on VAX 2, 4 on VAX 9000 */
465       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
466         fmt = "e";      /* all constant rotate counts are short */
467       break;
468     case PLUS:
469       /* Check for small negative integer operand: subl2 can be used with
470          a short positive constant instead.  */
471       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
472         if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
473           fmt = "e";
474     case MINUS:
475       c = (mode == DFmode) ? 13 : 8;    /* 6/8 on VAX 9000, 16/15 on VAX 2 */
476     case IOR:
477     case XOR:
478       c = 3;
479       break;
480     case AND:
481       /* AND is special because the first operand is complemented. */
482       c = 3;
483       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
484         {
485           if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
486             c = 4;
487           fmt = "e";
488           i = 1;
489         }
490       break;
491     case NEG:
492       if (mode == DFmode)
493         return 9;
494       else if (mode == SFmode)
495         return 6;
496       else if (mode == DImode)
497         return 4;
498     case NOT:
499       return 2;
500     case ZERO_EXTRACT:
501     case SIGN_EXTRACT:
502       c = 15;
503       break;
504     case MEM:
505       if (mode == DImode || mode == DFmode)
506         c = 5;                          /* 7 on VAX 2 */
507       else
508         c = 3;                          /* 4 on VAX 2 */
509       x = XEXP (x, 0);
510       if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
511         return c;
512       return c + vax_address_cost (x);
513     default:
514       c = 3;
515       break;
516     }
517
518
519   /* Now look inside the expression.  Operands which are not registers or
520      short constants add to the cost.
521
522      FMT and I may have been adjusted in the switch above for instructions
523      which require special handling */
524
525   while (*fmt++ == 'e')
526     {
527       register rtx op = XEXP (x, i++);
528       code = GET_CODE (op);
529
530       /* A NOT is likely to be found as the first operand of an AND
531          (in which case the relevant cost is of the operand inside
532          the not) and not likely to be found anywhere else.  */
533       if (code == NOT)
534         op = XEXP (op, 0), code = GET_CODE (op);
535
536       switch (code)
537         {
538         case CONST_INT:
539           if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
540             c += 1;             /* 2 on VAX 2 */
541           break;
542         case CONST:
543         case LABEL_REF:
544         case SYMBOL_REF:
545           c += 1;               /* 2 on VAX 2 */
546           break;
547         case CONST_DOUBLE:
548           if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
549             {
550               /* Registers are faster than floating point constants -- even
551                  those constants which can be encoded in a single byte.  */
552               if (vax_float_literal (op))
553                 c++;
554               else
555                 c += (GET_MODE (x) == DFmode) ? 3 : 2;
556             }
557           else
558             {
559               if (CONST_DOUBLE_HIGH (op) != 0
560                   || (unsigned)CONST_DOUBLE_LOW (op) > 63)
561                 c += 2;
562             }
563           break;
564         case MEM:
565           c += 1;               /* 2 on VAX 2 */
566           if (GET_CODE (XEXP (op, 0)) != REG)
567             c += vax_address_cost (XEXP (op, 0));
568           break;
569         case REG:
570         case SUBREG:
571           break;
572         default:
573           c += 1;
574           break;
575         }
576     }
577   return c;
578 }
579
580 /* Check a `double' value for validity for a particular machine mode.  */
581
582 static char *float_strings[] =
583 {
584    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
585   "-1.70141173319264430e+38",
586    "2.93873587705571877e-39", /* 2^-128 */
587   "-2.93873587705571877e-39"
588 };
589
590 static REAL_VALUE_TYPE float_values[4];
591
592 static int inited_float_values = 0;
593
594
595 int
596 check_float_value (mode, d, overflow)
597      enum machine_mode mode;
598      REAL_VALUE_TYPE *d;
599      int overflow;
600 {
601   if (inited_float_values == 0)
602     {
603       int i;
604       for (i = 0; i < 4; i++)
605         {
606           float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
607         }
608
609       inited_float_values = 1;
610     }
611
612   if (overflow)
613     {
614       bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE));
615       return 1;
616     }
617
618   if ((mode) == SFmode)
619     {
620       REAL_VALUE_TYPE r;
621       bcopy (d, &r, sizeof (REAL_VALUE_TYPE));
622       if (REAL_VALUES_LESS (float_values[0], r))
623         {
624           bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE));
625           return 1;
626         }
627       else if (REAL_VALUES_LESS (r, float_values[1]))
628         {
629           bcopy (&float_values[1], d, sizeof (REAL_VALUE_TYPE));
630           return 1;
631         }
632       else if (REAL_VALUES_LESS (dconst0, r)
633                 && REAL_VALUES_LESS (r, float_values[2]))
634         {
635           bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));
636           return 1;
637         }
638       else if (REAL_VALUES_LESS (r, dconst0)
639                 && REAL_VALUES_LESS (float_values[3], r))
640         {
641           bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));
642           return 1;
643         }
644     }
645
646   return 0;
647 }
648 \f
649 /* Linked list of all externals that are to be emitted when optimizing
650    for the global pointer if they haven't been declared by the end of
651    the program with an appropriate .comm or initialization.  */
652
653 struct extern_list {
654   struct extern_list *next;     /* next external */
655   char *name;                   /* name of the external */
656 } *extern_head = 0;
657
658 /* Return 1 if NAME has already had an external definition;
659    0 if it has not (so caller should output one).  */
660
661 int
662 vms_check_external (name)
663      char *name;
664 {
665   register struct extern_list *p;
666
667   for (p = extern_head; p; p = p->next)
668     if (!strcmp (p->name, name))
669       return 1;
670
671   p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
672   p->next = extern_head;
673   p->name = name;
674   extern_head = p;
675   return 0;
676 }
677 \f
678 #ifdef VMS
679 /* Additional support code for VMS. */
680
681 #ifdef QSORT_WORKAROUND
682   /*
683         Do not use VAXCRTL's qsort() due to a severe bug:  once you've
684         sorted something which has a size that's an exact multiple of 4
685         and is longword aligned, you cannot safely sort anything which
686         is either not a multiple of 4 in size or not longword aligned.
687         A static "move-by-longword" optimization flag inside qsort() is
688         never reset.  This is known of affect VMS V4.6 through VMS V5.5-1.
689
690         In this work-around an insertion sort is used for simplicity.
691         The qsort code from glibc should probably be used instead.
692    */
693 void
694 not_qsort (array, count, size, compare)
695      void *array;
696      unsigned count, size;
697      int (*compare)();
698 {
699
700   if (size == sizeof (short))
701     {
702       register int i;
703       register short *next, *prev;
704       short tmp, *base = array;
705
706       for (next = base, i = count - 1; i > 0; i--)
707         {
708           prev = next++;
709           if ((*compare)(next, prev) < 0)
710             {
711               tmp = *next;
712               do  *(prev + 1) = *prev;
713                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
714               *(prev + 1) = tmp;
715             }
716         }
717     }
718   else if (size == sizeof (long))
719     {
720       register int i;
721       register long *next, *prev;
722       long tmp, *base = array;
723
724       for (next = base, i = count - 1; i > 0; i--)
725         {
726           prev = next++;
727           if ((*compare)(next, prev) < 0)
728             {
729               tmp = *next;
730               do  *(prev + 1) = *prev;
731                 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
732               *(prev + 1) = tmp;
733             }
734         }
735     }
736   else  /* arbitrary size */
737     {
738 #ifdef USE_C_ALLOCA
739       extern void *alloca ();
740 #endif
741       register int i;
742       register char *next, *prev, *tmp = alloca (size), *base = array;
743
744       for (next = base, i = count - 1; i > 0; i--)
745         {   /* count-1 forward iterations */
746           prev = next,  next += size;           /* increment front pointer */
747           if ((*compare)(next, prev) < 0)
748             {   /* found element out of order; move others up then re-insert */
749               memcpy (tmp, next, size);         /* save smaller element */
750               do { memcpy (prev + size, prev, size); /* move larger elem. up */
751                    prev -= size;                /* decrement back pointer */
752                  } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);
753               memcpy (prev + size, tmp, size);  /* restore small element */
754             }
755         }
756 #ifdef USE_C_ALLOCA
757       alloca (0);
758 #endif
759     }
760
761   return;
762 }
763 #endif /* QSORT_WORKAROUND */
764
765 #endif /* VMS */