1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
46 extern char *version_string
;
47 extern int rtx_equal_function_value_matters
;
49 /* Specify which cpu to schedule for. */
51 enum processor_type alpha_cpu
;
52 static char* const alpha_cpu_name
[] =
57 /* Specify how accurate floating-point traps need to be. */
59 enum alpha_trap_precision alpha_tp
;
61 /* Specify the floating-point rounding mode. */
63 enum alpha_fp_rounding_mode alpha_fprm
;
65 /* Specify which things cause traps. */
67 enum alpha_fp_trap_mode alpha_fptm
;
69 /* Strings decoded into the above options. */
71 char *alpha_cpu_string
; /* -mcpu= */
72 char *alpha_tp_string
; /* -mtrap-precision=[p|s|i] */
73 char *alpha_fprm_string
; /* -mfp-rounding-mode=[n|m|c|d] */
74 char *alpha_fptm_string
; /* -mfp-trap-mode=[n|u|su|sui] */
75 char *alpha_mlat_string
; /* -mmemory-latency= */
77 /* Save information from a "cmpxx" operation until the branch or scc is
80 rtx alpha_compare_op0
, alpha_compare_op1
;
81 int alpha_compare_fp_p
;
83 /* Define the information needed to modify the epilogue for EH. */
85 rtx alpha_eh_epilogue_sp_ofs
;
87 /* Non-zero if inside of a function, because the Alpha asm can't
88 handle .files inside of functions. */
90 static int inside_function
= FALSE
;
92 /* If non-null, this rtx holds the return address for the function. */
94 static rtx alpha_return_addr_rtx
;
96 /* The number of cycles of latency we should assume on memory reads. */
98 int alpha_memory_latency
= 3;
100 /* Whether the function needs the GP. */
102 static int alpha_function_needs_gp
;
104 /* The alias set for prologue/epilogue register save/restore. */
106 static int alpha_sr_alias_set
;
108 /* Declarations of static functions. */
109 static void alpha_set_memflags_1
110 PROTO((rtx
, int, int, int));
111 static rtx alpha_emit_set_const_1
112 PROTO((rtx
, enum machine_mode
, HOST_WIDE_INT
, int));
113 static void alpha_expand_unaligned_load_words
114 PROTO((rtx
*out_regs
, rtx smem
, HOST_WIDE_INT words
, HOST_WIDE_INT ofs
));
115 static void alpha_expand_unaligned_store_words
116 PROTO((rtx
*out_regs
, rtx smem
, HOST_WIDE_INT words
, HOST_WIDE_INT ofs
));
117 static void alpha_sa_mask
118 PROTO((unsigned long *imaskP
, unsigned long *fmaskP
));
119 static int alpha_does_function_need_gp
123 /* Get the number of args of a function in one of two ways. */
125 #define NUM_ARGS current_function_args_info.num_args
127 #define NUM_ARGS current_function_args_info
133 /* Parse target option strings. */
139 = TARGET_CPU_DEFAULT
& MASK_CPU_EV6
? PROCESSOR_EV6
140 : (TARGET_CPU_DEFAULT
& MASK_CPU_EV5
? PROCESSOR_EV5
: PROCESSOR_EV4
);
142 if (alpha_cpu_string
)
144 if (! strcmp (alpha_cpu_string
, "ev4")
145 || ! strcmp (alpha_cpu_string
, "21064"))
147 alpha_cpu
= PROCESSOR_EV4
;
148 target_flags
&= ~ (MASK_BWX
| MASK_CIX
| MASK_MAX
);
150 else if (! strcmp (alpha_cpu_string
, "ev5")
151 || ! strcmp (alpha_cpu_string
, "21164"))
153 alpha_cpu
= PROCESSOR_EV5
;
154 target_flags
&= ~ (MASK_BWX
| MASK_CIX
| MASK_MAX
);
156 else if (! strcmp (alpha_cpu_string
, "ev56")
157 || ! strcmp (alpha_cpu_string
, "21164a"))
159 alpha_cpu
= PROCESSOR_EV5
;
160 target_flags
|= MASK_BWX
;
161 target_flags
&= ~ (MASK_CIX
| MASK_MAX
);
163 else if (! strcmp (alpha_cpu_string
, "pca56")
164 || ! strcmp (alpha_cpu_string
, "21164PC")
165 || ! strcmp (alpha_cpu_string
, "21164pc"))
167 alpha_cpu
= PROCESSOR_EV5
;
168 target_flags
|= MASK_BWX
| MASK_MAX
;
169 target_flags
&= ~ MASK_CIX
;
171 else if (! strcmp (alpha_cpu_string
, "ev6")
172 || ! strcmp (alpha_cpu_string
, "21264"))
174 alpha_cpu
= PROCESSOR_EV6
;
175 target_flags
|= MASK_BWX
| MASK_CIX
| MASK_MAX
;
178 error ("bad value `%s' for -mcpu switch", alpha_cpu_string
);
181 alpha_tp
= ALPHA_TP_PROG
;
182 alpha_fprm
= ALPHA_FPRM_NORM
;
183 alpha_fptm
= ALPHA_FPTM_N
;
187 alpha_tp
= ALPHA_TP_INSN
;
188 alpha_fptm
= ALPHA_FPTM_SU
;
191 if (TARGET_IEEE_WITH_INEXACT
)
193 alpha_tp
= ALPHA_TP_INSN
;
194 alpha_fptm
= ALPHA_FPTM_SUI
;
199 if (! strcmp (alpha_tp_string
, "p"))
200 alpha_tp
= ALPHA_TP_PROG
;
201 else if (! strcmp (alpha_tp_string
, "f"))
202 alpha_tp
= ALPHA_TP_FUNC
;
203 else if (! strcmp (alpha_tp_string
, "i"))
204 alpha_tp
= ALPHA_TP_INSN
;
206 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string
);
209 if (alpha_fprm_string
)
211 if (! strcmp (alpha_fprm_string
, "n"))
212 alpha_fprm
= ALPHA_FPRM_NORM
;
213 else if (! strcmp (alpha_fprm_string
, "m"))
214 alpha_fprm
= ALPHA_FPRM_MINF
;
215 else if (! strcmp (alpha_fprm_string
, "c"))
216 alpha_fprm
= ALPHA_FPRM_CHOP
;
217 else if (! strcmp (alpha_fprm_string
,"d"))
218 alpha_fprm
= ALPHA_FPRM_DYN
;
220 error ("bad value `%s' for -mfp-rounding-mode switch",
224 if (alpha_fptm_string
)
226 if (strcmp (alpha_fptm_string
, "n") == 0)
227 alpha_fptm
= ALPHA_FPTM_N
;
228 else if (strcmp (alpha_fptm_string
, "u") == 0)
229 alpha_fptm
= ALPHA_FPTM_U
;
230 else if (strcmp (alpha_fptm_string
, "su") == 0)
231 alpha_fptm
= ALPHA_FPTM_SU
;
232 else if (strcmp (alpha_fptm_string
, "sui") == 0)
233 alpha_fptm
= ALPHA_FPTM_SUI
;
235 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string
);
238 /* Do some sanity checks on the above option. */
240 if ((alpha_fptm
== ALPHA_FPTM_SU
|| alpha_fptm
== ALPHA_FPTM_SUI
)
241 && alpha_tp
!= ALPHA_TP_INSN
)
243 warning ("fp software completion requires -mtrap-precision=i");
244 alpha_tp
= ALPHA_TP_INSN
;
247 if (TARGET_FLOAT_VAX
)
249 if (alpha_fprm
== ALPHA_FPRM_MINF
|| alpha_fprm
== ALPHA_FPRM_DYN
)
251 warning ("rounding mode not supported for VAX floats");
252 alpha_fprm
= ALPHA_FPRM_NORM
;
254 if (alpha_fptm
== ALPHA_FPTM_SUI
)
256 warning ("trap mode not supported for VAX floats");
257 alpha_fptm
= ALPHA_FPTM_SU
;
265 if (!alpha_mlat_string
)
266 alpha_mlat_string
= "L1";
268 if (ISDIGIT ((unsigned char)alpha_mlat_string
[0])
269 && (lat
= strtol (alpha_mlat_string
, &end
, 10), *end
== '\0'))
271 else if ((alpha_mlat_string
[0] == 'L' || alpha_mlat_string
[0] == 'l')
272 && ISDIGIT ((unsigned char)alpha_mlat_string
[1])
273 && alpha_mlat_string
[2] == '\0')
275 static int const cache_latency
[][4] =
277 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
278 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
279 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
282 lat
= alpha_mlat_string
[1] - '0';
283 if (lat
< 0 || lat
> 3 || cache_latency
[alpha_cpu
][lat
-1] == -1)
285 warning ("L%d cache latency unknown for %s",
286 lat
, alpha_cpu_name
[alpha_cpu
]);
290 lat
= cache_latency
[alpha_cpu
][lat
-1];
292 else if (! strcmp (alpha_mlat_string
, "main"))
294 /* Most current memories have about 370ns latency. This is
295 a reasonable guess for a fast cpu. */
300 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string
);
304 alpha_memory_latency
= lat
;
307 /* Default the definition of "small data" to 8 bytes. */
311 /* Acquire a unique set number for our register saves and restores. */
312 alpha_sr_alias_set
= new_alias_set ();
315 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
323 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
325 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
331 /* Returns 1 if OP is either the constant zero or a register. If a
332 register, it must be in the proper mode unless MODE is VOIDmode. */
335 reg_or_0_operand (op
, mode
)
337 enum machine_mode mode
;
339 return op
== const0_rtx
|| register_operand (op
, mode
);
342 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
346 reg_or_6bit_operand (op
, mode
)
348 enum machine_mode mode
;
350 return ((GET_CODE (op
) == CONST_INT
351 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
352 || register_operand (op
, mode
));
356 /* Return 1 if OP is an 8-bit constant or any register. */
359 reg_or_8bit_operand (op
, mode
)
361 enum machine_mode mode
;
363 return ((GET_CODE (op
) == CONST_INT
364 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
365 || register_operand (op
, mode
));
368 /* Return 1 if OP is an 8-bit constant. */
371 cint8_operand (op
, mode
)
373 enum machine_mode mode ATTRIBUTE_UNUSED
;
375 return ((GET_CODE (op
) == CONST_INT
376 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100));
379 /* Return 1 if the operand is a valid second operand to an add insn. */
382 add_operand (op
, mode
)
384 enum machine_mode mode
;
386 if (GET_CODE (op
) == CONST_INT
)
387 /* Constraints I, J, O and P are covered by K. */
388 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K')
389 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'L'));
391 return register_operand (op
, mode
);
394 /* Return 1 if the operand is a valid second operand to a sign-extending
398 sext_add_operand (op
, mode
)
400 enum machine_mode mode
;
402 if (GET_CODE (op
) == CONST_INT
)
403 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'I')
404 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'O'));
406 return register_operand (op
, mode
);
409 /* Return 1 if OP is the constant 4 or 8. */
412 const48_operand (op
, mode
)
414 enum machine_mode mode ATTRIBUTE_UNUSED
;
416 return (GET_CODE (op
) == CONST_INT
417 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
420 /* Return 1 if OP is a valid first operand to an AND insn. */
423 and_operand (op
, mode
)
425 enum machine_mode mode
;
427 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
428 return (zap_mask (CONST_DOUBLE_LOW (op
))
429 && zap_mask (CONST_DOUBLE_HIGH (op
)));
431 if (GET_CODE (op
) == CONST_INT
)
432 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
433 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
434 || zap_mask (INTVAL (op
)));
436 return register_operand (op
, mode
);
439 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
442 or_operand (op
, mode
)
444 enum machine_mode mode
;
446 if (GET_CODE (op
) == CONST_INT
)
447 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
448 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
450 return register_operand (op
, mode
);
453 /* Return 1 if OP is a constant that is the width, in bits, of an integral
454 mode smaller than DImode. */
457 mode_width_operand (op
, mode
)
459 enum machine_mode mode ATTRIBUTE_UNUSED
;
461 return (GET_CODE (op
) == CONST_INT
462 && (INTVAL (op
) == 8 || INTVAL (op
) == 16
463 || INTVAL (op
) == 32 || INTVAL (op
) == 64));
466 /* Return 1 if OP is a constant that is the width of an integral machine mode
467 smaller than an integer. */
470 mode_mask_operand (op
, mode
)
472 enum machine_mode mode ATTRIBUTE_UNUSED
;
474 #if HOST_BITS_PER_WIDE_INT == 32
475 if (GET_CODE (op
) == CONST_DOUBLE
)
476 return (CONST_DOUBLE_LOW (op
) == -1
477 && (CONST_DOUBLE_HIGH (op
) == -1
478 || CONST_DOUBLE_HIGH (op
) == 0));
480 if (GET_CODE (op
) == CONST_DOUBLE
)
481 return (CONST_DOUBLE_LOW (op
) == -1 && CONST_DOUBLE_HIGH (op
) == 0);
484 return (GET_CODE (op
) == CONST_INT
485 && (INTVAL (op
) == 0xff
486 || INTVAL (op
) == 0xffff
487 || INTVAL (op
) == (HOST_WIDE_INT
)0xffffffff
488 #if HOST_BITS_PER_WIDE_INT == 64
494 /* Return 1 if OP is a multiple of 8 less than 64. */
497 mul8_operand (op
, mode
)
499 enum machine_mode mode ATTRIBUTE_UNUSED
;
501 return (GET_CODE (op
) == CONST_INT
502 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
503 && (INTVAL (op
) & 7) == 0);
506 /* Return 1 if OP is the constant zero in floating-point. */
509 fp0_operand (op
, mode
)
511 enum machine_mode mode
;
513 return (GET_MODE (op
) == mode
514 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
517 /* Return 1 if OP is the floating-point constant zero or a register. */
520 reg_or_fp0_operand (op
, mode
)
522 enum machine_mode mode
;
524 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
527 /* Return 1 if OP is a hard floating-point register. */
530 hard_fp_register_operand (op
, mode
)
532 enum machine_mode mode
;
534 return ((GET_CODE (op
) == REG
&& REGNO_REG_CLASS (REGNO (op
)) == FLOAT_REGS
)
535 || (GET_CODE (op
) == SUBREG
536 && hard_fp_register_operand (SUBREG_REG (op
), mode
)));
539 /* Return 1 if OP is a register or a constant integer. */
543 reg_or_cint_operand (op
, mode
)
545 enum machine_mode mode
;
547 return (GET_CODE (op
) == CONST_INT
548 || register_operand (op
, mode
));
551 /* Return 1 if OP is something that can be reloaded into a register;
552 if it is a MEM, it need not be valid. */
555 some_operand (op
, mode
)
557 enum machine_mode mode
;
559 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
562 switch (GET_CODE (op
))
564 case REG
: case MEM
: case CONST_DOUBLE
: case CONST_INT
: case LABEL_REF
:
565 case SYMBOL_REF
: case CONST
:
569 return some_operand (SUBREG_REG (op
), VOIDmode
);
578 /* Return 1 if OP is a valid operand for the source of a move insn. */
581 input_operand (op
, mode
)
583 enum machine_mode mode
;
585 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
588 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
591 switch (GET_CODE (op
))
596 /* This handles both the Windows/NT and OSF cases. */
597 return mode
== ptr_mode
|| mode
== DImode
;
603 if (register_operand (op
, mode
))
605 /* ... fall through ... */
607 return ((TARGET_BWX
|| (mode
!= HImode
&& mode
!= QImode
))
608 && general_operand (op
, mode
));
611 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
614 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
626 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
630 current_file_function_operand (op
, mode
)
632 enum machine_mode mode ATTRIBUTE_UNUSED
;
634 return (GET_CODE (op
) == SYMBOL_REF
635 && ! profile_flag
&& ! profile_block_flag
636 && (SYMBOL_REF_FLAG (op
)
637 || op
== XEXP (DECL_RTL (current_function_decl
), 0)));
640 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
643 call_operand (op
, mode
)
645 enum machine_mode mode
;
650 return (GET_CODE (op
) == SYMBOL_REF
651 || (GET_CODE (op
) == REG
652 && (TARGET_OPEN_VMS
|| TARGET_WINDOWS_NT
|| REGNO (op
) == 27)));
655 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
656 comparisons are valid in which insn. */
659 alpha_comparison_operator (op
, mode
)
661 enum machine_mode mode
;
663 enum rtx_code code
= GET_CODE (op
);
665 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
668 return (code
== EQ
|| code
== LE
|| code
== LT
669 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
672 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
675 alpha_swapped_comparison_operator (op
, mode
)
677 enum machine_mode mode
;
679 enum rtx_code code
= GET_CODE (op
);
681 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
684 code
= swap_condition (code
);
685 return (code
== EQ
|| code
== LE
|| code
== LT
686 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
689 /* Return 1 if OP is a signed comparison operation. */
692 signed_comparison_operator (op
, mode
)
694 enum machine_mode mode ATTRIBUTE_UNUSED
;
696 switch (GET_CODE (op
))
698 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
708 /* Return 1 if this is a divide or modulus operator. */
711 divmod_operator (op
, mode
)
713 enum machine_mode mode ATTRIBUTE_UNUSED
;
715 switch (GET_CODE (op
))
717 case DIV
: case MOD
: case UDIV
: case UMOD
:
727 /* Return 1 if this memory address is a known aligned register plus
728 a constant. It must be a valid address. This means that we can do
729 this as an aligned reference plus some offset.
731 Take into account what reload will do.
733 We could say that out-of-range stack slots are alignable, but that would
734 complicate get_aligned_mem and it isn't worth the trouble since few
735 functions have large stack space. */
738 aligned_memory_operand (op
, mode
)
740 enum machine_mode mode
;
742 if (GET_CODE (op
) == SUBREG
)
744 if (GET_MODE (op
) != mode
)
746 op
= SUBREG_REG (op
);
747 mode
= GET_MODE (op
);
750 if (reload_in_progress
&& GET_CODE (op
) == REG
751 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
752 op
= reg_equiv_mem
[REGNO (op
)];
754 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
755 || ! memory_address_p (mode
, XEXP (op
, 0)))
760 if (GET_CODE (op
) == PLUS
)
763 return (GET_CODE (op
) == REG
764 && REGNO_POINTER_ALIGN (REGNO (op
)) >= 4);
767 /* Similar, but return 1 if OP is a MEM which is not alignable. */
770 unaligned_memory_operand (op
, mode
)
772 enum machine_mode mode
;
774 if (GET_CODE (op
) == SUBREG
)
776 if (GET_MODE (op
) != mode
)
778 op
= SUBREG_REG (op
);
779 mode
= GET_MODE (op
);
782 if (reload_in_progress
&& GET_CODE (op
) == REG
783 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
784 op
= reg_equiv_mem
[REGNO (op
)];
786 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
)
791 if (! memory_address_p (mode
, op
))
794 if (GET_CODE (op
) == PLUS
)
797 return (GET_CODE (op
) != REG
798 || REGNO_POINTER_ALIGN (REGNO (op
)) < 4);
801 /* Return 1 if OP is either a register or an unaligned memory location. */
804 reg_or_unaligned_mem_operand (op
, mode
)
806 enum machine_mode mode
;
808 return register_operand (op
, mode
) || unaligned_memory_operand (op
, mode
);
811 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
814 any_memory_operand (op
, mode
)
816 enum machine_mode mode ATTRIBUTE_UNUSED
;
818 return (GET_CODE (op
) == MEM
819 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
820 || (reload_in_progress
&& GET_CODE (op
) == REG
821 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
822 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
823 && GET_CODE (SUBREG_REG (op
)) == REG
824 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
827 /* Returns 1 if OP is not an eliminable register.
829 This exists to cure a pathological abort in the s8addq (et al) patterns,
831 long foo () { long t; bar(); return (long) &t * 26107; }
833 which run afoul of a hack in reload to cure a (presumably) similar
834 problem with lea-type instructions on other targets. But there is
835 one of us and many of them, so work around the problem by selectively
836 preventing combine from making the optimization. */
839 reg_not_elim_operand (op
, mode
)
841 enum machine_mode mode
;
844 if (GET_CODE (op
) == SUBREG
)
845 inner
= SUBREG_REG (op
);
846 if (inner
== frame_pointer_rtx
|| inner
== arg_pointer_rtx
)
849 return register_operand (op
, mode
);
852 /* Return 1 if this function can directly return via $26. */
857 return (! TARGET_OPEN_VMS
&& reload_completed
&& alpha_sa_size () == 0
858 && get_frame_size () == 0
859 && current_function_outgoing_args_size
== 0
860 && current_function_pretend_args_size
== 0);
863 /* Return 1 is OP is a memory location that is not an reference (using
864 an AND) to an unaligned location. Take into account what reload
868 normal_memory_operand (op
, mode
)
870 enum machine_mode mode
;
872 if (reload_in_progress
&& GET_CODE (op
) == REG
873 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
875 op
= reg_equiv_mem
[REGNO (op
)];
877 /* This may not have been assigned an equivalent address if it will
878 be eliminated. In that case, it doesn't matter what we do. */
883 return GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) != AND
;
886 /* REF is an alignable memory location. Place an aligned SImode
887 reference into *PALIGNED_MEM and the number of bits to shift into
891 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
893 rtx
*paligned_mem
, *pbitnum
;
896 HOST_WIDE_INT offset
= 0;
898 if (GET_CODE (ref
) == SUBREG
)
900 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
901 if (BYTES_BIG_ENDIAN
)
902 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
903 - MIN (UNITS_PER_WORD
,
904 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
905 ref
= SUBREG_REG (ref
);
908 if (GET_CODE (ref
) == REG
)
909 ref
= reg_equiv_mem
[REGNO (ref
)];
911 if (reload_in_progress
)
912 base
= find_replacement (&XEXP (ref
, 0));
914 base
= XEXP (ref
, 0);
916 if (GET_CODE (base
) == PLUS
)
917 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
919 *paligned_mem
= gen_rtx_MEM (SImode
, plus_constant (base
, offset
& ~3));
920 MEM_COPY_ATTRIBUTES (*paligned_mem
, ref
);
921 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
923 /* Sadly, we cannot use alias sets here because we may overlap other
924 data in a different alias set. */
925 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
927 *pbitnum
= GEN_INT ((offset
& 3) * 8);
930 /* Similar, but just get the address. Handle the two reload cases.
931 Add EXTRA_OFFSET to the address we return. */
934 get_unaligned_address (ref
, extra_offset
)
939 HOST_WIDE_INT offset
= 0;
941 if (GET_CODE (ref
) == SUBREG
)
943 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
944 if (BYTES_BIG_ENDIAN
)
945 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
946 - MIN (UNITS_PER_WORD
,
947 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
948 ref
= SUBREG_REG (ref
);
951 if (GET_CODE (ref
) == REG
)
952 ref
= reg_equiv_mem
[REGNO (ref
)];
954 if (reload_in_progress
)
955 base
= find_replacement (&XEXP (ref
, 0));
957 base
= XEXP (ref
, 0);
959 if (GET_CODE (base
) == PLUS
)
960 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
962 return plus_constant (base
, offset
+ extra_offset
);
965 /* Subfunction of the following function. Update the flags of any MEM
966 found in part of X. */
969 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
971 int in_struct_p
, volatile_p
, unchanging_p
;
975 switch (GET_CODE (x
))
979 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
980 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
985 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
990 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
992 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
997 MEM_IN_STRUCT_P (x
) = in_struct_p
;
998 MEM_VOLATILE_P (x
) = volatile_p
;
999 RTX_UNCHANGING_P (x
) = unchanging_p
;
1000 /* Sadly, we cannot use alias sets because the extra aliasing
1001 produced by the AND interferes. Given that two-byte quantities
1002 are the only thing we would be able to differentiate anyway,
1003 there does not seem to be any point in convoluting the early
1004 out of the alias check. */
1005 /* MEM_ALIAS_SET (x) = alias_set; */
1013 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1014 perform a memory operation, look for any MEMs in either a SET_DEST or
1015 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1016 REF into each of the MEMs found. If REF is not a MEM, don't do
1020 alpha_set_memflags (insn
, ref
)
1024 int in_struct_p
, volatile_p
, unchanging_p
;
1026 if (GET_CODE (ref
) != MEM
)
1029 in_struct_p
= MEM_IN_STRUCT_P (ref
);
1030 volatile_p
= MEM_VOLATILE_P (ref
);
1031 unchanging_p
= RTX_UNCHANGING_P (ref
);
1033 /* This is only called from alpha.md, after having had something
1034 generated from one of the insn patterns. So if everything is
1035 zero, the pattern is already up-to-date. */
1036 if (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
)
1039 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
1042 /* Try to output insns to set TARGET equal to the constant C if it can be
1043 done in less than N insns. Do all computations in MODE. Returns the place
1044 where the output has been placed if it can be done and the insns have been
1045 emitted. If it would take more than N insns, zero is returned and no
1046 insns and emitted. */
1049 alpha_emit_set_const (target
, mode
, c
, n
)
1051 enum machine_mode mode
;
1058 /* Try 1 insn, then 2, then up to N. */
1059 for (i
= 1; i
<= n
; i
++)
1060 if ((pat
= alpha_emit_set_const_1 (target
, mode
, c
, i
)) != 0)
1066 /* Internal routine for the above to check for N or below insns. */
1069 alpha_emit_set_const_1 (target
, mode
, c
, n
)
1071 enum machine_mode mode
;
1075 HOST_WIDE_INT
new = c
;
1077 /* Use a pseudo if highly optimizing and still generating RTL. */
1079 = (flag_expensive_optimizations
&& rtx_equal_function_value_matters
1083 #if HOST_BITS_PER_WIDE_INT == 64
1084 /* We are only called for SImode and DImode. If this is SImode, ensure that
1085 we are sign extended to a full word. This does not make any sense when
1086 cross-compiling on a narrow machine. */
1089 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
1092 /* If this is a sign-extended 32-bit constant, we can do this in at most
1093 three insns, so do it if we have enough insns left. We always have
1094 a sign-extended 32-bit constant when compiling on a narrow machine. */
1096 if (HOST_BITS_PER_WIDE_INT
!= 64
1097 || c
>> 31 == -1 || c
>> 31 == 0)
1099 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
1100 HOST_WIDE_INT tmp1
= c
- low
;
1102 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1103 HOST_WIDE_INT extra
= 0;
1105 /* If HIGH will be interpreted as negative but the constant is
1106 positive, we must adjust it to do two ldha insns. */
1108 if ((high
& 0x8000) != 0 && c
>= 0)
1112 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1115 if (c
== low
|| (low
== 0 && extra
== 0))
1117 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1118 but that meant that we can't handle INT_MIN on 32-bit machines
1119 (like NT/Alpha), because we recurse indefinitely through
1120 emit_move_insn to gen_movdi. So instead, since we know exactly
1121 what we want, create it explicitly. */
1124 target
= gen_reg_rtx (mode
);
1125 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (c
)));
1128 else if (n
>= 2 + (extra
!= 0))
1130 temp
= copy_to_suggested_reg (GEN_INT (low
), subtarget
, mode
);
1133 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (extra
<< 16),
1134 subtarget
, 0, OPTAB_WIDEN
);
1136 return expand_binop (mode
, add_optab
, temp
, GEN_INT (high
<< 16),
1137 target
, 0, OPTAB_WIDEN
);
1141 /* If we couldn't do it that way, try some other methods. But if we have
1142 no instructions left, don't bother. Likewise, if this is SImode and
1143 we can't make pseudos, we can't do anything since the expand_binop
1144 and expand_unop calls will widen and try to make pseudos. */
1147 || (mode
== SImode
&& ! rtx_equal_function_value_matters
))
1150 #if HOST_BITS_PER_WIDE_INT == 64
1151 /* First, see if can load a value into the target that is the same as the
1152 constant except that all bytes that are 0 are changed to be 0xff. If we
1153 can, then we can do a ZAPNOT to obtain the desired constant. */
1155 for (i
= 0; i
< 64; i
+= 8)
1156 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
1157 new |= (HOST_WIDE_INT
) 0xff << i
;
1159 /* We are only called for SImode and DImode. If this is SImode, ensure that
1160 we are sign extended to a full word. */
1163 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1166 && (temp
= alpha_emit_set_const (subtarget
, mode
, new, n
- 1)) != 0)
1167 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new),
1168 target
, 0, OPTAB_WIDEN
);
1171 /* Next, see if we can load a related constant and then shift and possibly
1172 negate it to get the constant we want. Try this once each increasing
1173 numbers of insns. */
1175 for (i
= 1; i
< n
; i
++)
1177 /* First try complementing. */
1178 if ((temp
= alpha_emit_set_const (subtarget
, mode
, ~ c
, i
)) != 0)
1179 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
1181 /* Next try to form a constant and do a left shift. We can do this
1182 if some low-order bits are zero; the exact_log2 call below tells
1183 us that information. The bits we are shifting out could be any
1184 value, but here we'll just try the 0- and sign-extended forms of
1185 the constant. To try to increase the chance of having the same
1186 constant in more than one insn, start at the highest number of
1187 bits to shift, but try all possibilities in case a ZAPNOT will
1190 if ((bits
= exact_log2 (c
& - c
)) > 0)
1191 for (; bits
> 0; bits
--)
1192 if ((temp
= (alpha_emit_set_const
1194 (unsigned HOST_WIDE_INT
) (c
>> bits
), i
))) != 0
1195 || ((temp
= (alpha_emit_set_const
1197 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
1199 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
1200 target
, 0, OPTAB_WIDEN
);
1202 /* Now try high-order zero bits. Here we try the shifted-in bits as
1203 all zero and all ones. Be careful to avoid shifting outside the
1204 mode and to avoid shifting outside the host wide int size. */
1205 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1206 confuse the recursive call and set all of the high 32 bits. */
1208 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1209 - floor_log2 (c
) - 1 - (HOST_BITS_PER_WIDE_INT
< 64))) > 0)
1210 for (; bits
> 0; bits
--)
1211 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1213 || ((temp
= (alpha_emit_set_const
1215 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1218 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
1219 target
, 1, OPTAB_WIDEN
);
1221 /* Now try high-order 1 bits. We get that with a sign-extension.
1222 But one bit isn't enough here. Be careful to avoid shifting outside
1223 the mode and to avoid shifting outside the host wide int size. */
1225 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1226 - floor_log2 (~ c
) - 2)) > 0)
1227 for (; bits
> 0; bits
--)
1228 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1230 || ((temp
= (alpha_emit_set_const
1232 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1235 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
1236 target
, 0, OPTAB_WIDEN
);
1242 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1243 fall back to a straight forward decomposition. We do this to avoid
1244 exponential run times encountered when looking for longer sequences
1245 with alpha_emit_set_const. */
1248 alpha_emit_set_long_const (target
, c1
, c2
)
1250 HOST_WIDE_INT c1
, c2
;
1252 HOST_WIDE_INT d1
, d2
, d3
, d4
;
1254 /* Decompose the entire word */
1255 #if HOST_BITS_PER_WIDE_INT >= 64
1256 if (c2
!= -(c1
< 0))
1258 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1260 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1261 c1
= (c1
- d2
) >> 32;
1262 d3
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1264 d4
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1268 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1270 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1274 d3
= ((c2
& 0xffff) ^ 0x8000) - 0x8000;
1276 d4
= ((c2
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1281 /* Construct the high word */
1284 emit_move_insn (target
, GEN_INT (d4
));
1286 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d3
)));
1289 emit_move_insn (target
, GEN_INT (d3
));
1291 /* Shift it into place */
1292 emit_move_insn (target
, gen_rtx_ASHIFT (DImode
, target
, GEN_INT (32)));
1294 /* Add in the low bits. */
1296 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d2
)));
1298 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d1
)));
1303 /* Generate the comparison for a conditional branch. */
1306 alpha_emit_conditional_branch (code
)
1309 enum rtx_code cmp_code
, branch_code
;
1310 enum machine_mode cmp_mode
, branch_mode
= VOIDmode
;
1311 rtx op0
= alpha_compare_op0
, op1
= alpha_compare_op1
;
1314 /* The general case: fold the comparison code to the types of compares
1315 that we have, choosing the branch as necessary. */
1318 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
1319 /* We have these compares: */
1320 cmp_code
= code
, branch_code
= NE
;
1324 /* This must be reversed. */
1325 cmp_code
= EQ
, branch_code
= EQ
;
1328 case GE
: case GT
: case GEU
: case GTU
:
1329 /* For FP, we swap them, for INT, we reverse them. */
1330 if (alpha_compare_fp_p
)
1332 cmp_code
= swap_condition (code
);
1334 tem
= op0
, op0
= op1
, op1
= tem
;
1338 cmp_code
= reverse_condition (code
);
1347 if (alpha_compare_fp_p
)
1352 /* When we are not as concerned about non-finite values, and we
1353 are comparing against zero, we can branch directly. */
1354 if (op1
== CONST0_RTX (DFmode
))
1355 cmp_code
= NIL
, branch_code
= code
;
1356 else if (op0
== CONST0_RTX (DFmode
))
1358 /* Undo the swap we probably did just above. */
1359 tem
= op0
, op0
= op1
, op1
= tem
;
1360 branch_code
= swap_condition (cmp_code
);
1366 /* ??? We mark the the branch mode to be CCmode to prevent the
1367 compare and branch from being combined, since the compare
1368 insn follows IEEE rules that the branch does not. */
1369 branch_mode
= CCmode
;
1376 /* The following optimizations are only for signed compares. */
1377 if (code
!= LEU
&& code
!= LTU
&& code
!= GEU
&& code
!= GTU
)
1379 /* Whee. Compare and branch against 0 directly. */
1380 if (op1
== const0_rtx
)
1381 cmp_code
= NIL
, branch_code
= code
;
1383 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1384 bypass between logicals and br/cmov on EV5. But we don't want to
1385 force valid immediate constants into registers needlessly. */
1386 else if (GET_CODE (op1
) == CONST_INT
)
1388 HOST_WIDE_INT v
= INTVAL (op1
), n
= -v
;
1390 if (! CONST_OK_FOR_LETTER_P (v
, 'I')
1391 && (CONST_OK_FOR_LETTER_P (n
, 'K')
1392 || CONST_OK_FOR_LETTER_P (n
, 'L')))
1394 cmp_code
= PLUS
, branch_code
= code
;
1401 /* Force op0 into a register. */
1402 if (GET_CODE (op0
) != REG
)
1403 op0
= force_reg (cmp_mode
, op0
);
1405 /* Emit an initial compare instruction, if necessary. */
1407 if (cmp_code
!= NIL
)
1409 tem
= gen_reg_rtx (cmp_mode
);
1410 emit_move_insn (tem
, gen_rtx_fmt_ee (cmp_code
, cmp_mode
, op0
, op1
));
1413 /* Return the branch comparison. */
1414 return gen_rtx_fmt_ee (branch_code
, branch_mode
, tem
, CONST0_RTX (cmp_mode
));
1418 /* Rewrite a comparison against zero CMP of the form
1419 (CODE (cc0) (const_int 0)) so it can be written validly in
1420 a conditional move (if_then_else CMP ...).
1421 If both of the operands that set cc0 are non-zero we must emit
1422 an insn to perform the compare (it can't be done within
1423 the conditional move). */
1425 alpha_emit_conditional_move (cmp
, mode
)
1427 enum machine_mode mode
;
1429 enum rtx_code code
= GET_CODE (cmp
);
1430 enum rtx_code cmov_code
= NE
;
1431 rtx op0
= alpha_compare_op0
;
1432 rtx op1
= alpha_compare_op1
;
1433 enum machine_mode cmp_mode
1434 = (GET_MODE (op0
) == VOIDmode
? DImode
: GET_MODE (op0
));
1435 enum machine_mode cmp_op_mode
= alpha_compare_fp_p
? DFmode
: DImode
;
1436 enum machine_mode cmov_mode
= VOIDmode
;
1439 if (alpha_compare_fp_p
!= FLOAT_MODE_P (mode
))
1442 /* We may be able to use a conditional move directly.
1443 This avoids emitting spurious compares. */
1444 if (signed_comparison_operator (cmp
, cmp_op_mode
)
1445 && (!alpha_compare_fp_p
|| flag_fast_math
)
1446 && (op0
== CONST0_RTX (cmp_mode
) || op1
== CONST0_RTX (cmp_mode
)))
1447 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
1449 /* We can't put the comparison insides a conditional move;
1450 emit a compare instruction and put that inside the
1451 conditional move. Make sure we emit only comparisons we have;
1452 swap or reverse as necessary. */
1456 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
1457 /* We have these compares: */
1461 /* This must be reversed. */
1462 code
= reverse_condition (code
);
1466 case GE
: case GT
: case GEU
: case GTU
:
1467 /* These must be swapped. Make sure the new first operand is in
1469 code
= swap_condition (code
);
1470 tem
= op0
, op0
= op1
, op1
= tem
;
1471 op0
= force_reg (cmp_mode
, op0
);
1478 /* ??? We mark the branch mode to be CCmode to prevent the compare
1479 and cmov from being combined, since the compare insn follows IEEE
1480 rules that the cmov does not. */
1481 if (alpha_compare_fp_p
&& !flag_fast_math
)
1484 tem
= gen_reg_rtx (cmp_op_mode
);
1485 emit_move_insn (tem
, gen_rtx_fmt_ee (code
, cmp_op_mode
, op0
, op1
));
1486 return gen_rtx_fmt_ee (cmov_code
, cmov_mode
, tem
, CONST0_RTX (cmp_op_mode
));
1489 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1493 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1494 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1495 lda r3,X(r11) lda r3,X+2(r11)
1496 extwl r1,r3,r1 extql r1,r3,r1
1497 extwh r2,r3,r2 extqh r2,r3,r2
1498 or r1.r2.r1 or r1,r2,r1
1501 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1502 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1503 lda r3,X(r11) lda r3,X(r11)
1504 extll r1,r3,r1 extll r1,r3,r1
1505 extlh r2,r3,r2 extlh r2,r3,r2
1506 or r1.r2.r1 addl r1,r2,r1
1508 quad: ldq_u r1,X(r11)
1517 alpha_expand_unaligned_load (tgt
, mem
, size
, ofs
, sign
)
1519 HOST_WIDE_INT size
, ofs
;
1522 rtx meml
, memh
, addr
, extl
, exth
;
1523 enum machine_mode mode
;
1525 meml
= gen_reg_rtx (DImode
);
1526 memh
= gen_reg_rtx (DImode
);
1527 addr
= gen_reg_rtx (DImode
);
1528 extl
= gen_reg_rtx (DImode
);
1529 exth
= gen_reg_rtx (DImode
);
1531 emit_move_insn (meml
,
1532 change_address (mem
, DImode
,
1533 gen_rtx_AND (DImode
,
1534 plus_constant (XEXP (mem
, 0),
1538 emit_move_insn (memh
,
1539 change_address (mem
, DImode
,
1540 gen_rtx_AND (DImode
,
1541 plus_constant (XEXP (mem
, 0),
1545 if (sign
&& size
== 2)
1547 emit_move_insn (addr
, plus_constant (XEXP (mem
, 0), ofs
+2));
1549 emit_insn (gen_extxl (extl
, meml
, GEN_INT (64), addr
));
1550 emit_insn (gen_extqh (exth
, memh
, addr
));
1552 /* We must use tgt here for the target. Alpha-vms port fails if we use
1553 addr for the target, because addr is marked as a pointer and combine
1554 knows that pointers are always sign-extended 32 bit values. */
1555 addr
= expand_binop (DImode
, ior_optab
, extl
, exth
, tgt
, 1, OPTAB_WIDEN
);
1556 addr
= expand_binop (DImode
, ashr_optab
, addr
, GEN_INT (48),
1557 addr
, 1, OPTAB_WIDEN
);
1561 emit_move_insn (addr
, plus_constant (XEXP (mem
, 0), ofs
));
1562 emit_insn (gen_extxl (extl
, meml
, GEN_INT (size
*8), addr
));
1566 emit_insn (gen_extwh (exth
, memh
, addr
));
1571 emit_insn (gen_extlh (exth
, memh
, addr
));
1576 emit_insn (gen_extqh (exth
, memh
, addr
));
1581 addr
= expand_binop (mode
, ior_optab
, gen_lowpart (mode
, extl
),
1582 gen_lowpart (mode
, exth
), gen_lowpart (mode
, tgt
),
1587 emit_move_insn (tgt
, gen_lowpart(GET_MODE (tgt
), addr
));
1590 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1593 alpha_expand_unaligned_store (dst
, src
, size
, ofs
)
1595 HOST_WIDE_INT size
, ofs
;
1597 rtx dstl
, dsth
, addr
, insl
, insh
, meml
, memh
;
1599 dstl
= gen_reg_rtx (DImode
);
1600 dsth
= gen_reg_rtx (DImode
);
1601 insl
= gen_reg_rtx (DImode
);
1602 insh
= gen_reg_rtx (DImode
);
1604 meml
= change_address (dst
, DImode
,
1605 gen_rtx_AND (DImode
,
1606 plus_constant (XEXP (dst
, 0), ofs
),
1608 memh
= change_address (dst
, DImode
,
1609 gen_rtx_AND (DImode
,
1610 plus_constant (XEXP (dst
, 0),
1614 emit_move_insn (dsth
, memh
);
1615 emit_move_insn (dstl
, meml
);
1616 addr
= copy_addr_to_reg (plus_constant (XEXP (dst
, 0), ofs
));
1618 if (src
!= const0_rtx
)
1620 emit_insn (gen_insxh (insh
, gen_lowpart (DImode
, src
),
1621 GEN_INT (size
*8), addr
));
1626 emit_insn (gen_inswl (insl
, gen_lowpart (HImode
, src
), addr
));
1629 emit_insn (gen_insll (insl
, gen_lowpart (SImode
, src
), addr
));
1632 emit_insn (gen_insql (insl
, src
, addr
));
1637 emit_insn (gen_mskxh (dsth
, dsth
, GEN_INT (size
*8), addr
));
1642 emit_insn (gen_mskxl (dstl
, dstl
, GEN_INT (0xffff), addr
));
1645 emit_insn (gen_mskxl (dstl
, dstl
, GEN_INT (0xffffffff), addr
));
1649 #if HOST_BITS_PER_WIDE_INT == 32
1650 rtx msk
= immed_double_const (0xffffffff, 0xffffffff, DImode
);
1652 rtx msk
= immed_double_const (0xffffffffffffffff, 0, DImode
);
1654 emit_insn (gen_mskxl (dstl
, dstl
, msk
, addr
));
1659 if (src
!= const0_rtx
)
1661 dsth
= expand_binop (DImode
, ior_optab
, insh
, dsth
, dsth
, 0, OPTAB_WIDEN
);
1662 dstl
= expand_binop (DImode
, ior_optab
, insl
, dstl
, dstl
, 0, OPTAB_WIDEN
);
1665 /* Must store high before low for degenerate case of aligned. */
1666 emit_move_insn (memh
, dsth
);
1667 emit_move_insn (meml
, dstl
);
1670 /* The block move code tries to maximize speed by separating loads and
1671 stores at the expense of register pressure: we load all of the data
1672 before we store it back out. There are two secondary effects worth
1673 mentioning, that this speeds copying to/from aligned and unaligned
1674 buffers, and that it makes the code significantly easier to write. */
1676 #define MAX_MOVE_WORDS 8
1678 /* Load an integral number of consecutive unaligned quadwords. */
1681 alpha_expand_unaligned_load_words (out_regs
, smem
, words
, ofs
)
1684 HOST_WIDE_INT words
, ofs
;
1686 rtx
const im8
= GEN_INT (-8);
1687 rtx
const i64
= GEN_INT (64);
1688 rtx ext_tmps
[MAX_MOVE_WORDS
], data_regs
[MAX_MOVE_WORDS
+1];
1692 /* Generate all the tmp registers we need. */
1693 for (i
= 0; i
< words
; ++i
)
1695 data_regs
[i
] = out_regs
[i
];
1696 ext_tmps
[i
] = gen_reg_rtx (DImode
);
1698 data_regs
[words
] = gen_reg_rtx (DImode
);
1701 smem
= change_address (smem
, GET_MODE (smem
),
1702 plus_constant (XEXP (smem
, 0), ofs
));
1704 /* Load up all of the source data. */
1705 for (i
= 0; i
< words
; ++i
)
1707 emit_move_insn (data_regs
[i
],
1708 change_address (smem
, DImode
,
1709 gen_rtx_AND (DImode
,
1710 plus_constant (XEXP(smem
,0),
1714 emit_move_insn (data_regs
[words
],
1715 change_address (smem
, DImode
,
1716 gen_rtx_AND (DImode
,
1717 plus_constant (XEXP(smem
,0),
1721 /* Extract the half-word fragments. Unfortunately DEC decided to make
1722 extxh with offset zero a noop instead of zeroing the register, so
1723 we must take care of that edge condition ourselves with cmov. */
1725 sreg
= copy_addr_to_reg (XEXP (smem
, 0));
1726 areg
= expand_binop (DImode
, and_optab
, sreg
, GEN_INT (7), NULL
,
1728 for (i
= 0; i
< words
; ++i
)
1730 emit_insn (gen_extxl (data_regs
[i
], data_regs
[i
], i64
, sreg
));
1732 emit_insn (gen_extqh (ext_tmps
[i
], data_regs
[i
+1], sreg
));
1733 emit_insn (gen_rtx_SET (VOIDmode
, ext_tmps
[i
],
1734 gen_rtx_IF_THEN_ELSE (DImode
,
1735 gen_rtx_EQ (DImode
, areg
,
1737 const0_rtx
, ext_tmps
[i
])));
1740 /* Merge the half-words into whole words. */
1741 for (i
= 0; i
< words
; ++i
)
1743 out_regs
[i
] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
1744 ext_tmps
[i
], data_regs
[i
], 1, OPTAB_WIDEN
);
1748 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1749 may be NULL to store zeros. */
1752 alpha_expand_unaligned_store_words (data_regs
, dmem
, words
, ofs
)
1755 HOST_WIDE_INT words
, ofs
;
1757 rtx
const im8
= GEN_INT (-8);
1758 rtx
const i64
= GEN_INT (64);
1759 #if HOST_BITS_PER_WIDE_INT == 32
1760 rtx
const im1
= immed_double_const (0xffffffff, 0xffffffff, DImode
);
1762 rtx
const im1
= immed_double_const (0xffffffffffffffff, 0, DImode
);
1764 rtx ins_tmps
[MAX_MOVE_WORDS
];
1765 rtx st_tmp_1
, st_tmp_2
, dreg
;
1766 rtx st_addr_1
, st_addr_2
;
1769 /* Generate all the tmp registers we need. */
1770 if (data_regs
!= NULL
)
1771 for (i
= 0; i
< words
; ++i
)
1772 ins_tmps
[i
] = gen_reg_rtx(DImode
);
1773 st_tmp_1
= gen_reg_rtx(DImode
);
1774 st_tmp_2
= gen_reg_rtx(DImode
);
1777 dmem
= change_address (dmem
, GET_MODE (dmem
),
1778 plus_constant (XEXP (dmem
, 0), ofs
));
1781 st_addr_2
= change_address (dmem
, DImode
,
1782 gen_rtx_AND (DImode
,
1783 plus_constant (XEXP(dmem
,0),
1786 st_addr_1
= change_address (dmem
, DImode
,
1787 gen_rtx_AND (DImode
,
1791 /* Load up the destination end bits. */
1792 emit_move_insn (st_tmp_2
, st_addr_2
);
1793 emit_move_insn (st_tmp_1
, st_addr_1
);
1795 /* Shift the input data into place. */
1796 dreg
= copy_addr_to_reg (XEXP (dmem
, 0));
1797 if (data_regs
!= NULL
)
1799 for (i
= words
-1; i
>= 0; --i
)
1801 emit_insn (gen_insxh (ins_tmps
[i
], data_regs
[i
], i64
, dreg
));
1802 emit_insn (gen_insql (data_regs
[i
], data_regs
[i
], dreg
));
1804 for (i
= words
-1; i
> 0; --i
)
1806 ins_tmps
[i
-1] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
1807 ins_tmps
[i
-1], ins_tmps
[i
-1], 1,
1812 /* Split and merge the ends with the destination data. */
1813 emit_insn (gen_mskxh (st_tmp_2
, st_tmp_2
, i64
, dreg
));
1814 emit_insn (gen_mskxl (st_tmp_1
, st_tmp_1
, im1
, dreg
));
1816 if (data_regs
!= NULL
)
1818 st_tmp_2
= expand_binop (DImode
, ior_optab
, st_tmp_2
, ins_tmps
[words
-1],
1819 st_tmp_2
, 1, OPTAB_WIDEN
);
1820 st_tmp_1
= expand_binop (DImode
, ior_optab
, st_tmp_1
, data_regs
[0],
1821 st_tmp_1
, 1, OPTAB_WIDEN
);
1825 emit_move_insn (st_addr_2
, st_tmp_2
);
1826 for (i
= words
-1; i
> 0; --i
)
1828 emit_move_insn (change_address (dmem
, DImode
,
1829 gen_rtx_AND (DImode
,
1830 plus_constant(XEXP (dmem
,0),
1833 data_regs
? ins_tmps
[i
-1] : const0_rtx
);
1835 emit_move_insn (st_addr_1
, st_tmp_1
);
1839 /* Expand string/block move operations.
1841 operands[0] is the pointer to the destination.
1842 operands[1] is the pointer to the source.
1843 operands[2] is the number of bytes to move.
1844 operands[3] is the alignment. */
1847 alpha_expand_block_move (operands
)
1850 rtx bytes_rtx
= operands
[2];
1851 rtx align_rtx
= operands
[3];
1852 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
1853 HOST_WIDE_INT bytes
= orig_bytes
;
1854 HOST_WIDE_INT src_align
= INTVAL (align_rtx
);
1855 HOST_WIDE_INT dst_align
= src_align
;
1856 rtx orig_src
= operands
[1];
1857 rtx orig_dst
= operands
[0];
1858 rtx data_regs
[2*MAX_MOVE_WORDS
+16];
1860 int i
, words
, ofs
, nregs
= 0;
1864 if (bytes
> MAX_MOVE_WORDS
*8)
1867 /* Look for additional alignment information from recorded register info. */
1869 tmp
= XEXP (orig_src
, 0);
1870 if (GET_CODE (tmp
) == REG
)
1872 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > src_align
)
1873 src_align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
1875 else if (GET_CODE (tmp
) == PLUS
1876 && GET_CODE (XEXP (tmp
, 0)) == REG
1877 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
1879 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
1880 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
1884 if (a
>= 8 && c
% 8 == 0)
1886 else if (a
>= 4 && c
% 4 == 0)
1888 else if (a
>= 2 && c
% 2 == 0)
1893 tmp
= XEXP (orig_dst
, 0);
1894 if (GET_CODE (tmp
) == REG
)
1896 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > dst_align
)
1897 dst_align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
1899 else if (GET_CODE (tmp
) == PLUS
1900 && GET_CODE (XEXP (tmp
, 0)) == REG
1901 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
1903 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
1904 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
1908 if (a
>= 8 && c
% 8 == 0)
1910 else if (a
>= 4 && c
% 4 == 0)
1912 else if (a
>= 2 && c
% 2 == 0)
1918 * Load the entire block into registers.
1921 if (GET_CODE (XEXP (orig_src
, 0)) == ADDRESSOF
)
1923 enum machine_mode mode
;
1924 tmp
= XEXP (XEXP (orig_src
, 0), 0);
1926 mode
= mode_for_size (bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
1928 && GET_MODE_SIZE (GET_MODE (tmp
)) <= bytes
)
1930 /* Whee! Optimize the load to use the existing register. */
1931 data_regs
[nregs
++] = gen_lowpart (mode
, tmp
);
1935 /* ??? We could potentially be copying 3 bytes or whatnot from
1936 a wider reg. Probably not worth worrying about. */
1937 /* No appropriate mode; fall back on memory. */
1938 orig_src
= change_address (orig_src
, GET_MODE (orig_src
),
1939 copy_addr_to_reg (XEXP (orig_src
, 0)));
1943 if (src_align
>= 8 && bytes
>= 8)
1947 for (i
= 0; i
< words
; ++i
)
1948 data_regs
[nregs
+i
] = gen_reg_rtx(DImode
);
1950 for (i
= 0; i
< words
; ++i
)
1952 emit_move_insn (data_regs
[nregs
+i
],
1953 change_address(orig_src
, DImode
,
1954 plus_constant (XEXP (orig_src
, 0),
1962 if (src_align
>= 4 && bytes
>= 4)
1966 for (i
= 0; i
< words
; ++i
)
1967 data_regs
[nregs
+i
] = gen_reg_rtx(SImode
);
1969 for (i
= 0; i
< words
; ++i
)
1971 emit_move_insn (data_regs
[nregs
+i
],
1972 change_address(orig_src
, SImode
,
1973 plus_constant (XEXP (orig_src
, 0),
1985 for (i
= 0; i
< words
+1; ++i
)
1986 data_regs
[nregs
+i
] = gen_reg_rtx(DImode
);
1988 alpha_expand_unaligned_load_words(data_regs
+nregs
, orig_src
, words
, ofs
);
1994 if (!TARGET_BWX
&& bytes
>= 8)
1996 data_regs
[nregs
++] = tmp
= gen_reg_rtx (DImode
);
1997 alpha_expand_unaligned_load (tmp
, orig_src
, 8, ofs
, 0);
2001 if (!TARGET_BWX
&& bytes
>= 4)
2003 data_regs
[nregs
++] = tmp
= gen_reg_rtx (SImode
);
2004 alpha_expand_unaligned_load (tmp
, orig_src
, 4, ofs
, 0);
2013 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
2014 emit_move_insn (tmp
,
2015 change_address (orig_src
, HImode
,
2016 plus_constant (XEXP (orig_src
, 0),
2020 } while (bytes
>= 2);
2022 else if (!TARGET_BWX
)
2024 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
2025 alpha_expand_unaligned_load (tmp
, orig_src
, 2, ofs
, 0);
2032 data_regs
[nregs
++] = tmp
= gen_reg_rtx (QImode
);
2033 emit_move_insn (tmp
,
2034 change_address (orig_src
, QImode
,
2035 plus_constant (XEXP (orig_src
, 0),
2042 if (nregs
> (int)(sizeof(data_regs
)/sizeof(*data_regs
)))
2046 * Now save it back out again.
2051 if (GET_CODE (XEXP (orig_dst
, 0)) == ADDRESSOF
)
2053 enum machine_mode mode
;
2054 tmp
= XEXP (XEXP (orig_dst
, 0), 0);
2056 mode
= mode_for_size (orig_bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
2057 if (GET_MODE (tmp
) == mode
&& nregs
== 1)
2059 emit_move_insn (tmp
, data_regs
[0]);
2064 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2065 /* ??? Optimize mode < dst_mode with strict_low_part. */
2067 /* No appropriate mode; fall back on memory. We can speed things
2068 up by recognizing extra alignment information. */
2069 orig_dst
= change_address (orig_dst
, GET_MODE (orig_dst
),
2070 copy_addr_to_reg (XEXP (orig_dst
, 0)));
2071 dst_align
= GET_MODE_SIZE (GET_MODE (tmp
));
2074 /* Write out the data in whatever chunks reading the source allowed. */
2077 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2079 emit_move_insn (change_address(orig_dst
, DImode
,
2080 plus_constant (XEXP (orig_dst
, 0),
2089 /* If the source has remaining DImode regs, write them out in
2091 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2093 tmp
= expand_binop (DImode
, lshr_optab
, data_regs
[i
], GEN_INT (32),
2094 NULL_RTX
, 1, OPTAB_WIDEN
);
2096 emit_move_insn (change_address(orig_dst
, SImode
,
2097 plus_constant (XEXP (orig_dst
, 0),
2099 gen_lowpart (SImode
, data_regs
[i
]));
2100 emit_move_insn (change_address(orig_dst
, SImode
,
2101 plus_constant (XEXP (orig_dst
, 0),
2103 gen_lowpart (SImode
, tmp
));
2108 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
2110 emit_move_insn (change_address(orig_dst
, SImode
,
2111 plus_constant (XEXP (orig_dst
, 0),
2118 if (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2120 /* Write out a remaining block of words using unaligned methods. */
2122 for (words
= 1; i
+words
< nregs
; ++words
)
2123 if (GET_MODE (data_regs
[i
+words
]) != DImode
)
2127 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 8, ofs
);
2129 alpha_expand_unaligned_store_words (data_regs
+i
, orig_dst
, words
, ofs
);
2135 /* Due to the above, this won't be aligned. */
2136 /* ??? If we have more than one of these, consider constructing full
2137 words in registers and using alpha_expand_unaligned_store_words. */
2138 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
2140 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 4, ofs
);
2146 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
2148 emit_move_insn (change_address (orig_dst
, HImode
,
2149 plus_constant (XEXP (orig_dst
, 0),
2156 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
2158 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 2, ofs
);
2162 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == QImode
)
2164 emit_move_insn (change_address (orig_dst
, QImode
,
2165 plus_constant (XEXP (orig_dst
, 0),
2180 alpha_expand_block_clear (operands
)
2183 rtx bytes_rtx
= operands
[1];
2184 rtx align_rtx
= operands
[2];
2185 HOST_WIDE_INT bytes
= INTVAL (bytes_rtx
);
2186 HOST_WIDE_INT align
= INTVAL (align_rtx
);
2187 rtx orig_dst
= operands
[0];
2189 HOST_WIDE_INT i
, words
, ofs
= 0;
2193 if (bytes
> MAX_MOVE_WORDS
*8)
2196 /* Look for stricter alignment. */
2198 tmp
= XEXP (orig_dst
, 0);
2199 if (GET_CODE (tmp
) == REG
)
2201 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > align
)
2202 align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
2204 else if (GET_CODE (tmp
) == PLUS
2205 && GET_CODE (XEXP (tmp
, 0)) == REG
2206 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
2208 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
2209 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
2213 if (a
>= 8 && c
% 8 == 0)
2215 else if (a
>= 4 && c
% 4 == 0)
2217 else if (a
>= 2 && c
% 2 == 0)
2222 /* Handle a block of contiguous words first. */
2224 if (align
>= 8 && bytes
>= 8)
2228 for (i
= 0; i
< words
; ++i
)
2230 emit_move_insn (change_address(orig_dst
, DImode
,
2231 plus_constant (XEXP (orig_dst
, 0),
2239 if (align
>= 4 && bytes
>= 4)
2243 for (i
= 0; i
< words
; ++i
)
2245 emit_move_insn (change_address(orig_dst
, SImode
,
2246 plus_constant (XEXP (orig_dst
, 0),
2258 alpha_expand_unaligned_store_words (NULL
, orig_dst
, words
, ofs
);
2264 /* Next clean up any trailing pieces. We know from the contiguous
2265 block move that there are no aligned SImode or DImode hunks left. */
2267 if (!TARGET_BWX
&& bytes
>= 8)
2269 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 8, ofs
);
2273 if (!TARGET_BWX
&& bytes
>= 4)
2275 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 4, ofs
);
2284 emit_move_insn (change_address (orig_dst
, HImode
,
2285 plus_constant (XEXP (orig_dst
, 0),
2290 } while (bytes
>= 2);
2292 else if (!TARGET_BWX
)
2294 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 2, ofs
);
2301 emit_move_insn (change_address (orig_dst
, QImode
,
2302 plus_constant (XEXP (orig_dst
, 0),
2313 /* Adjust the cost of a scheduling dependency. Return the new cost of
2314 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2317 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
2324 enum attr_type insn_type
, dep_insn_type
;
2326 /* If the dependence is an anti-dependence, there is no cost. For an
2327 output dependence, there is sometimes a cost, but it doesn't seem
2328 worth handling those few cases. */
2330 if (REG_NOTE_KIND (link
) != 0)
2333 /* If we can't recognize the insns, we can't really do anything. */
2334 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
2337 insn_type
= get_attr_type (insn
);
2338 dep_insn_type
= get_attr_type (dep_insn
);
2340 /* Bring in the user-defined memory latency. */
2341 if (dep_insn_type
== TYPE_ILD
2342 || dep_insn_type
== TYPE_FLD
2343 || dep_insn_type
== TYPE_LDSYM
)
2344 cost
+= alpha_memory_latency
-1;
2349 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2350 being stored, we can sometimes lower the cost. */
2352 if ((insn_type
== TYPE_IST
|| insn_type
== TYPE_FST
)
2353 && (set
= single_set (dep_insn
)) != 0
2354 && GET_CODE (PATTERN (insn
)) == SET
2355 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
2357 switch (dep_insn_type
)
2361 /* No savings here. */
2365 /* In these cases, we save one cycle. */
2369 /* In all other cases, we save two cycles. */
2370 return MAX (0, cost
- 2);
2374 /* Another case that needs adjustment is an arithmetic or logical
2375 operation. It's cost is usually one cycle, but we default it to
2376 two in the MD file. The only case that it is actually two is
2377 for the address in loads, stores, and jumps. */
2379 if (dep_insn_type
== TYPE_IADD
|| dep_insn_type
== TYPE_ILOG
)
2394 /* The final case is when a compare feeds into an integer branch;
2395 the cost is only one cycle in that case. */
2397 if (dep_insn_type
== TYPE_ICMP
&& insn_type
== TYPE_IBR
)
2402 /* And the lord DEC saith: "A special bypass provides an effective
2403 latency of 0 cycles for an ICMP or ILOG insn producing the test
2404 operand of an IBR or ICMOV insn." */
2406 if ((dep_insn_type
== TYPE_ICMP
|| dep_insn_type
== TYPE_ILOG
)
2407 && (set
= single_set (dep_insn
)) != 0)
2409 /* A branch only has one input. This must be it. */
2410 if (insn_type
== TYPE_IBR
)
2412 /* A conditional move has three, make sure it is the test. */
2413 if (insn_type
== TYPE_ICMOV
2414 && GET_CODE (set_src
= PATTERN (insn
)) == SET
2415 && GET_CODE (set_src
= SET_SRC (set_src
)) == IF_THEN_ELSE
2416 && rtx_equal_p (SET_DEST (set
), XEXP (set_src
, 0)))
2420 /* "The multiplier is unable to receive data from IEU bypass paths.
2421 The instruction issues at the expected time, but its latency is
2422 increased by the time it takes for the input data to become
2423 available to the multiplier" -- which happens in pipeline stage
2424 six, when results are comitted to the register file. */
2426 if (insn_type
== TYPE_IMUL
)
2428 switch (dep_insn_type
)
2430 /* These insns produce their results in pipeline stage five. */
2437 /* Other integer insns produce results in pipeline stage four. */
2445 /* There is additional latency to move the result of (most) FP
2446 operations anywhere but the FP register file. */
2448 if ((insn_type
== TYPE_FST
|| insn_type
== TYPE_FTOI
)
2449 && (dep_insn_type
== TYPE_FADD
||
2450 dep_insn_type
== TYPE_FMUL
||
2451 dep_insn_type
== TYPE_FCMOV
))
2457 /* Otherwise, return the default cost. */
2461 /* Functions to save and restore alpha_return_addr_rtx. */
2463 struct machine_function
2469 alpha_save_machine_status (p
)
2472 struct machine_function
*machine
=
2473 (struct machine_function
*) xmalloc (sizeof (struct machine_function
));
2475 p
->machine
= machine
;
2476 machine
->ra_rtx
= alpha_return_addr_rtx
;
2480 alpha_restore_machine_status (p
)
2483 struct machine_function
*machine
= p
->machine
;
2485 alpha_return_addr_rtx
= machine
->ra_rtx
;
2488 p
->machine
= (struct machine_function
*)0;
2491 /* Do anything needed before RTL is emitted for each function. */
2494 alpha_init_expanders ()
2496 alpha_return_addr_rtx
= NULL_RTX
;
2497 alpha_eh_epilogue_sp_ofs
= NULL_RTX
;
2499 /* Arrange to save and restore machine status around nested functions. */
2500 save_machine_status
= alpha_save_machine_status
;
2501 restore_machine_status
= alpha_restore_machine_status
;
2504 /* Start the ball rolling with RETURN_ADDR_RTX. */
2507 alpha_return_addr (count
, frame
)
2509 rtx frame ATTRIBUTE_UNUSED
;
2516 if (alpha_return_addr_rtx
)
2517 return alpha_return_addr_rtx
;
2519 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2520 alpha_return_addr_rtx
= gen_reg_rtx (Pmode
);
2521 init
= gen_rtx_SET (VOIDmode
, alpha_return_addr_rtx
,
2522 gen_rtx_REG (Pmode
, REG_RA
));
2524 /* Emit the insn to the prologue with the other argument copies. */
2525 push_topmost_sequence ();
2526 emit_insn_after (init
, get_insns ());
2527 pop_topmost_sequence ();
2529 return alpha_return_addr_rtx
;
2533 alpha_ra_ever_killed ()
2537 #ifdef ASM_OUTPUT_MI_THUNK
2538 if (current_function_is_thunk
)
2541 if (!alpha_return_addr_rtx
)
2542 return regs_ever_live
[REG_RA
];
2544 push_topmost_sequence ();
2546 pop_topmost_sequence ();
2548 return reg_set_between_p (gen_rtx_REG (Pmode
, REG_RA
), top
, NULL_RTX
);
2552 /* Print an operand. Recognize special options, documented below. */
2555 print_operand (file
, x
, code
)
2565 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2566 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2567 mode. alpha_fprm controls which suffix is generated. */
2570 case ALPHA_FPRM_NORM
:
2572 case ALPHA_FPRM_MINF
:
2575 case ALPHA_FPRM_CHOP
:
2578 case ALPHA_FPRM_DYN
:
2585 /* Generates trap-mode suffix for instructions that accept the su
2586 suffix only (cmpt et al). */
2587 if (alpha_tp
== ALPHA_TP_INSN
)
2592 /* Generates trap-mode suffix for instructions that accept the
2593 v and sv suffix. The only instruction that needs this is cvtql. */
2602 case ALPHA_FPTM_SUI
:
2609 /* Generates trap-mode suffix for instructions that accept the
2610 v, sv, and svi suffix. The only instruction that needs this
2622 case ALPHA_FPTM_SUI
:
2623 fputs ("svi", file
);
2629 /* Generates trap-mode suffix for instructions that accept the u, su,
2630 and sui suffix. This is the bulk of the IEEE floating point
2631 instructions (addt et al). */
2642 case ALPHA_FPTM_SUI
:
2643 fputs ("sui", file
);
2649 /* Generates trap-mode suffix for instructions that accept the sui
2650 suffix (cvtqt and cvtqs). */
2655 case ALPHA_FPTM_SU
: /* cvtqt/cvtqs can't cause underflow */
2657 case ALPHA_FPTM_SUI
:
2658 fputs ("sui", file
);
2664 /* Generates single precision instruction suffix. */
2665 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'f' : 's'));
2669 /* Generates double precision instruction suffix. */
2670 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'g' : 't'));
2674 /* If this operand is the constant zero, write it as "$31". */
2675 if (GET_CODE (x
) == REG
)
2676 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2677 else if (x
== CONST0_RTX (GET_MODE (x
)))
2678 fprintf (file
, "$31");
2680 output_operand_lossage ("invalid %%r value");
2685 /* Similar, but for floating-point. */
2686 if (GET_CODE (x
) == REG
)
2687 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2688 else if (x
== CONST0_RTX (GET_MODE (x
)))
2689 fprintf (file
, "$f31");
2691 output_operand_lossage ("invalid %%R value");
2696 /* Write the 1's complement of a constant. */
2697 if (GET_CODE (x
) != CONST_INT
)
2698 output_operand_lossage ("invalid %%N value");
2700 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INTVAL (x
));
2704 /* Write 1 << C, for a constant C. */
2705 if (GET_CODE (x
) != CONST_INT
)
2706 output_operand_lossage ("invalid %%P value");
2708 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
) 1 << INTVAL (x
));
2712 /* Write the high-order 16 bits of a constant, sign-extended. */
2713 if (GET_CODE (x
) != CONST_INT
)
2714 output_operand_lossage ("invalid %%h value");
2716 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) >> 16);
2720 /* Write the low-order 16 bits of a constant, sign-extended. */
2721 if (GET_CODE (x
) != CONST_INT
)
2722 output_operand_lossage ("invalid %%L value");
2724 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
2725 (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
2729 /* Write mask for ZAP insn. */
2730 if (GET_CODE (x
) == CONST_DOUBLE
)
2732 HOST_WIDE_INT mask
= 0;
2733 HOST_WIDE_INT value
;
2735 value
= CONST_DOUBLE_LOW (x
);
2736 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
2741 value
= CONST_DOUBLE_HIGH (x
);
2742 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
2745 mask
|= (1 << (i
+ sizeof (int)));
2747 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
& 0xff);
2750 else if (GET_CODE (x
) == CONST_INT
)
2752 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
2754 for (i
= 0; i
< 8; i
++, value
>>= 8)
2758 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
2761 output_operand_lossage ("invalid %%m value");
2765 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2766 if (GET_CODE (x
) != CONST_INT
2767 || (INTVAL (x
) != 8 && INTVAL (x
) != 16
2768 && INTVAL (x
) != 32 && INTVAL (x
) != 64))
2769 output_operand_lossage ("invalid %%M value");
2771 fprintf (file
, "%s",
2772 (INTVAL (x
) == 8 ? "b"
2773 : INTVAL (x
) == 16 ? "w"
2774 : INTVAL (x
) == 32 ? "l"
2779 /* Similar, except do it from the mask. */
2780 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
2781 fprintf (file
, "b");
2782 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
2783 fprintf (file
, "w");
2784 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
2785 fprintf (file
, "l");
2786 #if HOST_BITS_PER_WIDE_INT == 32
2787 else if (GET_CODE (x
) == CONST_DOUBLE
2788 && CONST_DOUBLE_HIGH (x
) == 0
2789 && CONST_DOUBLE_LOW (x
) == -1)
2790 fprintf (file
, "l");
2791 else if (GET_CODE (x
) == CONST_DOUBLE
2792 && CONST_DOUBLE_HIGH (x
) == -1
2793 && CONST_DOUBLE_LOW (x
) == -1)
2794 fprintf (file
, "q");
2796 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == -1)
2797 fprintf (file
, "q");
2798 else if (GET_CODE (x
) == CONST_DOUBLE
2799 && CONST_DOUBLE_HIGH (x
) == 0
2800 && CONST_DOUBLE_LOW (x
) == -1)
2801 fprintf (file
, "q");
2804 output_operand_lossage ("invalid %%U value");
2808 /* Write the constant value divided by 8. */
2809 if (GET_CODE (x
) != CONST_INT
2810 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
2811 && (INTVAL (x
) & 7) != 8)
2812 output_operand_lossage ("invalid %%s value");
2814 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) / 8);
2818 /* Same, except compute (64 - c) / 8 */
2820 if (GET_CODE (x
) != CONST_INT
2821 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
2822 && (INTVAL (x
) & 7) != 8)
2823 output_operand_lossage ("invalid %%s value");
2825 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (64 - INTVAL (x
)) / 8);
2828 case 'C': case 'D': case 'c': case 'd':
2829 /* Write out comparison name. */
2831 enum rtx_code c
= GET_CODE (x
);
2833 if (GET_RTX_CLASS (c
) != '<')
2834 output_operand_lossage ("invalid %%C value");
2837 c
= reverse_condition (c
);
2838 else if (code
== 'c')
2839 c
= swap_condition (c
);
2840 else if (code
== 'd')
2841 c
= swap_condition (reverse_condition (c
));
2844 fprintf (file
, "ule");
2846 fprintf (file
, "ult");
2848 fprintf (file
, "%s", GET_RTX_NAME (c
));
2853 /* Write the divide or modulus operator. */
2854 switch (GET_CODE (x
))
2857 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
2860 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
2863 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
2866 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
2869 output_operand_lossage ("invalid %%E value");
2875 /* Write "_u" for unaligned access. */
2876 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
2877 fprintf (file
, "_u");
2881 if (GET_CODE (x
) == REG
)
2882 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2883 else if (GET_CODE (x
) == MEM
)
2884 output_address (XEXP (x
, 0));
2886 output_addr_const (file
, x
);
2890 output_operand_lossage ("invalid %%xn code");
2894 /* Emit RTL insns to initialize the variable parts of a trampoline at
2895 TRAMP. FNADDR is an RTX for the address of the function's pure
2896 code. CXT is an RTX for the static chain value for the function.
2898 The three offset parameters are for the individual template's
2899 layout. A JMPOFS < 0 indicates that the trampoline does not
2900 contain instructions at all.
2902 We assume here that a function will be called many more times than
2903 its address is taken (e.g., it might be passed to qsort), so we
2904 take the trouble to initialize the "hint" field in the JMP insn.
2905 Note that the hint field is PC (new) + 4 * bits 13:0. */
2908 alpha_initialize_trampoline (tramp
, fnaddr
, cxt
, fnofs
, cxtofs
, jmpofs
)
2909 rtx tramp
, fnaddr
, cxt
;
2910 int fnofs
, cxtofs
, jmpofs
;
2912 rtx temp
, temp1
, addr
;
2913 /* ??? Something is wrong with VMS codegen in that we get aborts when
2914 using ptr_mode. Hack around it for now. */
2915 enum machine_mode mode
= TARGET_OPEN_VMS
? Pmode
: ptr_mode
;
2917 /* Store function address and CXT. */
2918 addr
= memory_address (mode
, plus_constant (tramp
, fnofs
));
2919 emit_move_insn (gen_rtx (MEM
, mode
, addr
), fnaddr
);
2920 addr
= memory_address (mode
, plus_constant (tramp
, cxtofs
));
2921 emit_move_insn (gen_rtx (MEM
, mode
, addr
), cxt
);
2923 /* This has been disabled since the hint only has a 32k range, and in
2924 no existing OS is the stack within 32k of the text segment. */
2925 if (0 && jmpofs
>= 0)
2927 /* Compute hint value. */
2928 temp
= force_operand (plus_constant (tramp
, jmpofs
+4), NULL_RTX
);
2929 temp
= expand_binop (DImode
, sub_optab
, fnaddr
, temp
, temp
, 1,
2931 temp
= expand_shift (RSHIFT_EXPR
, Pmode
, temp
,
2932 build_int_2 (2, 0), NULL_RTX
, 1);
2933 temp
= expand_and (gen_lowpart (SImode
, temp
), GEN_INT (0x3fff), 0);
2935 /* Merge in the hint. */
2936 addr
= memory_address (SImode
, plus_constant (tramp
, jmpofs
));
2937 temp1
= force_reg (SImode
, gen_rtx (MEM
, SImode
, addr
));
2938 temp1
= expand_and (temp1
, GEN_INT (0xffffc000), NULL_RTX
);
2939 temp1
= expand_binop (SImode
, ior_optab
, temp1
, temp
, temp1
, 1,
2941 emit_move_insn (gen_rtx (MEM
, SImode
, addr
), temp1
);
2944 #ifdef TRANSFER_FROM_TRAMPOLINE
2945 emit_library_call (gen_rtx (SYMBOL_REF
, Pmode
, "__enable_execute_stack"),
2946 0, VOIDmode
, 1, addr
, Pmode
);
2950 emit_insn (gen_imb ());
2953 /* Do what is necessary for `va_start'. The argument is ignored;
2954 We look at the current function to determine if stdarg or varargs
2955 is used and fill in an initial va_list. A pointer to this constructor
2959 alpha_builtin_saveregs (arglist
)
2960 tree arglist ATTRIBUTE_UNUSED
;
2962 rtx block
, addr
, dest
, argsize
;
2963 tree fntype
= TREE_TYPE (current_function_decl
);
2964 int stdarg
= (TYPE_ARG_TYPES (fntype
) != 0
2965 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
2966 != void_type_node
));
2968 /* Compute the current position into the args, taking into account
2969 both registers and memory. Both of these are already included in
2972 argsize
= GEN_INT (NUM_ARGS
* UNITS_PER_WORD
);
2974 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2975 storing fp arg registers in the first 48 bytes, and the integer arg
2976 registers in the next 48 bytes. This is only done, however, if any
2977 integer registers need to be stored.
2979 If no integer registers need be stored, then we must subtract 48 in
2980 order to account for the integer arg registers which are counted in
2981 argsize above, but which are not actually stored on the stack. */
2983 if (TARGET_OPEN_VMS
)
2984 addr
= plus_constant (virtual_incoming_args_rtx
,
2985 NUM_ARGS
<= 5 + stdarg
2986 ? UNITS_PER_WORD
: - 6 * UNITS_PER_WORD
);
2988 addr
= (NUM_ARGS
<= 5 + stdarg
2989 ? plus_constant (virtual_incoming_args_rtx
,
2991 : plus_constant (virtual_incoming_args_rtx
,
2992 - (6 * UNITS_PER_WORD
)));
2994 /* For VMS, we include the argsize, while on Unix, it's handled as
2995 a separate field. */
2996 if (TARGET_OPEN_VMS
)
2997 addr
= plus_constant (addr
, INTVAL (argsize
));
2999 addr
= force_operand (addr
, NULL_RTX
);
3001 #ifdef POINTERS_EXTEND_UNSIGNED
3002 addr
= convert_memory_address (ptr_mode
, addr
);
3005 if (TARGET_OPEN_VMS
)
3009 /* Allocate the va_list constructor */
3010 block
= assign_stack_local (BLKmode
, 2 * UNITS_PER_WORD
, BITS_PER_WORD
);
3011 RTX_UNCHANGING_P (block
) = 1;
3012 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
3014 /* Store the address of the first integer register in the __base
3017 dest
= change_address (block
, ptr_mode
, XEXP (block
, 0));
3018 emit_move_insn (dest
, addr
);
3020 if (current_function_check_memory_usage
)
3021 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
3023 GEN_INT (GET_MODE_SIZE (ptr_mode
)),
3024 TYPE_MODE (sizetype
),
3025 GEN_INT (MEMORY_USE_RW
),
3026 TYPE_MODE (integer_type_node
));
3028 /* Store the argsize as the __va_offset member. */
3029 dest
= change_address (block
, TYPE_MODE (integer_type_node
),
3030 plus_constant (XEXP (block
, 0),
3031 POINTER_SIZE
/BITS_PER_UNIT
));
3032 emit_move_insn (dest
, argsize
);
3034 if (current_function_check_memory_usage
)
3035 emit_library_call (chkr_set_right_libfunc
, 1, VOIDmode
, 3,
3037 GEN_INT (GET_MODE_SIZE
3038 (TYPE_MODE (integer_type_node
))),
3039 TYPE_MODE (sizetype
),
3040 GEN_INT (MEMORY_USE_RW
),
3041 TYPE_MODE (integer_type_node
));
3043 /* Return the address of the va_list constructor, but don't put it in a
3044 register. Doing so would fail when not optimizing and produce worse
3045 code when optimizing. */
3046 return XEXP (block
, 0);
3050 /* This page contains routines that are used to determine what the function
3051 prologue and epilogue code will do and write them out. */
3053 /* Compute the size of the save area in the stack. */
3055 /* These variables are used for communication between the following functions.
3056 They indicate various things about the current function being compiled
3057 that are used to tell what kind of prologue, epilogue and procedure
3058 descriptior to generate. */
3060 /* Nonzero if we need a stack procedure. */
3061 static int vms_is_stack_procedure
;
3063 /* Register number (either FP or SP) that is used to unwind the frame. */
3064 static int vms_unwind_regno
;
3066 /* Register number used to save FP. We need not have one for RA since
3067 we don't modify it for register procedures. This is only defined
3068 for register frame procedures. */
3069 static int vms_save_fp_regno
;
3071 /* Register number used to reference objects off our PV. */
3072 static int vms_base_regno
;
3074 /* Compute register masks for saved registers. */
3077 alpha_sa_mask (imaskP
, fmaskP
)
3078 unsigned long *imaskP
;
3079 unsigned long *fmaskP
;
3081 unsigned long imask
= 0;
3082 unsigned long fmask
= 0;
3085 #ifdef ASM_OUTPUT_MI_THUNK
3086 if (!current_function_is_thunk
)
3089 if (TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3090 imask
|= (1L << HARD_FRAME_POINTER_REGNUM
);
3092 /* One for every register we have to save. */
3093 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3094 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
3095 && regs_ever_live
[i
] && i
!= REG_RA
)
3100 fmask
|= (1L << (i
- 32));
3103 if (imask
|| fmask
|| alpha_ra_ever_killed ())
3104 imask
|= (1L << REG_RA
);
3117 #ifdef ASM_OUTPUT_MI_THUNK
3118 if (current_function_is_thunk
)
3123 /* One for every register we have to save. */
3124 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3125 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
3126 && regs_ever_live
[i
] && i
!= REG_RA
)
3130 if (TARGET_OPEN_VMS
)
3132 /* Start by assuming we can use a register procedure if we don't
3133 make any calls (REG_RA not used) or need to save any
3134 registers and a stack procedure if we do. */
3135 vms_is_stack_procedure
= sa_size
!= 0 || alpha_ra_ever_killed ();
3137 /* Decide whether to refer to objects off our PV via FP or PV.
3138 If we need FP for something else or if we receive a nonlocal
3139 goto (which expects PV to contain the value), we must use PV.
3140 Otherwise, start by assuming we can use FP. */
3141 vms_base_regno
= (frame_pointer_needed
3142 || current_function_has_nonlocal_label
3143 || vms_is_stack_procedure
3144 || current_function_outgoing_args_size
3145 ? REG_PV
: HARD_FRAME_POINTER_REGNUM
);
3147 /* If we want to copy PV into FP, we need to find some register
3148 in which to save FP. */
3150 vms_save_fp_regno
= -1;
3151 if (vms_base_regno
== HARD_FRAME_POINTER_REGNUM
)
3152 for (i
= 0; i
< 32; i
++)
3153 if (! fixed_regs
[i
] && call_used_regs
[i
] && ! regs_ever_live
[i
])
3154 vms_save_fp_regno
= i
;
3156 if (vms_save_fp_regno
== -1)
3157 vms_base_regno
= REG_PV
, vms_is_stack_procedure
= 1;
3159 /* Stack unwinding should be done via FP unless we use it for PV. */
3160 vms_unwind_regno
= (vms_base_regno
== REG_PV
3161 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
3163 /* If this is a stack procedure, allow space for saving FP and RA. */
3164 if (vms_is_stack_procedure
)
3169 /* If some registers were saved but not RA, RA must also be saved,
3170 so leave space for it. */
3171 if (sa_size
!= 0 || alpha_ra_ever_killed ())
3174 /* Our size must be even (multiple of 16 bytes). */
3183 alpha_pv_save_size ()
3186 return vms_is_stack_procedure
? 8 : 0;
3193 return vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
;
3197 vms_valid_decl_attribute_p (decl
, attributes
, identifier
, args
)
3198 tree decl ATTRIBUTE_UNUSED
;
3199 tree attributes ATTRIBUTE_UNUSED
;
3203 if (is_attribute_p ("overlaid", identifier
))
3204 return (args
== NULL_TREE
);
3209 alpha_does_function_need_gp ()
3213 /* We never need a GP for Windows/NT or VMS. */
3214 if (TARGET_WINDOWS_NT
|| TARGET_OPEN_VMS
)
3217 #ifdef TARGET_PROFILING_NEEDS_GP
3222 #ifdef ASM_OUTPUT_MI_THUNK
3223 if (current_function_is_thunk
)
3227 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3228 Even if we are a static function, we still need to do this in case
3229 our address is taken and passed to something like qsort. */
3231 push_topmost_sequence ();
3232 insn
= get_insns ();
3233 pop_topmost_sequence ();
3235 for (; insn
; insn
= NEXT_INSN (insn
))
3236 if (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
3237 && GET_CODE (PATTERN (insn
)) != USE
3238 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
3240 enum attr_type type
= get_attr_type (insn
);
3241 if (type
== TYPE_LDSYM
|| type
== TYPE_JSR
)
3248 /* Write a version stamp. Don't write anything if we are running as a
3249 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3256 alpha_write_verstamp (file
)
3260 fprintf (file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
3264 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3268 set_frame_related_p ()
3270 rtx seq
= gen_sequence ();
3273 if (GET_CODE (seq
) == SEQUENCE
)
3275 int i
= XVECLEN (seq
, 0);
3277 RTX_FRAME_RELATED_P (XVECEXP (seq
, 0, i
)) = 1;
3278 return emit_insn (seq
);
3282 seq
= emit_insn (seq
);
3283 RTX_FRAME_RELATED_P (seq
) = 1;
3288 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3290 /* Write function prologue. */
3292 /* On vms we have two kinds of functions:
3294 - stack frame (PROC_STACK)
3295 these are 'normal' functions with local vars and which are
3296 calling other functions
3297 - register frame (PROC_REGISTER)
3298 keeps all data in registers, needs no stack
3300 We must pass this to the assembler so it can generate the
3301 proper pdsc (procedure descriptor)
3302 This is done with the '.pdesc' command.
3304 On not-vms, we don't really differentiate between the two, as we can
3305 simply allocate stack without saving registers. */
3308 alpha_expand_prologue ()
3310 /* Registers to save. */
3311 unsigned long imask
= 0;
3312 unsigned long fmask
= 0;
3313 /* Stack space needed for pushing registers clobbered by us. */
3314 HOST_WIDE_INT sa_size
;
3315 /* Complete stack size needed. */
3316 HOST_WIDE_INT frame_size
;
3317 /* Offset from base reg to register save area. */
3318 HOST_WIDE_INT reg_offset
;
3322 sa_size
= alpha_sa_size ();
3324 frame_size
= get_frame_size ();
3325 if (TARGET_OPEN_VMS
)
3326 frame_size
= ALPHA_ROUND (sa_size
3327 + (vms_is_stack_procedure
? 8 : 0)
3329 + current_function_pretend_args_size
);
3331 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3333 + ALPHA_ROUND (frame_size
3334 + current_function_pretend_args_size
));
3336 if (TARGET_OPEN_VMS
)
3339 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3341 alpha_sa_mask (&imask
, &fmask
);
3343 /* Adjust the stack by the frame size. If the frame size is > 4096
3344 bytes, we need to be sure we probe somewhere in the first and last
3345 4096 bytes (we can probably get away without the latter test) and
3346 every 8192 bytes in between. If the frame size is > 32768, we
3347 do this in a loop. Otherwise, we generate the explicit probe
3350 Note that we are only allowed to adjust sp once in the prologue. */
3352 if (frame_size
<= 32768)
3354 if (frame_size
> 4096)
3359 emit_insn (gen_probe_stack (GEN_INT (-probed
)));
3360 while ((probed
+= 8192) < frame_size
);
3362 /* We only have to do this probe if we aren't saving registers. */
3363 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
3364 emit_insn (gen_probe_stack (GEN_INT (-frame_size
)));
3367 if (frame_size
!= 0)
3369 FRP (emit_move_insn (stack_pointer_rtx
,
3370 plus_constant (stack_pointer_rtx
, -frame_size
)));
3375 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3376 number of 8192 byte blocks to probe. We then probe each block
3377 in the loop and then set SP to the proper location. If the
3378 amount remaining is > 4096, we have to do one more probe if we
3379 are not saving any registers. */
3381 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
3382 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
3383 rtx ptr
= gen_rtx_REG (DImode
, 22);
3384 rtx count
= gen_rtx_REG (DImode
, 23);
3386 emit_move_insn (count
, GEN_INT (blocks
));
3387 emit_move_insn (ptr
, plus_constant (stack_pointer_rtx
, 4096));
3389 /* Because of the difficulty in emitting a new basic block this
3390 late in the compilation, generate the loop as a single insn. */
3391 emit_insn (gen_prologue_stack_probe_loop (count
, ptr
));
3393 if (leftover
> 4096 && sa_size
== 0)
3395 rtx last
= gen_rtx_MEM (DImode
, plus_constant (ptr
, -leftover
));
3396 MEM_VOLATILE_P (last
) = 1;
3397 emit_move_insn (last
, const0_rtx
);
3400 ptr
= emit_move_insn (stack_pointer_rtx
, plus_constant (ptr
, -leftover
));
3402 /* This alternative is special, because the DWARF code cannot possibly
3403 intuit through the loop above. So we invent this note it looks at
3405 RTX_FRAME_RELATED_P (ptr
) = 1;
3407 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
3408 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
3409 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3410 GEN_INT (-frame_size
))),
3414 /* Cope with very large offsets to the register save area. */
3415 sa_reg
= stack_pointer_rtx
;
3416 if (reg_offset
+ sa_size
> 0x8000)
3418 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
3421 if (low
+ sa_size
<= 0x8000)
3422 bias
= reg_offset
- low
, reg_offset
= low
;
3424 bias
= reg_offset
, reg_offset
= 0;
3426 sa_reg
= gen_rtx_REG (DImode
, 24);
3427 FRP (emit_move_insn (sa_reg
, plus_constant (stack_pointer_rtx
, bias
)));
3430 /* Save regs in stack order. Beginning with VMS PV. */
3431 if (TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3433 mem
= gen_rtx_MEM (DImode
, stack_pointer_rtx
);
3434 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3435 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_PV
)));
3438 /* Save register RA next. */
3439 if (imask
& (1L << REG_RA
))
3441 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
3442 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3443 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_RA
)));
3444 imask
&= ~(1L << REG_RA
);
3448 /* Now save any other registers required to be saved. */
3449 for (i
= 0; i
< 32; i
++)
3450 if (imask
& (1L << i
))
3452 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
3453 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3454 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, i
)));
3458 for (i
= 0; i
< 32; i
++)
3459 if (fmask
& (1L << i
))
3461 mem
= gen_rtx_MEM (DFmode
, plus_constant (sa_reg
, reg_offset
));
3462 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3463 FRP (emit_move_insn (mem
, gen_rtx_REG (DFmode
, i
+32)));
3467 if (TARGET_OPEN_VMS
)
3469 if (!vms_is_stack_procedure
)
3471 /* Register frame procedures fave the fp. */
3472 FRP (emit_move_insn (gen_rtx_REG (DImode
, vms_save_fp_regno
),
3473 hard_frame_pointer_rtx
));
3476 if (vms_base_regno
!= REG_PV
)
3477 FRP (emit_move_insn (gen_rtx_REG (DImode
, vms_base_regno
),
3478 gen_rtx_REG (DImode
, REG_PV
)));
3480 if (vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
3482 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
3485 /* If we have to allocate space for outgoing args, do it now. */
3486 if (current_function_outgoing_args_size
!= 0)
3488 FRP (emit_move_insn (stack_pointer_rtx
,
3489 plus_constant (hard_frame_pointer_rtx
,
3490 - ALPHA_ROUND (current_function_outgoing_args_size
))));
3495 /* If we need a frame pointer, set it from the stack pointer. */
3496 if (frame_pointer_needed
)
3498 if (TARGET_CAN_FAULT_IN_PROLOGUE
)
3499 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
3502 /* This must always be the last instruction in the
3503 prologue, thus we emit a special move + clobber. */
3504 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx
,
3505 stack_pointer_rtx
, sa_reg
)));
3510 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3511 the prologue, for exception handling reasons, we cannot do this for
3512 any insn that might fault. We could prevent this for mems with a
3513 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3514 have to prevent all such scheduling with a blockage.
3516 Linux, on the other hand, never bothered to implement OSF/1's
3517 exception handling, and so doesn't care about such things. Anyone
3518 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3520 if (! TARGET_CAN_FAULT_IN_PROLOGUE
)
3521 emit_insn (gen_blockage ());
3524 /* Output the textual info surrounding the prologue. */
3527 alpha_start_function (file
, fnname
, decl
)
3530 tree decl ATTRIBUTE_UNUSED
;
3532 unsigned long imask
= 0;
3533 unsigned long fmask
= 0;
3534 /* Stack space needed for pushing registers clobbered by us. */
3535 HOST_WIDE_INT sa_size
;
3536 /* Complete stack size needed. */
3537 HOST_WIDE_INT frame_size
;
3538 /* Offset from base reg to register save area. */
3539 HOST_WIDE_INT reg_offset
;
3540 char *entry_label
= (char *) alloca (strlen (fnname
) + 6);
3543 sa_size
= alpha_sa_size ();
3545 frame_size
= get_frame_size ();
3546 if (TARGET_OPEN_VMS
)
3547 frame_size
= ALPHA_ROUND (sa_size
3548 + (vms_is_stack_procedure
? 8 : 0)
3550 + current_function_pretend_args_size
);
3552 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3554 + ALPHA_ROUND (frame_size
3555 + current_function_pretend_args_size
));
3557 if (TARGET_OPEN_VMS
)
3560 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3562 alpha_sa_mask (&imask
, &fmask
);
3564 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3565 We have to do that before the .ent directive as we cannot switch
3566 files within procedures with native ecoff because line numbers are
3567 linked to procedure descriptors.
3568 Outputting the lineno helps debugging of one line functions as they
3569 would otherwise get no line number at all. Please note that we would
3570 like to put out last_linenum from final.c, but it is not accessible. */
3572 if (write_symbols
== SDB_DEBUG
)
3574 ASM_OUTPUT_SOURCE_FILENAME (file
,
3575 DECL_SOURCE_FILE (current_function_decl
));
3576 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
3577 ASM_OUTPUT_SOURCE_LINE (file
,
3578 DECL_SOURCE_LINE (current_function_decl
));
3581 /* Issue function start and label. */
3582 if (TARGET_OPEN_VMS
|| !flag_inhibit_size_directive
)
3584 fputs ("\t.ent ", file
);
3585 assemble_name (file
, fnname
);
3589 strcpy (entry_label
, fnname
);
3590 if (TARGET_OPEN_VMS
)
3591 strcat (entry_label
, "..en");
3592 ASM_OUTPUT_LABEL (file
, entry_label
);
3593 inside_function
= TRUE
;
3595 if (TARGET_OPEN_VMS
)
3596 fprintf (file
, "\t.base $%d\n", vms_base_regno
);
3598 if (!TARGET_OPEN_VMS
&& TARGET_IEEE_CONFORMANT
3599 && !flag_inhibit_size_directive
)
3601 /* Set flags in procedure descriptor to request IEEE-conformant
3602 math-library routines. The value we set it to is PDSC_EXC_IEEE
3603 (/usr/include/pdsc.h). */
3604 fputs ("\t.eflag 48\n", file
);
3607 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3608 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
3609 alpha_arg_offset
= -frame_size
+ 48;
3611 /* Describe our frame. If the frame size is larger than an integer,
3612 print it as zero to avoid an assembler error. We won't be
3613 properly describing such a frame, but that's the best we can do. */
3614 if (TARGET_OPEN_VMS
)
3616 fprintf (file
, "\t.frame $%d,", vms_unwind_regno
);
3617 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3618 frame_size
>= (1l << 31) ? 0 : frame_size
);
3619 fputs (",$26,", file
);
3620 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, reg_offset
);
3623 else if (!flag_inhibit_size_directive
)
3625 fprintf (file
, "\t.frame $%d,",
3626 (frame_pointer_needed
3627 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
));
3628 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3629 frame_size
>= (1l << 31) ? 0 : frame_size
);
3630 fprintf (file
, ",$26,%d\n", current_function_pretend_args_size
);
3633 /* Describe which registers were spilled. */
3634 if (TARGET_OPEN_VMS
)
3637 /* ??? Does VMS care if mask contains ra? The old code did'nt
3638 set it, so I don't here. */
3639 fprintf (file
, "\t.mask 0x%lx,0\n", imask
& ~(1L << REG_RA
));
3641 fprintf (file
, "\t.fmask 0x%lx,0\n", fmask
);
3642 if (!vms_is_stack_procedure
)
3643 fprintf (file
, "\t.fp_save $%d\n", vms_save_fp_regno
);
3645 else if (!flag_inhibit_size_directive
)
3649 fprintf (file
, "\t.mask 0x%lx,", imask
);
3650 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3651 frame_size
>= (1l << 31) ? 0 : reg_offset
- frame_size
);
3654 for (i
= 0; i
< 32; ++i
)
3655 if (imask
& (1L << i
))
3661 fprintf (file
, "\t.fmask 0x%lx,", fmask
);
3662 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3663 frame_size
>= (1l << 31) ? 0 : reg_offset
- frame_size
);
3668 /* Emit GP related things. It is rather unfortunate about the alignment
3669 issues surrounding a CODE_LABEL that forces us to do the label in
3671 if (!TARGET_OPEN_VMS
&& !TARGET_WINDOWS_NT
)
3673 alpha_function_needs_gp
= alpha_does_function_need_gp ();
3674 if (alpha_function_needs_gp
)
3675 fputs ("\tldgp $29,0($27)\n", file
);
3678 assemble_name (file
, fnname
);
3679 fputs ("..ng:\n", file
);
3683 /* Ifdef'ed cause readonly_section and link_section are only
3685 readonly_section ();
3686 fprintf (file
, "\t.align 3\n");
3687 assemble_name (file
, fnname
); fputs ("..na:\n", file
);
3688 fputs ("\t.ascii \"", file
);
3689 assemble_name (file
, fnname
);
3690 fputs ("\\0\"\n", file
);
3693 fprintf (file
, "\t.align 3\n");
3694 fputs ("\t.name ", file
);
3695 assemble_name (file
, fnname
);
3696 fputs ("..na\n", file
);
3697 ASM_OUTPUT_LABEL (file
, fnname
);
3698 fprintf (file
, "\t.pdesc ");
3699 assemble_name (file
, fnname
);
3700 fprintf (file
, "..en,%s\n", vms_is_stack_procedure
? "stack" : "reg");
3701 alpha_need_linkage (fnname
, 1);
3706 /* Emit the .prologue note at the scheduled end of the prologue. */
3709 output_end_prologue (file
)
3712 if (TARGET_OPEN_VMS
)
3713 fputs ("\t.prologue\n", file
);
3714 else if (TARGET_WINDOWS_NT
)
3715 fputs ("\t.prologue 0\n", file
);
3716 else if (!flag_inhibit_size_directive
)
3717 fprintf (file
, "\t.prologue %d\n", alpha_function_needs_gp
);
3720 /* Write function epilogue. */
3722 /* ??? At some point we will want to support full unwind, and so will
3723 need to mark the epilogue as well. At the moment, we just confuse
3726 #define FRP(exp) exp
3729 alpha_expand_epilogue ()
3731 /* Registers to save. */
3732 unsigned long imask
= 0;
3733 unsigned long fmask
= 0;
3734 /* Stack space needed for pushing registers clobbered by us. */
3735 HOST_WIDE_INT sa_size
;
3736 /* Complete stack size needed. */
3737 HOST_WIDE_INT frame_size
;
3738 /* Offset from base reg to register save area. */
3739 HOST_WIDE_INT reg_offset
;
3740 int fp_is_frame_pointer
, fp_offset
;
3741 rtx sa_reg
, sa_reg_exp
= NULL
;
3742 rtx sp_adj1
, sp_adj2
, mem
;
3745 sa_size
= alpha_sa_size ();
3747 frame_size
= get_frame_size ();
3748 if (TARGET_OPEN_VMS
)
3749 frame_size
= ALPHA_ROUND (sa_size
3750 + (vms_is_stack_procedure
? 8 : 0)
3752 + current_function_pretend_args_size
);
3754 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3756 + ALPHA_ROUND (frame_size
3757 + current_function_pretend_args_size
));
3759 if (TARGET_OPEN_VMS
)
3762 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3764 alpha_sa_mask (&imask
, &fmask
);
3766 fp_is_frame_pointer
= ((TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3767 || (!TARGET_OPEN_VMS
&& frame_pointer_needed
));
3771 /* If we have a frame pointer, restore SP from it. */
3772 if ((TARGET_OPEN_VMS
3773 && vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
3774 || (!TARGET_OPEN_VMS
&& frame_pointer_needed
))
3776 FRP (emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
));
3779 /* Cope with very large offsets to the register save area. */
3780 sa_reg
= stack_pointer_rtx
;
3781 if (reg_offset
+ sa_size
> 0x8000)
3783 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
3786 if (low
+ sa_size
<= 0x8000)
3787 bias
= reg_offset
- low
, reg_offset
= low
;
3789 bias
= reg_offset
, reg_offset
= 0;
3791 sa_reg
= gen_rtx_REG (DImode
, 22);
3792 sa_reg_exp
= plus_constant (stack_pointer_rtx
, bias
);
3794 FRP (emit_move_insn (sa_reg
, sa_reg_exp
));
3797 /* Restore registers in order, excepting a true frame pointer. */
3799 if (! alpha_eh_epilogue_sp_ofs
)
3801 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, reg_offset
));
3802 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3803 FRP (emit_move_insn (gen_rtx_REG (DImode
, REG_RA
), mem
));
3806 imask
&= ~(1L << REG_RA
);
3808 for (i
= 0; i
< 32; ++i
)
3809 if (imask
& (1L << i
))
3811 if (i
== HARD_FRAME_POINTER_REGNUM
&& fp_is_frame_pointer
)
3812 fp_offset
= reg_offset
;
3815 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, reg_offset
));
3816 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3817 FRP (emit_move_insn (gen_rtx_REG (DImode
, i
), mem
));
3822 for (i
= 0; i
< 32; ++i
)
3823 if (fmask
& (1L << i
))
3825 mem
= gen_rtx_MEM (DFmode
, plus_constant(sa_reg
, reg_offset
));
3826 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3827 FRP (emit_move_insn (gen_rtx_REG (DFmode
, i
+32), mem
));
3832 if (frame_size
|| alpha_eh_epilogue_sp_ofs
)
3834 sp_adj1
= stack_pointer_rtx
;
3836 if (alpha_eh_epilogue_sp_ofs
)
3838 sp_adj1
= gen_rtx_REG (DImode
, 23);
3839 emit_move_insn (sp_adj1
,
3840 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3841 alpha_eh_epilogue_sp_ofs
));
3844 /* If the stack size is large, begin computation into a temporary
3845 register so as not to interfere with a potential fp restore,
3846 which must be consecutive with an SP restore. */
3847 if (frame_size
< 32768)
3848 sp_adj2
= GEN_INT (frame_size
);
3849 else if (frame_size
< 0x40007fffL
)
3851 int low
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
3853 sp_adj2
= plus_constant (sp_adj1
, frame_size
- low
);
3854 if (sa_reg_exp
&& rtx_equal_p (sa_reg_exp
, sp_adj2
))
3858 sp_adj1
= gen_rtx_REG (DImode
, 23);
3859 FRP (emit_move_insn (sp_adj1
, sp_adj2
));
3861 sp_adj2
= GEN_INT (low
);
3865 rtx tmp
= gen_rtx_REG (DImode
, 23);
3866 FRP (sp_adj2
= alpha_emit_set_const (tmp
, DImode
, frame_size
, 3));
3869 /* We can't drop new things to memory this late, afaik,
3870 so build it up by pieces. */
3871 FRP (sp_adj2
= alpha_emit_set_long_const (tmp
, frame_size
,
3872 -(frame_size
< 0)));
3878 /* From now on, things must be in order. So emit blockages. */
3880 /* Restore the frame pointer. */
3881 if (fp_is_frame_pointer
)
3883 emit_insn (gen_blockage ());
3884 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, fp_offset
));
3885 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3886 FRP (emit_move_insn (hard_frame_pointer_rtx
, mem
));
3888 else if (TARGET_OPEN_VMS
)
3890 emit_insn (gen_blockage ());
3891 FRP (emit_move_insn (hard_frame_pointer_rtx
,
3892 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
3895 /* Restore the stack pointer. */
3896 emit_insn (gen_blockage ());
3897 FRP (emit_move_insn (stack_pointer_rtx
,
3898 gen_rtx_PLUS (DImode
, sp_adj1
, sp_adj2
)));
3902 if (TARGET_OPEN_VMS
&& !vms_is_stack_procedure
)
3904 emit_insn (gen_blockage ());
3905 FRP (emit_move_insn (hard_frame_pointer_rtx
,
3906 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
3911 emit_jump_insn (gen_return_internal ());
3914 /* Output the rest of the textual info surrounding the epilogue. */
3917 alpha_end_function (file
, fnname
, decl
)
3920 tree decl ATTRIBUTE_UNUSED
;
3922 /* End the function. */
3923 if (!flag_inhibit_size_directive
)
3925 fputs ("\t.end ", file
);
3926 assemble_name (file
, fnname
);
3929 inside_function
= FALSE
;
3931 /* Show that we know this function if it is called again.
3933 Don't do this for global functions in object files destined for a
3934 shared library because the function may be overridden by the application
3936 ??? Is this just ELF? */
3938 if (!flag_pic
|| !TREE_PUBLIC (current_function_decl
))
3939 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
3942 /* Debugging support. */
3946 /* Count the number of sdb related labels are generated (to find block
3947 start and end boundaries). */
3949 int sdb_label_count
= 0;
3951 /* Next label # for each statement. */
3953 static int sym_lineno
= 0;
3955 /* Count the number of .file directives, so that .loc is up to date. */
3957 static int num_source_filenames
= 0;
3959 /* Name of the file containing the current function. */
3961 static char *current_function_file
= "";
3963 /* Offsets to alpha virtual arg/local debugging pointers. */
3965 long alpha_arg_offset
;
3966 long alpha_auto_offset
;
3968 /* Emit a new filename to a stream. */
3971 alpha_output_filename (stream
, name
)
3975 static int first_time
= TRUE
;
3976 char ltext_label_name
[100];
3981 ++num_source_filenames
;
3982 current_function_file
= name
;
3983 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
3984 output_quoted_string (stream
, name
);
3985 fprintf (stream
, "\n");
3986 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
3987 fprintf (stream
, "\t#@stabs\n");
3990 else if (write_symbols
== DBX_DEBUG
)
3992 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
3993 fprintf (stream
, "%s ", ASM_STABS_OP
);
3994 output_quoted_string (stream
, name
);
3995 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
3998 else if (name
!= current_function_file
3999 && strcmp (name
, current_function_file
) != 0)
4001 if (inside_function
&& ! TARGET_GAS
)
4002 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
4005 ++num_source_filenames
;
4006 current_function_file
= name
;
4007 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
4010 output_quoted_string (stream
, name
);
4011 fprintf (stream
, "\n");
4015 /* Emit a linenumber to a stream. */
4018 alpha_output_lineno (stream
, line
)
4022 if (write_symbols
== DBX_DEBUG
)
4024 /* mips-tfile doesn't understand .stabd directives. */
4026 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4027 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
4030 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
4033 /* Structure to show the current status of registers and memory. */
4035 struct shadow_summary
4038 unsigned long i
: 31; /* Mask of int regs */
4039 unsigned long fp
: 31; /* Mask of fp regs */
4040 unsigned long mem
: 1; /* mem == imem | fpmem */
4044 static void summarize_insn
PROTO((rtx
, struct shadow_summary
*, int));
4045 static void alpha_handle_trap_shadows
PROTO((rtx
));
4047 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4048 to the summary structure. SET is nonzero if the insn is setting the
4049 object, otherwise zero. */
4052 summarize_insn (x
, sum
, set
)
4054 struct shadow_summary
*sum
;
4063 switch (GET_CODE (x
))
4065 /* ??? Note that this case would be incorrect if the Alpha had a
4066 ZERO_EXTRACT in SET_DEST. */
4068 summarize_insn (SET_SRC (x
), sum
, 0);
4069 summarize_insn (SET_DEST (x
), sum
, 1);
4073 summarize_insn (XEXP (x
, 0), sum
, 1);
4077 summarize_insn (XEXP (x
, 0), sum
, 0);
4081 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
4082 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
4086 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
4087 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
4091 summarize_insn (SUBREG_REG (x
), sum
, 0);
4096 int regno
= REGNO (x
);
4097 unsigned long mask
= 1UL << (regno
% 32);
4099 if (regno
== 31 || regno
== 63)
4105 sum
->defd
.i
|= mask
;
4107 sum
->defd
.fp
|= mask
;
4112 sum
->used
.i
|= mask
;
4114 sum
->used
.fp
|= mask
;
4125 /* Find the regs used in memory address computation: */
4126 summarize_insn (XEXP (x
, 0), sum
, 0);
4129 case CONST_INT
: case CONST_DOUBLE
:
4130 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
4133 /* Handle common unary and binary ops for efficiency. */
4134 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
4135 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
4136 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
4137 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
4138 case NE
: case EQ
: case GE
: case GT
: case LE
:
4139 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
4140 summarize_insn (XEXP (x
, 0), sum
, 0);
4141 summarize_insn (XEXP (x
, 1), sum
, 0);
4144 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
4145 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
4146 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
4147 case SQRT
: case FFS
:
4148 summarize_insn (XEXP (x
, 0), sum
, 0);
4152 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
4153 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4154 switch (format_ptr
[i
])
4157 summarize_insn (XEXP (x
, i
), sum
, 0);
4161 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
4162 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
4174 /* Ensure a sufficient number of `trapb' insns are in the code when
4175 the user requests code with a trap precision of functions or
4178 In naive mode, when the user requests a trap-precision of
4179 "instruction", a trapb is needed after every instruction that may
4180 generate a trap. This ensures that the code is resumption safe but
4183 When optimizations are turned on, we delay issuing a trapb as long
4184 as possible. In this context, a trap shadow is the sequence of
4185 instructions that starts with a (potentially) trap generating
4186 instruction and extends to the next trapb or call_pal instruction
4187 (but GCC never generates call_pal by itself). We can delay (and
4188 therefore sometimes omit) a trapb subject to the following
4191 (a) On entry to the trap shadow, if any Alpha register or memory
4192 location contains a value that is used as an operand value by some
4193 instruction in the trap shadow (live on entry), then no instruction
4194 in the trap shadow may modify the register or memory location.
4196 (b) Within the trap shadow, the computation of the base register
4197 for a memory load or store instruction may not involve using the
4198 result of an instruction that might generate an UNPREDICTABLE
4201 (c) Within the trap shadow, no register may be used more than once
4202 as a destination register. (This is to make life easier for the
4205 (d) The trap shadow may not include any branch instructions. */
4208 alpha_handle_trap_shadows (insns
)
4211 struct shadow_summary shadow
;
4212 int trap_pending
, exception_nesting
;
4216 exception_nesting
= 0;
4219 shadow
.used
.mem
= 0;
4220 shadow
.defd
= shadow
.used
;
4222 for (i
= insns
; i
; i
= NEXT_INSN (i
))
4224 if (GET_CODE (i
) == NOTE
)
4226 switch (NOTE_LINE_NUMBER (i
))
4228 case NOTE_INSN_EH_REGION_BEG
:
4229 exception_nesting
++;
4234 case NOTE_INSN_EH_REGION_END
:
4235 exception_nesting
--;
4240 case NOTE_INSN_EPILOGUE_BEG
:
4241 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
4246 else if (trap_pending
)
4248 if (alpha_tp
== ALPHA_TP_FUNC
)
4250 if (GET_CODE (i
) == JUMP_INSN
4251 && GET_CODE (PATTERN (i
)) == RETURN
)
4254 else if (alpha_tp
== ALPHA_TP_INSN
)
4258 struct shadow_summary sum
;
4263 sum
.defd
= sum
.used
;
4265 switch (GET_CODE (i
))
4268 /* Annoyingly, get_attr_trap will abort on these. */
4269 if (GET_CODE (PATTERN (i
)) == USE
4270 || GET_CODE (PATTERN (i
)) == CLOBBER
)
4273 summarize_insn (PATTERN (i
), &sum
, 0);
4275 if ((sum
.defd
.i
& shadow
.defd
.i
)
4276 || (sum
.defd
.fp
& shadow
.defd
.fp
))
4278 /* (c) would be violated */
4282 /* Combine shadow with summary of current insn: */
4283 shadow
.used
.i
|= sum
.used
.i
;
4284 shadow
.used
.fp
|= sum
.used
.fp
;
4285 shadow
.used
.mem
|= sum
.used
.mem
;
4286 shadow
.defd
.i
|= sum
.defd
.i
;
4287 shadow
.defd
.fp
|= sum
.defd
.fp
;
4288 shadow
.defd
.mem
|= sum
.defd
.mem
;
4290 if ((sum
.defd
.i
& shadow
.used
.i
)
4291 || (sum
.defd
.fp
& shadow
.used
.fp
)
4292 || (sum
.defd
.mem
& shadow
.used
.mem
))
4294 /* (a) would be violated (also takes care of (b)) */
4295 if (get_attr_trap (i
) == TRAP_YES
4296 && ((sum
.defd
.i
& sum
.used
.i
)
4297 || (sum
.defd
.fp
& sum
.used
.fp
)))
4316 n
= emit_insn_before (gen_trapb (), i
);
4317 PUT_MODE (n
, TImode
);
4318 PUT_MODE (i
, TImode
);
4322 shadow
.used
.mem
= 0;
4323 shadow
.defd
= shadow
.used
;
4328 if ((exception_nesting
> 0 || alpha_tp
>= ALPHA_TP_FUNC
)
4329 && GET_CODE (i
) == INSN
4330 && GET_CODE (PATTERN (i
)) != USE
4331 && GET_CODE (PATTERN (i
)) != CLOBBER
4332 && get_attr_trap (i
) == TRAP_YES
)
4334 if (optimize
&& !trap_pending
)
4335 summarize_insn (PATTERN (i
), &shadow
, 0);
4342 /* Alpha can only issue instruction groups simultaneously if they are
4343 suitibly aligned. This is very processor-specific. */
4345 enum alphaev4_pipe
{
4352 enum alphaev5_pipe
{
4363 static enum alphaev4_pipe alphaev4_insn_pipe
PROTO((rtx
));
4364 static enum alphaev5_pipe alphaev5_insn_pipe
PROTO((rtx
));
4365 static rtx alphaev4_next_group
PROTO((rtx
, int*, int*));
4366 static rtx alphaev5_next_group
PROTO((rtx
, int*, int*));
4367 static rtx alphaev4_next_nop
PROTO((int*));
4368 static rtx alphaev5_next_nop
PROTO((int*));
4370 static void alpha_align_insns
4371 PROTO((rtx
, int, rtx (*)(rtx
, int*, int*), rtx (*)(int*), int));
4373 static enum alphaev4_pipe
4374 alphaev4_insn_pipe (insn
)
4377 if (recog_memoized (insn
) < 0)
4379 if (get_attr_length (insn
) != 4)
4382 switch (get_attr_type (insn
))
4415 static enum alphaev5_pipe
4416 alphaev5_insn_pipe (insn
)
4419 if (recog_memoized (insn
) < 0)
4421 if (get_attr_length (insn
) != 4)
4424 switch (get_attr_type (insn
))
4464 /* IN_USE is a mask of the slots currently filled within the insn group.
4465 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4466 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4468 LEN is, of course, the length of the group in bytes. */
4471 alphaev4_next_group (insn
, pin_use
, plen
)
4473 int *pin_use
, *plen
;
4479 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i'
4480 || GET_CODE (PATTERN (insn
)) == CLOBBER
4481 || GET_CODE (PATTERN (insn
)) == USE
)
4486 enum alphaev4_pipe pipe
;
4488 pipe
= alphaev4_insn_pipe (insn
);
4492 /* Force complex instructions to start new groups. */
4496 /* If this is a completely unrecognized insn, its an asm.
4497 We don't know how long it is, so record length as -1 to
4498 signal a needed realignment. */
4499 if (recog_memoized (insn
) < 0)
4502 len
= get_attr_length (insn
);
4506 if (in_use
& EV4_IB0
)
4508 if (in_use
& EV4_IB1
)
4513 in_use
|= EV4_IB0
| EV4_IBX
;
4517 if (in_use
& EV4_IB0
)
4519 if (!(in_use
& EV4_IBX
) || (in_use
& EV4_IB1
))
4527 if (in_use
& EV4_IB1
)
4537 /* Haifa doesn't do well scheduling branches. */
4538 if (GET_CODE (insn
) == JUMP_INSN
)
4542 insn
= next_nonnote_insn (insn
);
4544 if (!insn
|| GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
4547 /* Let Haifa tell us where it thinks insn group boundaries are. */
4548 if (GET_MODE (insn
) == TImode
)
4551 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
4556 insn
= next_nonnote_insn (insn
);
4564 /* IN_USE is a mask of the slots currently filled within the insn group.
4565 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4566 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4568 LEN is, of course, the length of the group in bytes. */
4571 alphaev5_next_group (insn
, pin_use
, plen
)
4573 int *pin_use
, *plen
;
4579 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i'
4580 || GET_CODE (PATTERN (insn
)) == CLOBBER
4581 || GET_CODE (PATTERN (insn
)) == USE
)
4586 enum alphaev5_pipe pipe
;
4588 pipe
= alphaev5_insn_pipe (insn
);
4592 /* Force complex instructions to start new groups. */
4596 /* If this is a completely unrecognized insn, its an asm.
4597 We don't know how long it is, so record length as -1 to
4598 signal a needed realignment. */
4599 if (recog_memoized (insn
) < 0)
4602 len
= get_attr_length (insn
);
4605 /* ??? Most of the places below, we would like to abort, as
4606 it would indicate an error either in Haifa, or in the
4607 scheduling description. Unfortunately, Haifa never
4608 schedules the last instruction of the BB, so we don't
4609 have an accurate TI bit to go off. */
4611 if (in_use
& EV5_E0
)
4613 if (in_use
& EV5_E1
)
4618 in_use
|= EV5_E0
| EV5_E01
;
4622 if (in_use
& EV5_E0
)
4624 if (!(in_use
& EV5_E01
) || (in_use
& EV5_E1
))
4632 if (in_use
& EV5_E1
)
4638 if (in_use
& EV5_FA
)
4640 if (in_use
& EV5_FM
)
4645 in_use
|= EV5_FA
| EV5_FAM
;
4649 if (in_use
& EV5_FA
)
4655 if (in_use
& EV5_FM
)
4668 /* Haifa doesn't do well scheduling branches. */
4669 /* ??? If this is predicted not-taken, slotting continues, except
4670 that no more IBR, FBR, or JSR insns may be slotted. */
4671 if (GET_CODE (insn
) == JUMP_INSN
)
4675 insn
= next_nonnote_insn (insn
);
4677 if (!insn
|| GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
4680 /* Let Haifa tell us where it thinks insn group boundaries are. */
4681 if (GET_MODE (insn
) == TImode
)
4684 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
4689 insn
= next_nonnote_insn (insn
);
4698 alphaev4_next_nop (pin_use
)
4701 int in_use
= *pin_use
;
4704 if (!(in_use
& EV4_IB0
))
4709 else if ((in_use
& (EV4_IBX
|EV4_IB1
)) == EV4_IBX
)
4714 else if (TARGET_FP
&& !(in_use
& EV4_IB1
))
4727 alphaev5_next_nop (pin_use
)
4730 int in_use
= *pin_use
;
4733 if (!(in_use
& EV5_E1
))
4738 else if (TARGET_FP
&& !(in_use
& EV5_FA
))
4743 else if (TARGET_FP
&& !(in_use
& EV5_FM
))
4755 /* The instruction group alignment main loop. */
4758 alpha_align_insns (insns
, max_align
, next_group
, next_nop
, gp_in_use
)
4761 rtx (*next_group
) PROTO((rtx
, int*, int*));
4762 rtx (*next_nop
) PROTO((int*));
4765 /* ALIGN is the known alignment for the insn group. */
4767 /* OFS is the offset of the current insn in the insn group. */
4769 int prev_in_use
, in_use
, len
;
4772 /* Let shorten branches care for assigning alignments to code labels. */
4773 shorten_branches (insns
);
4775 align
= (FUNCTION_BOUNDARY
/BITS_PER_UNIT
< max_align
4776 ? FUNCTION_BOUNDARY
/BITS_PER_UNIT
: max_align
);
4778 /* Account for the initial GP load, which happens before the scheduled
4779 prologue we emitted as RTL. */
4780 ofs
= prev_in_use
= 0;
4781 if (alpha_does_function_need_gp())
4783 ofs
= 8 & (align
- 1);
4784 prev_in_use
= gp_in_use
;
4788 if (GET_CODE (i
) == NOTE
)
4789 i
= next_nonnote_insn (i
);
4793 next
= (*next_group
)(i
, &in_use
, &len
);
4795 /* When we see a label, resync alignment etc. */
4796 if (GET_CODE (i
) == CODE_LABEL
)
4798 int new_align
= 1 << label_to_alignment (i
);
4799 if (new_align
>= align
)
4801 align
= new_align
< max_align
? new_align
: max_align
;
4804 else if (ofs
& (new_align
-1))
4805 ofs
= (ofs
| (new_align
-1)) + 1;
4810 /* Handle complex instructions special. */
4811 else if (in_use
== 0)
4813 /* Asms will have length < 0. This is a signal that we have
4814 lost alignment knowledge. Assume, however, that the asm
4815 will not mis-align instructions. */
4824 /* If the known alignment is smaller than the recognized insn group,
4825 realign the output. */
4826 else if (align
< len
)
4828 int new_log_align
= len
> 8 ? 4 : 3;
4831 where
= prev_nonnote_insn (i
);
4832 if (!where
|| GET_CODE (where
) != CODE_LABEL
)
4835 emit_insn_before (gen_realign (GEN_INT (new_log_align
)), where
);
4836 align
= 1 << new_log_align
;
4840 /* If the group won't fit in the same INT16 as the previous,
4841 we need to add padding to keep the group together. Rather
4842 than simply leaving the insn filling to the assembler, we
4843 can make use of the knowledge of what sorts of instructions
4844 were issued in the previous group to make sure that all of
4845 the added nops are really free. */
4846 else if (ofs
+ len
> align
)
4848 int nop_count
= (align
- ofs
) / 4;
4851 /* Insert nops before labels and branches to truely merge the
4852 execution of the nops with the previous instruction group. */
4853 where
= prev_nonnote_insn (i
);
4856 if (GET_CODE (where
) == CODE_LABEL
)
4858 rtx where2
= prev_nonnote_insn (where
);
4859 if (where2
&& GET_CODE (where2
) == JUMP_INSN
)
4862 else if (GET_CODE (where
) != JUMP_INSN
)
4869 emit_insn_before ((*next_nop
)(&prev_in_use
), where
);
4870 while (--nop_count
);
4874 ofs
= (ofs
+ len
) & (align
- 1);
4875 prev_in_use
= in_use
;
4881 /* Machine dependant reorg pass. */
4887 if (alpha_tp
!= ALPHA_TP_PROG
|| flag_exceptions
)
4888 alpha_handle_trap_shadows (insns
);
4891 /* Due to the number of extra trapb insns, don't bother fixing up
4892 alignment when trap precision is instruction. Moreover, we can
4893 only do our job when sched2 is run and Haifa is our scheduler. */
4894 if (optimize
&& !optimize_size
4895 && alpha_tp
!= ALPHA_TP_INSN
4896 && flag_schedule_insns_after_reload
)
4898 if (alpha_cpu
== PROCESSOR_EV4
)
4899 alpha_align_insns (insns
, 8, alphaev4_next_group
,
4900 alphaev4_next_nop
, EV4_IB0
);
4901 else if (alpha_cpu
== PROCESSOR_EV5
)
4902 alpha_align_insns (insns
, 16, alphaev5_next_group
,
4903 alphaev5_next_nop
, EV5_E01
| EV5_E0
);
4909 /* Check a floating-point value for validity for a particular machine mode. */
4911 static char * const float_strings
[] =
4913 /* These are for FLOAT_VAX. */
4914 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4915 "-1.70141173319264430e+38",
4916 "2.93873587705571877e-39", /* 2^-128 */
4917 "-2.93873587705571877e-39",
4918 /* These are for the default broken IEEE mode, which traps
4919 on infinity or denormal numbers. */
4920 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4921 "-3.402823466385288598117e+38",
4922 "1.1754943508222875079687e-38", /* 2^-126 */
4923 "-1.1754943508222875079687e-38",
4926 static REAL_VALUE_TYPE float_values
[8];
4927 static int inited_float_values
= 0;
4930 check_float_value (mode
, d
, overflow
)
4931 enum machine_mode mode
;
4933 int overflow ATTRIBUTE_UNUSED
;
4936 if (TARGET_IEEE
|| TARGET_IEEE_CONFORMANT
|| TARGET_IEEE_WITH_INEXACT
)
4939 if (inited_float_values
== 0)
4942 for (i
= 0; i
< 8; i
++)
4943 float_values
[i
] = REAL_VALUE_ATOF (float_strings
[i
], DFmode
);
4945 inited_float_values
= 1;
4951 REAL_VALUE_TYPE
*fvptr
;
4953 if (TARGET_FLOAT_VAX
)
4954 fvptr
= &float_values
[0];
4956 fvptr
= &float_values
[4];
4958 bcopy ((char *) d
, (char *) &r
, sizeof (REAL_VALUE_TYPE
));
4959 if (REAL_VALUES_LESS (fvptr
[0], r
))
4961 bcopy ((char *) &fvptr
[0], (char *) d
,
4962 sizeof (REAL_VALUE_TYPE
));
4965 else if (REAL_VALUES_LESS (r
, fvptr
[1]))
4967 bcopy ((char *) &fvptr
[1], (char *) d
,
4968 sizeof (REAL_VALUE_TYPE
));
4971 else if (REAL_VALUES_LESS (dconst0
, r
)
4972 && REAL_VALUES_LESS (r
, fvptr
[2]))
4974 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
4977 else if (REAL_VALUES_LESS (r
, dconst0
)
4978 && REAL_VALUES_LESS (fvptr
[3], r
))
4980 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
4990 /* Return the VMS argument type corresponding to MODE. */
4993 alpha_arg_type (mode
)
4994 enum machine_mode mode
;
4999 return TARGET_FLOAT_VAX
? FF
: FS
;
5001 return TARGET_FLOAT_VAX
? FD
: FT
;
5007 /* Return an rtx for an integer representing the VMS Argument Information
5011 alpha_arg_info_reg_val (cum
)
5012 CUMULATIVE_ARGS cum
;
5014 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
5017 for (i
= 0; i
< 6; i
++)
5018 regval
|= ((int) cum
.atypes
[i
]) << (i
* 3 + 8);
5020 return GEN_INT (regval
);
5023 /* Structure to collect function names for final output
5026 enum links_kind
{KIND_UNUSED
, KIND_LOCAL
, KIND_EXTERN
};
5029 struct alpha_links
{
5030 struct alpha_links
*next
;
5032 enum links_kind kind
;
5035 static struct alpha_links
*alpha_links_base
= 0;
5037 /* Make (or fake) .linkage entry for function call.
5039 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5042 alpha_need_linkage (name
, is_local
)
5047 struct alpha_links
*lptr
, *nptr
;
5052 /* Is this name already defined ? */
5054 for (lptr
= alpha_links_base
; lptr
; lptr
= lptr
->next
)
5055 if (strcmp (lptr
->name
, name
) == 0)
5059 /* Defined here but external assumed. */
5060 if (lptr
->kind
== KIND_EXTERN
)
5061 lptr
->kind
= KIND_LOCAL
;
5065 /* Used here but unused assumed. */
5066 if (lptr
->kind
== KIND_UNUSED
)
5067 lptr
->kind
= KIND_LOCAL
;
5072 nptr
= (struct alpha_links
*) xmalloc (sizeof (struct alpha_links
));
5073 nptr
->next
= alpha_links_base
;
5074 nptr
->name
= xstrdup (name
);
5076 /* Assume external if no definition. */
5077 nptr
->kind
= (is_local
? KIND_UNUSED
: KIND_EXTERN
);
5079 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5080 get_identifier (name
);
5082 alpha_links_base
= nptr
;
5089 alpha_write_linkage (stream
)
5092 struct alpha_links
*lptr
, *nptr
;
5094 readonly_section ();
5096 fprintf (stream
, "\t.align 3\n");
5098 for (lptr
= alpha_links_base
; lptr
; lptr
= nptr
)
5102 if (lptr
->kind
== KIND_UNUSED
5103 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr
->name
)))
5106 fprintf (stream
, "$%s..lk:\n", lptr
->name
);
5107 if (lptr
->kind
== KIND_LOCAL
)
5109 /* Local and used, build linkage pair. */
5110 fprintf (stream
, "\t.quad %s..en\n", lptr
->name
);
5111 fprintf (stream
, "\t.quad %s\n", lptr
->name
);
5114 /* External and used, request linkage pair. */
5115 fprintf (stream
, "\t.linkage %s\n", lptr
->name
);
5122 alpha_need_linkage (name
, is_local
)
5123 char *name ATTRIBUTE_UNUSED
;
5124 int is_local ATTRIBUTE_UNUSED
;
5128 #endif /* OPEN_VMS */