1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996 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"
41 /* Specify how accurate floating-point traps need to be. */
43 enum alpha_trap_precision alpha_tp
;
45 /* Specify the floating-point rounding mode. */
47 enum alpha_fp_rounding_mode alpha_fprm
;
49 /* Specify which things cause traps. */
51 enum alpha_fp_trap_mode alpha_fptm
;
53 /* Strings decoded into the above options. */
54 char *alpha_tp_string
; /* -mtrap-precision=[p|s|i] */
55 char *alpha_fprm_string
; /* -mfp-rounding-mode=[n|m|c|d] */
56 char *alpha_fptm_string
; /* -mfp-trap-mode=[n|u|su|sui] */
58 /* Save information from a "cmpxx" operation until the branch or scc is
61 rtx alpha_compare_op0
, alpha_compare_op1
;
62 int alpha_compare_fp_p
;
64 /* Save the name of the current function as used by the assembler. This
65 is used by the epilogue. */
67 char *alpha_function_name
;
69 /* Non-zero if inside of a function, because the Alpha asm can't
70 handle .files inside of functions. */
72 static int inside_function
= FALSE
;
74 /* Non-zero if an instruction that may cause a trap is pending. */
76 static int trap_pending
= 0;
78 /* Nonzero if the current function needs gp. */
80 int alpha_function_needs_gp
;
82 extern char *version_string
;
83 extern int rtx_equal_function_value_matters
;
85 /* Declarations of static functions. */
86 static void alpha_set_memflags_1
PROTO((rtx
, int, int, int));
87 static rtx alpha_emit_set_const_1
PROTO((rtx
, enum machine_mode
,
89 static void add_long_const
PROTO((FILE *, HOST_WIDE_INT
, int, int, int));
91 /* Parse target option strings. */
96 alpha_tp
= ALPHA_TP_PROG
;
97 alpha_fprm
= ALPHA_FPRM_NORM
;
98 alpha_fptm
= ALPHA_FPTM_N
;
102 alpha_tp_string
= "i";
103 alpha_fptm_string
= "su";
104 target_flags
|= MASK_IEEE_CONFORMANT
;
107 if (TARGET_IEEE_WITH_INEXACT
)
109 alpha_tp_string
= "i";
110 alpha_fptm_string
= "sui";
111 target_flags
|= MASK_IEEE_CONFORMANT
;
115 switch (alpha_tp_string
[0])
118 alpha_tp
= ALPHA_TP_PROG
;
122 alpha_tp
= ALPHA_TP_FUNC
;
126 alpha_tp
= ALPHA_TP_INSN
;
130 error ("bad value (%s) for -mtrap-precision switch",
135 if (alpha_fprm_string
)
136 switch (alpha_fprm_string
[0])
139 alpha_fprm
= ALPHA_FPRM_NORM
;
143 alpha_fprm
= ALPHA_FPRM_MINF
;
147 alpha_fprm
= ALPHA_FPRM_CHOP
;
151 alpha_fprm
= ALPHA_FPRM_DYN
;
155 error ("bad value (%s) for -mfp-rounding-mode switch",
160 if (alpha_fptm_string
)
161 if (strcmp (alpha_fptm_string
, "n") == 0)
162 alpha_fptm
= ALPHA_FPTM_N
;
163 else if (strcmp (alpha_fptm_string
, "u") == 0)
164 alpha_fptm
= ALPHA_FPTM_U
;
165 else if (strcmp (alpha_fptm_string
, "su") == 0)
166 alpha_fptm
= ALPHA_FPTM_SU
;
167 else if (strcmp (alpha_fptm_string
, "sui") == 0)
168 alpha_fptm
= ALPHA_FPTM_SUI
;
170 error ("bad value (%s) for -mfp-trap-mode switch",
173 /* Do some sanity checks on the above option. */
175 if (alpha_fptm
>= ALPHA_FPTM_SU
&& alpha_tp
!= ALPHA_TP_INSN
)
177 error ("fp software completion requires -mtrap-precision=i");
178 alpha_tp
= ALPHA_TP_INSN
;
182 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
190 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
192 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
198 /* Returns 1 if OP is either the constant zero or a register. If a
199 register, it must be in the proper mode unless MODE is VOIDmode. */
202 reg_or_0_operand (op
, mode
)
204 enum machine_mode mode
;
206 return op
== const0_rtx
|| register_operand (op
, mode
);
209 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
213 reg_or_6bit_operand (op
, mode
)
215 enum machine_mode mode
;
217 return ((GET_CODE (op
) == CONST_INT
218 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
219 || register_operand (op
, mode
));
223 /* Return 1 if OP is an 8-bit constant or any register. */
226 reg_or_8bit_operand (op
, mode
)
228 enum machine_mode mode
;
230 return ((GET_CODE (op
) == CONST_INT
231 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
232 || register_operand (op
, mode
));
235 /* Return 1 if OP is an 8-bit constant. */
238 cint8_operand (op
, mode
)
240 enum machine_mode mode
;
242 return (GET_CODE (op
) == CONST_INT
243 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100);
246 /* Return 1 if the operand is a valid second operand to an add insn. */
249 add_operand (op
, mode
)
251 enum machine_mode mode
;
253 if (GET_CODE (op
) == CONST_INT
)
254 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K')
255 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'L')
256 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'O'));
258 return register_operand (op
, mode
);
261 /* Return 1 if the operand is a valid second operand to a sign-extending
265 sext_add_operand (op
, mode
)
267 enum machine_mode mode
;
269 if (GET_CODE (op
) == CONST_INT
)
270 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 255
271 || (unsigned HOST_WIDE_INT
) (- INTVAL (op
)) < 255);
273 return register_operand (op
, mode
);
276 /* Return 1 if OP is the constant 4 or 8. */
279 const48_operand (op
, mode
)
281 enum machine_mode mode
;
283 return (GET_CODE (op
) == CONST_INT
284 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
287 /* Return 1 if OP is a valid first operand to an AND insn. */
290 and_operand (op
, mode
)
292 enum machine_mode mode
;
294 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
295 return (zap_mask (CONST_DOUBLE_LOW (op
))
296 && zap_mask (CONST_DOUBLE_HIGH (op
)));
298 if (GET_CODE (op
) == CONST_INT
)
299 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
300 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
301 || zap_mask (INTVAL (op
)));
303 return register_operand (op
, mode
);
306 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
309 or_operand (op
, mode
)
311 enum machine_mode mode
;
313 if (GET_CODE (op
) == CONST_INT
)
314 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
315 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
317 return register_operand (op
, mode
);
320 /* Return 1 if OP is a constant that is the width, in bits, of an integral
321 mode smaller than DImode. */
324 mode_width_operand (op
, mode
)
326 enum machine_mode mode
;
328 return (GET_CODE (op
) == CONST_INT
329 && (INTVAL (op
) == 8 || INTVAL (op
) == 16 || INTVAL (op
) == 32));
332 /* Return 1 if OP is a constant that is the width of an integral machine mode
333 smaller than an integer. */
336 mode_mask_operand (op
, mode
)
338 enum machine_mode mode
;
340 #if HOST_BITS_PER_WIDE_INT == 32
341 if (GET_CODE (op
) == CONST_DOUBLE
)
342 return CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == -1;
345 return (GET_CODE (op
) == CONST_INT
346 && (INTVAL (op
) == 0xff
347 || INTVAL (op
) == 0xffff
348 #if HOST_BITS_PER_WIDE_INT == 64
349 || INTVAL (op
) == 0xffffffff
354 /* Return 1 if OP is a multiple of 8 less than 64. */
357 mul8_operand (op
, mode
)
359 enum machine_mode mode
;
361 return (GET_CODE (op
) == CONST_INT
362 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
363 && (INTVAL (op
) & 7) == 0);
366 /* Return 1 if OP is the constant zero in floating-point. */
369 fp0_operand (op
, mode
)
371 enum machine_mode mode
;
373 return (GET_MODE (op
) == mode
374 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
377 /* Return 1 if OP is the floating-point constant zero or a register. */
380 reg_or_fp0_operand (op
, mode
)
382 enum machine_mode mode
;
384 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
387 /* Return 1 if OP is a register or a constant integer. */
391 reg_or_cint_operand (op
, mode
)
393 enum machine_mode mode
;
395 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
398 /* Return 1 if OP is something that can be reloaded into a register;
399 if it is a MEM, it need not be valid. */
402 some_operand (op
, mode
)
404 enum machine_mode mode
;
406 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
409 switch (GET_CODE (op
))
411 case REG
: case MEM
: case CONST_DOUBLE
:
412 case CONST_INT
: case LABEL_REF
: case SYMBOL_REF
: case CONST
:
416 return some_operand (SUBREG_REG (op
), VOIDmode
);
422 /* Return 1 if OP is a valid operand for the source of a move insn. */
425 input_operand (op
, mode
)
427 enum machine_mode mode
;
429 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
432 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
435 switch (GET_CODE (op
))
440 /* This handles both the Windows/NT and OSF cases. */
441 return mode
== ptr_mode
|| mode
== DImode
;
447 if (register_operand (op
, mode
))
449 /* ... fall through ... */
451 return mode
!= HImode
&& mode
!= QImode
&& general_operand (op
, mode
);
454 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
457 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
463 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
467 current_file_function_operand (op
, mode
)
469 enum machine_mode mode
;
471 return (GET_CODE (op
) == SYMBOL_REF
472 && ! profile_flag
&& ! profile_block_flag
473 && (SYMBOL_REF_FLAG (op
)
474 || op
== XEXP (DECL_RTL (current_function_decl
), 0)));
477 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
480 call_operand (op
, mode
)
482 enum machine_mode mode
;
487 return (GET_CODE (op
) == SYMBOL_REF
488 || (GET_CODE (op
) == REG
&& REGNO (op
) == 27));
491 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
492 comparisons are valid in which insn. */
495 alpha_comparison_operator (op
, mode
)
497 enum machine_mode mode
;
499 enum rtx_code code
= GET_CODE (op
);
501 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
504 return (code
== EQ
|| code
== LE
|| code
== LT
505 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
508 /* Return 1 if OP is a signed comparison operation. */
511 signed_comparison_operator (op
, mode
)
513 enum machine_mode mode
;
515 switch (GET_CODE (op
))
517 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
524 /* Return 1 if this is a divide or modulus operator. */
527 divmod_operator (op
, mode
)
529 enum machine_mode mode
;
531 switch (GET_CODE (op
))
533 case DIV
: case MOD
: case UDIV
: case UMOD
:
540 /* Return 1 if this memory address is a known aligned register plus
541 a constant. It must be a valid address. This means that we can do
542 this as an aligned reference plus some offset.
544 Take into account what reload will do.
546 We could say that out-of-range stack slots are alignable, but that would
547 complicate get_aligned_mem and it isn't worth the trouble since few
548 functions have large stack space. */
551 aligned_memory_operand (op
, mode
)
553 enum machine_mode mode
;
555 if (GET_CODE (op
) == SUBREG
)
557 if (GET_MODE (op
) != mode
)
559 op
= SUBREG_REG (op
);
560 mode
= GET_MODE (op
);
563 if (reload_in_progress
&& GET_CODE (op
) == REG
564 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
565 op
= reg_equiv_mem
[REGNO (op
)];
567 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
568 || ! memory_address_p (mode
, XEXP (op
, 0)))
573 if (GET_CODE (op
) == PLUS
)
576 return (GET_CODE (op
) == REG
577 && REGNO_POINTER_ALIGN (REGNO (op
)) >= 4);
580 /* Similar, but return 1 if OP is a MEM which is not alignable. */
583 unaligned_memory_operand (op
, mode
)
585 enum machine_mode mode
;
587 if (GET_CODE (op
) == SUBREG
)
589 if (GET_MODE (op
) != mode
)
591 op
= SUBREG_REG (op
);
592 mode
= GET_MODE (op
);
595 if (reload_in_progress
&& GET_CODE (op
) == REG
596 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
597 op
= reg_equiv_mem
[REGNO (op
)];
599 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
)
604 if (! memory_address_p (mode
, op
))
607 if (GET_CODE (op
) == PLUS
)
610 return (GET_CODE (op
) != REG
611 || REGNO_POINTER_ALIGN (REGNO (op
)) < 4);
614 /* Return 1 if OP is either a register or an unaligned memory location. */
617 reg_or_unaligned_mem_operand (op
, mode
)
619 enum machine_mode mode
;
621 return register_operand (op
, mode
) || unaligned_memory_operand (op
, mode
);
624 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
627 any_memory_operand (op
, mode
)
629 enum machine_mode mode
;
631 return (GET_CODE (op
) == MEM
632 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
633 || (reload_in_progress
&& GET_CODE (op
) == REG
634 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
635 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
636 && GET_CODE (SUBREG_REG (op
)) == REG
637 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
640 /* REF is an alignable memory location. Place an aligned SImode
641 reference into *PALIGNED_MEM and the number of bits to shift into
645 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
647 rtx
*paligned_mem
, *pbitnum
;
650 HOST_WIDE_INT offset
= 0;
652 if (GET_CODE (ref
) == SUBREG
)
654 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
655 if (BYTES_BIG_ENDIAN
)
656 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
657 - MIN (UNITS_PER_WORD
,
658 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
659 ref
= SUBREG_REG (ref
);
662 if (GET_CODE (ref
) == REG
)
663 ref
= reg_equiv_mem
[REGNO (ref
)];
665 if (reload_in_progress
)
666 base
= find_replacement (&XEXP (ref
, 0));
668 base
= XEXP (ref
, 0);
670 if (GET_CODE (base
) == PLUS
)
671 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
673 *paligned_mem
= gen_rtx (MEM
, SImode
,
674 plus_constant (base
, offset
& ~3));
675 MEM_IN_STRUCT_P (*paligned_mem
) = MEM_IN_STRUCT_P (ref
);
676 MEM_VOLATILE_P (*paligned_mem
) = MEM_VOLATILE_P (ref
);
677 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
679 *pbitnum
= GEN_INT ((offset
& 3) * 8);
682 /* Similar, but just get the address. Handle the two reload cases.
683 Add EXTRA_OFFSET to the address we return. */
686 get_unaligned_address (ref
, extra_offset
)
691 HOST_WIDE_INT offset
= 0;
693 if (GET_CODE (ref
) == SUBREG
)
695 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
696 if (BYTES_BIG_ENDIAN
)
697 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
698 - MIN (UNITS_PER_WORD
,
699 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
700 ref
= SUBREG_REG (ref
);
703 if (GET_CODE (ref
) == REG
)
704 ref
= reg_equiv_mem
[REGNO (ref
)];
706 if (reload_in_progress
)
707 base
= find_replacement (&XEXP (ref
, 0));
709 base
= XEXP (ref
, 0);
711 if (GET_CODE (base
) == PLUS
)
712 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
714 return plus_constant (base
, offset
+ extra_offset
);
717 /* Subfunction of the following function. Update the flags of any MEM
718 found in part of X. */
721 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
723 int in_struct_p
, volatile_p
, unchanging_p
;
727 switch (GET_CODE (x
))
731 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
732 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
737 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
742 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
744 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
749 MEM_IN_STRUCT_P (x
) = in_struct_p
;
750 MEM_VOLATILE_P (x
) = volatile_p
;
751 RTX_UNCHANGING_P (x
) = unchanging_p
;
756 /* Given INSN, which is either an INSN or a SEQUENCE generated to
757 perform a memory operation, look for any MEMs in either a SET_DEST or
758 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
759 REF into each of the MEMs found. If REF is not a MEM, don't do
763 alpha_set_memflags (insn
, ref
)
767 /* Note that it is always safe to get these flags, though they won't
768 be what we think if REF is not a MEM. */
769 int in_struct_p
= MEM_IN_STRUCT_P (ref
);
770 int volatile_p
= MEM_VOLATILE_P (ref
);
771 int unchanging_p
= RTX_UNCHANGING_P (ref
);
773 if (GET_CODE (ref
) != MEM
774 || (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
))
777 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
780 /* Try to output insns to set TARGET equal to the constant C if it can be
781 done in less than N insns. Do all computations in MODE. Returns the place
782 where the output has been placed if it can be done and the insns have been
783 emitted. If it would take more than N insns, zero is returned and no
784 insns and emitted. */
787 alpha_emit_set_const (target
, mode
, c
, n
)
789 enum machine_mode mode
;
796 /* Try 1 insn, then 2, then up to N. */
797 for (i
= 1; i
<= n
; i
++)
798 if ((pat
= alpha_emit_set_const_1 (target
, mode
, c
, i
)) != 0)
804 /* Internal routine for the above to check for N or below insns. */
807 alpha_emit_set_const_1 (target
, mode
, c
, n
)
809 enum machine_mode mode
;
813 HOST_WIDE_INT
new = c
;
815 /* Use a pseudo if highly optimizing and still generating RTL. */
817 = (flag_expensive_optimizations
&& rtx_equal_function_value_matters
821 #if HOST_BITS_PER_WIDE_INT == 64
822 /* We are only called for SImode and DImode. If this is SImode, ensure that
823 we are sign extended to a full word. This does not make any sense when
824 cross-compiling on a narrow machine. */
827 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
830 /* If this is a sign-extended 32-bit constant, we can do this in at most
831 three insns, so do it if we have enough insns left. We always have
832 a sign-extended 32-bit constant when compiling on a narrow machine.
833 Note that we cannot handle the constant 0x80000000. */
835 if ((HOST_BITS_PER_WIDE_INT
!= 64
836 || c
>> 31 == -1 || c
>> 31 == 0)
839 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
840 HOST_WIDE_INT tmp1
= c
- low
;
842 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
843 HOST_WIDE_INT extra
= 0;
845 /* If HIGH will be interpreted as negative but the constant is
846 positive, we must adjust it to do two ldha insns. */
848 if ((high
& 0x8000) != 0 && c
>= 0)
852 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
855 if (c
== low
|| (low
== 0 && extra
== 0))
856 return copy_to_suggested_reg (GEN_INT (c
), target
, mode
);
857 else if (n
>= 2 + (extra
!= 0))
859 temp
= copy_to_suggested_reg (GEN_INT (low
), subtarget
, mode
);
862 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (extra
<< 16),
863 subtarget
, 0, OPTAB_WIDEN
);
865 return expand_binop (mode
, add_optab
, temp
, GEN_INT (high
<< 16),
866 target
, 0, OPTAB_WIDEN
);
870 /* If we couldn't do it that way, try some other methods. But if we have
871 no instructions left, don't bother. Likewise, if this is SImode and
872 we can't make pseudos, we can't do anything since the expand_binop
873 and expand_unop calls will widen and try to make pseudos. */
876 || (mode
== SImode
&& ! rtx_equal_function_value_matters
))
879 #if HOST_BITS_PER_WIDE_INT == 64
880 /* First, see if can load a value into the target that is the same as the
881 constant except that all bytes that are 0 are changed to be 0xff. If we
882 can, then we can do a ZAPNOT to obtain the desired constant. */
884 for (i
= 0; i
< 64; i
+= 8)
885 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
886 new |= (HOST_WIDE_INT
) 0xff << i
;
888 /* We are only called for SImode and DImode. If this is SImode, ensure that
889 we are sign extended to a full word. */
892 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
895 && (temp
= alpha_emit_set_const (subtarget
, mode
, new, n
- 1)) != 0)
896 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new),
897 target
, 0, OPTAB_WIDEN
);
900 /* Next, see if we can load a related constant and then shift and possibly
901 negate it to get the constant we want. Try this once each increasing
904 for (i
= 1; i
< n
; i
++)
906 /* First try complementing. */
907 if ((temp
= alpha_emit_set_const (subtarget
, mode
, ~ c
, i
)) != 0)
908 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
910 /* Next try to form a constant and do a left shift. We can do this
911 if some low-order bits are zero; the exact_log2 call below tells
912 us that information. The bits we are shifting out could be any
913 value, but here we'll just try the 0- and sign-extended forms of
914 the constant. To try to increase the chance of having the same
915 constant in more than one insn, start at the highest number of
916 bits to shift, but try all possibilities in case a ZAPNOT will
919 if ((bits
= exact_log2 (c
& - c
)) > 0)
920 for (; bits
> 0; bits
--)
921 if ((temp
= (alpha_emit_set_const
923 (unsigned HOST_WIDE_INT
) c
>> bits
, i
))) != 0
924 || ((temp
= (alpha_emit_set_const
926 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
928 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
929 target
, 0, OPTAB_WIDEN
);
931 /* Now try high-order zero bits. Here we try the shifted-in bits as
932 all zero and all ones. Be careful to avoid shifting outside the
933 mode and to avoid shifting outside the host wide int size. */
935 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
936 - floor_log2 (c
) - 1)) > 0)
937 for (; bits
> 0; bits
--)
938 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
940 || ((temp
= (alpha_emit_set_const
942 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
945 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
946 target
, 1, OPTAB_WIDEN
);
948 /* Now try high-order 1 bits. We get that with a sign-extension.
949 But one bit isn't enough here. Be careful to avoid shifting outside
950 the mode and to avoid shifting outside the host wide int size. */
952 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
953 - floor_log2 (~ c
) - 2)) > 0)
954 for (; bits
> 0; bits
--)
955 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
957 || ((temp
= (alpha_emit_set_const
959 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
962 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
963 target
, 0, OPTAB_WIDEN
);
969 /* Adjust the cost of a scheduling dependency. Return the new cost of
970 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
973 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
981 /* If the dependence is an anti-dependence, there is no cost. For an
982 output dependence, there is sometimes a cost, but it doesn't seem
983 worth handling those few cases. */
985 if (REG_NOTE_KIND (link
) != 0)
988 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
989 we can sometimes lower the cost. */
991 if (recog_memoized (insn
) >= 0 && get_attr_type (insn
) == TYPE_ST
992 && (set
= single_set (dep_insn
)) != 0
993 && GET_CODE (PATTERN (insn
)) == SET
994 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
995 switch (get_attr_type (dep_insn
))
998 /* No savings here. */
1003 /* In these cases, we save one cycle. */
1007 /* In all other cases, we save two cycles. */
1008 return MAX (0, cost
- 4);
1011 /* Another case that needs adjustment is an arithmetic or logical
1012 operation. It's cost is usually one cycle, but we default it to
1013 two in the MD file. The only case that it is actually two is
1014 for the address in loads and stores. */
1016 if (recog_memoized (dep_insn
) >= 0
1017 && get_attr_type (dep_insn
) == TYPE_IADDLOG
)
1018 switch (get_attr_type (insn
))
1028 /* The final case is when a compare feeds into an integer branch. The cost
1029 is only one cycle in that case. */
1031 if (recog_memoized (dep_insn
) >= 0
1032 && get_attr_type (dep_insn
) == TYPE_ICMP
1033 && recog_memoized (insn
) >= 0
1034 && get_attr_type (insn
) == TYPE_IBR
)
1037 /* Otherwise, return the default cost. */
1042 /* Print an operand. Recognize special options, documented below. */
1045 print_operand (file
, x
, code
)
1055 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1056 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1057 mode. alpha_fprm controls which suffix is generated. */
1060 case ALPHA_FPRM_NORM
:
1062 case ALPHA_FPRM_MINF
:
1065 case ALPHA_FPRM_CHOP
:
1068 case ALPHA_FPRM_DYN
:
1075 /* Generates trap-mode suffix for instructions that accept the su
1076 suffix only (cmpt et al). */
1077 if (alpha_tp
== ALPHA_TP_INSN
)
1082 /* Generates trap-mode suffix for instructions that accept the u, su,
1083 and sui suffix. This is the bulk of the IEEE floating point
1084 instructions (addt et al). */
1095 case ALPHA_FPTM_SUI
:
1096 fputs ("sui", file
);
1102 /* Generates trap-mode suffix for instructions that accept the sui
1103 suffix (cvtqt and cvtqs). */
1106 case ALPHA_FPTM_N
: case ALPHA_FPTM_U
:
1107 case ALPHA_FPTM_SU
: /* cvtqt/cvtqs can't cause underflow */
1109 case ALPHA_FPTM_SUI
:
1110 fputs ("sui", file
);
1116 /* If this operand is the constant zero, write it as "$31". */
1117 if (GET_CODE (x
) == REG
)
1118 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1119 else if (x
== CONST0_RTX (GET_MODE (x
)))
1120 fprintf (file
, "$31");
1122 output_operand_lossage ("invalid %%r value");
1127 /* Similar, but for floating-point. */
1128 if (GET_CODE (x
) == REG
)
1129 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1130 else if (x
== CONST0_RTX (GET_MODE (x
)))
1131 fprintf (file
, "$f31");
1133 output_operand_lossage ("invalid %%R value");
1138 /* Write the 1's complement of a constant. */
1139 if (GET_CODE (x
) != CONST_INT
)
1140 output_operand_lossage ("invalid %%N value");
1142 fprintf (file
, "%ld", ~ INTVAL (x
));
1146 /* Write 1 << C, for a constant C. */
1147 if (GET_CODE (x
) != CONST_INT
)
1148 output_operand_lossage ("invalid %%P value");
1150 fprintf (file
, "%ld", (HOST_WIDE_INT
) 1 << INTVAL (x
));
1154 /* Write the high-order 16 bits of a constant, sign-extended. */
1155 if (GET_CODE (x
) != CONST_INT
)
1156 output_operand_lossage ("invalid %%h value");
1158 fprintf (file
, "%ld", INTVAL (x
) >> 16);
1162 /* Write the low-order 16 bits of a constant, sign-extended. */
1163 if (GET_CODE (x
) != CONST_INT
)
1164 output_operand_lossage ("invalid %%L value");
1166 fprintf (file
, "%ld", (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
1170 /* Write mask for ZAP insn. */
1171 if (GET_CODE (x
) == CONST_DOUBLE
)
1173 HOST_WIDE_INT mask
= 0;
1174 HOST_WIDE_INT value
;
1176 value
= CONST_DOUBLE_LOW (x
);
1177 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
1182 value
= CONST_DOUBLE_HIGH (x
);
1183 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
1186 mask
|= (1 << (i
+ sizeof (int)));
1188 fprintf (file
, "%ld", mask
& 0xff);
1191 else if (GET_CODE (x
) == CONST_INT
)
1193 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
1195 for (i
= 0; i
< 8; i
++, value
>>= 8)
1199 fprintf (file
, "%ld", mask
);
1202 output_operand_lossage ("invalid %%m value");
1206 /* 'b', 'w', or 'l' as the value of the constant. */
1207 if (GET_CODE (x
) != CONST_INT
1208 || (INTVAL (x
) != 8 && INTVAL (x
) != 16 && INTVAL (x
) != 32))
1209 output_operand_lossage ("invalid %%M value");
1211 fprintf (file
, "%s",
1212 INTVAL (x
) == 8 ? "b" : INTVAL (x
) == 16 ? "w" : "l");
1216 /* Similar, except do it from the mask. */
1217 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
1218 fprintf (file
, "b");
1219 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
1220 fprintf (file
, "w");
1221 #if HOST_BITS_PER_WIDE_INT == 32
1222 else if (GET_CODE (x
) == CONST_DOUBLE
1223 && CONST_DOUBLE_HIGH (x
) == 0
1224 && CONST_DOUBLE_LOW (x
) == -1)
1225 fprintf (file
, "l");
1227 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
1228 fprintf (file
, "l");
1231 output_operand_lossage ("invalid %%U value");
1235 /* Write the constant value divided by 8. */
1236 if (GET_CODE (x
) != CONST_INT
1237 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
1238 && (INTVAL (x
) & 7) != 8)
1239 output_operand_lossage ("invalid %%s value");
1241 fprintf (file
, "%ld", INTVAL (x
) / 8);
1245 /* Same, except compute (64 - c) / 8 */
1247 if (GET_CODE (x
) != CONST_INT
1248 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
1249 && (INTVAL (x
) & 7) != 8)
1250 output_operand_lossage ("invalid %%s value");
1252 fprintf (file
, "%ld", (64 - INTVAL (x
)) / 8);
1256 /* Write out comparison name. */
1257 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
1258 output_operand_lossage ("invalid %%C value");
1260 if (GET_CODE (x
) == LEU
)
1261 fprintf (file
, "ule");
1262 else if (GET_CODE (x
) == LTU
)
1263 fprintf (file
, "ult");
1265 fprintf (file
, "%s", GET_RTX_NAME (GET_CODE (x
)));
1269 /* Similar, but write reversed code. We can't get an unsigned code
1271 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
1272 output_operand_lossage ("invalid %%D value");
1274 fprintf (file
, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x
))));
1278 /* Similar to `c', but swap. We can't get unsigned here either. */
1279 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
1280 output_operand_lossage ("invalid %%D value");
1282 fprintf (file
, "%s", GET_RTX_NAME (swap_condition (GET_CODE (x
))));
1286 /* Similar, but reverse and swap. We can't get unsigned here either. */
1287 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
1288 output_operand_lossage ("invalid %%D value");
1290 fprintf (file
, "%s",
1291 GET_RTX_NAME (swap_condition (reverse_condition ((GET_CODE (x
))))));
1295 /* Write the divide or modulus operator. */
1296 switch (GET_CODE (x
))
1299 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
1302 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
1305 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
1308 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
1311 output_operand_lossage ("invalid %%E value");
1317 /* Write "_u" for unaligned access. */
1318 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
1319 fprintf (file
, "_u");
1323 if (GET_CODE (x
) == REG
)
1324 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1325 else if (GET_CODE (x
) == MEM
)
1326 output_address (XEXP (x
, 0));
1328 output_addr_const (file
, x
);
1332 output_operand_lossage ("invalid %%xn code");
1336 /* Do what is necessary for `va_start'. The argument is ignored;
1337 We look at the current function to determine if stdarg or varargs
1338 is used and fill in an initial va_list. A pointer to this constructor
1342 alpha_builtin_saveregs (arglist
)
1345 rtx block
, addr
, argsize
;
1346 tree fntype
= TREE_TYPE (current_function_decl
);
1347 int stdarg
= (TYPE_ARG_TYPES (fntype
) != 0
1348 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
1349 != void_type_node
));
1351 /* Compute the current position into the args, taking into account
1352 both registers and memory. Both of these are already included in
1353 current_function_args_info. */
1355 argsize
= GEN_INT (current_function_args_info
* UNITS_PER_WORD
);
1357 /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1358 storing fp arg registers in the first 48 bytes, and the integer arg
1359 registers in the next 48 bytes. This is only done, however, if any
1360 integer registers need to be stored.
1362 If no integer registers need be stored, then we must subtract 48 in
1363 order to account for the integer arg registers which are counted in
1364 argsize above, but which are not actually stored on the stack. */
1366 addr
= (current_function_args_info
<= 5 + stdarg
1367 ? plus_constant (virtual_incoming_args_rtx
, 6 * UNITS_PER_WORD
)
1368 : plus_constant (virtual_incoming_args_rtx
, - (6 * UNITS_PER_WORD
)));
1370 addr
= force_operand (addr
, NULL_RTX
);
1372 /* Allocate the va_list constructor */
1373 block
= assign_stack_local (BLKmode
, 2 * UNITS_PER_WORD
, BITS_PER_WORD
);
1374 RTX_UNCHANGING_P (block
) = 1;
1375 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
1377 /* Store the address of the first integer register in the __base member. */
1379 #ifdef POINTERS_EXTEND_UNSIGNED
1380 addr
= convert_memory_address (ptr_mode
, addr
);
1383 emit_move_insn (change_address (block
, ptr_mode
, XEXP (block
, 0)), addr
);
1385 /* Store the argsize as the __va_offset member. */
1386 emit_move_insn (change_address (block
, TYPE_MODE (integer_type_node
),
1387 plus_constant (XEXP (block
, 0),
1388 POINTER_SIZE
/BITS_PER_UNIT
)),
1391 /* Return the address of the va_list constructor, but don't put it in a
1392 register. Doing so would fail when not optimizing and produce worse
1393 code when optimizing. */
1394 return XEXP (block
, 0);
1397 /* This page contains routines that are used to determine what the function
1398 prologue and epilogue code will do and write them out. */
1400 /* Compute the size of the save area in the stack. */
1408 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1409 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
])
1412 /* If some registers were saved but not reg 26, reg 26 must also
1413 be saved, so leave space for it. */
1414 if (size
!= 0 && ! regs_ever_live
[26])
1417 /* Our size must be even (multiple of 16 bytes). */
1424 /* Return 1 if this function can directly return via $26. */
1429 return (reload_completed
&& alpha_sa_size () == 0
1430 && get_frame_size () == 0
1431 && current_function_outgoing_args_size
== 0
1432 && current_function_pretend_args_size
== 0);
1435 /* Write a version stamp. Don't write anything if we are running as a
1436 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1438 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__)
1443 alpha_write_verstamp (file
)
1447 fprintf (file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
1451 /* Write code to add constant C to register number IN_REG (possibly 31)
1452 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
1453 usually this will be OUT_REG, but should not be if OUT_REG is
1454 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1455 Write the code to FILE. */
1458 add_long_const (file
, c
, in_reg
, out_reg
, temp_reg
)
1461 int in_reg
, out_reg
, temp_reg
;
1463 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
1464 HOST_WIDE_INT tmp1
= c
- low
;
1465 HOST_WIDE_INT high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1466 HOST_WIDE_INT extra
= 0;
1468 /* We don't have code to write out constants larger than 32 bits. */
1469 #if HOST_BITS_PER_LONG_INT == 64
1470 if ((unsigned HOST_WIDE_INT
) c
>> 32 != 0)
1474 /* If HIGH will be interpreted as negative, we must adjust it to do two
1475 ldha insns. Note that we will never be building a negative constant
1482 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1487 int result_reg
= (extra
== 0 && high
== 0) ? out_reg
: temp_reg
;
1489 if (low
>= 0 && low
< 255)
1490 fprintf (file
, "\taddq $%d,%d,$%d\n", in_reg
, low
, result_reg
);
1492 fprintf (file
, "\tlda $%d,%d($%d)\n", result_reg
, low
, in_reg
);
1494 in_reg
= result_reg
;
1499 int result_reg
= (high
== 0) ? out_reg
: temp_reg
;
1501 fprintf (file
, "\tldah $%d,%d($%d)\n", result_reg
, extra
, in_reg
);
1502 in_reg
= result_reg
;
1506 fprintf (file
, "\tldah $%d,%d($%d)\n", out_reg
, high
, in_reg
);
1509 /* Write function prologue. */
1512 output_prolog (file
, size
)
1516 HOST_WIDE_INT out_args_size
1517 = ALPHA_ROUND (current_function_outgoing_args_size
);
1518 HOST_WIDE_INT sa_size
= alpha_sa_size ();
1519 HOST_WIDE_INT frame_size
1520 = (out_args_size
+ sa_size
1521 + ALPHA_ROUND (size
+ current_function_pretend_args_size
));
1522 HOST_WIDE_INT reg_offset
= out_args_size
;
1523 HOST_WIDE_INT start_reg_offset
= reg_offset
;
1524 HOST_WIDE_INT actual_start_reg_offset
= start_reg_offset
;
1525 int int_reg_save_area_size
= 0;
1527 unsigned reg_mask
= 0;
1530 /* Ecoff can handle multiple .file directives, so put out file and lineno.
1531 We have to do that before the .ent directive as we cannot switch
1532 files within procedures with native ecoff because line numbers are
1533 linked to procedure descriptors.
1534 Outputting the lineno helps debugging of one line functions as they
1535 would otherwise get no line number at all. Please note that we would
1536 like to put out last_linenum from final.c, but it is not accessible. */
1538 if (write_symbols
== SDB_DEBUG
)
1540 ASM_OUTPUT_SOURCE_FILENAME (file
,
1541 DECL_SOURCE_FILE (current_function_decl
));
1542 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
1543 ASM_OUTPUT_SOURCE_LINE (file
,
1544 DECL_SOURCE_LINE (current_function_decl
));
1547 /* The assembly language programmer's guide states that the second argument
1548 to the .ent directive, the lex_level, is ignored by the assembler,
1549 so we might as well omit it. */
1551 fprintf (file
, "\t.ent ");
1552 assemble_name (file
, alpha_function_name
);
1553 fprintf (file
, "\n");
1554 ASM_OUTPUT_LABEL (file
, alpha_function_name
);
1555 inside_function
= TRUE
;
1557 if (TARGET_IEEE_CONFORMANT
)
1558 /* Set flags in procedure descriptor to request IEEE-conformant
1559 math-library routines. The value we set it to is PDSC_EXC_IEEE
1560 (/usr/include/pdsc.h). */
1561 fprintf (file
, "\t.eflag 48\n");
1563 /* Set up offsets to alpha virtual arg/local debugging pointer. */
1565 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
1566 alpha_arg_offset
= -frame_size
+ 48;
1568 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
1569 Even if we are a static function, we still need to do this in case
1570 our address is taken and passed to something like qsort.
1572 We never need a GP for Windows/NT. */
1574 alpha_function_needs_gp
= 0;
1576 #ifdef TARGET_PROFILING_NEEDS_GP
1578 alpha_function_needs_gp
= 1;
1581 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1582 if ((GET_CODE (insn
) == CALL_INSN
)
1583 || (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
1584 && GET_CODE (PATTERN (insn
)) != USE
1585 && GET_CODE (PATTERN (insn
)) != CLOBBER
1586 && (get_attr_type (insn
) == TYPE_LDSYM
1587 || get_attr_type (insn
) == TYPE_ISUBR
)))
1589 alpha_function_needs_gp
= 1;
1593 if (WINDOWS_NT
== 0)
1595 if (alpha_function_needs_gp
)
1596 fprintf (file
, "\tldgp $29,0($27)\n");
1598 /* Put a label after the GP load so we can enter the function at it. */
1599 assemble_name (file
, alpha_function_name
);
1600 fprintf (file
, "..ng:\n");
1603 /* Adjust the stack by the frame size. If the frame size is > 4096
1604 bytes, we need to be sure we probe somewhere in the first and last
1605 4096 bytes (we can probably get away without the latter test) and
1606 every 8192 bytes in between. If the frame size is > 32768, we
1607 do this in a loop. Otherwise, we generate the explicit probe
1610 Note that we are only allowed to adjust sp once in the prologue. */
1612 if (frame_size
< 32768)
1614 if (frame_size
> 4096)
1618 fprintf (file
, "\tstq $31,-%d($30)\n", probed
);
1620 while (probed
+ 8192 < frame_size
)
1621 fprintf (file
, "\tstq $31,-%d($30)\n", probed
+= 8192);
1623 /* We only have to do this probe if we aren't saving registers. */
1624 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
1625 fprintf (file
, "\tstq $31,-%d($30)\n", frame_size
);
1628 if (frame_size
!= 0)
1629 fprintf (file
, "\tlda $30,-%d($30)\n", frame_size
);
1633 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1634 number of 8192 byte blocks to probe. We then probe each block
1635 in the loop and then set SP to the proper location. If the
1636 amount remaining is > 4096, we have to do one more probe if we
1637 are not saving any registers. */
1639 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
1640 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
1642 add_long_const (file
, blocks
, 31, 5, 5);
1644 fprintf (file
, "\tlda $4,4096($30)\n");
1646 assemble_name (file
, alpha_function_name
);
1647 fprintf (file
, "..sc:\n");
1649 fprintf (file
, "\tstq $31,-8192($4)\n");
1650 fprintf (file
, "\tsubq $5,1,$5\n");
1651 fprintf (file
, "\tlda $4,-8192($4)\n");
1653 fprintf (file
, "\tbne $5,");
1654 assemble_name (file
, alpha_function_name
);
1655 fprintf (file
, "..sc\n");
1657 if (leftover
> 4096 && sa_size
== 0)
1658 fprintf (file
, "\tstq $31,-%d($4)\n", leftover
);
1660 fprintf (file
, "\tlda $30,-%d($4)\n", leftover
);
1663 /* Describe our frame. */
1664 fprintf (file
, "\t.frame $%d,%d,$26,%d\n",
1665 (frame_pointer_needed
1666 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
),
1667 frame_size
, current_function_pretend_args_size
);
1669 /* Save register 26 if any other register needs to be saved. */
1672 reg_mask
|= 1 << 26;
1673 fprintf (file
, "\tstq $26,%d($30)\n", reg_offset
);
1675 int_reg_save_area_size
+= 8;
1678 /* Now save any other used integer registers required to be saved. */
1679 for (i
= 0; i
< 32; i
++)
1680 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
] && i
!= 26)
1683 fprintf (file
, "\tstq $%d,%d($30)\n", i
, reg_offset
);
1685 int_reg_save_area_size
+= 8;
1688 /* Print the register mask and do floating-point saves. */
1690 fprintf (file
, "\t.mask 0x%x,%d\n", reg_mask
,
1691 actual_start_reg_offset
- frame_size
);
1693 start_reg_offset
= reg_offset
;
1696 for (i
= 0; i
< 32; i
++)
1697 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1698 && regs_ever_live
[i
+ 32])
1701 fprintf (file
, "\tstt $f%d,%d($30)\n", i
, reg_offset
);
1705 /* Print the floating-point mask, if we've saved any fp register. */
1707 fprintf (file
, "\t.fmask 0x%x,%d\n", reg_mask
,
1708 actual_start_reg_offset
- frame_size
+ int_reg_save_area_size
);
1710 /* If we need a frame pointer, set it from the stack pointer. Note that
1711 this must always be the last instruction in the prologue. */
1712 if (frame_pointer_needed
)
1713 fprintf (file
, "\tbis $30,$30,$15\n");
1715 /* End the prologue and say if we used gp. */
1716 fprintf (file
, "\t.prologue %d\n", alpha_function_needs_gp
);
1719 /* Write function epilogue. */
1722 output_epilog (file
, size
)
1726 rtx insn
= get_last_insn ();
1727 HOST_WIDE_INT out_args_size
1728 = ALPHA_ROUND (current_function_outgoing_args_size
);
1729 HOST_WIDE_INT sa_size
= alpha_sa_size ();
1730 HOST_WIDE_INT frame_size
1731 = (out_args_size
+ sa_size
1732 + ALPHA_ROUND (size
+ current_function_pretend_args_size
));
1733 HOST_WIDE_INT reg_offset
= out_args_size
;
1734 HOST_WIDE_INT frame_size_from_reg_save
= frame_size
- reg_offset
;
1736 = frame_pointer_needed
&& regs_ever_live
[HARD_FRAME_POINTER_REGNUM
];
1739 /* If the last insn was a BARRIER, we don't have to write anything except
1740 the .end pseudo-op. */
1741 if (GET_CODE (insn
) == NOTE
)
1742 insn
= prev_nonnote_insn (insn
);
1743 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
1747 final_prescan_insn (NULL_RTX
, NULL_PTR
, 0);
1749 /* If we have a frame pointer, restore SP from it. */
1750 if (frame_pointer_needed
)
1751 fprintf (file
, "\tbis $15,$15,$30\n");
1753 /* Restore all the registers, starting with the return address
1757 fprintf (file
, "\tldq $26,%d($30)\n", reg_offset
);
1761 /* Now restore any other used integer registers that that we saved,
1762 except for FP if it is being used as FP, since it must be
1765 for (i
= 0; i
< 32; i
++)
1766 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
]
1769 if (i
== HARD_FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
1770 fp_offset
= reg_offset
;
1772 fprintf (file
, "\tldq $%d,%d($30)\n", i
, reg_offset
);
1776 for (i
= 0; i
< 32; i
++)
1777 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1778 && regs_ever_live
[i
+ 32])
1780 fprintf (file
, "\tldt $f%d,%d($30)\n", i
, reg_offset
);
1784 /* If the stack size is large and we have a frame pointer, compute the
1785 size of the stack into a register because the old FP restore, stack
1786 pointer adjust, and return are required to be consecutive
1788 if (frame_size
> 32767 && restore_fp
)
1789 add_long_const (file
, frame_size
, 31, 1, 1);
1791 /* If we needed a frame pointer and we have to restore it, do it
1792 now. This must be done in one instruction immediately
1793 before the SP update. */
1794 if (restore_fp
&& fp_offset
)
1795 fprintf (file
, "\tldq $15,%d($30)\n", fp_offset
);
1797 /* Now update the stack pointer, if needed. Only one instruction must
1798 modify the stack pointer. It must be the last instruction in the
1799 sequence and must be an ADDQ or LDA instruction. If the frame
1800 pointer was loaded above, we may only put one instruction here. */
1802 if (frame_size
> 32768 && restore_fp
)
1803 fprintf (file
, "\taddq $1,$30,$30\n");
1805 add_long_const (file
, frame_size
, 30, 30, 1);
1807 /* Finally return to the caller. */
1808 fprintf (file
, "\tret $31,($26),1\n");
1811 /* End the function. */
1812 fprintf (file
, "\t.end ");
1813 assemble_name (file
, alpha_function_name
);
1814 fprintf (file
, "\n");
1815 inside_function
= FALSE
;
1817 /* Show that we know this function if it is called again. */
1818 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
1821 /* Debugging support. */
1825 /* Count the number of sdb related labels are generated (to find block
1826 start and end boundaries). */
1828 int sdb_label_count
= 0;
1830 /* Next label # for each statement. */
1832 static int sym_lineno
= 0;
1834 /* Count the number of .file directives, so that .loc is up to date. */
1836 static int num_source_filenames
= 0;
1838 /* Name of the file containing the current function. */
1840 static char *current_function_file
= "";
1842 /* Offsets to alpha virtual arg/local debugging pointers. */
1844 long alpha_arg_offset
;
1845 long alpha_auto_offset
;
1847 /* Emit a new filename to a stream. */
1850 alpha_output_filename (stream
, name
)
1854 static int first_time
= TRUE
;
1855 char ltext_label_name
[100];
1860 ++num_source_filenames
;
1861 current_function_file
= name
;
1862 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
1863 output_quoted_string (stream
, name
);
1864 fprintf (stream
, "\n");
1865 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1866 fprintf (stream
, "\t#@stabs\n");
1869 else if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1871 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
1872 fprintf (stream
, "%s ", ASM_STABS_OP
);
1873 output_quoted_string (stream
, name
);
1874 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
1877 else if (name
!= current_function_file
1878 && strcmp (name
, current_function_file
) != 0)
1880 if (inside_function
&& ! TARGET_GAS
)
1881 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
1884 ++num_source_filenames
;
1885 current_function_file
= name
;
1886 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
1889 output_quoted_string (stream
, name
);
1890 fprintf (stream
, "\n");
1894 /* Emit a linenumber to a stream. */
1897 alpha_output_lineno (stream
, line
)
1901 if (! TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1903 /* mips-tfile doesn't understand .stabd directives. */
1905 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1906 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
1909 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
1912 /* Structure to show the current status of registers and memory. */
1914 struct shadow_summary
1917 unsigned long i
: 32; /* Mask of int regs */
1918 unsigned long fp
: 32; /* Mask of fp regs */
1919 unsigned long mem
: 1; /* mem == imem | fpmem */
1923 /* Summary the effects of expression X on the machine. Update SUM, a pointer
1924 to the summary structure. SET is nonzero if the insn is setting the
1925 object, otherwise zero. */
1928 summarize_insn (x
, sum
, set
)
1930 struct shadow_summary
*sum
;
1939 switch (GET_CODE (x
))
1941 /* ??? Note that this case would be incorrect if the Alpha had a
1942 ZERO_EXTRACT in SET_DEST. */
1944 summarize_insn (SET_SRC (x
), sum
, 0);
1945 summarize_insn (SET_DEST (x
), sum
, 1);
1949 summarize_insn (XEXP (x
, 0), sum
, 1);
1953 summarize_insn (XEXP (x
, 0), sum
, 0);
1957 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
1958 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
1963 int regno
= REGNO (x
);
1964 unsigned long mask
= 1UL << (regno
% 32);
1966 if (regno
== 31 || regno
== 63)
1972 sum
->defd
.i
|= mask
;
1974 sum
->defd
.fp
|= mask
;
1979 sum
->used
.i
|= mask
;
1981 sum
->used
.fp
|= mask
;
1992 /* Find the regs used in memory address computation: */
1993 summarize_insn (XEXP (x
, 0), sum
, 0);
1997 summarize_insn (SUBREG_REG (x
), sum
, 0);
2000 case CONST_INT
: case CONST_DOUBLE
:
2001 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
2004 /* Handle common unary and binary ops for efficiency. */
2005 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
2006 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
2007 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
2008 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
2009 case NE
: case EQ
: case GE
: case GT
: case LE
:
2010 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
2011 summarize_insn (XEXP (x
, 0), sum
, 0);
2012 summarize_insn (XEXP (x
, 1), sum
, 0);
2015 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
2016 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
2017 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
2018 case SQRT
: case FFS
:
2019 summarize_insn (XEXP (x
, 0), sum
, 0);
2023 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
2024 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2025 switch (format_ptr
[i
])
2028 summarize_insn (XEXP (x
, i
), sum
, 0);
2032 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
2033 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
2042 /* This function is executed just prior to the output of assembler code for
2043 INSN to modify the extracted operands so they will be output differently.
2045 OPVEC is the vector containing the operands extracted from INSN, and
2046 NOPERANDS is the number of elements of the vector which contain meaningful
2047 data for this insn. The contents of this vector are what will be used to
2048 convert the insn template into assembler code, so you can change the
2049 assembler output by changing the contents of the vector.
2051 We use this function to ensure a sufficient number of `trapb' instructions
2052 are in the code when the user requests code with a trap precision of
2053 functions or instructions.
2055 In naive mode, when the user requests a trap-precision of "instruction", a
2056 trapb is needed after every instruction that may generate a trap (and after
2057 jsr/bsr instructions, because called functions may import a trap from the
2058 caller). This ensures that the code is resumption safe but it is also slow.
2060 When optimizations are turned on, we delay issuing a trapb as long as
2061 possible. In this context, a trap shadow is the sequence of instructions
2062 that starts with a (potentially) trap generating instruction and extends to
2063 the next trapb or call_pal instruction (but GCC never generates call_pal by
2064 itself). We can delay (and therefore sometimes omit) a trapb subject to the
2065 following conditions:
2067 (a) On entry to the trap shadow, if any Alpha register or memory location
2068 contains a value that is used as an operand value by some instruction in
2069 the trap shadow (live on entry), then no instruction in the trap shadow
2070 may modify the register or memory location.
2072 (b) Within the trap shadow, the computation of the base register for a
2073 memory load or store instruction may not involve using the result
2074 of an instruction that might generate an UNPREDICTABLE result.
2076 (c) Within the trap shadow, no register may be used more than once as a
2077 destination register. (This is to make life easier for the trap-handler.)
2079 (d) The trap shadow may not include any branch instructions.
2084 final_prescan_insn (insn
, opvec
, noperands
)
2089 static struct shadow_summary shadow
= {0, 0, 0, 0, 0};
2091 #define CLOSE_SHADOW \
2094 fputs ("\ttrapb\n", asm_out_file); \
2096 bzero ((char *) &shadow, sizeof shadow); \
2100 if (alpha_tp
== ALPHA_TP_PROG
)
2107 /* Generate one trapb before epilogue (indicated by INSN==0) */
2113 if (optimize
&& insn
!= 0)
2115 struct shadow_summary sum
= {0, 0, 0};
2117 switch (GET_CODE(insn
))
2120 summarize_insn (PATTERN (insn
), &sum
, 0);
2122 if ((sum
.defd
.i
& shadow
.defd
.i
)
2123 || (sum
.defd
.fp
& shadow
.defd
.fp
))
2125 /* (c) would be violated */
2130 /* Combine shadow with summary of current insn: */
2131 shadow
.used
.i
|= sum
.used
.i
;
2132 shadow
.used
.fp
|= sum
.used
.fp
;
2133 shadow
.used
.mem
|= sum
.used
.mem
;
2134 shadow
.defd
.i
|= sum
.defd
.i
;
2135 shadow
.defd
.fp
|= sum
.defd
.fp
;
2136 shadow
.defd
.mem
|= sum
.defd
.mem
;
2138 if ((sum
.defd
.i
& shadow
.used
.i
)
2139 || (sum
.defd
.fp
& shadow
.used
.fp
)
2140 || (sum
.defd
.mem
& shadow
.used
.mem
))
2142 /* (a) would be violated (also takes care of (b)). */
2143 if (get_attr_trap (insn
) == TRAP_YES
2144 && ((sum
.defd
.i
& sum
.used
.i
)
2145 || (sum
.defd
.fp
& sum
.used
.fp
)))
2168 if (insn
!= 0 && get_attr_trap (insn
) == TRAP_YES
)
2170 if (optimize
&& !trap_pending
&& GET_CODE (insn
) == INSN
)
2171 summarize_insn (PATTERN (insn
), &shadow
, 0);