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.
5 This file is part of GNU CC.
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)
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.
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. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
32 #include "insn-attr.h"
38 #include "target-def.h"
40 static int follows_p PARAMS ((rtx, rtx));
41 static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
43 static void vms_asm_out_constructor PARAMS ((rtx, int));
44 static void vms_asm_out_destructor PARAMS ((rtx, int));
47 /* Initialize the GCC target structure. */
48 #undef TARGET_ASM_ALIGNED_HI_OP
49 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
51 #undef TARGET_ASM_FUNCTION_PROLOGUE
52 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
54 struct gcc_target targetm = TARGET_INITIALIZER;
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.
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. */
66 vax_output_function_prologue (file, size)
71 register int mask = 0;
73 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
74 if (regs_ever_live[regno] && !call_used_regs[regno])
77 fprintf (file, "\t.word 0x%x\n", mask);
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.
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.
99 const char *p = current_function_name;
100 int is_main = strcmp ("main", p) == 0;
101 # define __MAIN_NAME " main("
103 while (!is_main && *p != '\0')
105 if (*p == *__MAIN_NAME
106 && strncmp (p, __MAIN_NAME, sizeof __MAIN_NAME - sizeof "") == 0)
113 fprintf (file, "\t%s\n\t%s\n", "clrl -(sp)", "jsb _C$MAIN_ARGS");
116 size -= STARTING_FRAME_OFFSET;
118 fprintf (file, "\tmovab %d(sp),sp\n", -size);
120 fprintf (file, "\tsubl2 $%d,sp\n", size);
123 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
126 split_quadword_operands (operands, low, n)
128 int n ATTRIBUTE_UNUSED;
131 /* Split operands. */
133 low[0] = low[1] = low[2] = 0;
134 for (i = 0; i < 3; 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))
141 rtx addr = XEXP (operands[i], 0);
142 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
143 if (which_alternative == 0 && i == 0)
145 addr = XEXP (operands[i], 0);
146 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
151 low[i] = operand_subword (operands[i], 0, 0, DImode);
152 operands[i] = operand_subword (operands[i], 1, 0, DImode);
158 print_operand_address (file, addr)
162 register rtx reg1, breg, ireg;
166 switch (GET_CODE (addr))
170 addr = XEXP (addr, 0);
174 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
178 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
182 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
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.
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,
195 reg1 = 0; ireg = 0; breg = 0; offset = 0;
197 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
198 || GET_CODE (XEXP (addr, 0)) == MEM)
200 offset = XEXP (addr, 0);
201 addr = XEXP (addr, 1);
203 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
204 || GET_CODE (XEXP (addr, 1)) == MEM)
206 offset = XEXP (addr, 1);
207 addr = XEXP (addr, 0);
209 else if (GET_CODE (XEXP (addr, 1)) == MULT)
211 ireg = XEXP (addr, 1);
212 addr = XEXP (addr, 0);
214 else if (GET_CODE (XEXP (addr, 0)) == MULT)
216 ireg = XEXP (addr, 0);
217 addr = XEXP (addr, 1);
219 else if (GET_CODE (XEXP (addr, 1)) == REG)
221 reg1 = XEXP (addr, 1);
222 addr = XEXP (addr, 0);
224 else if (GET_CODE (XEXP (addr, 0)) == REG)
226 reg1 = XEXP (addr, 0);
227 addr = XEXP (addr, 1);
232 if (GET_CODE (addr) == REG)
239 else if (GET_CODE (addr) == MULT)
241 else if (GET_CODE (addr) == PLUS)
243 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
244 || GET_CODE (XEXP (addr, 0)) == MEM)
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)));
255 offset = XEXP (addr, 0);
257 else if (GET_CODE (XEXP (addr, 0)) == REG)
260 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
262 reg1 = XEXP (addr, 0);
264 else if (GET_CODE (XEXP (addr, 0)) == MULT)
268 ireg = XEXP (addr, 0);
273 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
274 || GET_CODE (XEXP (addr, 1)) == MEM)
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)));
285 offset = XEXP (addr, 1);
287 else if (GET_CODE (XEXP (addr, 1)) == REG)
290 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
292 reg1 = XEXP (addr, 1);
294 else if (GET_CODE (XEXP (addr, 1)) == MULT)
298 ireg = XEXP (addr, 1);
306 /* If REG1 is non-zero, figure out if it is a base or index register. */
309 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
320 output_address (offset);
323 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
327 if (GET_CODE (ireg) == MULT)
328 ireg = XEXP (ireg, 0);
329 if (GET_CODE (ireg) != REG)
331 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
336 output_addr_const (file, addr);
344 switch (GET_CODE (op))
376 register enum machine_mode mode;
377 REAL_VALUE_TYPE r, s;
380 if (GET_CODE (c) != CONST_DOUBLE)
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])
390 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
392 for (i = 0; i < 7; i++)
395 REAL_VALUE_FROM_INT (s, x, 0, mode);
397 if (REAL_VALUES_EQUAL (r, s))
399 if (!exact_real_inverse (mode, &s))
401 if (REAL_VALUES_EQUAL (r, s))
408 /* Return the cost in cycles of a memory address, relative to register
411 Each of the following adds the indicated number of cycles:
415 1 - indexing and/or offset(register)
420 vax_address_cost (addr)
423 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
424 rtx plus_op0 = 0, plus_op1 = 0;
426 switch (GET_CODE (addr))
436 indexed = 1; /* 2 on VAX 2 */
439 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
441 offset = (unsigned)(INTVAL(addr)+128) > 256;
445 offset = 1; /* 2 on VAX 2 */
447 case LABEL_REF: /* this is probably a byte offset from the pc */
453 plus_op1 = XEXP (addr, 0);
455 plus_op0 = XEXP (addr, 0);
456 addr = XEXP (addr, 1);
459 indir = 2; /* 3 on VAX 2 */
460 addr = XEXP (addr, 0);
466 /* Up to 3 things can be added in an address. They are stored in
467 plus_op0, plus_op1, and addr. */
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;
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
497 register enum rtx_code code = GET_CODE (x);
498 enum machine_mode mode = GET_MODE (x);
500 int i = 0; /* may be modified in switch */
501 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
513 c = 16; /* 4 on VAX 9000 */
516 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
519 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
524 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
527 return MAX_COST; /* Mode is not supported. */
532 return MAX_COST; /* Mode is not supported. */
537 c = 30; /* highly variable */
538 else if (mode == DFmode)
539 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
542 c = 11; /* 25 on VAX 2 */
549 return MAX_COST; /* Mode is not supported. */
553 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
557 c = 7; /* 17 on VAX 2 */
565 c = 10; /* 6 on VAX 9000 */
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 */
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)
580 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
586 /* AND is special because the first operand is complemented. */
588 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
590 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
599 else if (mode == SFmode)
601 else if (mode == DImode)
610 if (mode == DImode || mode == DFmode)
611 c = 5; /* 7 on VAX 2 */
613 c = 3; /* 4 on VAX 2 */
615 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
617 return c + vax_address_cost (x);
624 /* Now look inside the expression. Operands which are not registers or
625 short constants add to the cost.
627 FMT and I may have been adjusted in the switch above for instructions
628 which require special handling */
630 while (*fmt++ == 'e')
632 register rtx op = XEXP (x, i++);
633 code = GET_CODE (op);
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. */
639 op = XEXP (op, 0), code = GET_CODE (op);
644 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
645 c += 1; /* 2 on VAX 2 */
650 c += 1; /* 2 on VAX 2 */
653 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
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))
660 c += (GET_MODE (x) == DFmode) ? 3 : 2;
664 if (CONST_DOUBLE_HIGH (op) != 0
665 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
670 c += 1; /* 2 on VAX 2 */
671 if (GET_CODE (XEXP (op, 0)) != REG)
672 c += vax_address_cost (XEXP (op, 0));
685 /* Check a `double' value for validity for a particular machine mode. */
687 static const char *const float_strings[] =
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"
695 static REAL_VALUE_TYPE float_values[4];
697 static int inited_float_values = 0;
701 check_float_value (mode, d, overflow)
702 enum machine_mode mode;
706 if (inited_float_values == 0)
709 for (i = 0; i < 4; i++)
711 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
714 inited_float_values = 1;
719 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
723 if ((mode) == SFmode)
726 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
727 if (REAL_VALUES_LESS (float_values[0], r))
729 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
732 else if (REAL_VALUES_LESS (r, float_values[1]))
734 memcpy (d, &float_values[1], sizeof (REAL_VALUE_TYPE));
737 else if (REAL_VALUES_LESS (dconst0, r)
738 && REAL_VALUES_LESS (r, float_values[2]))
740 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
743 else if (REAL_VALUES_LESS (r, dconst0)
744 && REAL_VALUES_LESS (float_values[3], r))
746 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
755 /* Additional support code for VMS target. */
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. */
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;
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. */
773 vms_check_external (decl, name, pending)
778 register struct extern_list *p, *p0;
780 for (p = extern_head; p; p = p->next)
781 if (!strcmp (p->name, name))
784 for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)
785 if (!strcmp (p->name, name))
790 /* Was pending, but has now been defined; move it to other list. */
791 if (p == pending_head)
792 pending_head = p->next;
795 p->next = extern_head;
800 /* Not previously seen; create a new list entry. */
801 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
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));
812 p->next = pending_head;
817 /* Size and section type don't matter; link to `declared' list. */
818 p->size = p->in_const = 0; /* arbitrary init */
820 p->next = extern_head;
827 vms_flush_pending_externals (file)
830 register struct extern_list *p;
834 /* Move next pending declaration to the "done" list. */
836 pending_head = p->next;
837 p->next = extern_head;
840 /* Now output the actual declaration. */
845 fputs (".comm ", file);
846 assemble_name (file, p->name);
847 fprintf (file, ",%d\n", p->size);
852 vms_asm_out_constructor (symbol, priority)
854 int priority ATTRIBUTE_UNUSED;
856 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
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);
864 vms_asm_out_destructor (symbol, priority)
866 int priority ATTRIBUTE_UNUSED;
868 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
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);
874 #endif /* VMS_TARGET */
876 /* Additional support code for VMS host. */
877 /* ??? This should really be in libiberty; vax.c is a target file. */
878 #ifdef QSORT_WORKAROUND
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.
888 In this work-around an insertion sort is used for simplicity.
889 The qsort code from glibc should probably be used instead.
892 not_qsort (array, count, size, compare)
894 unsigned count, size;
898 if (size == sizeof (short))
901 register short *next, *prev;
902 short tmp, *base = array;
904 for (next = base, i = count - 1; i > 0; i--)
907 if ((*compare)(next, prev) < 0)
910 do *(prev + 1) = *prev;
911 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
916 else if (size == sizeof (long))
919 register long *next, *prev;
920 long tmp, *base = array;
922 for (next = base, i = count - 1; i > 0; i--)
925 if ((*compare)(next, prev) < 0)
928 do *(prev + 1) = *prev;
929 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
934 else /* arbitrary size */
937 register char *next, *prev, *tmp = alloca (size), *base = array;
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 */
958 #endif /* QSORT_WORKAROUND */
960 /* Return 1 if insn A follows B. */
968 for (p = a; p != b; p = NEXT_INSN (p))
975 /* Returns 1 if we know operand OP was 0 before INSN. */
978 reg_was_0_p (insn, op)
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));