1 /* Subroutines for insn-output.c for VAX.
2 Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000
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 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
379 union {double d; int i[2];} val;
382 if (GET_CODE (c) != CONST_DOUBLE)
387 if (c == const_tiny_rtx[(int) mode][0]
388 || c == const_tiny_rtx[(int) mode][1]
389 || c == const_tiny_rtx[(int) mode][2])
392 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
394 val.i[0] = CONST_DOUBLE_LOW (c);
395 val.i[1] = CONST_DOUBLE_HIGH (c);
397 for (i = 0; i < 7; i ++)
398 if (val.d == 1 << i || val.d == 1 / (1 << i))
405 /* Return the cost in cycles of a memory address, relative to register
408 Each of the following adds the indicated number of cycles:
412 1 - indexing and/or offset(register)
417 vax_address_cost (addr)
420 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
421 rtx plus_op0 = 0, plus_op1 = 0;
423 switch (GET_CODE (addr))
433 indexed = 1; /* 2 on VAX 2 */
436 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
438 offset = (unsigned)(INTVAL(addr)+128) > 256;
442 offset = 1; /* 2 on VAX 2 */
444 case LABEL_REF: /* this is probably a byte offset from the pc */
450 plus_op1 = XEXP (addr, 0);
452 plus_op0 = XEXP (addr, 0);
453 addr = XEXP (addr, 1);
456 indir = 2; /* 3 on VAX 2 */
457 addr = XEXP (addr, 0);
463 /* Up to 3 things can be added in an address. They are stored in
464 plus_op0, plus_op1, and addr. */
478 /* Indexing and register+offset can both be used (except on a VAX 2)
479 without increasing execution time over either one alone. */
480 if (reg && indexed && offset)
481 return reg + indir + offset + predec;
482 return reg + indexed + indir + offset + predec;
486 /* Cost of an expression on a VAX. This version has costs tuned for the
487 CVAX chip (found in the VAX 3 series) with comments for variations on
494 register enum rtx_code code = GET_CODE (x);
495 enum machine_mode mode = GET_MODE (x);
497 int i = 0; /* may be modified in switch */
498 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
510 c = 16; /* 4 on VAX 9000 */
513 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
516 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
521 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
532 c = 30; /* highly variable */
533 else if (mode == DFmode)
534 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
537 c = 11; /* 25 on VAX 2 */
546 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
550 c = 7; /* 17 on VAX 2 */
558 c = 10; /* 6 on VAX 9000 */
562 c = 6; /* 5 on VAX 2, 4 on VAX 9000 */
563 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
564 fmt = "e"; /* all constant rotate counts are short */
567 /* Check for small negative integer operand: subl2 can be used with
568 a short positive constant instead. */
569 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
570 if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
573 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
579 /* AND is special because the first operand is complemented. */
581 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
583 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
592 else if (mode == SFmode)
594 else if (mode == DImode)
603 if (mode == DImode || mode == DFmode)
604 c = 5; /* 7 on VAX 2 */
606 c = 3; /* 4 on VAX 2 */
608 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
610 return c + vax_address_cost (x);
617 /* Now look inside the expression. Operands which are not registers or
618 short constants add to the cost.
620 FMT and I may have been adjusted in the switch above for instructions
621 which require special handling */
623 while (*fmt++ == 'e')
625 register rtx op = XEXP (x, i++);
626 code = GET_CODE (op);
628 /* A NOT is likely to be found as the first operand of an AND
629 (in which case the relevant cost is of the operand inside
630 the not) and not likely to be found anywhere else. */
632 op = XEXP (op, 0), code = GET_CODE (op);
637 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
638 c += 1; /* 2 on VAX 2 */
643 c += 1; /* 2 on VAX 2 */
646 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
648 /* Registers are faster than floating point constants -- even
649 those constants which can be encoded in a single byte. */
650 if (vax_float_literal (op))
653 c += (GET_MODE (x) == DFmode) ? 3 : 2;
657 if (CONST_DOUBLE_HIGH (op) != 0
658 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
663 c += 1; /* 2 on VAX 2 */
664 if (GET_CODE (XEXP (op, 0)) != REG)
665 c += vax_address_cost (XEXP (op, 0));
678 /* Check a `double' value for validity for a particular machine mode. */
680 static const char *const float_strings[] =
682 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
683 "-1.70141173319264430e+38",
684 "2.93873587705571877e-39", /* 2^-128 */
685 "-2.93873587705571877e-39"
688 static REAL_VALUE_TYPE float_values[4];
690 static int inited_float_values = 0;
694 check_float_value (mode, d, overflow)
695 enum machine_mode mode;
699 if (inited_float_values == 0)
702 for (i = 0; i < 4; i++)
704 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
707 inited_float_values = 1;
712 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
716 if ((mode) == SFmode)
719 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
720 if (REAL_VALUES_LESS (float_values[0], r))
722 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
725 else if (REAL_VALUES_LESS (r, float_values[1]))
727 memcpy (d, &float_values[1], sizeof (REAL_VALUE_TYPE));
730 else if (REAL_VALUES_LESS (dconst0, r)
731 && REAL_VALUES_LESS (r, float_values[2]))
733 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
736 else if (REAL_VALUES_LESS (r, dconst0)
737 && REAL_VALUES_LESS (float_values[3], r))
739 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
748 /* Additional support code for VMS target. */
750 /* Linked list of all externals that are to be emitted when optimizing
751 for the global pointer if they haven't been declared by the end of
752 the program with an appropriate .comm or initialization. */
756 struct extern_list *next; /* next external */
757 const char *name; /* name of the external */
758 int size; /* external's actual size */
759 int in_const; /* section type flag */
760 } *extern_head = 0, *pending_head = 0;
762 /* Check whether NAME is already on the external definition list. If not,
763 add it to either that list or the pending definition list. */
766 vms_check_external (decl, name, pending)
771 register struct extern_list *p, *p0;
773 for (p = extern_head; p; p = p->next)
774 if (!strcmp (p->name, name))
777 for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)
778 if (!strcmp (p->name, name))
783 /* Was pending, but has now been defined; move it to other list. */
784 if (p == pending_head)
785 pending_head = p->next;
788 p->next = extern_head;
793 /* Not previously seen; create a new list entry. */
794 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
799 /* Save the size and section type and link to `pending' list. */
800 p->size = (DECL_SIZE (decl) == 0) ? 0 :
801 TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
802 size_int (BITS_PER_UNIT)));
803 p->in_const = (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl));
805 p->next = pending_head;
810 /* Size and section type don't matter; link to `declared' list. */
811 p->size = p->in_const = 0; /* arbitrary init */
813 p->next = extern_head;
820 vms_flush_pending_externals (file)
823 register struct extern_list *p;
827 /* Move next pending declaration to the "done" list. */
829 pending_head = p->next;
830 p->next = extern_head;
833 /* Now output the actual declaration. */
838 fputs (".comm ", file);
839 assemble_name (file, p->name);
840 fprintf (file, ",%d\n", p->size);
845 vms_asm_out_constructor (symbol, priority)
847 int priority ATTRIBUTE_UNUSED;
849 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
851 fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_init_1:\n\t.long\t");
852 assemble_name (asm_out_file, XSTR (symbol, 0));
853 fputc ('\n', asm_out_file);
857 vms_asm_out_destructor (symbol, priority)
859 int priority ATTRIBUTE_UNUSED;
861 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
863 fprintf (asm_out_file,"$$PsectAttributes_NOOVR$$__gxx_clean_1:\n\t.long\t");
864 assemble_name (asm_out_file, XSTR (symbol, 0));
865 fputc ('\n', asm_out_file);
867 #endif /* VMS_TARGET */
869 /* Additional support code for VMS host. */
870 /* ??? This should really be in libiberty; vax.c is a target file. */
871 #ifdef QSORT_WORKAROUND
873 Do not use VAXCRTL's qsort() due to a severe bug: once you've
874 sorted something which has a size that's an exact multiple of 4
875 and is longword aligned, you cannot safely sort anything which
876 is either not a multiple of 4 in size or not longword aligned.
877 A static "move-by-longword" optimization flag inside qsort() is
878 never reset. This is known to affect VMS V4.6 through VMS V5.5-1,
879 and was finally fixed in VMS V5.5-2.
881 In this work-around an insertion sort is used for simplicity.
882 The qsort code from glibc should probably be used instead.
885 not_qsort (array, count, size, compare)
887 unsigned count, size;
891 if (size == sizeof (short))
894 register short *next, *prev;
895 short tmp, *base = array;
897 for (next = base, i = count - 1; i > 0; i--)
900 if ((*compare)(next, prev) < 0)
903 do *(prev + 1) = *prev;
904 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
909 else if (size == sizeof (long))
912 register long *next, *prev;
913 long tmp, *base = array;
915 for (next = base, i = count - 1; i > 0; i--)
918 if ((*compare)(next, prev) < 0)
921 do *(prev + 1) = *prev;
922 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
927 else /* arbitrary size */
930 register char *next, *prev, *tmp = alloca (size), *base = array;
932 for (next = base, i = count - 1; i > 0; i--)
933 { /* count-1 forward iterations */
934 prev = next, next += size; /* increment front pointer */
935 if ((*compare)(next, prev) < 0)
936 { /* found element out of order; move others up then re-insert */
937 memcpy (tmp, next, size); /* save smaller element */
938 do { memcpy (prev + size, prev, size); /* move larger elem. up */
939 prev -= size; /* decrement back pointer */
940 } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);
941 memcpy (prev + size, tmp, size); /* restore small element */
951 #endif /* QSORT_WORKAROUND */
953 /* Return 1 if insn A follows B. */
961 for (p = a; p != b; p = NEXT_INSN (p))
968 /* Returns 1 if we know operand OP was 0 before INSN. */
971 reg_was_0_p (insn, op)
976 return ((link = find_reg_note (insn, REG_WAS_0, 0))
977 /* Make sure the insn that stored the 0 is still present
978 and doesn't follow INSN in the insn sequence. */
979 && ! INSN_DELETED_P (XEXP (link, 0))
980 && GET_CODE (XEXP (link, 0)) != NOTE
981 && ! follows_p (XEXP (link, 0), insn)
982 /* Make sure cross jumping didn't happen here. */
983 && no_labels_between_p (XEXP (link, 0), insn)
984 /* Make sure the reg hasn't been clobbered. */
985 && ! reg_set_between_p (op, XEXP (link, 0), insn));