1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
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"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
44 extern char *version_string
;
45 extern int rtx_equal_function_value_matters
;
47 /* Specify which cpu to schedule for. */
49 enum processor_type alpha_cpu
;
51 /* Specify how accurate floating-point traps need to be. */
53 enum alpha_trap_precision alpha_tp
;
55 /* Specify the floating-point rounding mode. */
57 enum alpha_fp_rounding_mode alpha_fprm
;
59 /* Specify which things cause traps. */
61 enum alpha_fp_trap_mode alpha_fptm
;
63 /* Strings decoded into the above options. */
65 char *alpha_cpu_string
; /* -mcpu=ev[4|5] */
66 char *alpha_tp_string
; /* -mtrap-precision=[p|s|i] */
67 char *alpha_fprm_string
; /* -mfp-rounding-mode=[n|m|c|d] */
68 char *alpha_fptm_string
; /* -mfp-trap-mode=[n|u|su|sui] */
70 /* Save information from a "cmpxx" operation until the branch or scc is
73 rtx alpha_compare_op0
, alpha_compare_op1
;
74 int alpha_compare_fp_p
;
76 /* Save the name of the current function as used by the assembler. This
77 is used by the epilogue. */
79 char *alpha_function_name
;
81 /* Non-zero if inside of a function, because the Alpha asm can't
82 handle .files inside of functions. */
84 static int inside_function
= FALSE
;
86 /* Nonzero if the current function needs gp. */
88 int alpha_function_needs_gp
;
90 /* If non-null, this rtx holds the return address for the function. */
92 static rtx alpha_return_addr_rtx
;
94 /* Declarations of static functions. */
95 static void alpha_set_memflags_1
PROTO((rtx
, int, int, int));
96 static rtx alpha_emit_set_const_1
PROTO((rtx
, enum machine_mode
,
98 static void add_long_const
PROTO((FILE *, HOST_WIDE_INT
, int, int, int));
100 /* Compute the size of the save area in the stack. */
101 static void alpha_sa_mask
PROTO((unsigned long *imaskP
,
102 unsigned long *fmaskP
));
103 /* Get the number of args of a function in one of two ways. */
105 #define NUM_ARGS current_function_args_info.num_args
107 #define NUM_ARGS current_function_args_info
110 /* Parse target option strings. */
116 = TARGET_CPU_DEFAULT
& MASK_CPU_EV6
? PROCESSOR_EV6
117 : (TARGET_CPU_DEFAULT
& MASK_CPU_EV5
? PROCESSOR_EV5
: PROCESSOR_EV4
);
119 if (alpha_cpu_string
)
121 if (! strcmp (alpha_cpu_string
, "ev4")
122 || ! strcmp (alpha_cpu_string
, "21064"))
124 alpha_cpu
= PROCESSOR_EV4
;
125 target_flags
&= ~ (MASK_BWX
| MASK_CIX
| MASK_MAX
);
127 else if (! strcmp (alpha_cpu_string
, "ev5")
128 || ! strcmp (alpha_cpu_string
, "21164"))
130 alpha_cpu
= PROCESSOR_EV5
;
131 target_flags
&= ~ (MASK_BWX
| MASK_CIX
| MASK_MAX
);
133 else if (! strcmp (alpha_cpu_string
, "ev56")
134 || ! strcmp (alpha_cpu_string
, "21164a"))
136 alpha_cpu
= PROCESSOR_EV5
;
137 target_flags
|= MASK_BWX
;
138 target_flags
&= ~ (MASK_CIX
| MASK_MAX
);
140 else if (! strcmp (alpha_cpu_string
, "pca56")
141 || ! strcmp (alpha_cpu_string
, "21164PC"))
143 alpha_cpu
= PROCESSOR_EV5
;
144 target_flags
|= MASK_BWX
| MASK_MAX
;
145 target_flags
&= ~ MASK_CIX
;
147 else if (! strcmp (alpha_cpu_string
, "ev6")
148 || ! strcmp (alpha_cpu_string
, "21264"))
150 alpha_cpu
= PROCESSOR_EV6
;
151 target_flags
|= MASK_BWX
| MASK_CIX
| MASK_MAX
;
154 error ("bad value `%s' for -mcpu switch", alpha_cpu_string
);
157 alpha_tp
= ALPHA_TP_PROG
;
158 alpha_fprm
= ALPHA_FPRM_NORM
;
159 alpha_fptm
= ALPHA_FPTM_N
;
163 alpha_tp
= ALPHA_TP_INSN
;
164 alpha_fptm
= ALPHA_FPTM_SU
;
167 if (TARGET_IEEE_WITH_INEXACT
)
169 alpha_tp
= ALPHA_TP_INSN
;
170 alpha_fptm
= ALPHA_FPTM_SUI
;
175 if (! strcmp (alpha_tp_string
, "p"))
176 alpha_tp
= ALPHA_TP_PROG
;
177 else if (! strcmp (alpha_tp_string
, "f"))
178 alpha_tp
= ALPHA_TP_FUNC
;
179 else if (! strcmp (alpha_tp_string
, "i"))
180 alpha_tp
= ALPHA_TP_INSN
;
182 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string
);
185 if (alpha_fprm_string
)
187 if (! strcmp (alpha_fprm_string
, "n"))
188 alpha_fprm
= ALPHA_FPRM_NORM
;
189 else if (! strcmp (alpha_fprm_string
, "m"))
190 alpha_fprm
= ALPHA_FPRM_MINF
;
191 else if (! strcmp (alpha_fprm_string
, "c"))
192 alpha_fprm
= ALPHA_FPRM_CHOP
;
193 else if (! strcmp (alpha_fprm_string
,"d"))
194 alpha_fprm
= ALPHA_FPRM_DYN
;
196 error ("bad value `%s' for -mfp-rounding-mode switch",
200 if (alpha_fptm_string
)
202 if (strcmp (alpha_fptm_string
, "n") == 0)
203 alpha_fptm
= ALPHA_FPTM_N
;
204 else if (strcmp (alpha_fptm_string
, "u") == 0)
205 alpha_fptm
= ALPHA_FPTM_U
;
206 else if (strcmp (alpha_fptm_string
, "su") == 0)
207 alpha_fptm
= ALPHA_FPTM_SU
;
208 else if (strcmp (alpha_fptm_string
, "sui") == 0)
209 alpha_fptm
= ALPHA_FPTM_SUI
;
211 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string
);
214 /* Do some sanity checks on the above option. */
216 if ((alpha_fptm
== ALPHA_FPTM_SU
|| alpha_fptm
== ALPHA_FPTM_SUI
)
217 && alpha_tp
!= ALPHA_TP_INSN
)
219 warning ("fp software completion requires -mtrap-precision=i");
220 alpha_tp
= ALPHA_TP_INSN
;
223 if (TARGET_FLOAT_VAX
)
225 if (alpha_fprm
== ALPHA_FPRM_MINF
|| alpha_fprm
== ALPHA_FPRM_DYN
)
227 warning ("rounding mode not supported for VAX floats");
228 alpha_fprm
= ALPHA_FPRM_NORM
;
230 if (alpha_fptm
== ALPHA_FPTM_SUI
)
232 warning ("trap mode not supported for VAX floats");
233 alpha_fptm
= ALPHA_FPTM_SU
;
238 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
246 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
248 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
254 /* Returns 1 if OP is either the constant zero or a register. If a
255 register, it must be in the proper mode unless MODE is VOIDmode. */
258 reg_or_0_operand (op
, mode
)
260 enum machine_mode mode
;
262 return op
== const0_rtx
|| register_operand (op
, mode
);
265 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
269 reg_or_6bit_operand (op
, mode
)
271 enum machine_mode mode
;
273 return ((GET_CODE (op
) == CONST_INT
274 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
275 || register_operand (op
, mode
));
279 /* Return 1 if OP is an 8-bit constant or any register. */
282 reg_or_8bit_operand (op
, mode
)
284 enum machine_mode mode
;
286 return ((GET_CODE (op
) == CONST_INT
287 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
288 || register_operand (op
, mode
));
291 /* Return 1 if OP is an 8-bit constant. */
294 cint8_operand (op
, mode
)
296 enum machine_mode mode
;
298 return (GET_CODE (op
) == CONST_INT
299 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100);
302 /* Return 1 if the operand is a valid second operand to an add insn. */
305 add_operand (op
, mode
)
307 enum machine_mode mode
;
309 if (GET_CODE (op
) == CONST_INT
)
310 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K')
311 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'L')
312 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'O'));
314 return register_operand (op
, mode
);
317 /* Return 1 if the operand is a valid second operand to a sign-extending
321 sext_add_operand (op
, mode
)
323 enum machine_mode mode
;
325 if (GET_CODE (op
) == CONST_INT
)
326 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 255
327 || (unsigned HOST_WIDE_INT
) (- INTVAL (op
)) < 255);
329 return register_operand (op
, mode
);
332 /* Return 1 if OP is the constant 4 or 8. */
335 const48_operand (op
, mode
)
337 enum machine_mode mode
;
339 return (GET_CODE (op
) == CONST_INT
340 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
343 /* Return 1 if OP is a valid first operand to an AND insn. */
346 and_operand (op
, mode
)
348 enum machine_mode mode
;
350 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
351 return (zap_mask (CONST_DOUBLE_LOW (op
))
352 && zap_mask (CONST_DOUBLE_HIGH (op
)));
354 if (GET_CODE (op
) == CONST_INT
)
355 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
356 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
357 || zap_mask (INTVAL (op
)));
359 return register_operand (op
, mode
);
362 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
365 or_operand (op
, mode
)
367 enum machine_mode mode
;
369 if (GET_CODE (op
) == CONST_INT
)
370 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
371 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
373 return register_operand (op
, mode
);
376 /* Return 1 if OP is a constant that is the width, in bits, of an integral
377 mode smaller than DImode. */
380 mode_width_operand (op
, mode
)
382 enum machine_mode mode
;
384 return (GET_CODE (op
) == CONST_INT
385 && (INTVAL (op
) == 8 || INTVAL (op
) == 16 || INTVAL (op
) == 32));
388 /* Return 1 if OP is a constant that is the width of an integral machine mode
389 smaller than an integer. */
392 mode_mask_operand (op
, mode
)
394 enum machine_mode mode
;
396 #if HOST_BITS_PER_WIDE_INT == 32
397 if (GET_CODE (op
) == CONST_DOUBLE
)
398 return CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == -1;
401 return (GET_CODE (op
) == CONST_INT
402 && (INTVAL (op
) == 0xff
403 || INTVAL (op
) == 0xffff
404 #if HOST_BITS_PER_WIDE_INT == 64
405 || INTVAL (op
) == 0xffffffff
410 /* Return 1 if OP is a multiple of 8 less than 64. */
413 mul8_operand (op
, mode
)
415 enum machine_mode mode
;
417 return (GET_CODE (op
) == CONST_INT
418 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
419 && (INTVAL (op
) & 7) == 0);
422 /* Return 1 if OP is the constant zero in floating-point. */
425 fp0_operand (op
, mode
)
427 enum machine_mode mode
;
429 return (GET_MODE (op
) == mode
430 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
433 /* Return 1 if OP is the floating-point constant zero or a register. */
436 reg_or_fp0_operand (op
, mode
)
438 enum machine_mode mode
;
440 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
443 /* Return 1 if OP is a register or a constant integer. */
447 reg_or_cint_operand (op
, mode
)
449 enum machine_mode mode
;
451 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
454 /* Return 1 if OP is something that can be reloaded into a register;
455 if it is a MEM, it need not be valid. */
458 some_operand (op
, mode
)
460 enum machine_mode mode
;
462 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
465 switch (GET_CODE (op
))
467 case REG
: case MEM
: case CONST_DOUBLE
:
468 case CONST_INT
: case LABEL_REF
: case SYMBOL_REF
: case CONST
:
472 return some_operand (SUBREG_REG (op
), VOIDmode
);
478 /* Return 1 if OP is a valid operand for the source of a move insn. */
481 input_operand (op
, mode
)
483 enum machine_mode mode
;
485 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
488 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
491 switch (GET_CODE (op
))
496 /* This handles both the Windows/NT and OSF cases. */
497 return mode
== ptr_mode
|| mode
== DImode
;
503 if (register_operand (op
, mode
))
505 /* ... fall through ... */
507 return ((TARGET_BWX
|| (mode
!= HImode
&& mode
!= QImode
))
508 && general_operand (op
, mode
));
511 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
514 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
520 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
524 current_file_function_operand (op
, mode
)
526 enum machine_mode mode
;
528 return (GET_CODE (op
) == SYMBOL_REF
529 && ! profile_flag
&& ! profile_block_flag
530 && (SYMBOL_REF_FLAG (op
)
531 || op
== XEXP (DECL_RTL (current_function_decl
), 0)));
534 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
537 call_operand (op
, mode
)
539 enum machine_mode mode
;
544 return (GET_CODE (op
) == SYMBOL_REF
545 || (GET_CODE (op
) == REG
546 && (TARGET_OPEN_VMS
|| TARGET_WINDOWS_NT
|| REGNO (op
) == 27)));
549 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
550 comparisons are valid in which insn. */
553 alpha_comparison_operator (op
, mode
)
555 enum machine_mode mode
;
557 enum rtx_code code
= GET_CODE (op
);
559 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
562 return (code
== EQ
|| code
== LE
|| code
== LT
563 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
566 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
569 alpha_swapped_comparison_operator (op
, mode
)
571 enum machine_mode mode
;
573 enum rtx_code code
= GET_CODE (op
);
575 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
578 code
= swap_condition (code
);
579 return (code
== EQ
|| code
== LE
|| code
== LT
580 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
583 /* Return 1 if OP is a signed comparison operation. */
586 signed_comparison_operator (op
, mode
)
588 enum machine_mode mode
;
590 switch (GET_CODE (op
))
592 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
599 /* Return 1 if this is a divide or modulus operator. */
602 divmod_operator (op
, mode
)
604 enum machine_mode mode
;
606 switch (GET_CODE (op
))
608 case DIV
: case MOD
: case UDIV
: case UMOD
:
615 /* Return 1 if this memory address is a known aligned register plus
616 a constant. It must be a valid address. This means that we can do
617 this as an aligned reference plus some offset.
619 Take into account what reload will do.
621 We could say that out-of-range stack slots are alignable, but that would
622 complicate get_aligned_mem and it isn't worth the trouble since few
623 functions have large stack space. */
626 aligned_memory_operand (op
, mode
)
628 enum machine_mode mode
;
630 if (GET_CODE (op
) == SUBREG
)
632 if (GET_MODE (op
) != mode
)
634 op
= SUBREG_REG (op
);
635 mode
= GET_MODE (op
);
638 if (reload_in_progress
&& GET_CODE (op
) == REG
639 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
640 op
= reg_equiv_mem
[REGNO (op
)];
642 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
643 || ! memory_address_p (mode
, XEXP (op
, 0)))
648 if (GET_CODE (op
) == PLUS
)
651 return (GET_CODE (op
) == REG
652 && REGNO_POINTER_ALIGN (REGNO (op
)) >= 4);
655 /* Similar, but return 1 if OP is a MEM which is not alignable. */
658 unaligned_memory_operand (op
, mode
)
660 enum machine_mode mode
;
662 if (GET_CODE (op
) == SUBREG
)
664 if (GET_MODE (op
) != mode
)
666 op
= SUBREG_REG (op
);
667 mode
= GET_MODE (op
);
670 if (reload_in_progress
&& GET_CODE (op
) == REG
671 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
672 op
= reg_equiv_mem
[REGNO (op
)];
674 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
)
679 if (! memory_address_p (mode
, op
))
682 if (GET_CODE (op
) == PLUS
)
685 return (GET_CODE (op
) != REG
686 || REGNO_POINTER_ALIGN (REGNO (op
)) < 4);
689 /* Return 1 if OP is either a register or an unaligned memory location. */
692 reg_or_unaligned_mem_operand (op
, mode
)
694 enum machine_mode mode
;
696 return register_operand (op
, mode
) || unaligned_memory_operand (op
, mode
);
699 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
702 any_memory_operand (op
, mode
)
704 enum machine_mode mode
;
706 return (GET_CODE (op
) == MEM
707 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
708 || (reload_in_progress
&& GET_CODE (op
) == REG
709 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
710 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
711 && GET_CODE (SUBREG_REG (op
)) == REG
712 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
715 /* REF is an alignable memory location. Place an aligned SImode
716 reference into *PALIGNED_MEM and the number of bits to shift into
720 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
722 rtx
*paligned_mem
, *pbitnum
;
725 HOST_WIDE_INT offset
= 0;
727 if (GET_CODE (ref
) == SUBREG
)
729 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
730 if (BYTES_BIG_ENDIAN
)
731 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
732 - MIN (UNITS_PER_WORD
,
733 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
734 ref
= SUBREG_REG (ref
);
737 if (GET_CODE (ref
) == REG
)
738 ref
= reg_equiv_mem
[REGNO (ref
)];
740 if (reload_in_progress
)
741 base
= find_replacement (&XEXP (ref
, 0));
743 base
= XEXP (ref
, 0);
745 if (GET_CODE (base
) == PLUS
)
746 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
748 *paligned_mem
= gen_rtx (MEM
, SImode
,
749 plus_constant (base
, offset
& ~3));
750 MEM_IN_STRUCT_P (*paligned_mem
) = MEM_IN_STRUCT_P (ref
);
751 MEM_VOLATILE_P (*paligned_mem
) = MEM_VOLATILE_P (ref
);
752 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
754 *pbitnum
= GEN_INT ((offset
& 3) * 8);
757 /* Similar, but just get the address. Handle the two reload cases.
758 Add EXTRA_OFFSET to the address we return. */
761 get_unaligned_address (ref
, extra_offset
)
766 HOST_WIDE_INT offset
= 0;
768 if (GET_CODE (ref
) == SUBREG
)
770 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
771 if (BYTES_BIG_ENDIAN
)
772 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
773 - MIN (UNITS_PER_WORD
,
774 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
775 ref
= SUBREG_REG (ref
);
778 if (GET_CODE (ref
) == REG
)
779 ref
= reg_equiv_mem
[REGNO (ref
)];
781 if (reload_in_progress
)
782 base
= find_replacement (&XEXP (ref
, 0));
784 base
= XEXP (ref
, 0);
786 if (GET_CODE (base
) == PLUS
)
787 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
789 return plus_constant (base
, offset
+ extra_offset
);
792 /* Subfunction of the following function. Update the flags of any MEM
793 found in part of X. */
796 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
798 int in_struct_p
, volatile_p
, unchanging_p
;
802 switch (GET_CODE (x
))
806 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
807 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
812 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
817 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
819 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
824 MEM_IN_STRUCT_P (x
) = in_struct_p
;
825 MEM_VOLATILE_P (x
) = volatile_p
;
826 RTX_UNCHANGING_P (x
) = unchanging_p
;
831 /* Given INSN, which is either an INSN or a SEQUENCE generated to
832 perform a memory operation, look for any MEMs in either a SET_DEST or
833 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
834 REF into each of the MEMs found. If REF is not a MEM, don't do
838 alpha_set_memflags (insn
, ref
)
842 /* Note that it is always safe to get these flags, though they won't
843 be what we think if REF is not a MEM. */
844 int in_struct_p
= MEM_IN_STRUCT_P (ref
);
845 int volatile_p
= MEM_VOLATILE_P (ref
);
846 int unchanging_p
= RTX_UNCHANGING_P (ref
);
848 if (GET_CODE (ref
) != MEM
849 || (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
))
852 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
855 /* Try to output insns to set TARGET equal to the constant C if it can be
856 done in less than N insns. Do all computations in MODE. Returns the place
857 where the output has been placed if it can be done and the insns have been
858 emitted. If it would take more than N insns, zero is returned and no
859 insns and emitted. */
862 alpha_emit_set_const (target
, mode
, c
, n
)
864 enum machine_mode mode
;
871 /* Try 1 insn, then 2, then up to N. */
872 for (i
= 1; i
<= n
; i
++)
873 if ((pat
= alpha_emit_set_const_1 (target
, mode
, c
, i
)) != 0)
879 /* Internal routine for the above to check for N or below insns. */
882 alpha_emit_set_const_1 (target
, mode
, c
, n
)
884 enum machine_mode mode
;
888 HOST_WIDE_INT
new = c
;
890 /* Use a pseudo if highly optimizing and still generating RTL. */
892 = (flag_expensive_optimizations
&& rtx_equal_function_value_matters
896 #if HOST_BITS_PER_WIDE_INT == 64
897 /* We are only called for SImode and DImode. If this is SImode, ensure that
898 we are sign extended to a full word. This does not make any sense when
899 cross-compiling on a narrow machine. */
902 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
905 /* If this is a sign-extended 32-bit constant, we can do this in at most
906 three insns, so do it if we have enough insns left. We always have
907 a sign-extended 32-bit constant when compiling on a narrow machine. */
909 if (HOST_BITS_PER_WIDE_INT
!= 64
910 || c
>> 31 == -1 || c
>> 31 == 0)
912 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
913 HOST_WIDE_INT tmp1
= c
- low
;
915 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
916 HOST_WIDE_INT extra
= 0;
918 /* If HIGH will be interpreted as negative but the constant is
919 positive, we must adjust it to do two ldha insns. */
921 if ((high
& 0x8000) != 0 && c
>= 0)
925 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
928 if (c
== low
|| (low
== 0 && extra
== 0))
930 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
931 but that meant that we can't handle INT_MIN on 32-bit machines
932 (like NT/Alpha), because we recurse indefinitely through
933 emit_move_insn to gen_movdi. So instead, since we know exactly
934 what we want, create it explicitly. */
937 target
= gen_reg_rtx (mode
);
938 emit_insn (gen_rtx (SET
, VOIDmode
, target
, GEN_INT (c
)));
941 else if (n
>= 2 + (extra
!= 0))
943 temp
= copy_to_suggested_reg (GEN_INT (low
), subtarget
, mode
);
946 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (extra
<< 16),
947 subtarget
, 0, OPTAB_WIDEN
);
949 return expand_binop (mode
, add_optab
, temp
, GEN_INT (high
<< 16),
950 target
, 0, OPTAB_WIDEN
);
954 /* If we couldn't do it that way, try some other methods. But if we have
955 no instructions left, don't bother. Likewise, if this is SImode and
956 we can't make pseudos, we can't do anything since the expand_binop
957 and expand_unop calls will widen and try to make pseudos. */
960 || (mode
== SImode
&& ! rtx_equal_function_value_matters
))
963 #if HOST_BITS_PER_WIDE_INT == 64
964 /* First, see if can load a value into the target that is the same as the
965 constant except that all bytes that are 0 are changed to be 0xff. If we
966 can, then we can do a ZAPNOT to obtain the desired constant. */
968 for (i
= 0; i
< 64; i
+= 8)
969 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
970 new |= (HOST_WIDE_INT
) 0xff << i
;
972 /* We are only called for SImode and DImode. If this is SImode, ensure that
973 we are sign extended to a full word. */
976 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
979 && (temp
= alpha_emit_set_const (subtarget
, mode
, new, n
- 1)) != 0)
980 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new),
981 target
, 0, OPTAB_WIDEN
);
984 /* Next, see if we can load a related constant and then shift and possibly
985 negate it to get the constant we want. Try this once each increasing
988 for (i
= 1; i
< n
; i
++)
990 /* First try complementing. */
991 if ((temp
= alpha_emit_set_const (subtarget
, mode
, ~ c
, i
)) != 0)
992 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
994 /* Next try to form a constant and do a left shift. We can do this
995 if some low-order bits are zero; the exact_log2 call below tells
996 us that information. The bits we are shifting out could be any
997 value, but here we'll just try the 0- and sign-extended forms of
998 the constant. To try to increase the chance of having the same
999 constant in more than one insn, start at the highest number of
1000 bits to shift, but try all possibilities in case a ZAPNOT will
1003 if ((bits
= exact_log2 (c
& - c
)) > 0)
1004 for (; bits
> 0; bits
--)
1005 if ((temp
= (alpha_emit_set_const
1007 (unsigned HOST_WIDE_INT
) c
>> bits
, i
))) != 0
1008 || ((temp
= (alpha_emit_set_const
1010 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
1012 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
1013 target
, 0, OPTAB_WIDEN
);
1015 /* Now try high-order zero bits. Here we try the shifted-in bits as
1016 all zero and all ones. Be careful to avoid shifting outside the
1017 mode and to avoid shifting outside the host wide int size. */
1018 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1019 confuse the recursive call and set all of the high 32 bits. */
1021 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1022 - floor_log2 (c
) - 1 - (HOST_BITS_PER_WIDE_INT
< 64))) > 0)
1023 for (; bits
> 0; bits
--)
1024 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1026 || ((temp
= (alpha_emit_set_const
1028 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1031 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
1032 target
, 1, OPTAB_WIDEN
);
1034 /* Now try high-order 1 bits. We get that with a sign-extension.
1035 But one bit isn't enough here. Be careful to avoid shifting outside
1036 the mode and to avoid shifting outside the host wide int size. */
1038 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1039 - floor_log2 (~ c
) - 2)) > 0)
1040 for (; bits
> 0; bits
--)
1041 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1043 || ((temp
= (alpha_emit_set_const
1045 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1048 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
1049 target
, 0, OPTAB_WIDEN
);
1055 #if HOST_BITS_PER_WIDE_INT == 64
1056 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1057 fall back to a straight forward decomposition. We do this to avoid
1058 exponential run times encountered when looking for longer sequences
1059 with alpha_emit_set_const. */
1062 alpha_emit_set_long_const (target
, c
)
1066 /* Use a pseudo if highly optimizing and still generating RTL. */
1068 = (flag_expensive_optimizations
&& rtx_equal_function_value_matters
1070 HOST_WIDE_INT d1
, d2
, d3
, d4
;
1073 /* Decompose the entire word */
1074 d1
= ((c
& 0xffff) ^ 0x8000) - 0x8000;
1076 d2
= ((c
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1078 d3
= ((c
& 0xffff) ^ 0x8000) - 0x8000;
1080 d4
= ((c
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1085 /* Construct the high word */
1087 r1
= copy_to_suggested_reg (GEN_INT (d4
), subtarget
, DImode
);
1089 r1
= copy_to_suggested_reg (GEN_INT (d3
), subtarget
, DImode
);
1091 r1
= expand_binop (DImode
, add_optab
, GEN_INT (d3
), GEN_INT (d4
),
1092 subtarget
, 0, OPTAB_WIDEN
);
1094 /* Shift it into place */
1095 r2
= expand_binop (DImode
, ashl_optab
, r1
, GEN_INT (32),
1096 subtarget
, 0, OPTAB_WIDEN
);
1098 if (subtarget
== 0 && d1
== d3
&& d2
== d4
)
1099 r1
= expand_binop (DImode
, add_optab
, r1
, r2
, subtarget
, 0, OPTAB_WIDEN
);
1104 /* Add in the low word */
1106 r1
= expand_binop (DImode
, add_optab
, r1
, GEN_INT (d2
),
1107 subtarget
, 0, OPTAB_WIDEN
);
1109 r1
= expand_binop (DImode
, add_optab
, r1
, GEN_INT (d1
),
1110 subtarget
, 0, OPTAB_WIDEN
);
1114 r1
= copy_to_suggested_reg(r1
, target
, DImode
);
1118 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1120 /* Rewrite a comparison against zero CMP of the form
1121 (CODE (cc0) (const_int 0)) so it can be written validly in
1122 a conditional move (if_then_else CMP ...).
1123 If both of the operands that set cc0 are non-zero we must emit
1124 an insn to perform the compare (it can't be done within
1125 the conditional move). */
1127 alpha_emit_conditional_move (cmp
, mode
)
1129 enum machine_mode mode
;
1131 enum rtx_code code
= GET_CODE (cmp
);
1132 enum rtx_code cmov_code
= NE
;
1133 rtx op0
= alpha_compare_op0
;
1134 rtx op1
= alpha_compare_op1
;
1135 enum machine_mode cmp_mode
1136 = (GET_MODE (op0
) == VOIDmode
? DImode
: GET_MODE (op0
));
1137 enum machine_mode cmp_op_mode
= alpha_compare_fp_p
? DFmode
: DImode
;
1140 if (alpha_compare_fp_p
!= FLOAT_MODE_P (mode
))
1143 /* We may be able to use a conditional move directly.
1144 This avoids emitting spurious compares. */
1145 if (signed_comparison_operator (cmp
, cmp_op_mode
)
1146 && (op0
== CONST0_RTX (cmp_mode
) || op1
== CONST0_RTX (cmp_mode
)))
1147 return gen_rtx (code
, VOIDmode
, op0
, op1
);
1149 /* We can't put the comparison insides a conditional move;
1150 emit a compare instruction and put that inside the
1151 conditional move. Make sure we emit only comparisons we have;
1152 swap or reverse as necessary. */
1156 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
1157 /* We have these compares: */
1161 /* This must be reversed. */
1162 code
= reverse_condition (code
);
1166 case GE
: case GT
: case GEU
: case GTU
:
1167 /* These must be swapped. Make sure the new first operand is in
1169 code
= swap_condition (code
);
1170 tem
= op0
, op0
= op1
, op1
= tem
;
1171 op0
= force_reg (cmp_mode
, op0
);
1178 tem
= gen_reg_rtx (cmp_op_mode
);
1179 emit_move_insn (tem
, gen_rtx (code
, cmp_op_mode
, op0
, op1
));
1180 return gen_rtx (cmov_code
, VOIDmode
, tem
, CONST0_RTX (cmp_op_mode
));
1183 /* Adjust the cost of a scheduling dependency. Return the new cost of
1184 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
1187 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
1195 /* If the dependence is an anti-dependence, there is no cost. For an
1196 output dependence, there is sometimes a cost, but it doesn't seem
1197 worth handling those few cases. */
1199 if (REG_NOTE_KIND (link
) != 0)
1202 if (alpha_cpu
== PROCESSOR_EV5
)
1204 /* And the lord DEC saith: "A special bypass provides an effective
1205 latency of 0 cycles for an ICMP or ILOG insn producing the test
1206 operand of an IBR or CMOV insn." */
1207 if (recog_memoized (dep_insn
) >= 0
1208 && (get_attr_type (dep_insn
) == TYPE_ICMP
1209 || get_attr_type (dep_insn
) == TYPE_ILOG
)
1210 && recog_memoized (insn
) >= 0
1211 && (get_attr_type (insn
) == TYPE_IBR
1212 || (get_attr_type (insn
) == TYPE_CMOV
1213 && !((set
= single_set (dep_insn
)) != 0
1214 && GET_CODE (PATTERN (insn
)) == SET
1215 && (set_src
= SET_SRC (PATTERN (insn
)),
1216 GET_CODE (set_src
) == IF_THEN_ELSE
)
1217 && (set
= SET_DEST (set
),
1218 rtx_equal_p (set
, XEXP (set_src
, 1))
1219 || rtx_equal_p (set
, XEXP (set_src
, 2)))))))
1222 /* On EV5 it takes longer to get data to the multiplier than to
1223 anywhere else, so increase costs. */
1225 if (recog_memoized (insn
) >= 0
1226 && recog_memoized (dep_insn
) >= 0
1227 && (get_attr_type (insn
) == TYPE_IMULL
1228 || get_attr_type (insn
) == TYPE_IMULQ
1229 || get_attr_type (insn
) == TYPE_IMULH
)
1230 && (set
= single_set (dep_insn
)) != 0
1231 && GET_CODE (PATTERN (insn
)) == SET
1232 && (set_src
= SET_SRC (PATTERN (insn
)),
1233 GET_CODE (set_src
) == MULT
)
1234 && (set
= SET_DEST (set
),
1235 rtx_equal_p (set
, XEXP (set_src
, 0))
1236 || rtx_equal_p (set
, XEXP (set_src
, 1))))
1238 switch (get_attr_type (insn
))
1257 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
1258 being stored, we can sometimes lower the cost. */
1260 if (recog_memoized (insn
) >= 0 && get_attr_type (insn
) == TYPE_ST
1261 && (set
= single_set (dep_insn
)) != 0
1262 && GET_CODE (PATTERN (insn
)) == SET
1263 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
1265 switch (get_attr_type (dep_insn
))
1268 /* No savings here. */
1274 /* In these cases, we save one cycle. */
1278 /* In all other cases, we save two cycles. */
1279 return MAX (0, cost
- 2);
1283 /* Another case that needs adjustment is an arithmetic or logical
1284 operation. It's cost is usually one cycle, but we default it to
1285 two in the MD file. The only case that it is actually two is
1286 for the address in loads and stores. */
1288 if (recog_memoized (dep_insn
) >= 0
1289 && (get_attr_type (dep_insn
) == TYPE_IADD
1290 || get_attr_type (dep_insn
) == TYPE_ILOG
))
1292 switch (get_attr_type (insn
))
1302 /* The final case is when a compare feeds into an integer branch;
1303 the cost is only one cycle in that case. */
1305 if (recog_memoized (dep_insn
) >= 0
1306 && get_attr_type (dep_insn
) == TYPE_ICMP
1307 && recog_memoized (insn
) >= 0
1308 && get_attr_type (insn
) == TYPE_IBR
)
1312 /* Otherwise, return the default cost. */
1316 /* Functions to save and restore alpha_return_addr_rtx. */
1318 struct machine_function
1324 alpha_save_machine_status (p
)
1327 struct machine_function
*machine
=
1328 (struct machine_function
*) xmalloc (sizeof (struct machine_function
));
1330 p
->machine
= machine
;
1331 machine
->ra_rtx
= alpha_return_addr_rtx
;
1335 alpha_restore_machine_status (p
)
1338 struct machine_function
*machine
= p
->machine
;
1340 alpha_return_addr_rtx
= machine
->ra_rtx
;
1343 p
->machine
= (struct machine_function
*)0;
1346 /* Do anything needed before RTL is emitted for each function. */
1349 alpha_init_expanders ()
1351 alpha_return_addr_rtx
= NULL_RTX
;
1353 /* Arrange to save and restore machine status around nested functions. */
1354 save_machine_status
= alpha_save_machine_status
;
1355 restore_machine_status
= alpha_restore_machine_status
;
1358 /* Start the ball rolling with RETURN_ADDR_RTX. */
1361 alpha_return_addr (count
, frame
)
1370 if (alpha_return_addr_rtx
)
1371 return alpha_return_addr_rtx
;
1373 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
1374 alpha_return_addr_rtx
= gen_reg_rtx (Pmode
);
1375 init
= gen_rtx (SET
, Pmode
, alpha_return_addr_rtx
, gen_rtx (REG
, Pmode
, 26));
1377 /* Emit the insn to the prologue with the other argument copies. */
1378 push_topmost_sequence ();
1379 emit_insn_after (init
, get_insns ());
1380 pop_topmost_sequence ();
1382 return alpha_return_addr_rtx
;
1386 alpha_ra_ever_killed ()
1390 if (!alpha_return_addr_rtx
)
1391 return regs_ever_live
[REG_RA
];
1393 return reg_set_between_p (gen_rtx (REG
, REG_RA
), get_insns(), NULL_RTX
);
1397 /* Print an operand. Recognize special options, documented below. */
1400 print_operand (file
, x
, code
)
1410 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1411 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1412 mode. alpha_fprm controls which suffix is generated. */
1415 case ALPHA_FPRM_NORM
:
1417 case ALPHA_FPRM_MINF
:
1420 case ALPHA_FPRM_CHOP
:
1423 case ALPHA_FPRM_DYN
:
1430 /* Generates trap-mode suffix for instructions that accept the su
1431 suffix only (cmpt et al). */
1432 if (alpha_tp
== ALPHA_TP_INSN
)
1437 /* Generates trap-mode suffix for instructions that accept the u, su,
1438 and sui suffix. This is the bulk of the IEEE floating point
1439 instructions (addt et al). */
1450 case ALPHA_FPTM_SUI
:
1451 fputs ("sui", file
);
1457 /* Generates trap-mode suffix for instructions that accept the sui
1458 suffix (cvtqt and cvtqs). */
1461 case ALPHA_FPTM_N
: case ALPHA_FPTM_U
:
1462 case ALPHA_FPTM_SU
: /* cvtqt/cvtqs can't cause underflow */
1464 case ALPHA_FPTM_SUI
:
1465 fputs ("sui", file
);
1471 /* Generates single precision instruction suffix. */
1472 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'f' : 's'));
1476 /* Generates double precision instruction suffix. */
1477 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'g' : 't'));
1481 /* If this operand is the constant zero, write it as "$31". */
1482 if (GET_CODE (x
) == REG
)
1483 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1484 else if (x
== CONST0_RTX (GET_MODE (x
)))
1485 fprintf (file
, "$31");
1487 output_operand_lossage ("invalid %%r value");
1492 /* Similar, but for floating-point. */
1493 if (GET_CODE (x
) == REG
)
1494 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1495 else if (x
== CONST0_RTX (GET_MODE (x
)))
1496 fprintf (file
, "$f31");
1498 output_operand_lossage ("invalid %%R value");
1503 /* Write the 1's complement of a constant. */
1504 if (GET_CODE (x
) != CONST_INT
)
1505 output_operand_lossage ("invalid %%N value");
1507 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INTVAL (x
));
1511 /* Write 1 << C, for a constant C. */
1512 if (GET_CODE (x
) != CONST_INT
)
1513 output_operand_lossage ("invalid %%P value");
1515 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
) 1 << INTVAL (x
));
1519 /* Write the high-order 16 bits of a constant, sign-extended. */
1520 if (GET_CODE (x
) != CONST_INT
)
1521 output_operand_lossage ("invalid %%h value");
1523 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) >> 16);
1527 /* Write the low-order 16 bits of a constant, sign-extended. */
1528 if (GET_CODE (x
) != CONST_INT
)
1529 output_operand_lossage ("invalid %%L value");
1531 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
1532 (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
1536 /* Write mask for ZAP insn. */
1537 if (GET_CODE (x
) == CONST_DOUBLE
)
1539 HOST_WIDE_INT mask
= 0;
1540 HOST_WIDE_INT value
;
1542 value
= CONST_DOUBLE_LOW (x
);
1543 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
1548 value
= CONST_DOUBLE_HIGH (x
);
1549 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
1552 mask
|= (1 << (i
+ sizeof (int)));
1554 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
& 0xff);
1557 else if (GET_CODE (x
) == CONST_INT
)
1559 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
1561 for (i
= 0; i
< 8; i
++, value
>>= 8)
1565 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
1568 output_operand_lossage ("invalid %%m value");
1572 /* 'b', 'w', or 'l' as the value of the constant. */
1573 if (GET_CODE (x
) != CONST_INT
1574 || (INTVAL (x
) != 8 && INTVAL (x
) != 16 && INTVAL (x
) != 32))
1575 output_operand_lossage ("invalid %%M value");
1577 fprintf (file
, "%s",
1578 INTVAL (x
) == 8 ? "b" : INTVAL (x
) == 16 ? "w" : "l");
1582 /* Similar, except do it from the mask. */
1583 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
1584 fprintf (file
, "b");
1585 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
1586 fprintf (file
, "w");
1587 #if HOST_BITS_PER_WIDE_INT == 32
1588 else if (GET_CODE (x
) == CONST_DOUBLE
1589 && CONST_DOUBLE_HIGH (x
) == 0
1590 && CONST_DOUBLE_LOW (x
) == -1)
1591 fprintf (file
, "l");
1593 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
1594 fprintf (file
, "l");
1597 output_operand_lossage ("invalid %%U value");
1601 /* Write the constant value divided by 8. */
1602 if (GET_CODE (x
) != CONST_INT
1603 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
1604 && (INTVAL (x
) & 7) != 8)
1605 output_operand_lossage ("invalid %%s value");
1607 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) / 8);
1611 /* Same, except compute (64 - c) / 8 */
1613 if (GET_CODE (x
) != CONST_INT
1614 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
1615 && (INTVAL (x
) & 7) != 8)
1616 output_operand_lossage ("invalid %%s value");
1618 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (64 - INTVAL (x
)) / 8);
1621 case 'C': case 'D': case 'c': case 'd':
1622 /* Write out comparison name. */
1624 enum rtx_code c
= GET_CODE (x
);
1626 if (GET_RTX_CLASS (c
) != '<')
1627 output_operand_lossage ("invalid %%C value");
1630 c
= reverse_condition (c
);
1631 else if (code
== 'c')
1632 c
= swap_condition (c
);
1633 else if (code
== 'd')
1634 c
= swap_condition (reverse_condition (c
));
1637 fprintf (file
, "ule");
1639 fprintf (file
, "ult");
1641 fprintf (file
, "%s", GET_RTX_NAME (c
));
1646 /* Write the divide or modulus operator. */
1647 switch (GET_CODE (x
))
1650 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
1653 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
1656 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
1659 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
1662 output_operand_lossage ("invalid %%E value");
1668 /* Write "_u" for unaligned access. */
1669 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
1670 fprintf (file
, "_u");
1674 if (GET_CODE (x
) == REG
)
1675 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1676 else if (GET_CODE (x
) == MEM
)
1677 output_address (XEXP (x
, 0));
1679 output_addr_const (file
, x
);
1683 output_operand_lossage ("invalid %%xn code");
1687 /* Do what is necessary for `va_start'. The argument is ignored;
1688 We look at the current function to determine if stdarg or varargs
1689 is used and fill in an initial va_list. A pointer to this constructor
1693 alpha_builtin_saveregs (arglist
)
1696 rtx block
, addr
, dest
, argsize
;
1697 tree fntype
= TREE_TYPE (current_function_decl
);
1698 int stdarg
= (TYPE_ARG_TYPES (fntype
) != 0
1699 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
1700 != void_type_node
));
1702 /* Compute the current position into the args, taking into account
1703 both registers and memory. Both of these are already included in
1706 argsize
= GEN_INT (NUM_ARGS
* UNITS_PER_WORD
);
1708 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1709 storing fp arg registers in the first 48 bytes, and the integer arg
1710 registers in the next 48 bytes. This is only done, however, if any
1711 integer registers need to be stored.
1713 If no integer registers need be stored, then we must subtract 48 in
1714 order to account for the integer arg registers which are counted in
1715 argsize above, but which are not actually stored on the stack. */
1717 if (TARGET_OPEN_VMS
)
1718 addr
= plus_constant (virtual_incoming_args_rtx
,
1719 NUM_ARGS
<= 5 + stdarg
1720 ? UNITS_PER_WORD
: - 6 * UNITS_PER_WORD
);
1722 addr
= (NUM_ARGS
<= 5 + stdarg
1723 ? plus_constant (virtual_incoming_args_rtx
,
1725 : plus_constant (virtual_incoming_args_rtx
,
1726 - (6 * UNITS_PER_WORD
)));
1728 /* For VMS, we include the argsize, while on Unix, it's handled as
1729 a separate field. */
1730 if (TARGET_OPEN_VMS
)
1731 addr
= plus_constant (addr
, INTVAL (argsize
));
1733 addr
= force_operand (addr
, NULL_RTX
);
1735 #ifdef POINTERS_EXTEND_UNSIGNED
1736 addr
= convert_memory_address (ptr_mode
, addr
);
1739 if (TARGET_OPEN_VMS
)
1743 /* Allocate the va_list constructor */
1744 block
= assign_stack_local (BLKmode
, 2 * UNITS_PER_WORD
, BITS_PER_WORD
);
1745 RTX_UNCHANGING_P (block
) = 1;
1746 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
1748 /* Store the address of the first integer register in the __base
1751 dest
= change_address (block
, ptr_mode
, XEXP (block
, 0));
1752 emit_move_insn (dest
, addr
);
1754 if (flag_check_memory_usage
)
1755 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
1757 GEN_INT (GET_MODE_SIZE (ptr_mode
)),
1758 TYPE_MODE (sizetype
),
1759 GEN_INT (MEMORY_USE_RW
),
1760 TYPE_MODE (integer_type_node
));
1762 /* Store the argsize as the __va_offset member. */
1763 dest
= change_address (block
, TYPE_MODE (integer_type_node
),
1764 plus_constant (XEXP (block
, 0),
1765 POINTER_SIZE
/BITS_PER_UNIT
));
1766 emit_move_insn (dest
, argsize
);
1768 if (flag_check_memory_usage
)
1769 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
1771 GEN_INT (GET_MODE_SIZE
1772 (TYPE_MODE (integer_type_node
))),
1773 TYPE_MODE (sizetype
),
1774 GEN_INT (MEMORY_USE_RW
),
1775 TYPE_MODE (integer_type_node
));
1777 /* Return the address of the va_list constructor, but don't put it in a
1778 register. Doing so would fail when not optimizing and produce worse
1779 code when optimizing. */
1780 return XEXP (block
, 0);
1791 /* Find the current function's return address.
1793 ??? It would be better to arrange things such that if we would ordinarily
1794 have been a leaf function and we didn't spill the hard reg that we
1795 wouldn't have to save the register in the prolog. But it's not clear
1796 how to get the right information at the right time. */
1798 static rtx alpha_return_addr_rtx
;
1801 alpha_return_addr ()
1805 if ((ret
= alpha_return_addr_rtx
) == NULL
)
1807 alpha_return_addr_rtx
= ret
= gen_reg_rtx (Pmode
);
1809 emit_insn_after (gen_rtx (SET
, VOIDmode
, ret
,
1810 gen_rtx (REG
, Pmode
, REG_RA
)),
1817 /* This page contains routines that are used to determine what the function
1818 prologue and epilogue code will do and write them out. */
1820 /* Compute the size of the save area in the stack. */
1824 /* These variables are used for communication between the following functions.
1825 They indicate various things about the current function being compiled
1826 that are used to tell what kind of prologue, epilogue and procedure
1827 descriptior to generate. */
1829 /* Nonzero if we need a stack procedure. */
1830 static int is_stack_procedure
;
1832 /* Register number (either FP or SP) that is used to unwind the frame. */
1833 static int unwind_regno
;
1835 /* Register number used to save FP. We need not have one for RA since
1836 we don't modify it for register procedures. This is only defined
1837 for register frame procedures. */
1838 static int save_fp_regno
;
1840 /* Register number used to reference objects off our PV. */
1841 static int base_regno
;
1843 /* Compute register masks for saved registers. */
1846 alpha_sa_mask (imaskP
, fmaskP
)
1847 unsigned long *imaskP
;
1848 unsigned long *fmaskP
;
1850 unsigned long imask
= 0;
1851 unsigned long fmask
= 0;
1854 if (is_stack_procedure
)
1855 imask
|= (1L << HARD_FRAME_POINTER_REGNUM
);
1857 /* One for every register we have to save. */
1859 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1860 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
1861 && regs_ever_live
[i
] && i
!= REG_RA
)
1866 fmask
|= (1L << (i
- 32));
1879 HOST_WIDE_INT stack_needed
;
1882 /* One for every register we have to save. */
1884 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1885 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
1886 && regs_ever_live
[i
] && i
!= REG_RA
)
1889 /* Start by assuming we can use a register procedure if we don't make any
1890 calls (REG_RA not used) or need to save any registers and a stack
1891 procedure if we do. */
1892 is_stack_procedure
= sa_size
!= 0 || alpha_ra_ever_killed ();
1894 /* Decide whether to refer to objects off our PV via FP or PV.
1895 If we need need FP for something else or if we receive a nonlocal
1896 goto (which expects PV to contain the value), we must use PV.
1897 Otherwise, start by assuming we can use FP. */
1898 base_regno
= (frame_pointer_needed
|| current_function_has_nonlocal_label
1899 || is_stack_procedure
1900 || current_function_outgoing_args_size
1901 ? REG_PV
: HARD_FRAME_POINTER_REGNUM
);
1903 /* If we want to copy PV into FP, we need to find some register in which to
1908 if (base_regno
== HARD_FRAME_POINTER_REGNUM
)
1909 for (i
= 0; i
< 32; i
++)
1910 if (! fixed_regs
[i
] && call_used_regs
[i
] && ! regs_ever_live
[i
])
1913 if (save_fp_regno
== -1)
1914 base_regno
= REG_PV
, is_stack_procedure
= 1;
1916 /* Stack unwinding should be done via FP unless we use it for PV. */
1918 = base_regno
== REG_PV
? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
;
1920 /* If this is a stack procedure, allow space for saving FP and RA. */
1921 if (is_stack_procedure
)
1928 alpha_pv_save_size ()
1931 return is_stack_procedure
? 8 : 0;
1938 return unwind_regno
== HARD_FRAME_POINTER_REGNUM
;
1941 #else /* ! OPEN_VMS */
1949 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1950 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
1951 && regs_ever_live
[i
] && i
!= REG_RA
)
1954 /* If some registers were saved but not reg 26, reg 26 must also
1955 be saved, so leave space for it. */
1956 if (size
!= 0 || alpha_ra_ever_killed ())
1959 /* Our size must be even (multiple of 16 bytes). */
1966 #endif /* ! OPEN_VMS */
1968 /* Return 1 if this function can directly return via $26. */
1973 return (! TARGET_OPEN_VMS
&& reload_completed
&& alpha_sa_size () == 0
1974 && get_frame_size () == 0
1975 && current_function_outgoing_args_size
== 0
1976 && current_function_pretend_args_size
== 0);
1979 /* Write a version stamp. Don't write anything if we are running as a
1980 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1982 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__) && !defined(VMS)
1987 alpha_write_verstamp (file
)
1991 fprintf (file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
1995 /* Write code to add constant C to register number IN_REG (possibly 31)
1996 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
1997 usually this will be OUT_REG, but should not be if OUT_REG is
1998 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1999 Write the code to FILE. */
2002 add_long_const (file
, c
, in_reg
, out_reg
, temp_reg
)
2005 int in_reg
, out_reg
, temp_reg
;
2007 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
2008 HOST_WIDE_INT tmp1
= c
- low
;
2009 HOST_WIDE_INT high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
2010 HOST_WIDE_INT extra
= 0;
2012 /* We don't have code to write out constants larger than 32 bits. */
2013 #if HOST_BITS_PER_LONG_INT == 64
2014 if ((unsigned HOST_WIDE_INT
) c
>> 32 != 0)
2018 /* If HIGH will be interpreted as negative, we must adjust it to do two
2019 ldha insns. Note that we will never be building a negative constant
2026 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
2031 int result_reg
= (extra
== 0 && high
== 0) ? out_reg
: temp_reg
;
2033 if (low
>= 0 && low
< 255)
2034 fprintf (file
, "\taddq $%d,%d,$%d\n", in_reg
, low
, result_reg
);
2036 fprintf (file
, "\tlda $%d,%d($%d)\n", result_reg
, low
, in_reg
);
2038 in_reg
= result_reg
;
2043 int result_reg
= (high
== 0) ? out_reg
: temp_reg
;
2045 fprintf (file
, "\tldah $%d,%d($%d)\n", result_reg
, extra
, in_reg
);
2046 in_reg
= result_reg
;
2050 fprintf (file
, "\tldah $%d,%d($%d)\n", out_reg
, high
, in_reg
);
2053 /* Write function prologue. */
2057 /* On vms we have two kinds of functions:
2059 - stack frame (PROC_STACK)
2060 these are 'normal' functions with local vars and which are
2061 calling other functions
2062 - register frame (PROC_REGISTER)
2063 keeps all data in registers, needs no stack
2065 We must pass this to the assembler so it can generate the
2066 proper pdsc (procedure descriptor)
2067 This is done with the '.pdesc' command.
2069 size is the stack size needed for local variables. */
2072 output_prolog (file
, size
)
2076 unsigned long imask
= 0;
2077 unsigned long fmask
= 0;
2078 /* Stack space needed for pushing registers clobbered by us. */
2079 HOST_WIDE_INT sa_size
;
2080 /* Complete stack size needed. */
2081 HOST_WIDE_INT frame_size
;
2082 /* Offset from base reg to register save area. */
2084 /* Offset during register save. */
2086 /* Label for the procedure entry. */
2087 char *entry_label
= (char *) alloca (strlen (alpha_function_name
) + 6);
2090 sa_size
= alpha_sa_size ();
2092 = ALPHA_ROUND (sa_size
2093 + (is_stack_procedure
? 8 : 0)
2094 + size
+ current_function_pretend_args_size
);
2096 /* Issue function start and label. */
2097 fprintf (file
, "\t.ent ");
2098 assemble_name (file
, alpha_function_name
);
2099 fprintf (file
, "\n");
2100 sprintf (entry_label
, "$%s..en", alpha_function_name
);
2101 ASM_OUTPUT_LABEL (file
, entry_label
);
2102 inside_function
= TRUE
;
2104 fprintf (file
, "\t.base $%d\n", base_regno
);
2106 /* Calculate register masks for clobbered registers. */
2108 if (is_stack_procedure
)
2109 alpha_sa_mask (&imask
, &fmask
);
2111 /* Adjust the stack by the frame size. If the frame size is > 4096
2112 bytes, we need to be sure we probe somewhere in the first and last
2113 4096 bytes (we can probably get away without the latter test) and
2114 every 8192 bytes in between. If the frame size is > 32768, we
2115 do this in a loop. Otherwise, we generate the explicit probe
2118 Note that we are only allowed to adjust sp once in the prologue. */
2120 if (frame_size
< 32768)
2122 if (frame_size
> 4096)
2126 fprintf (file
, "\tstq $31,-%d($30)\n", probed
);
2128 while (probed
+ 8192 < frame_size
)
2129 fprintf (file
, "\tstq $31,-%d($30)\n", probed
+= 8192);
2131 /* We only have to do this probe if we aren't saving registers. */
2132 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
2133 fprintf (file
, "\tstq $31,-%d($30)\n", frame_size
);
2136 if (frame_size
!= 0)
2137 fprintf (file
, "\tlda $30,-%d($30)\n", frame_size
);
2141 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
2142 number of 8192 byte blocks to probe. We then probe each block
2143 in the loop and then set SP to the proper location. If the
2144 amount remaining is > 4096, we have to do one more probe if we
2145 are not saving any registers. */
2147 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
2148 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
2150 add_long_const (file
, blocks
, 31, 23, 23);
2152 fprintf (file
, "\tlda $22,4096($30)\n");
2155 assemble_name (file
, alpha_function_name
);
2156 fprintf (file
, "..sc:\n");
2158 fprintf (file
, "\tstq $31,-8192($22)\n");
2159 fprintf (file
, "\tsubq $23,1,$23\n");
2160 fprintf (file
, "\tlda $22,-8192($22)\n");
2162 fprintf (file
, "\tbne $23,$");
2163 assemble_name (file
, alpha_function_name
);
2164 fprintf (file
, "..sc\n");
2166 if (leftover
> 4096 && sa_size
== 0)
2167 fprintf (file
, "\tstq $31,-%d($22)\n", leftover
);
2169 fprintf (file
, "\tlda $30,-%d($22)\n", leftover
);
2172 if (is_stack_procedure
)
2174 int reg_offset
= rsa_offset
;
2176 /* Store R26 (RA) first. */
2177 fprintf (file
, "\tstq $26,%d($30)\n", reg_offset
);
2180 /* Store integer regs. according to mask. */
2181 for (i
= 0; i
< 32; i
++)
2182 if (imask
& (1L<<i
))
2184 fprintf (file
, "\tstq $%d,%d($30)\n", i
, reg_offset
);
2188 /* Print the register mask and do floating-point saves. */
2191 fprintf (file
, "\t.mask 0x%x,0\n", imask
);
2193 for (i
= 0; i
< 32; i
++)
2195 if (fmask
& (1L << i
))
2197 fprintf (file
, "\tstt $f%d,%d($30)\n", i
, reg_offset
);
2202 /* Print the floating-point mask, if we've saved any fp register. */
2204 fprintf (file
, "\t.fmask 0x%x,0\n", fmask
);
2206 fprintf (file
, "\tstq $27,0($30)\n");
2210 fprintf (file
, "\t.fp_save $%d\n", save_fp_regno
);
2211 fprintf (file
, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM
,
2212 HARD_FRAME_POINTER_REGNUM
, save_fp_regno
);
2215 if (base_regno
!= REG_PV
)
2216 fprintf (file
, "\tbis $%d,$%d,$%d\n", REG_PV
, REG_PV
, base_regno
);
2218 if (unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
2219 fprintf (file
, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM
,
2220 STACK_POINTER_REGNUM
, HARD_FRAME_POINTER_REGNUM
);
2222 /* Describe our frame. */
2223 fprintf (file
, "\t.frame $%d,%d,$26,%d\n",
2224 unwind_regno
, frame_size
, rsa_offset
);
2226 /* If we have to allocate space for outgoing args, do it now. */
2227 if (current_function_outgoing_args_size
!= 0)
2228 fprintf (file
, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM
,
2229 - ALPHA_ROUND (current_function_outgoing_args_size
),
2230 HARD_FRAME_POINTER_REGNUM
);
2232 fprintf (file
, "\t.prologue\n");
2235 fprintf (file
, "\t.align 3\n");
2236 ASM_OUTPUT_LABEL (file
, alpha_function_name
);
2237 fprintf (file
, "\t.pdesc $");
2238 assemble_name (file
, alpha_function_name
);
2239 fprintf (file
, "..en,%s\n", is_stack_procedure
? "stack" : "reg");
2240 alpha_need_linkage (alpha_function_name
, 1);
2246 /* Write function epilogue. */
2249 output_epilog (file
, size
)
2253 unsigned long imask
= 0;
2254 unsigned long fmask
= 0;
2255 /* Stack space needed for pushing registers clobbered by us. */
2256 HOST_WIDE_INT sa_size
= alpha_sa_size ();
2257 /* Complete stack size needed. */
2258 HOST_WIDE_INT frame_size
2259 = ALPHA_ROUND (sa_size
2260 + (is_stack_procedure
? 8 : 0)
2261 + size
+ current_function_pretend_args_size
);
2263 rtx insn
= get_last_insn ();
2265 /* If the last insn was a BARRIER, we don't have to write anything except
2266 the .end pseudo-op. */
2268 if (GET_CODE (insn
) == NOTE
)
2269 insn
= prev_nonnote_insn (insn
);
2271 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
2273 /* Restore clobbered registers, load FP last. */
2275 if (is_stack_procedure
)
2281 if (unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
2282 fprintf (file
, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM
,
2283 HARD_FRAME_POINTER_REGNUM
, STACK_POINTER_REGNUM
);
2285 alpha_sa_mask (&imask
, &fmask
);
2287 /* Start reloading registers after RA. */
2288 reg_offset
= rsa_offset
+ 8;
2290 for (i
= 0; i
< 32; i
++)
2291 if (imask
& (1L<<i
))
2293 if (i
== HARD_FRAME_POINTER_REGNUM
)
2294 fp_offset
= reg_offset
;
2296 fprintf (file
, "\tldq $%d,%d($30)\n",
2301 for (i
= 0; i
< 32; i
++)
2302 if (fmask
& (1L << i
))
2304 fprintf (file
, "\tldt $f%d,%d($30)\n", i
, reg_offset
);
2308 /* Restore R26 (RA). */
2309 fprintf (file
, "\tldq $26,%d($30)\n", rsa_offset
);
2311 /* Restore R29 (FP). */
2312 fprintf (file
, "\tldq $29,%d($30)\n", fp_offset
);
2315 fprintf (file
, "\tbis $%d,$%d,$%d\n", save_fp_regno
, save_fp_regno
,
2316 HARD_FRAME_POINTER_REGNUM
);
2318 if (frame_size
!= 0)
2320 if (frame_size
< 32768)
2321 fprintf (file
, "\tlda $30,%d($30)\n", frame_size
);
2324 long high
= frame_size
>> 16;
2325 long low
= frame_size
& 0xffff;
2329 low
= -32768 + (low
& 0x7fff);
2331 fprintf (file
, "\tldah $2,%ld($31)\n", high
);
2332 fprintf (file
, "\tlda $2,%ld($2)\n", low
);
2333 fprintf (file
, "\taddq $30,$2,$30\n");
2337 /* Finally return to the caller. */
2338 fprintf (file
, "\tret $31,($26),1\n");
2341 /* End the function. */
2342 fprintf (file
, "\t.end ");
2343 assemble_name (file
, alpha_function_name
);
2344 fprintf (file
, "\n");
2345 inside_function
= FALSE
;
2347 /* Show that we know this function if it is called again. */
2348 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
2351 #else /* !OPEN_VMS */
2354 alpha_does_function_need_gp ()
2358 /* We never need a GP for Windows/NT. */
2359 if (TARGET_WINDOWS_NT
)
2362 #ifdef TARGET_PROFILING_NEEDS_GP
2367 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
2368 Even if we are a static function, we still need to do this in case
2369 our address is taken and passed to something like qsort. */
2371 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
2372 if (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
2373 && GET_CODE (PATTERN (insn
)) != USE
2374 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
2376 enum attr_type type
= get_attr_type (insn
);
2377 if (type
== TYPE_LDSYM
|| type
== TYPE_JSR
)
2385 vms_valid_decl_attribute_p (decl
, attributes
, identifier
, args
)
2391 if (is_attribute_p ("overlaid", identifier
))
2392 return (args
== NULL_TREE
);
2397 output_prolog (file
, size
)
2401 HOST_WIDE_INT out_args_size
2402 = ALPHA_ROUND (current_function_outgoing_args_size
);
2403 HOST_WIDE_INT sa_size
= alpha_sa_size ();
2404 HOST_WIDE_INT frame_size
2405 = (out_args_size
+ sa_size
2406 + ALPHA_ROUND (size
+ current_function_pretend_args_size
));
2407 HOST_WIDE_INT reg_offset
= out_args_size
;
2408 HOST_WIDE_INT start_reg_offset
= reg_offset
;
2409 HOST_WIDE_INT actual_start_reg_offset
= start_reg_offset
;
2410 int int_reg_save_area_size
= 0;
2411 unsigned reg_mask
= 0;
2414 /* Ecoff can handle multiple .file directives, so put out file and lineno.
2415 We have to do that before the .ent directive as we cannot switch
2416 files within procedures with native ecoff because line numbers are
2417 linked to procedure descriptors.
2418 Outputting the lineno helps debugging of one line functions as they
2419 would otherwise get no line number at all. Please note that we would
2420 like to put out last_linenum from final.c, but it is not accessible. */
2422 if (write_symbols
== SDB_DEBUG
)
2424 ASM_OUTPUT_SOURCE_FILENAME (file
,
2425 DECL_SOURCE_FILE (current_function_decl
));
2426 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
2427 ASM_OUTPUT_SOURCE_LINE (file
,
2428 DECL_SOURCE_LINE (current_function_decl
));
2431 /* The assembly language programmer's guide states that the second argument
2432 to the .ent directive, the lex_level, is ignored by the assembler,
2433 so we might as well omit it. */
2435 if (!flag_inhibit_size_directive
)
2437 fprintf (file
, "\t.ent ");
2438 assemble_name (file
, alpha_function_name
);
2439 fprintf (file
, "\n");
2441 ASM_OUTPUT_LABEL (file
, alpha_function_name
);
2442 inside_function
= TRUE
;
2444 if (TARGET_IEEE_CONFORMANT
&& !flag_inhibit_size_directive
)
2445 /* Set flags in procedure descriptor to request IEEE-conformant
2446 math-library routines. The value we set it to is PDSC_EXC_IEEE
2447 (/usr/include/pdsc.h). */
2448 fprintf (file
, "\t.eflag 48\n");
2450 /* Set up offsets to alpha virtual arg/local debugging pointer. */
2452 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
2453 alpha_arg_offset
= -frame_size
+ 48;
2455 alpha_function_needs_gp
= alpha_does_function_need_gp ();
2457 if (TARGET_WINDOWS_NT
== 0)
2459 if (alpha_function_needs_gp
)
2460 fprintf (file
, "\tldgp $29,0($27)\n");
2462 /* Put a label after the GP load so we can enter the function at it. */
2464 assemble_name (file
, alpha_function_name
);
2465 fprintf (file
, "..ng:\n");
2468 /* Adjust the stack by the frame size. If the frame size is > 4096
2469 bytes, we need to be sure we probe somewhere in the first and last
2470 4096 bytes (we can probably get away without the latter test) and
2471 every 8192 bytes in between. If the frame size is > 32768, we
2472 do this in a loop. Otherwise, we generate the explicit probe
2475 Note that we are only allowed to adjust sp once in the prologue. */
2477 if (frame_size
< 32768)
2479 if (frame_size
> 4096)
2483 fprintf (file
, "\tstq $31,-%d($30)\n", probed
);
2485 while (probed
+ 8192 < frame_size
)
2486 fprintf (file
, "\tstq $31,-%d($30)\n", probed
+= 8192);
2488 /* We only have to do this probe if we aren't saving registers. */
2489 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
2490 fprintf (file
, "\tstq $31,-%d($30)\n", frame_size
);
2493 if (frame_size
!= 0)
2494 fprintf (file
, "\tlda $30,-%d($30)\n", frame_size
);
2498 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
2499 number of 8192 byte blocks to probe. We then probe each block
2500 in the loop and then set SP to the proper location. If the
2501 amount remaining is > 4096, we have to do one more probe if we
2502 are not saving any registers. */
2504 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
2505 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
2507 add_long_const (file
, blocks
, 31, 5, 5);
2509 fprintf (file
, "\tlda $4,4096($30)\n");
2512 assemble_name (file
, alpha_function_name
);
2513 fprintf (file
, "..sc:\n");
2515 fprintf (file
, "\tstq $31,-8192($4)\n");
2516 fprintf (file
, "\tsubq $5,1,$5\n");
2517 fprintf (file
, "\tlda $4,-8192($4)\n");
2519 fprintf (file
, "\tbne $5,$");
2520 assemble_name (file
, alpha_function_name
);
2521 fprintf (file
, "..sc\n");
2523 if (leftover
> 4096 && sa_size
== 0)
2524 fprintf (file
, "\tstq $31,-%d($4)\n", leftover
);
2526 fprintf (file
, "\tlda $30,-%d($4)\n", leftover
);
2529 /* Describe our frame. */
2530 if (!flag_inhibit_size_directive
)
2532 fprintf (file
, "\t.frame $%d,%d,$26,%d\n",
2533 (frame_pointer_needed
2534 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
),
2535 frame_size
, current_function_pretend_args_size
);
2538 /* Cope with very large offsets to the register save area. */
2540 if (reg_offset
+ sa_size
> 0x8000)
2542 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
2543 if (low
+ sa_size
<= 0x8000)
2545 add_long_const (file
, reg_offset
- low
, 30, 24, 24);
2550 add_long_const (file
, reg_offset
, 30, 24, 24);
2556 /* Save register RA if any other register needs to be saved. */
2559 reg_mask
|= 1 << REG_RA
;
2560 fprintf (file
, "\tstq $26,%d($%d)\n", reg_offset
, sa_reg
);
2562 int_reg_save_area_size
+= 8;
2565 /* Now save any other used integer registers required to be saved. */
2566 for (i
= 0; i
< 32; i
++)
2567 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
2568 && regs_ever_live
[i
] && i
!= REG_RA
)
2571 fprintf (file
, "\tstq $%d,%d($%d)\n", i
, reg_offset
, sa_reg
);
2573 int_reg_save_area_size
+= 8;
2576 /* Print the register mask and do floating-point saves. */
2577 if (reg_mask
&& !flag_inhibit_size_directive
)
2578 fprintf (file
, "\t.mask 0x%x,%d\n", reg_mask
,
2579 actual_start_reg_offset
- frame_size
);
2581 start_reg_offset
= reg_offset
;
2584 for (i
= 0; i
< 32; i
++)
2585 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
2586 && regs_ever_live
[i
+ 32])
2589 fprintf (file
, "\tstt $f%d,%d($%d)\n", i
, reg_offset
, sa_reg
);
2593 /* Print the floating-point mask, if we've saved any fp register. */
2594 if (reg_mask
&& !flag_inhibit_size_directive
)
2595 fprintf (file
, "\t.fmask 0x%x,%d\n", reg_mask
,
2596 actual_start_reg_offset
- frame_size
+ int_reg_save_area_size
);
2598 /* If we need a frame pointer, set it from the stack pointer. Note that
2599 this must always be the last instruction in the prologue. */
2600 if (frame_pointer_needed
)
2601 fprintf (file
, "\tbis $30,$30,$15\n");
2603 /* End the prologue and say if we used gp. */
2604 if (!flag_inhibit_size_directive
)
2605 fprintf (file
, "\t.prologue %d\n", alpha_function_needs_gp
);
2608 /* Write function epilogue. */
2611 output_epilog (file
, size
)
2615 rtx insn
= get_last_insn ();
2616 HOST_WIDE_INT out_args_size
2617 = ALPHA_ROUND (current_function_outgoing_args_size
);
2618 HOST_WIDE_INT sa_size
= alpha_sa_size ();
2619 HOST_WIDE_INT frame_size
2620 = (out_args_size
+ sa_size
2621 + ALPHA_ROUND (size
+ current_function_pretend_args_size
));
2622 HOST_WIDE_INT reg_offset
= out_args_size
;
2623 HOST_WIDE_INT frame_size_from_reg_save
= frame_size
- reg_offset
;
2625 = frame_pointer_needed
&& regs_ever_live
[HARD_FRAME_POINTER_REGNUM
];
2628 /* If the last insn was a BARRIER, we don't have to write anything except
2629 the .end pseudo-op. */
2630 if (GET_CODE (insn
) == NOTE
)
2631 insn
= prev_nonnote_insn (insn
);
2632 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
2637 /* If we have a frame pointer, restore SP from it. */
2638 if (frame_pointer_needed
)
2639 fprintf (file
, "\tbis $15,$15,$30\n");
2641 /* Cope with large offsets to the register save area. */
2643 if (reg_offset
+ sa_size
> 0x8000)
2645 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
2646 if (low
+ sa_size
<= 0x8000)
2648 add_long_const (file
, reg_offset
- low
, 30, 24, 24);
2653 add_long_const (file
, reg_offset
, 30, 24, 24);
2659 /* Restore all the registers, starting with the return address
2663 fprintf (file
, "\tldq $26,%d($%d)\n", reg_offset
, sa_reg
);
2667 /* Now restore any other used integer registers that that we saved,
2668 except for FP if it is being used as FP, since it must be
2671 for (i
= 0; i
< 32; i
++)
2672 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
]
2675 if (i
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
2676 fp_offset
= reg_offset
;
2678 fprintf (file
, "\tldq $%d,%d($%d)\n", i
, reg_offset
, sa_reg
);
2682 for (i
= 0; i
< 32; i
++)
2683 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
2684 && regs_ever_live
[i
+ 32])
2686 fprintf (file
, "\tldt $f%d,%d($%d)\n", i
, reg_offset
, sa_reg
);
2690 /* If the stack size is large and we have a frame pointer, compute the
2691 size of the stack into a register because the old FP restore, stack
2692 pointer adjust, and return are required to be consecutive
2694 if (frame_size
> 32767 && restore_fp
)
2695 add_long_const (file
, frame_size
, 31, 1, 1);
2697 /* If we needed a frame pointer and we have to restore it, do it
2698 now. This must be done in one instruction immediately
2699 before the SP update. */
2700 if (restore_fp
&& fp_offset
)
2701 fprintf (file
, "\tldq $15,%d($%d)\n", fp_offset
, sa_reg
);
2703 /* Now update the stack pointer, if needed. Only one instruction must
2704 modify the stack pointer. It must be the last instruction in the
2705 sequence and must be an ADDQ or LDA instruction. If the frame
2706 pointer was loaded above, we may only put one instruction here. */
2708 if (frame_size
> 32768 && restore_fp
)
2709 fprintf (file
, "\taddq $1,$30,$30\n");
2711 add_long_const (file
, frame_size
, 30, 30, 1);
2713 /* Finally return to the caller. */
2714 fprintf (file
, "\tret $31,($26),1\n");
2717 /* End the function. */
2718 if (!flag_inhibit_size_directive
)
2720 fprintf (file
, "\t.end ");
2721 assemble_name (file
, alpha_function_name
);
2722 fprintf (file
, "\n");
2724 inside_function
= FALSE
;
2726 /* Show that we know this function if it is called again. */
2727 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
2729 alpha_return_addr_rtx
= 0;
2731 #endif /* !OPEN_VMS */
2733 /* Debugging support. */
2737 /* Count the number of sdb related labels are generated (to find block
2738 start and end boundaries). */
2740 int sdb_label_count
= 0;
2742 /* Next label # for each statement. */
2744 static int sym_lineno
= 0;
2746 /* Count the number of .file directives, so that .loc is up to date. */
2748 static int num_source_filenames
= 0;
2750 /* Name of the file containing the current function. */
2752 static char *current_function_file
= "";
2754 /* Offsets to alpha virtual arg/local debugging pointers. */
2756 long alpha_arg_offset
;
2757 long alpha_auto_offset
;
2759 /* Emit a new filename to a stream. */
2762 alpha_output_filename (stream
, name
)
2766 static int first_time
= TRUE
;
2767 char ltext_label_name
[100];
2772 ++num_source_filenames
;
2773 current_function_file
= name
;
2774 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
2775 output_quoted_string (stream
, name
);
2776 fprintf (stream
, "\n");
2777 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
2778 fprintf (stream
, "\t#@stabs\n");
2781 else if (write_symbols
== DBX_DEBUG
)
2783 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
2784 fprintf (stream
, "%s ", ASM_STABS_OP
);
2785 output_quoted_string (stream
, name
);
2786 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
2789 else if (name
!= current_function_file
2790 && strcmp (name
, current_function_file
) != 0)
2792 if (inside_function
&& ! TARGET_GAS
)
2793 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
2796 ++num_source_filenames
;
2797 current_function_file
= name
;
2798 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
2801 output_quoted_string (stream
, name
);
2802 fprintf (stream
, "\n");
2806 /* Emit a linenumber to a stream. */
2809 alpha_output_lineno (stream
, line
)
2813 if (write_symbols
== DBX_DEBUG
)
2815 /* mips-tfile doesn't understand .stabd directives. */
2817 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
2818 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
2821 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
2824 /* Structure to show the current status of registers and memory. */
2826 struct shadow_summary
2829 unsigned long i
: 31; /* Mask of int regs */
2830 unsigned long fp
: 31; /* Mask of fp regs */
2831 unsigned long mem
: 1; /* mem == imem | fpmem */
2835 /* Summary the effects of expression X on the machine. Update SUM, a pointer
2836 to the summary structure. SET is nonzero if the insn is setting the
2837 object, otherwise zero. */
2840 summarize_insn (x
, sum
, set
)
2842 struct shadow_summary
*sum
;
2851 switch (GET_CODE (x
))
2853 /* ??? Note that this case would be incorrect if the Alpha had a
2854 ZERO_EXTRACT in SET_DEST. */
2856 summarize_insn (SET_SRC (x
), sum
, 0);
2857 summarize_insn (SET_DEST (x
), sum
, 1);
2861 summarize_insn (XEXP (x
, 0), sum
, 1);
2865 summarize_insn (XEXP (x
, 0), sum
, 0);
2869 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
2870 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
2874 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
2875 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
2884 int regno
= REGNO (x
);
2885 unsigned long mask
= 1UL << (regno
% 32);
2887 if (regno
== 31 || regno
== 63)
2893 sum
->defd
.i
|= mask
;
2895 sum
->defd
.fp
|= mask
;
2900 sum
->used
.i
|= mask
;
2902 sum
->used
.fp
|= mask
;
2913 /* Find the regs used in memory address computation: */
2914 summarize_insn (XEXP (x
, 0), sum
, 0);
2917 case CONST_INT
: case CONST_DOUBLE
:
2918 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
2921 /* Handle common unary and binary ops for efficiency. */
2922 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
2923 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
2924 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
2925 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
2926 case NE
: case EQ
: case GE
: case GT
: case LE
:
2927 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
2928 summarize_insn (XEXP (x
, 0), sum
, 0);
2929 summarize_insn (XEXP (x
, 1), sum
, 0);
2932 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
2933 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
2934 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
2935 case SQRT
: case FFS
:
2936 summarize_insn (XEXP (x
, 0), sum
, 0);
2940 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
2941 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2942 switch (format_ptr
[i
])
2945 summarize_insn (XEXP (x
, i
), sum
, 0);
2949 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
2950 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
2959 /* Ensure a sufficient number of `trapb' insns are in the code when the user
2960 requests code with a trap precision of functions or instructions.
2962 In naive mode, when the user requests a trap-precision of "instruction", a
2963 trapb is needed after every instruction that may generate a trap (and after
2964 jsr/bsr instructions, because called functions may import a trap from the
2965 caller). This ensures that the code is resumption safe but it is also slow.
2967 When optimizations are turned on, we delay issuing a trapb as long as
2968 possible. In this context, a trap shadow is the sequence of instructions
2969 that starts with a (potentially) trap generating instruction and extends to
2970 the next trapb or call_pal instruction (but GCC never generates call_pal by
2971 itself). We can delay (and therefore sometimes omit) a trapb subject to the
2972 following conditions:
2974 (a) On entry to the trap shadow, if any Alpha register or memory location
2975 contains a value that is used as an operand value by some instruction in
2976 the trap shadow (live on entry), then no instruction in the trap shadow
2977 may modify the register or memory location.
2979 (b) Within the trap shadow, the computation of the base register for a
2980 memory load or store instruction may not involve using the result
2981 of an instruction that might generate an UNPREDICTABLE result.
2983 (c) Within the trap shadow, no register may be used more than once as a
2984 destination register. (This is to make life easier for the trap-handler.)
2986 (d) The trap shadow may not include any branch instructions. */
2989 alpha_handle_trap_shadows (insns
)
2992 struct shadow_summary shadow
;
2993 int trap_pending
, exception_nesting
;
2996 if (alpha_tp
== ALPHA_TP_PROG
&& !flag_exceptions
)
3000 exception_nesting
= 0;
3003 shadow
.used
.mem
= 0;
3004 shadow
.defd
= shadow
.used
;
3006 for (i
= insns
; i
; i
= NEXT_INSN (i
))
3008 if (GET_CODE (i
) == NOTE
)
3010 switch (NOTE_LINE_NUMBER (i
))
3012 case NOTE_INSN_EH_REGION_BEG
:
3013 exception_nesting
++;
3018 case NOTE_INSN_EH_REGION_END
:
3019 exception_nesting
--;
3024 case NOTE_INSN_EPILOGUE_BEG
:
3025 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
3030 else if (trap_pending
)
3032 if (alpha_tp
== ALPHA_TP_FUNC
)
3034 if (GET_CODE (i
) == JUMP_INSN
3035 && GET_CODE (PATTERN (i
)) == RETURN
)
3038 else if (alpha_tp
== ALPHA_TP_INSN
)
3042 struct shadow_summary sum
;
3047 sum
.defd
= sum
.used
;
3049 switch (GET_CODE (i
))
3052 /* Annoyingly, get_attr_trap will abort on USE. */
3053 if (GET_CODE (PATTERN (i
)) == USE
)
3056 summarize_insn (PATTERN (i
), &sum
, 0);
3058 if ((sum
.defd
.i
& shadow
.defd
.i
)
3059 || (sum
.defd
.fp
& shadow
.defd
.fp
))
3061 /* (c) would be violated */
3065 /* Combine shadow with summary of current insn: */
3066 shadow
.used
.i
|= sum
.used
.i
;
3067 shadow
.used
.fp
|= sum
.used
.fp
;
3068 shadow
.used
.mem
|= sum
.used
.mem
;
3069 shadow
.defd
.i
|= sum
.defd
.i
;
3070 shadow
.defd
.fp
|= sum
.defd
.fp
;
3071 shadow
.defd
.mem
|= sum
.defd
.mem
;
3073 if ((sum
.defd
.i
& shadow
.used
.i
)
3074 || (sum
.defd
.fp
& shadow
.used
.fp
)
3075 || (sum
.defd
.mem
& shadow
.used
.mem
))
3077 /* (a) would be violated (also takes care of (b)) */
3078 if (get_attr_trap (i
) == TRAP_YES
3079 && ((sum
.defd
.i
& sum
.used
.i
)
3080 || (sum
.defd
.fp
& sum
.used
.fp
)))
3099 emit_insn_before (gen_trapb (), i
);
3103 shadow
.used
.mem
= 0;
3104 shadow
.defd
= shadow
.used
;
3109 if ((exception_nesting
> 0 || alpha_tp
>= ALPHA_TP_FUNC
)
3110 && GET_CODE (i
) == INSN
3111 && GET_CODE (PATTERN (i
)) != USE
3112 && GET_CODE (PATTERN (i
)) != CLOBBER
3113 && get_attr_trap (i
) == TRAP_YES
)
3115 if (optimize
&& !trap_pending
)
3116 summarize_insn (PATTERN (i
), &shadow
, 0);
3122 /* Machine dependant reorg pass. */
3128 alpha_handle_trap_shadows (insns
);
3132 /* Check a floating-point value for validity for a particular machine mode. */
3134 static char *float_strings
[] =
3136 /* These are for FLOAT_VAX. */
3137 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
3138 "-1.70141173319264430e+38",
3139 "2.93873587705571877e-39", /* 2^-128 */
3140 "-2.93873587705571877e-39",
3141 /* These are for the default broken IEEE mode, which traps
3142 on infinity or denormal numbers. */
3143 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
3144 "-3.402823466385288598117e+38",
3145 "1.1754943508222875079687e-38", /* 2^-126 */
3146 "-1.1754943508222875079687e-38",
3149 static REAL_VALUE_TYPE float_values
[8];
3150 static int inited_float_values
= 0;
3153 check_float_value (mode
, d
, overflow
)
3154 enum machine_mode mode
;
3159 if (TARGET_IEEE
|| TARGET_IEEE_CONFORMANT
|| TARGET_IEEE_WITH_INEXACT
)
3162 if (inited_float_values
== 0)
3165 for (i
= 0; i
< 8; i
++)
3166 float_values
[i
] = REAL_VALUE_ATOF (float_strings
[i
], DFmode
);
3168 inited_float_values
= 1;
3174 REAL_VALUE_TYPE
*fvptr
;
3176 if (TARGET_FLOAT_VAX
)
3177 fvptr
= &float_values
[0];
3179 fvptr
= &float_values
[4];
3181 bcopy ((char *) d
, (char *) &r
, sizeof (REAL_VALUE_TYPE
));
3182 if (REAL_VALUES_LESS (fvptr
[0], r
))
3184 bcopy ((char *) &fvptr
[0], (char *) d
,
3185 sizeof (REAL_VALUE_TYPE
));
3188 else if (REAL_VALUES_LESS (r
, fvptr
[1]))
3190 bcopy ((char *) &fvptr
[1], (char *) d
,
3191 sizeof (REAL_VALUE_TYPE
));
3194 else if (REAL_VALUES_LESS (dconst0
, r
)
3195 && REAL_VALUES_LESS (r
, fvptr
[2]))
3197 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
3200 else if (REAL_VALUES_LESS (r
, dconst0
)
3201 && REAL_VALUES_LESS (fvptr
[3], r
))
3203 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
3213 /* Return the VMS argument type corresponding to MODE. */
3216 alpha_arg_type (mode
)
3217 enum machine_mode mode
;
3222 return TARGET_FLOAT_VAX
? FF
: FS
;
3224 return TARGET_FLOAT_VAX
? FD
: FT
;
3230 /* Return an rtx for an integer representing the VMS Argument Information
3234 alpha_arg_info_reg_val (cum
)
3235 CUMULATIVE_ARGS cum
;
3237 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
3240 for (i
= 0; i
< 6; i
++)
3241 regval
|= ((int) cum
.atypes
[i
]) << (i
* 3 + 8);
3243 return GEN_INT (regval
);
3246 /* Structure to collect function names for final output
3249 enum links_kind
{KIND_UNUSED
, KIND_LOCAL
, KIND_EXTERN
};
3252 struct alpha_links
{
3253 struct alpha_links
*next
;
3255 enum links_kind kind
;
3258 static struct alpha_links
*alpha_links_base
= 0;
3260 /* Make (or fake) .linkage entry for function call.
3262 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
3265 alpha_need_linkage (name
, is_local
)
3270 struct alpha_links
*lptr
, *nptr
;
3275 /* Is this name already defined ? */
3277 for (lptr
= alpha_links_base
; lptr
; lptr
= lptr
->next
)
3278 if (strcmp (lptr
->name
, name
) == 0)
3282 /* Defined here but external assumed. */
3283 if (lptr
->kind
== KIND_EXTERN
)
3284 lptr
->kind
= KIND_LOCAL
;
3288 /* Used here but unused assumed. */
3289 if (lptr
->kind
== KIND_UNUSED
)
3290 lptr
->kind
= KIND_LOCAL
;
3295 nptr
= (struct alpha_links
*) xmalloc (sizeof (struct alpha_links
));
3296 nptr
->next
= alpha_links_base
;
3297 nptr
->name
= xstrdup (name
);
3299 /* Assume external if no definition. */
3300 nptr
->kind
= (is_local
? KIND_UNUSED
: KIND_EXTERN
);
3302 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
3303 get_identifier (name
);
3305 alpha_links_base
= nptr
;
3312 alpha_write_linkage (stream
)
3315 struct alpha_links
*lptr
, *nptr
;
3317 readonly_section ();
3319 fprintf (stream
, "\t.align 3\n");
3321 for (lptr
= alpha_links_base
; lptr
; lptr
= nptr
)
3325 if (lptr
->kind
== KIND_UNUSED
3326 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr
->name
)))
3329 fprintf (stream
, "$%s..lk:\n", lptr
->name
);
3330 if (lptr
->kind
== KIND_LOCAL
)
3332 /* Local and used, build linkage pair. */
3333 fprintf (stream
, "\t.quad $%s..en\n", lptr
->name
);
3334 fprintf (stream
, "\t.quad %s\n", lptr
->name
);
3337 /* External and used, request linkage pair. */
3338 fprintf (stream
, "\t.linkage %s\n", lptr
->name
);
3345 alpha_need_linkage (name
, is_local
)
3351 #endif /* OPEN_VMS */