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. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
33 #include "insn-attr.h"
39 #include "target-def.h"
41 static int follows_p
PARAMS ((rtx
, rtx
));
42 static void vax_output_function_prologue
PARAMS ((FILE *, HOST_WIDE_INT
));
44 static void vms_asm_out_constructor
PARAMS ((rtx
, int));
45 static void vms_asm_out_destructor
PARAMS ((rtx
, int));
46 static void vms_select_section
PARAMS ((tree
, int, unsigned HOST_WIDE_INT
));
47 static void vms_encode_section_info
PARAMS ((tree
, int));
48 static void vms_globalize_label
PARAMS ((FILE *, const char *));
51 /* Initialize the GCC target structure. */
52 #undef TARGET_ASM_ALIGNED_HI_OP
53 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
55 #undef TARGET_ASM_FUNCTION_PROLOGUE
56 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
59 #undef TARGET_ASM_SELECT_SECTION
60 #define TARGET_ASM_SELECT_SECTION vms_select_section
61 #undef TARGET_ENCODE_SECTION_INFO
62 #define TARGET_ENCODE_SECTION_INFO vms_encode_section_info
63 #undef TARGET_ASM_GLOBALIZE_LABEL
64 #define TARGET_ASM_GLOBALIZE_LABEL vms_globalize_label
67 struct gcc_target targetm
= TARGET_INITIALIZER
;
69 /* Generate the assembly code for function entry. FILE is a stdio
70 stream to output the code to. SIZE is an int: how many units of
71 temporary storage to allocate.
73 Refer to the array `regs_ever_live' to determine which registers to
74 save; `regs_ever_live[I]' is nonzero if register number I is ever
75 used in the function. This function is responsible for knowing
76 which registers should not be saved even if used. */
79 vax_output_function_prologue (file
, size
)
84 register int mask
= 0;
86 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
87 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
90 fprintf (file
, "\t.word 0x%x\n", mask
);
95 * This works for both gcc and g++. It first checks to see if
96 * the current routine is "main", which will only happen for
97 * GCC, and add the jsb if it is. If is not the case then try
98 * and see if __MAIN_NAME is part of current_function_name,
99 * which will only happen if we are running g++, and add the jsb
100 * if it is. In gcc there should never be a paren in the
101 * function name, and in g++ there is always a "(" in the
102 * function name, thus there should never be any confusion.
104 * Adjusting the stack pointer by 4 before calling C$MAIN_ARGS
105 * is required when linking with the VMS POSIX version of the C
106 * run-time library; using `subl2 $4,r0' is adequate but we use
107 * `clrl -(sp)' instead. The extra 4 bytes could be removed
108 * after the call because STARTING_FRAME_OFFSET's setting of -4
109 * will end up adding them right back again, but don't bother.
112 const char *p
= current_function_name
;
113 int is_main
= strcmp ("main", p
) == 0;
114 # define __MAIN_NAME " main("
116 while (!is_main
&& *p
!= '\0')
118 if (*p
== *__MAIN_NAME
119 && strncmp (p
, __MAIN_NAME
, sizeof __MAIN_NAME
- sizeof "") == 0)
126 fprintf (file
, "\tclrl -(%ssp)\n\tjsb _C$MAIN_ARGS\n",
130 size
-= STARTING_FRAME_OFFSET
;
132 fprintf (file
, "\tmovab %d(%ssp),%ssp\n", -size
, REGISTER_PREFIX
,
135 fprintf (file
, "\tsubl2 $%d,%ssp\n", size
, REGISTER_PREFIX
);
138 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
141 split_quadword_operands (operands
, low
, n
)
143 int n ATTRIBUTE_UNUSED
;
146 /* Split operands. */
148 low
[0] = low
[1] = low
[2] = 0;
149 for (i
= 0; i
< 3; i
++)
152 /* it's already been figured out */;
153 else if (GET_CODE (operands
[i
]) == MEM
154 && (GET_CODE (XEXP (operands
[i
], 0)) == POST_INC
))
156 rtx addr
= XEXP (operands
[i
], 0);
157 operands
[i
] = low
[i
] = gen_rtx_MEM (SImode
, addr
);
158 if (which_alternative
== 0 && i
== 0)
160 addr
= XEXP (operands
[i
], 0);
161 operands
[i
+1] = low
[i
+1] = gen_rtx_MEM (SImode
, addr
);
166 low
[i
] = operand_subword (operands
[i
], 0, 0, DImode
);
167 operands
[i
] = operand_subword (operands
[i
], 1, 0, DImode
);
173 print_operand_address (file
, addr
)
177 register rtx reg1
, breg
, ireg
;
181 switch (GET_CODE (addr
))
185 addr
= XEXP (addr
, 0);
189 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
193 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
197 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
201 /* There can be either two or three things added here. One must be a
202 REG. One can be either a REG or a MULT of a REG and an appropriate
203 constant, and the third can only be a constant or a MEM.
205 We get these two or three things and put the constant or MEM in
206 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
207 a register and can't tell yet if it is a base or index register,
210 reg1
= 0; ireg
= 0; breg
= 0; offset
= 0;
212 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
213 || GET_CODE (XEXP (addr
, 0)) == MEM
)
215 offset
= XEXP (addr
, 0);
216 addr
= XEXP (addr
, 1);
218 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
219 || GET_CODE (XEXP (addr
, 1)) == MEM
)
221 offset
= XEXP (addr
, 1);
222 addr
= XEXP (addr
, 0);
224 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
226 ireg
= XEXP (addr
, 1);
227 addr
= XEXP (addr
, 0);
229 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
231 ireg
= XEXP (addr
, 0);
232 addr
= XEXP (addr
, 1);
234 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
236 reg1
= XEXP (addr
, 1);
237 addr
= XEXP (addr
, 0);
239 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
241 reg1
= XEXP (addr
, 0);
242 addr
= XEXP (addr
, 1);
247 if (GET_CODE (addr
) == REG
)
254 else if (GET_CODE (addr
) == MULT
)
256 else if (GET_CODE (addr
) == PLUS
)
258 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
259 || GET_CODE (XEXP (addr
, 0)) == MEM
)
263 if (GET_CODE (offset
) == CONST_INT
)
264 offset
= plus_constant (XEXP (addr
, 0), INTVAL (offset
));
265 else if (GET_CODE (XEXP (addr
, 0)) == CONST_INT
)
266 offset
= plus_constant (offset
, INTVAL (XEXP (addr
, 0)));
270 offset
= XEXP (addr
, 0);
272 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
275 ireg
= reg1
, breg
= XEXP (addr
, 0), reg1
= 0;
277 reg1
= XEXP (addr
, 0);
279 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
283 ireg
= XEXP (addr
, 0);
288 if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
289 || GET_CODE (XEXP (addr
, 1)) == MEM
)
293 if (GET_CODE (offset
) == CONST_INT
)
294 offset
= plus_constant (XEXP (addr
, 1), INTVAL (offset
));
295 else if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
296 offset
= plus_constant (offset
, INTVAL (XEXP (addr
, 1)));
300 offset
= XEXP (addr
, 1);
302 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
305 ireg
= reg1
, breg
= XEXP (addr
, 1), reg1
= 0;
307 reg1
= XEXP (addr
, 1);
309 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
313 ireg
= XEXP (addr
, 1);
321 /* If REG1 is nonzero, figure out if it is a base or index register. */
324 if (breg
!= 0 || (offset
&& GET_CODE (offset
) == MEM
))
335 output_address (offset
);
338 fprintf (file
, "(%s)", reg_names
[REGNO (breg
)]);
342 if (GET_CODE (ireg
) == MULT
)
343 ireg
= XEXP (ireg
, 0);
344 if (GET_CODE (ireg
) != REG
)
346 fprintf (file
, "[%s]", reg_names
[REGNO (ireg
)]);
351 output_addr_const (file
, addr
);
359 switch (GET_CODE (op
))
391 register enum machine_mode mode
;
392 REAL_VALUE_TYPE r
, s
;
395 if (GET_CODE (c
) != CONST_DOUBLE
)
400 if (c
== const_tiny_rtx
[(int) mode
][0]
401 || c
== const_tiny_rtx
[(int) mode
][1]
402 || c
== const_tiny_rtx
[(int) mode
][2])
405 REAL_VALUE_FROM_CONST_DOUBLE (r
, c
);
407 for (i
= 0; i
< 7; i
++)
410 REAL_VALUE_FROM_INT (s
, x
, 0, mode
);
412 if (REAL_VALUES_EQUAL (r
, s
))
414 if (!exact_real_inverse (mode
, &s
))
416 if (REAL_VALUES_EQUAL (r
, s
))
423 /* Return the cost in cycles of a memory address, relative to register
426 Each of the following adds the indicated number of cycles:
430 1 - indexing and/or offset(register)
435 vax_address_cost (addr
)
438 int reg
= 0, indexed
= 0, indir
= 0, offset
= 0, predec
= 0;
439 rtx plus_op0
= 0, plus_op1
= 0;
441 switch (GET_CODE (addr
))
451 indexed
= 1; /* 2 on VAX 2 */
454 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
456 offset
= (unsigned)(INTVAL(addr
)+128) > 256;
460 offset
= 1; /* 2 on VAX 2 */
462 case LABEL_REF
: /* this is probably a byte offset from the pc */
468 plus_op1
= XEXP (addr
, 0);
470 plus_op0
= XEXP (addr
, 0);
471 addr
= XEXP (addr
, 1);
474 indir
= 2; /* 3 on VAX 2 */
475 addr
= XEXP (addr
, 0);
481 /* Up to 3 things can be added in an address. They are stored in
482 plus_op0, plus_op1, and addr. */
496 /* Indexing and register+offset can both be used (except on a VAX 2)
497 without increasing execution time over either one alone. */
498 if (reg
&& indexed
&& offset
)
499 return reg
+ indir
+ offset
+ predec
;
500 return reg
+ indexed
+ indir
+ offset
+ predec
;
504 /* Cost of an expression on a VAX. This version has costs tuned for the
505 CVAX chip (found in the VAX 3 series) with comments for variations on
512 register enum rtx_code code
= GET_CODE (x
);
513 enum machine_mode mode
= GET_MODE (x
);
515 int i
= 0; /* may be modified in switch */
516 const char *fmt
= GET_RTX_FORMAT (code
); /* may be modified in switch */
528 c
= 16; /* 4 on VAX 9000 */
531 c
= 9; /* 4 on VAX 9000, 12 on VAX 2 */
534 c
= 16; /* 6 on VAX 9000, 28 on VAX 2 */
539 c
= 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
542 return MAX_COST
; /* Mode is not supported. */
547 return MAX_COST
; /* Mode is not supported. */
552 c
= 30; /* highly variable */
553 else if (mode
== DFmode
)
554 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
557 c
= 11; /* 25 on VAX 2 */
564 return MAX_COST
; /* Mode is not supported. */
568 c
= 6 + (mode
== DFmode
) + (GET_MODE (XEXP (x
, 0)) != SImode
);
572 c
= 7; /* 17 on VAX 2 */
580 c
= 10; /* 6 on VAX 9000 */
584 c
= 6; /* 5 on VAX 2, 4 on VAX 9000 */
585 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
586 fmt
= "e"; /* all constant rotate counts are short */
589 /* Check for small negative integer operand: subl2 can be used with
590 a short positive constant instead. */
591 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
592 if ((unsigned)(INTVAL (XEXP (x
, 1)) + 63) < 127)
595 c
= (mode
== DFmode
) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
601 /* AND is special because the first operand is complemented. */
603 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
605 if ((unsigned)~INTVAL (XEXP (x
, 0)) > 63)
614 else if (mode
== SFmode
)
616 else if (mode
== DImode
)
625 if (mode
== DImode
|| mode
== DFmode
)
626 c
= 5; /* 7 on VAX 2 */
628 c
= 3; /* 4 on VAX 2 */
630 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == POST_INC
)
632 return c
+ vax_address_cost (x
);
639 /* Now look inside the expression. Operands which are not registers or
640 short constants add to the cost.
642 FMT and I may have been adjusted in the switch above for instructions
643 which require special handling */
645 while (*fmt
++ == 'e')
647 register rtx op
= XEXP (x
, i
++);
648 code
= GET_CODE (op
);
650 /* A NOT is likely to be found as the first operand of an AND
651 (in which case the relevant cost is of the operand inside
652 the not) and not likely to be found anywhere else. */
654 op
= XEXP (op
, 0), code
= GET_CODE (op
);
659 if ((unsigned)INTVAL (op
) > 63 && GET_MODE (x
) != QImode
)
660 c
+= 1; /* 2 on VAX 2 */
665 c
+= 1; /* 2 on VAX 2 */
668 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
670 /* Registers are faster than floating point constants -- even
671 those constants which can be encoded in a single byte. */
672 if (vax_float_literal (op
))
675 c
+= (GET_MODE (x
) == DFmode
) ? 3 : 2;
679 if (CONST_DOUBLE_HIGH (op
) != 0
680 || (unsigned)CONST_DOUBLE_LOW (op
) > 63)
685 c
+= 1; /* 2 on VAX 2 */
686 if (GET_CODE (XEXP (op
, 0)) != REG
)
687 c
+= vax_address_cost (XEXP (op
, 0));
701 /* Additional support code for VMS target. */
703 /* Linked list of all externals that are to be emitted when optimizing
704 for the global pointer if they haven't been declared by the end of
705 the program with an appropriate .comm or initialization. */
709 struct extern_list
*next
; /* next external */
710 const char *name
; /* name of the external */
711 int size
; /* external's actual size */
712 int in_const
; /* section type flag */
713 } *extern_head
= 0, *pending_head
= 0;
715 /* Check whether NAME is already on the external definition list. If not,
716 add it to either that list or the pending definition list. */
719 vms_check_external (decl
, name
, pending
)
724 register struct extern_list
*p
, *p0
;
726 for (p
= extern_head
; p
; p
= p
->next
)
727 if (!strcmp (p
->name
, name
))
730 for (p
= pending_head
, p0
= 0; p
; p0
= p
, p
= p
->next
)
731 if (!strcmp (p
->name
, name
))
736 /* Was pending, but has now been defined; move it to other list. */
737 if (p
== pending_head
)
738 pending_head
= p
->next
;
741 p
->next
= extern_head
;
746 /* Not previously seen; create a new list entry. */
747 p
= (struct extern_list
*) xmalloc (sizeof (struct extern_list
));
752 /* Save the size and section type and link to `pending' list. */
753 p
->size
= (DECL_SIZE (decl
) == 0) ? 0 :
754 TREE_INT_CST_LOW (size_binop (CEIL_DIV_EXPR
, DECL_SIZE (decl
),
755 size_int (BITS_PER_UNIT
)));
756 p
->in_const
= (TREE_READONLY (decl
) && ! TREE_THIS_VOLATILE (decl
));
758 p
->next
= pending_head
;
763 /* Size and section type don't matter; link to `declared' list. */
764 p
->size
= p
->in_const
= 0; /* arbitrary init */
766 p
->next
= extern_head
;
773 vms_flush_pending_externals (file
)
776 register struct extern_list
*p
;
780 /* Move next pending declaration to the "done" list. */
782 pending_head
= p
->next
;
783 p
->next
= extern_head
;
786 /* Now output the actual declaration. */
791 fputs (".comm ", file
);
792 assemble_name (file
, p
->name
);
793 fprintf (file
, ",%d\n", p
->size
);
798 vms_asm_out_constructor (symbol
, priority
)
800 int priority ATTRIBUTE_UNUSED
;
802 fprintf (asm_out_file
,".globl $$PsectAttributes_NOOVR$$__gxx_init_1\n");
804 fprintf (asm_out_file
,"$$PsectAttributes_NOOVR$$__gxx_init_1:\n\t.long\t");
805 assemble_name (asm_out_file
, XSTR (symbol
, 0));
806 fputc ('\n', asm_out_file
);
810 vms_asm_out_destructor (symbol
, priority
)
812 int priority ATTRIBUTE_UNUSED
;
814 fprintf (asm_out_file
,".globl $$PsectAttributes_NOOVR$$__gxx_clean_1\n");
816 fprintf (asm_out_file
,"$$PsectAttributes_NOOVR$$__gxx_clean_1:\n\t.long\t");
817 assemble_name (asm_out_file
, XSTR (symbol
, 0));
818 fputc ('\n', asm_out_file
);
822 vms_select_section (exp
, reloc
, align
)
824 int reloc ATTRIBUTE_UNUSED
;
825 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
;
827 if (TREE_CODE (exp
) == VAR_DECL
)
829 if (TREE_READONLY (exp
) && ! TREE_THIS_VOLATILE (exp
)
830 && DECL_INITIAL (exp
)
831 && (DECL_INITIAL (exp
) == error_mark_node
832 || TREE_CONSTANT (DECL_INITIAL (exp
))))
834 if (TREE_PUBLIC (exp
))
842 if (TREE_CODE_CLASS (TREE_CODE (exp
)) == 'c')
844 if (TREE_CODE (exp
) == STRING_CST
&& flag_writable_strings
)
851 /* Make sure that external variables are correctly addressed. Under VMS
852 there is some brain damage in the linker that requires us to do this. */
855 vms_encode_section_info (decl
, first
)
857 int first ATTRIBUTE_UNUSED
;
859 if (DECL_EXTERNAL (decl
) && TREE_PUBLIC (decl
))
860 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl
), 0)) = 1;
863 /* This is how to output a command to make the user-level label named NAME
864 defined for reference from other files. */
866 vms_globalize_label (stream
, name
)
870 default_globalize_label (stream
, name
);
871 vms_check_external (NULL_TREE
, name
, 0);
873 #endif /* VMS_TARGET */
875 /* Additional support code for VMS host. */
876 /* ??? This should really be in libiberty; vax.c is a target file. */
877 #ifdef QSORT_WORKAROUND
879 Do not use VAXCRTL's qsort() due to a severe bug: once you've
880 sorted something which has a size that's an exact multiple of 4
881 and is longword aligned, you cannot safely sort anything which
882 is either not a multiple of 4 in size or not longword aligned.
883 A static "move-by-longword" optimization flag inside qsort() is
884 never reset. This is known to affect VMS V4.6 through VMS V5.5-1,
885 and was finally fixed in VMS V5.5-2.
887 In this work-around an insertion sort is used for simplicity.
888 The qsort code from glibc should probably be used instead.
891 not_qsort (array
, count
, size
, compare
)
893 unsigned count
, size
;
897 if (size
== sizeof (short))
900 register short *next
, *prev
;
901 short tmp
, *base
= array
;
903 for (next
= base
, i
= count
- 1; i
> 0; i
--)
906 if ((*compare
)(next
, prev
) < 0)
909 do *(prev
+ 1) = *prev
;
910 while (--prev
>= base
? (*compare
)(&tmp
, prev
) < 0 : 0);
915 else if (size
== sizeof (long))
918 register long *next
, *prev
;
919 long tmp
, *base
= array
;
921 for (next
= base
, i
= count
- 1; i
> 0; i
--)
924 if ((*compare
)(next
, prev
) < 0)
927 do *(prev
+ 1) = *prev
;
928 while (--prev
>= base
? (*compare
)(&tmp
, prev
) < 0 : 0);
933 else /* arbitrary size */
936 register char *next
, *prev
, *tmp
= alloca (size
), *base
= array
;
938 for (next
= base
, i
= count
- 1; i
> 0; i
--)
939 { /* count-1 forward iterations */
940 prev
= next
, next
+= size
; /* increment front pointer */
941 if ((*compare
)(next
, prev
) < 0)
942 { /* found element out of order; move others up then re-insert */
943 memcpy (tmp
, next
, size
); /* save smaller element */
944 do { memcpy (prev
+ size
, prev
, size
); /* move larger elem. up */
945 prev
-= size
; /* decrement back pointer */
946 } while (prev
>= base
? (*compare
)(tmp
, prev
) < 0 : 0);
947 memcpy (prev
+ size
, tmp
, size
); /* restore small element */
957 #endif /* QSORT_WORKAROUND */
959 /* Return 1 if insn A follows B. */
967 for (p
= a
; p
!= b
; p
= NEXT_INSN (p
))
974 /* Returns 1 if we know operand OP was 0 before INSN. */
977 reg_was_0_p (insn
, op
)
982 return ((link
= find_reg_note (insn
, REG_WAS_0
, 0))
983 /* Make sure the insn that stored the 0 is still present
984 and doesn't follow INSN in the insn sequence. */
985 && ! INSN_DELETED_P (XEXP (link
, 0))
986 && GET_CODE (XEXP (link
, 0)) != NOTE
987 && ! follows_p (XEXP (link
, 0), insn
)
988 /* Make sure cross jumping didn't happen here. */
989 && no_labels_between_p (XEXP (link
, 0), insn
)
990 /* Make sure the reg hasn't been clobbered. */
991 && ! reg_set_between_p (op
, XEXP (link
, 0), insn
));