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));
45 static void vms_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT));
48 /* Initialize the GCC target structure. */
49 #undef TARGET_ASM_ALIGNED_HI_OP
50 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
52 #undef TARGET_ASM_FUNCTION_PROLOGUE
53 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
56 #undef TARGET_ASM_SELECT_SECTION
57 #define TARGET_ASM_SELECT_SECTION vms_select_section
60 struct gcc_target targetm = TARGET_INITIALIZER;
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.
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. */
72 vax_output_function_prologue (file, size)
77 register int mask = 0;
79 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
80 if (regs_ever_live[regno] && !call_used_regs[regno])
83 fprintf (file, "\t.word 0x%x\n", mask);
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.
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.
105 const char *p = current_function_name;
106 int is_main = strcmp ("main", p) == 0;
107 # define __MAIN_NAME " main("
109 while (!is_main && *p != '\0')
111 if (*p == *__MAIN_NAME
112 && strncmp (p, __MAIN_NAME, sizeof __MAIN_NAME - sizeof "") == 0)
119 fprintf (file, "\t%s\n\t%s\n", "clrl -(sp)", "jsb _C$MAIN_ARGS");
122 size -= STARTING_FRAME_OFFSET;
124 fprintf (file, "\tmovab %d(sp),sp\n", -size);
126 fprintf (file, "\tsubl2 $%d,sp\n", size);
129 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
132 split_quadword_operands (operands, low, n)
134 int n ATTRIBUTE_UNUSED;
137 /* Split operands. */
139 low[0] = low[1] = low[2] = 0;
140 for (i = 0; i < 3; 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))
147 rtx addr = XEXP (operands[i], 0);
148 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
149 if (which_alternative == 0 && i == 0)
151 addr = XEXP (operands[i], 0);
152 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
157 low[i] = operand_subword (operands[i], 0, 0, DImode);
158 operands[i] = operand_subword (operands[i], 1, 0, DImode);
164 print_operand_address (file, addr)
168 register rtx reg1, breg, ireg;
172 switch (GET_CODE (addr))
176 addr = XEXP (addr, 0);
180 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
184 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
188 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
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.
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,
201 reg1 = 0; ireg = 0; breg = 0; offset = 0;
203 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
204 || GET_CODE (XEXP (addr, 0)) == MEM)
206 offset = XEXP (addr, 0);
207 addr = XEXP (addr, 1);
209 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
210 || GET_CODE (XEXP (addr, 1)) == MEM)
212 offset = XEXP (addr, 1);
213 addr = XEXP (addr, 0);
215 else if (GET_CODE (XEXP (addr, 1)) == MULT)
217 ireg = XEXP (addr, 1);
218 addr = XEXP (addr, 0);
220 else if (GET_CODE (XEXP (addr, 0)) == MULT)
222 ireg = XEXP (addr, 0);
223 addr = XEXP (addr, 1);
225 else if (GET_CODE (XEXP (addr, 1)) == REG)
227 reg1 = XEXP (addr, 1);
228 addr = XEXP (addr, 0);
230 else if (GET_CODE (XEXP (addr, 0)) == REG)
232 reg1 = XEXP (addr, 0);
233 addr = XEXP (addr, 1);
238 if (GET_CODE (addr) == REG)
245 else if (GET_CODE (addr) == MULT)
247 else if (GET_CODE (addr) == PLUS)
249 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
250 || GET_CODE (XEXP (addr, 0)) == MEM)
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)));
261 offset = XEXP (addr, 0);
263 else if (GET_CODE (XEXP (addr, 0)) == REG)
266 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
268 reg1 = XEXP (addr, 0);
270 else if (GET_CODE (XEXP (addr, 0)) == MULT)
274 ireg = XEXP (addr, 0);
279 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
280 || GET_CODE (XEXP (addr, 1)) == MEM)
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)));
291 offset = XEXP (addr, 1);
293 else if (GET_CODE (XEXP (addr, 1)) == REG)
296 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
298 reg1 = XEXP (addr, 1);
300 else if (GET_CODE (XEXP (addr, 1)) == MULT)
304 ireg = XEXP (addr, 1);
312 /* If REG1 is non-zero, figure out if it is a base or index register. */
315 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
326 output_address (offset);
329 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
333 if (GET_CODE (ireg) == MULT)
334 ireg = XEXP (ireg, 0);
335 if (GET_CODE (ireg) != REG)
337 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
342 output_addr_const (file, addr);
350 switch (GET_CODE (op))
382 register enum machine_mode mode;
383 REAL_VALUE_TYPE r, s;
386 if (GET_CODE (c) != CONST_DOUBLE)
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])
396 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
398 for (i = 0; i < 7; i++)
401 REAL_VALUE_FROM_INT (s, x, 0, mode);
403 if (REAL_VALUES_EQUAL (r, s))
405 if (!exact_real_inverse (mode, &s))
407 if (REAL_VALUES_EQUAL (r, s))
414 /* Return the cost in cycles of a memory address, relative to register
417 Each of the following adds the indicated number of cycles:
421 1 - indexing and/or offset(register)
426 vax_address_cost (addr)
429 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
430 rtx plus_op0 = 0, plus_op1 = 0;
432 switch (GET_CODE (addr))
442 indexed = 1; /* 2 on VAX 2 */
445 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
447 offset = (unsigned)(INTVAL(addr)+128) > 256;
451 offset = 1; /* 2 on VAX 2 */
453 case LABEL_REF: /* this is probably a byte offset from the pc */
459 plus_op1 = XEXP (addr, 0);
461 plus_op0 = XEXP (addr, 0);
462 addr = XEXP (addr, 1);
465 indir = 2; /* 3 on VAX 2 */
466 addr = XEXP (addr, 0);
472 /* Up to 3 things can be added in an address. They are stored in
473 plus_op0, plus_op1, and addr. */
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;
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
503 register enum rtx_code code = GET_CODE (x);
504 enum machine_mode mode = GET_MODE (x);
506 int i = 0; /* may be modified in switch */
507 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
519 c = 16; /* 4 on VAX 9000 */
522 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
525 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
530 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
533 return MAX_COST; /* Mode is not supported. */
538 return MAX_COST; /* Mode is not supported. */
543 c = 30; /* highly variable */
544 else if (mode == DFmode)
545 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
548 c = 11; /* 25 on VAX 2 */
555 return MAX_COST; /* Mode is not supported. */
559 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
563 c = 7; /* 17 on VAX 2 */
571 c = 10; /* 6 on VAX 9000 */
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 */
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)
586 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
592 /* AND is special because the first operand is complemented. */
594 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
596 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
605 else if (mode == SFmode)
607 else if (mode == DImode)
616 if (mode == DImode || mode == DFmode)
617 c = 5; /* 7 on VAX 2 */
619 c = 3; /* 4 on VAX 2 */
621 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
623 return c + vax_address_cost (x);
630 /* Now look inside the expression. Operands which are not registers or
631 short constants add to the cost.
633 FMT and I may have been adjusted in the switch above for instructions
634 which require special handling */
636 while (*fmt++ == 'e')
638 register rtx op = XEXP (x, i++);
639 code = GET_CODE (op);
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. */
645 op = XEXP (op, 0), code = GET_CODE (op);
650 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
651 c += 1; /* 2 on VAX 2 */
656 c += 1; /* 2 on VAX 2 */
659 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
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))
666 c += (GET_MODE (x) == DFmode) ? 3 : 2;
670 if (CONST_DOUBLE_HIGH (op) != 0
671 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
676 c += 1; /* 2 on VAX 2 */
677 if (GET_CODE (XEXP (op, 0)) != REG)
678 c += vax_address_cost (XEXP (op, 0));
691 /* Check a `double' value for validity for a particular machine mode. */
693 static const char *const float_strings[] =
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"
701 static REAL_VALUE_TYPE float_values[4];
703 static int inited_float_values = 0;
707 check_float_value (mode, d, overflow)
708 enum machine_mode mode;
712 if (inited_float_values == 0)
715 for (i = 0; i < 4; i++)
717 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
720 inited_float_values = 1;
725 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
729 if ((mode) == SFmode)
732 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
733 if (REAL_VALUES_LESS (float_values[0], r))
735 memcpy (d, &float_values[0], sizeof (REAL_VALUE_TYPE));
738 else if (REAL_VALUES_LESS (r, float_values[1]))
740 memcpy (d, &float_values[1], sizeof (REAL_VALUE_TYPE));
743 else if (REAL_VALUES_LESS (dconst0, r)
744 && REAL_VALUES_LESS (r, float_values[2]))
746 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
749 else if (REAL_VALUES_LESS (r, dconst0)
750 && REAL_VALUES_LESS (float_values[3], r))
752 memcpy (d, &dconst0, sizeof (REAL_VALUE_TYPE));
761 /* Additional support code for VMS target. */
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. */
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;
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. */
779 vms_check_external (decl, name, pending)
784 register struct extern_list *p, *p0;
786 for (p = extern_head; p; p = p->next)
787 if (!strcmp (p->name, name))
790 for (p = pending_head, p0 = 0; p; p0 = p, p = p->next)
791 if (!strcmp (p->name, name))
796 /* Was pending, but has now been defined; move it to other list. */
797 if (p == pending_head)
798 pending_head = p->next;
801 p->next = extern_head;
806 /* Not previously seen; create a new list entry. */
807 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
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));
818 p->next = pending_head;
823 /* Size and section type don't matter; link to `declared' list. */
824 p->size = p->in_const = 0; /* arbitrary init */
826 p->next = extern_head;
833 vms_flush_pending_externals (file)
836 register struct extern_list *p;
840 /* Move next pending declaration to the "done" list. */
842 pending_head = p->next;
843 p->next = extern_head;
846 /* Now output the actual declaration. */
851 fputs (".comm ", file);
852 assemble_name (file, p->name);
853 fprintf (file, ",%d\n", p->size);
858 vms_asm_out_constructor (symbol, priority)
860 int priority ATTRIBUTE_UNUSED;
862 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
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);
870 vms_asm_out_destructor (symbol, priority)
872 int priority ATTRIBUTE_UNUSED;
874 fprintf (asm_out_file,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
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);
882 vax_select_section (exp, reloc, align)
884 int reloc ATTRIBUTE_UNUSED;
885 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
887 if (TREE_CODE (exp) == VAR_DECL)
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))))
894 if (TREE_PUBLIC (exp))
902 if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
904 if (TREE_CODE (exp) == STRING_CST && flag_writable_strings)
910 #endif /* VMS_TARGET */
912 /* Additional support code for VMS host. */
913 /* ??? This should really be in libiberty; vax.c is a target file. */
914 #ifdef QSORT_WORKAROUND
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.
924 In this work-around an insertion sort is used for simplicity.
925 The qsort code from glibc should probably be used instead.
928 not_qsort (array, count, size, compare)
930 unsigned count, size;
934 if (size == sizeof (short))
937 register short *next, *prev;
938 short tmp, *base = array;
940 for (next = base, i = count - 1; i > 0; i--)
943 if ((*compare)(next, prev) < 0)
946 do *(prev + 1) = *prev;
947 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
952 else if (size == sizeof (long))
955 register long *next, *prev;
956 long tmp, *base = array;
958 for (next = base, i = count - 1; i > 0; i--)
961 if ((*compare)(next, prev) < 0)
964 do *(prev + 1) = *prev;
965 while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
970 else /* arbitrary size */
973 register char *next, *prev, *tmp = alloca (size), *base = array;
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 */
994 #endif /* QSORT_WORKAROUND */
996 /* Return 1 if insn A follows B. */
1004 for (p = a; p != b; p = NEXT_INSN (p))
1011 /* Returns 1 if we know operand OP was 0 before INSN. */
1014 reg_was_0_p (insn, op)
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));