1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93-99, 2000 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
47 extern char *version_string;
48 extern int rtx_equal_function_value_matters;
50 /* Specify which cpu to schedule for. */
52 enum processor_type alpha_cpu;
53 static const char * const alpha_cpu_name[] =
58 /* Specify how accurate floating-point traps need to be. */
60 enum alpha_trap_precision alpha_tp;
62 /* Specify the floating-point rounding mode. */
64 enum alpha_fp_rounding_mode alpha_fprm;
66 /* Specify which things cause traps. */
68 enum alpha_fp_trap_mode alpha_fptm;
70 /* Strings decoded into the above options. */
72 const char *alpha_cpu_string; /* -mcpu= */
73 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
74 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
75 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
76 const char *alpha_mlat_string; /* -mmemory-latency= */
78 /* Save information from a "cmpxx" operation until the branch or scc is
81 struct alpha_compare alpha_compare;
83 /* Non-zero if inside of a function, because the Alpha asm can't
84 handle .files inside of functions. */
86 static int inside_function = FALSE;
88 /* The number of cycles of latency we should assume on memory reads. */
90 int alpha_memory_latency = 3;
92 /* Whether the function needs the GP. */
94 static int alpha_function_needs_gp;
96 /* The alias set for prologue/epilogue register save/restore. */
98 static int alpha_sr_alias_set;
100 /* Declarations of static functions. */
101 static void alpha_set_memflags_1
102 PARAMS ((rtx, int, int, int));
103 static rtx alpha_emit_set_const_1
104 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
105 static void alpha_expand_unaligned_load_words
106 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
107 static void alpha_expand_unaligned_store_words
108 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
109 static void alpha_sa_mask
110 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
111 static int alpha_does_function_need_gp
113 static void alpha_init_machine_status
114 PARAMS ((struct function *p));
115 static void alpha_mark_machine_status
116 PARAMS ((struct function *p));
117 static int alpha_ra_ever_killed PARAMS ((void));
118 static rtx set_frame_related_p PARAMS ((void));
121 /* Get the number of args of a function in one of two ways. */
123 #define NUM_ARGS current_function_args_info.num_args
125 #define NUM_ARGS current_function_args_info
131 /* Parse target option strings. */
136 alpha_tp = ALPHA_TP_PROG;
137 alpha_fprm = ALPHA_FPRM_NORM;
138 alpha_fptm = ALPHA_FPTM_N;
142 alpha_tp = ALPHA_TP_INSN;
143 alpha_fptm = ALPHA_FPTM_SU;
146 if (TARGET_IEEE_WITH_INEXACT)
148 alpha_tp = ALPHA_TP_INSN;
149 alpha_fptm = ALPHA_FPTM_SUI;
154 if (! strcmp (alpha_tp_string, "p"))
155 alpha_tp = ALPHA_TP_PROG;
156 else if (! strcmp (alpha_tp_string, "f"))
157 alpha_tp = ALPHA_TP_FUNC;
158 else if (! strcmp (alpha_tp_string, "i"))
159 alpha_tp = ALPHA_TP_INSN;
161 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
164 if (alpha_fprm_string)
166 if (! strcmp (alpha_fprm_string, "n"))
167 alpha_fprm = ALPHA_FPRM_NORM;
168 else if (! strcmp (alpha_fprm_string, "m"))
169 alpha_fprm = ALPHA_FPRM_MINF;
170 else if (! strcmp (alpha_fprm_string, "c"))
171 alpha_fprm = ALPHA_FPRM_CHOP;
172 else if (! strcmp (alpha_fprm_string,"d"))
173 alpha_fprm = ALPHA_FPRM_DYN;
175 error ("bad value `%s' for -mfp-rounding-mode switch",
179 if (alpha_fptm_string)
181 if (strcmp (alpha_fptm_string, "n") == 0)
182 alpha_fptm = ALPHA_FPTM_N;
183 else if (strcmp (alpha_fptm_string, "u") == 0)
184 alpha_fptm = ALPHA_FPTM_U;
185 else if (strcmp (alpha_fptm_string, "su") == 0)
186 alpha_fptm = ALPHA_FPTM_SU;
187 else if (strcmp (alpha_fptm_string, "sui") == 0)
188 alpha_fptm = ALPHA_FPTM_SUI;
190 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
194 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
195 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
197 if (alpha_cpu_string)
199 if (! strcmp (alpha_cpu_string, "ev4")
200 || ! strcmp (alpha_cpu_string, "ev45")
201 || ! strcmp (alpha_cpu_string, "21064"))
203 alpha_cpu = PROCESSOR_EV4;
204 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
206 else if (! strcmp (alpha_cpu_string, "ev5")
207 || ! strcmp (alpha_cpu_string, "21164"))
209 alpha_cpu = PROCESSOR_EV5;
210 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
212 else if (! strcmp (alpha_cpu_string, "ev56")
213 || ! strcmp (alpha_cpu_string, "21164a"))
215 alpha_cpu = PROCESSOR_EV5;
216 target_flags |= MASK_BWX;
217 target_flags &= ~ (MASK_MAX | MASK_FIX | MASK_CIX);
219 else if (! strcmp (alpha_cpu_string, "pca56")
220 || ! strcmp (alpha_cpu_string, "21164PC")
221 || ! strcmp (alpha_cpu_string, "21164pc"))
223 alpha_cpu = PROCESSOR_EV5;
224 target_flags |= MASK_BWX | MASK_MAX;
225 target_flags &= ~ (MASK_FIX | MASK_CIX);
227 else if (! strcmp (alpha_cpu_string, "ev6")
228 || ! strcmp (alpha_cpu_string, "21264"))
230 alpha_cpu = PROCESSOR_EV6;
231 target_flags |= MASK_BWX | MASK_MAX | MASK_FIX;
232 target_flags &= ~ (MASK_CIX);
234 else if (! strcmp (alpha_cpu_string, "ev67")
235 || ! strcmp (alpha_cpu_string, "21264a"))
237 alpha_cpu = PROCESSOR_EV6;
238 target_flags |= MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX;
241 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
244 /* Do some sanity checks on the above options. */
246 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
247 && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
249 warning ("fp software completion requires -mtrap-precision=i");
250 alpha_tp = ALPHA_TP_INSN;
253 if (alpha_cpu == PROCESSOR_EV6)
255 /* Except for EV6 pass 1 (not released), we always have precise
256 arithmetic traps. Which means we can do software completion
257 without minding trap shadows. */
258 alpha_tp = ALPHA_TP_PROG;
261 if (TARGET_FLOAT_VAX)
263 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
265 warning ("rounding mode not supported for VAX floats");
266 alpha_fprm = ALPHA_FPRM_NORM;
268 if (alpha_fptm == ALPHA_FPTM_SUI)
270 warning ("trap mode not supported for VAX floats");
271 alpha_fptm = ALPHA_FPTM_SU;
279 if (!alpha_mlat_string)
280 alpha_mlat_string = "L1";
282 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
283 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
285 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
286 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
287 && alpha_mlat_string[2] == '\0')
289 static int const cache_latency[][4] =
291 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
292 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
293 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
296 lat = alpha_mlat_string[1] - '0';
297 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
299 warning ("L%d cache latency unknown for %s",
300 lat, alpha_cpu_name[alpha_cpu]);
304 lat = cache_latency[alpha_cpu][lat-1];
306 else if (! strcmp (alpha_mlat_string, "main"))
308 /* Most current memories have about 370ns latency. This is
309 a reasonable guess for a fast cpu. */
314 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
318 alpha_memory_latency = lat;
321 /* Default the definition of "small data" to 8 bytes. */
325 /* Acquire a unique set number for our register saves and restores. */
326 alpha_sr_alias_set = new_alias_set ();
328 /* Set up function hooks. */
329 init_machine_status = alpha_init_machine_status;
330 mark_machine_status = alpha_mark_machine_status;
333 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
341 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
343 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
349 /* Returns 1 if OP is either the constant zero or a register. If a
350 register, it must be in the proper mode unless MODE is VOIDmode. */
353 reg_or_0_operand (op, mode)
355 enum machine_mode mode;
357 return op == const0_rtx || register_operand (op, mode);
360 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
364 reg_or_6bit_operand (op, mode)
366 enum machine_mode mode;
368 return ((GET_CODE (op) == CONST_INT
369 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
370 || register_operand (op, mode));
374 /* Return 1 if OP is an 8-bit constant or any register. */
377 reg_or_8bit_operand (op, mode)
379 enum machine_mode mode;
381 return ((GET_CODE (op) == CONST_INT
382 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
383 || register_operand (op, mode));
386 /* Return 1 if OP is an 8-bit constant. */
389 cint8_operand (op, mode)
391 enum machine_mode mode ATTRIBUTE_UNUSED;
393 return ((GET_CODE (op) == CONST_INT
394 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
397 /* Return 1 if the operand is a valid second operand to an add insn. */
400 add_operand (op, mode)
402 enum machine_mode mode;
404 if (GET_CODE (op) == CONST_INT)
405 /* Constraints I, J, O and P are covered by K. */
406 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
407 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
409 return register_operand (op, mode);
412 /* Return 1 if the operand is a valid second operand to a sign-extending
416 sext_add_operand (op, mode)
418 enum machine_mode mode;
420 if (GET_CODE (op) == CONST_INT)
421 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
422 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
424 return reg_not_elim_operand (op, mode);
427 /* Return 1 if OP is the constant 4 or 8. */
430 const48_operand (op, mode)
432 enum machine_mode mode ATTRIBUTE_UNUSED;
434 return (GET_CODE (op) == CONST_INT
435 && (INTVAL (op) == 4 || INTVAL (op) == 8));
438 /* Return 1 if OP is a valid first operand to an AND insn. */
441 and_operand (op, mode)
443 enum machine_mode mode;
445 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
446 return (zap_mask (CONST_DOUBLE_LOW (op))
447 && zap_mask (CONST_DOUBLE_HIGH (op)));
449 if (GET_CODE (op) == CONST_INT)
450 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
451 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
452 || zap_mask (INTVAL (op)));
454 return register_operand (op, mode);
457 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
460 or_operand (op, mode)
462 enum machine_mode mode;
464 if (GET_CODE (op) == CONST_INT)
465 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
466 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
468 return register_operand (op, mode);
471 /* Return 1 if OP is a constant that is the width, in bits, of an integral
472 mode smaller than DImode. */
475 mode_width_operand (op, mode)
477 enum machine_mode mode ATTRIBUTE_UNUSED;
479 return (GET_CODE (op) == CONST_INT
480 && (INTVAL (op) == 8 || INTVAL (op) == 16
481 || INTVAL (op) == 32 || INTVAL (op) == 64));
484 /* Return 1 if OP is a constant that is the width of an integral machine mode
485 smaller than an integer. */
488 mode_mask_operand (op, mode)
490 enum machine_mode mode ATTRIBUTE_UNUSED;
492 #if HOST_BITS_PER_WIDE_INT == 32
493 if (GET_CODE (op) == CONST_DOUBLE)
494 return (CONST_DOUBLE_LOW (op) == -1
495 && (CONST_DOUBLE_HIGH (op) == -1
496 || CONST_DOUBLE_HIGH (op) == 0));
498 if (GET_CODE (op) == CONST_DOUBLE)
499 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
502 return (GET_CODE (op) == CONST_INT
503 && (INTVAL (op) == 0xff
504 || INTVAL (op) == 0xffff
505 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
506 #if HOST_BITS_PER_WIDE_INT == 64
512 /* Return 1 if OP is a multiple of 8 less than 64. */
515 mul8_operand (op, mode)
517 enum machine_mode mode ATTRIBUTE_UNUSED;
519 return (GET_CODE (op) == CONST_INT
520 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
521 && (INTVAL (op) & 7) == 0);
524 /* Return 1 if OP is the constant zero in floating-point. */
527 fp0_operand (op, mode)
529 enum machine_mode mode;
531 return (GET_MODE (op) == mode
532 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
535 /* Return 1 if OP is the floating-point constant zero or a register. */
538 reg_or_fp0_operand (op, mode)
540 enum machine_mode mode;
542 return fp0_operand (op, mode) || register_operand (op, mode);
545 /* Return 1 if OP is a hard floating-point register. */
548 hard_fp_register_operand (op, mode)
550 enum machine_mode mode;
552 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
553 || (GET_CODE (op) == SUBREG
554 && hard_fp_register_operand (SUBREG_REG (op), mode)));
557 /* Return 1 if OP is a register or a constant integer. */
561 reg_or_cint_operand (op, mode)
563 enum machine_mode mode;
565 return (GET_CODE (op) == CONST_INT
566 || register_operand (op, mode));
569 /* Return 1 if OP is something that can be reloaded into a register;
570 if it is a MEM, it need not be valid. */
573 some_operand (op, mode)
575 enum machine_mode mode;
577 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
580 switch (GET_CODE (op))
582 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
583 case SYMBOL_REF: case CONST:
587 return some_operand (SUBREG_REG (op), VOIDmode);
596 /* Likewise, but don't accept constants. */
599 some_ni_operand (op, mode)
601 enum machine_mode mode;
603 if (GET_MODE (op) != mode && mode != VOIDmode)
606 if (GET_CODE (op) == SUBREG)
607 op = SUBREG_REG (op);
609 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
612 /* Return 1 if OP is a valid operand for the source of a move insn. */
615 input_operand (op, mode)
617 enum machine_mode mode;
619 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
622 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
625 switch (GET_CODE (op))
630 /* This handles both the Windows/NT and OSF cases. */
631 return mode == ptr_mode || mode == DImode;
638 if (register_operand (op, mode))
640 /* ... fall through ... */
642 return ((TARGET_BWX || (mode != HImode && mode != QImode))
643 && general_operand (op, mode));
646 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
649 return mode == QImode || mode == HImode || add_operand (op, mode);
661 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
665 current_file_function_operand (op, mode)
667 enum machine_mode mode ATTRIBUTE_UNUSED;
669 return (GET_CODE (op) == SYMBOL_REF
670 && ! profile_flag && ! profile_block_flag
671 && (SYMBOL_REF_FLAG (op)
672 || op == XEXP (DECL_RTL (current_function_decl), 0)));
675 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
678 call_operand (op, mode)
680 enum machine_mode mode;
685 return (GET_CODE (op) == SYMBOL_REF
686 || (GET_CODE (op) == REG
687 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
690 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
691 comparisons are valid in which insn. */
694 alpha_comparison_operator (op, mode)
696 enum machine_mode mode;
698 enum rtx_code code = GET_CODE (op);
700 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
703 return (code == EQ || code == LE || code == LT
704 || (mode == DImode && (code == LEU || code == LTU)));
707 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
710 alpha_swapped_comparison_operator (op, mode)
712 enum machine_mode mode;
714 enum rtx_code code = GET_CODE (op);
716 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
719 code = swap_condition (code);
720 return (code == EQ || code == LE || code == LT
721 || (mode == DImode && (code == LEU || code == LTU)));
724 /* Return 1 if OP is a signed comparison operation. */
727 signed_comparison_operator (op, mode)
729 enum machine_mode mode ATTRIBUTE_UNUSED;
731 switch (GET_CODE (op))
733 case EQ: case NE: case LE: case LT: case GE: case GT:
743 /* Return 1 if this is a divide or modulus operator. */
746 divmod_operator (op, mode)
748 enum machine_mode mode ATTRIBUTE_UNUSED;
750 switch (GET_CODE (op))
752 case DIV: case MOD: case UDIV: case UMOD:
762 /* Return 1 if this memory address is a known aligned register plus
763 a constant. It must be a valid address. This means that we can do
764 this as an aligned reference plus some offset.
766 Take into account what reload will do. */
769 aligned_memory_operand (op, mode)
771 enum machine_mode mode;
775 if (reload_in_progress)
778 if (GET_CODE (tmp) == SUBREG)
779 tmp = SUBREG_REG (tmp);
780 if (GET_CODE (tmp) == REG
781 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
783 op = reg_equiv_memory_loc[REGNO (tmp)];
789 if (GET_CODE (op) != MEM
790 || GET_MODE (op) != mode)
794 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
795 sorts of constructs. Dig for the real base register. */
796 if (reload_in_progress
797 && GET_CODE (op) == PLUS
798 && GET_CODE (XEXP (op, 0)) == PLUS)
799 base = XEXP (XEXP (op, 0), 0);
802 if (! memory_address_p (mode, op))
804 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
807 return (GET_CODE (base) == REG
808 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
811 /* Similar, but return 1 if OP is a MEM which is not alignable. */
814 unaligned_memory_operand (op, mode)
816 enum machine_mode mode;
820 if (reload_in_progress)
823 if (GET_CODE (tmp) == SUBREG)
824 tmp = SUBREG_REG (tmp);
825 if (GET_CODE (tmp) == REG
826 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
828 op = reg_equiv_memory_loc[REGNO (tmp)];
834 if (GET_CODE (op) != MEM
835 || GET_MODE (op) != mode)
839 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
840 sorts of constructs. Dig for the real base register. */
841 if (reload_in_progress
842 && GET_CODE (op) == PLUS
843 && GET_CODE (XEXP (op, 0)) == PLUS)
844 base = XEXP (XEXP (op, 0), 0);
847 if (! memory_address_p (mode, op))
849 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
852 return (GET_CODE (base) == REG
853 && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
856 /* Return 1 if OP is either a register or an unaligned memory location. */
859 reg_or_unaligned_mem_operand (op, mode)
861 enum machine_mode mode;
863 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
866 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
869 any_memory_operand (op, mode)
871 enum machine_mode mode ATTRIBUTE_UNUSED;
873 return (GET_CODE (op) == MEM
874 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
875 || (reload_in_progress && GET_CODE (op) == REG
876 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
877 || (reload_in_progress && GET_CODE (op) == SUBREG
878 && GET_CODE (SUBREG_REG (op)) == REG
879 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
882 /* Returns 1 if OP is not an eliminable register.
884 This exists to cure a pathological abort in the s8addq (et al) patterns,
886 long foo () { long t; bar(); return (long) &t * 26107; }
888 which run afoul of a hack in reload to cure a (presumably) similar
889 problem with lea-type instructions on other targets. But there is
890 one of us and many of them, so work around the problem by selectively
891 preventing combine from making the optimization. */
894 reg_not_elim_operand (op, mode)
896 enum machine_mode mode;
899 if (GET_CODE (op) == SUBREG)
900 inner = SUBREG_REG (op);
901 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
904 return register_operand (op, mode);
907 /* Return 1 is OP is a memory location that is not a reference (using
908 an AND) to an unaligned location. Take into account what reload
912 normal_memory_operand (op, mode)
914 enum machine_mode mode ATTRIBUTE_UNUSED;
916 if (reload_in_progress)
919 if (GET_CODE (tmp) == SUBREG)
920 tmp = SUBREG_REG (tmp);
921 if (GET_CODE (tmp) == REG
922 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
924 op = reg_equiv_memory_loc[REGNO (tmp)];
926 /* This may not have been assigned an equivalent address if it will
927 be eliminated. In that case, it doesn't matter what we do. */
933 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
936 /* Accept a register, but not a subreg of any kind. This allows us to
937 avoid pathological cases in reload wrt data movement common in
938 int->fp conversion. */
941 reg_no_subreg_operand (op, mode)
943 enum machine_mode mode;
945 if (GET_CODE (op) == SUBREG)
947 return register_operand (op, mode);
950 /* Recognize a addition operation that includes a constant. Used to
951 convince reload to canonize (plus (plus reg c1) c2) during register
955 addition_operation (op, mode)
957 enum machine_mode mode;
959 if (GET_MODE (op) != mode && mode != VOIDmode)
961 if (GET_CODE (op) == PLUS
962 && register_operand (XEXP (op, 0), mode)
963 && GET_CODE (XEXP (op, 1)) == CONST_INT
964 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
969 /* Return 1 if this function can directly return via $26. */
974 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
975 && get_frame_size () == 0
976 && current_function_outgoing_args_size == 0
977 && current_function_pretend_args_size == 0);
980 /* REF is an alignable memory location. Place an aligned SImode
981 reference into *PALIGNED_MEM and the number of bits to shift into
982 *PBITNUM. SCRATCH is a free register for use in reloading out
983 of range stack slots. */
986 get_aligned_mem (ref, paligned_mem, pbitnum)
988 rtx *paligned_mem, *pbitnum;
991 HOST_WIDE_INT offset = 0;
993 if (GET_CODE (ref) != MEM)
996 if (reload_in_progress
997 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
999 base = find_replacement (&XEXP (ref, 0));
1001 if (! memory_address_p (GET_MODE (ref), base))
1006 base = XEXP (ref, 0);
1009 if (GET_CODE (base) == PLUS)
1010 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1012 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1013 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1014 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
1016 /* Sadly, we cannot use alias sets here because we may overlap other
1017 data in a different alias set. */
1018 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
1020 *pbitnum = GEN_INT ((offset & 3) * 8);
1023 /* Similar, but just get the address. Handle the two reload cases.
1024 Add EXTRA_OFFSET to the address we return. */
1027 get_unaligned_address (ref, extra_offset)
1032 HOST_WIDE_INT offset = 0;
1034 if (GET_CODE (ref) != MEM)
1037 if (reload_in_progress
1038 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1040 base = find_replacement (&XEXP (ref, 0));
1042 if (! memory_address_p (GET_MODE (ref), base))
1047 base = XEXP (ref, 0);
1050 if (GET_CODE (base) == PLUS)
1051 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1053 return plus_constant (base, offset + extra_offset);
1056 /* Loading and storing HImode or QImode values to and from memory
1057 usually requires a scratch register. The exceptions are loading
1058 QImode and HImode from an aligned address to a general register
1059 unless byte instructions are permitted.
1061 We also cannot load an unaligned address or a paradoxical SUBREG
1062 into an FP register.
1064 We also cannot do integral arithmetic into FP regs, as might result
1065 from register elimination into a DImode fp register. */
1068 secondary_reload_class (class, mode, x, in)
1069 enum reg_class class;
1070 enum machine_mode mode;
1074 if (GET_CODE (x) == MEM
1075 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1076 || (GET_CODE (x) == SUBREG
1077 && (GET_CODE (SUBREG_REG (x)) == MEM
1078 || (GET_CODE (SUBREG_REG (x)) == REG
1079 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1081 if (class == FLOAT_REGS && mode != DImode)
1082 return GENERAL_REGS;
1083 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1085 if (!in || !aligned_memory_operand(x, mode))
1086 return GENERAL_REGS;
1090 if (class == FLOAT_REGS)
1092 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1093 return GENERAL_REGS;
1095 if (GET_CODE (x) == SUBREG
1096 && (GET_MODE_SIZE (GET_MODE (x))
1097 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1098 return GENERAL_REGS;
1100 if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
1101 return GENERAL_REGS;
1107 /* Subfunction of the following function. Update the flags of any MEM
1108 found in part of X. */
1111 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1113 int in_struct_p, volatile_p, unchanging_p;
1117 switch (GET_CODE (x))
1121 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1122 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1127 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1132 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1134 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1139 MEM_IN_STRUCT_P (x) = in_struct_p;
1140 MEM_VOLATILE_P (x) = volatile_p;
1141 RTX_UNCHANGING_P (x) = unchanging_p;
1142 /* Sadly, we cannot use alias sets because the extra aliasing
1143 produced by the AND interferes. Given that two-byte quantities
1144 are the only thing we would be able to differentiate anyway,
1145 there does not seem to be any point in convoluting the early
1146 out of the alias check. */
1147 /* MEM_ALIAS_SET (x) = alias_set; */
1155 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1156 perform a memory operation, look for any MEMs in either a SET_DEST or
1157 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1158 REF into each of the MEMs found. If REF is not a MEM, don't do
1162 alpha_set_memflags (insn, ref)
1166 int in_struct_p, volatile_p, unchanging_p;
1168 if (GET_CODE (ref) != MEM)
1171 in_struct_p = MEM_IN_STRUCT_P (ref);
1172 volatile_p = MEM_VOLATILE_P (ref);
1173 unchanging_p = RTX_UNCHANGING_P (ref);
1175 /* This is only called from alpha.md, after having had something
1176 generated from one of the insn patterns. So if everything is
1177 zero, the pattern is already up-to-date. */
1178 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1181 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1184 /* Try to output insns to set TARGET equal to the constant C if it can be
1185 done in less than N insns. Do all computations in MODE. Returns the place
1186 where the output has been placed if it can be done and the insns have been
1187 emitted. If it would take more than N insns, zero is returned and no
1188 insns and emitted. */
1191 alpha_emit_set_const (target, mode, c, n)
1193 enum machine_mode mode;
1200 /* Try 1 insn, then 2, then up to N. */
1201 for (i = 1; i <= n; i++)
1202 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1208 /* Internal routine for the above to check for N or below insns. */
1211 alpha_emit_set_const_1 (target, mode, c, n)
1213 enum machine_mode mode;
1217 HOST_WIDE_INT new = c;
1219 /* Use a pseudo if highly optimizing and still generating RTL. */
1221 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1225 #if HOST_BITS_PER_WIDE_INT == 64
1226 /* We are only called for SImode and DImode. If this is SImode, ensure that
1227 we are sign extended to a full word. This does not make any sense when
1228 cross-compiling on a narrow machine. */
1231 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1234 /* If this is a sign-extended 32-bit constant, we can do this in at most
1235 three insns, so do it if we have enough insns left. We always have
1236 a sign-extended 32-bit constant when compiling on a narrow machine. */
1238 if (HOST_BITS_PER_WIDE_INT != 64
1239 || c >> 31 == -1 || c >> 31 == 0)
1241 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1242 HOST_WIDE_INT tmp1 = c - low;
1244 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1245 HOST_WIDE_INT extra = 0;
1247 /* If HIGH will be interpreted as negative but the constant is
1248 positive, we must adjust it to do two ldha insns. */
1250 if ((high & 0x8000) != 0 && c >= 0)
1254 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1257 if (c == low || (low == 0 && extra == 0))
1259 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1260 but that meant that we can't handle INT_MIN on 32-bit machines
1261 (like NT/Alpha), because we recurse indefinitely through
1262 emit_move_insn to gen_movdi. So instead, since we know exactly
1263 what we want, create it explicitly. */
1266 target = gen_reg_rtx (mode);
1267 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1270 else if (n >= 2 + (extra != 0))
1272 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1275 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1276 subtarget, 0, OPTAB_WIDEN);
1278 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1279 target, 0, OPTAB_WIDEN);
1283 /* If we couldn't do it that way, try some other methods. But if we have
1284 no instructions left, don't bother. Likewise, if this is SImode and
1285 we can't make pseudos, we can't do anything since the expand_binop
1286 and expand_unop calls will widen and try to make pseudos. */
1289 || (mode == SImode && ! rtx_equal_function_value_matters))
1292 #if HOST_BITS_PER_WIDE_INT == 64
1293 /* First, see if can load a value into the target that is the same as the
1294 constant except that all bytes that are 0 are changed to be 0xff. If we
1295 can, then we can do a ZAPNOT to obtain the desired constant. */
1297 for (i = 0; i < 64; i += 8)
1298 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1299 new |= (HOST_WIDE_INT) 0xff << i;
1301 /* We are only called for SImode and DImode. If this is SImode, ensure that
1302 we are sign extended to a full word. */
1305 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1308 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1309 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1310 target, 0, OPTAB_WIDEN);
1313 /* Next, see if we can load a related constant and then shift and possibly
1314 negate it to get the constant we want. Try this once each increasing
1315 numbers of insns. */
1317 for (i = 1; i < n; i++)
1319 /* First try complementing. */
1320 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1321 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1323 /* Next try to form a constant and do a left shift. We can do this
1324 if some low-order bits are zero; the exact_log2 call below tells
1325 us that information. The bits we are shifting out could be any
1326 value, but here we'll just try the 0- and sign-extended forms of
1327 the constant. To try to increase the chance of having the same
1328 constant in more than one insn, start at the highest number of
1329 bits to shift, but try all possibilities in case a ZAPNOT will
1332 if ((bits = exact_log2 (c & - c)) > 0)
1333 for (; bits > 0; bits--)
1334 if ((temp = (alpha_emit_set_const
1336 (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1337 || ((temp = (alpha_emit_set_const
1339 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1341 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1342 target, 0, OPTAB_WIDEN);
1344 /* Now try high-order zero bits. Here we try the shifted-in bits as
1345 all zero and all ones. Be careful to avoid shifting outside the
1346 mode and to avoid shifting outside the host wide int size. */
1347 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1348 confuse the recursive call and set all of the high 32 bits. */
1350 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1351 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1352 for (; bits > 0; bits--)
1353 if ((temp = alpha_emit_set_const (subtarget, mode,
1355 || ((temp = (alpha_emit_set_const
1357 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1360 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1361 target, 1, OPTAB_WIDEN);
1363 /* Now try high-order 1 bits. We get that with a sign-extension.
1364 But one bit isn't enough here. Be careful to avoid shifting outside
1365 the mode and to avoid shifting outside the host wide int size. */
1367 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1368 - floor_log2 (~ c) - 2)) > 0)
1369 for (; bits > 0; bits--)
1370 if ((temp = alpha_emit_set_const (subtarget, mode,
1372 || ((temp = (alpha_emit_set_const
1374 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1377 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1378 target, 0, OPTAB_WIDEN);
1384 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1385 fall back to a straight forward decomposition. We do this to avoid
1386 exponential run times encountered when looking for longer sequences
1387 with alpha_emit_set_const. */
1390 alpha_emit_set_long_const (target, c1, c2)
1392 HOST_WIDE_INT c1, c2;
1394 HOST_WIDE_INT d1, d2, d3, d4;
1396 /* Decompose the entire word */
1397 #if HOST_BITS_PER_WIDE_INT >= 64
1398 if (c2 != -(c1 < 0))
1400 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1402 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1403 c1 = (c1 - d2) >> 32;
1404 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1406 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1410 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1412 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1416 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1418 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1423 /* Construct the high word */
1426 emit_move_insn (target, GEN_INT (d4));
1428 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1431 emit_move_insn (target, GEN_INT (d3));
1433 /* Shift it into place */
1434 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1436 /* Add in the low bits. */
1438 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1440 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1445 /* Generate the comparison for a conditional branch. */
1448 alpha_emit_conditional_branch (code)
1451 enum rtx_code cmp_code, branch_code;
1452 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1453 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1456 /* The general case: fold the comparison code to the types of compares
1457 that we have, choosing the branch as necessary. */
1460 case EQ: case LE: case LT: case LEU: case LTU:
1461 /* We have these compares: */
1462 cmp_code = code, branch_code = NE;
1466 /* This must be reversed. */
1467 cmp_code = EQ, branch_code = EQ;
1470 case GE: case GT: case GEU: case GTU:
1471 /* For FP, we swap them, for INT, we reverse them. */
1472 if (alpha_compare.fp_p)
1474 cmp_code = swap_condition (code);
1476 tem = op0, op0 = op1, op1 = tem;
1480 cmp_code = reverse_condition (code);
1489 if (alpha_compare.fp_p)
1494 /* When we are not as concerned about non-finite values, and we
1495 are comparing against zero, we can branch directly. */
1496 if (op1 == CONST0_RTX (DFmode))
1497 cmp_code = NIL, branch_code = code;
1498 else if (op0 == CONST0_RTX (DFmode))
1500 /* Undo the swap we probably did just above. */
1501 tem = op0, op0 = op1, op1 = tem;
1502 branch_code = swap_condition (cmp_code);
1508 /* ??? We mark the the branch mode to be CCmode to prevent the
1509 compare and branch from being combined, since the compare
1510 insn follows IEEE rules that the branch does not. */
1511 branch_mode = CCmode;
1518 /* The following optimizations are only for signed compares. */
1519 if (code != LEU && code != LTU && code != GEU && code != GTU)
1521 /* Whee. Compare and branch against 0 directly. */
1522 if (op1 == const0_rtx)
1523 cmp_code = NIL, branch_code = code;
1525 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1526 bypass between logicals and br/cmov on EV5. But we don't want to
1527 force valid immediate constants into registers needlessly. */
1528 else if (GET_CODE (op1) == CONST_INT)
1530 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1532 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1533 && (CONST_OK_FOR_LETTER_P (n, 'K')
1534 || CONST_OK_FOR_LETTER_P (n, 'L')))
1536 cmp_code = PLUS, branch_code = code;
1543 /* Force op0 into a register. */
1544 if (GET_CODE (op0) != REG)
1545 op0 = force_reg (cmp_mode, op0);
1547 /* Emit an initial compare instruction, if necessary. */
1549 if (cmp_code != NIL)
1551 tem = gen_reg_rtx (cmp_mode);
1552 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1555 /* Zero the operands. */
1556 memset (&alpha_compare, 0, sizeof (alpha_compare));
1558 /* Return the branch comparison. */
1559 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1563 /* Rewrite a comparison against zero CMP of the form
1564 (CODE (cc0) (const_int 0)) so it can be written validly in
1565 a conditional move (if_then_else CMP ...).
1566 If both of the operands that set cc0 are non-zero we must emit
1567 an insn to perform the compare (it can't be done within
1568 the conditional move). */
1570 alpha_emit_conditional_move (cmp, mode)
1572 enum machine_mode mode;
1574 enum rtx_code code = GET_CODE (cmp);
1575 enum rtx_code cmov_code = NE;
1576 rtx op0 = alpha_compare.op0;
1577 rtx op1 = alpha_compare.op1;
1578 int fp_p = alpha_compare.fp_p;
1579 enum machine_mode cmp_mode
1580 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1581 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1582 enum machine_mode cmov_mode = VOIDmode;
1583 int local_fast_math = flag_fast_math;
1586 /* Zero the operands. */
1587 memset (&alpha_compare, 0, sizeof (alpha_compare));
1589 if (fp_p != FLOAT_MODE_P (mode))
1591 enum rtx_code cmp_code;
1596 /* If we have fp<->int register move instructions, do a cmov by
1597 performing the comparison in fp registers, and move the
1598 zero/non-zero value to integer registers, where we can then
1599 use a normal cmov, or vice-versa. */
1603 case EQ: case LE: case LT: case LEU: case LTU:
1604 /* We have these compares. */
1605 cmp_code = code, code = NE;
1609 /* This must be reversed. */
1610 cmp_code = EQ, code = EQ;
1613 case GE: case GT: case GEU: case GTU:
1614 /* These must be swapped. */
1615 cmp_code = swap_condition (code);
1617 tem = op0, op0 = op1, op1 = tem;
1624 tem = gen_reg_rtx (cmp_op_mode);
1625 emit_insn (gen_rtx_SET (VOIDmode, tem,
1626 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1629 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1630 op0 = gen_lowpart (cmp_op_mode, tem);
1631 op1 = CONST0_RTX (cmp_op_mode);
1633 local_fast_math = 1;
1636 /* We may be able to use a conditional move directly.
1637 This avoids emitting spurious compares. */
1638 if (signed_comparison_operator (cmp, cmp_op_mode)
1639 && (!fp_p || local_fast_math)
1640 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1641 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1643 /* We can't put the comparison insides a conditional move;
1644 emit a compare instruction and put that inside the
1645 conditional move. Make sure we emit only comparisons we have;
1646 swap or reverse as necessary. */
1650 case EQ: case LE: case LT: case LEU: case LTU:
1651 /* We have these compares: */
1655 /* This must be reversed. */
1656 code = reverse_condition (code);
1660 case GE: case GT: case GEU: case GTU:
1661 /* These must be swapped. Make sure the new first operand is in
1663 code = swap_condition (code);
1664 tem = op0, op0 = op1, op1 = tem;
1665 op0 = force_reg (cmp_mode, op0);
1672 /* ??? We mark the branch mode to be CCmode to prevent the compare
1673 and cmov from being combined, since the compare insn follows IEEE
1674 rules that the cmov does not. */
1675 if (fp_p && !local_fast_math)
1678 tem = gen_reg_rtx (cmp_op_mode);
1679 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1680 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1683 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1687 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1688 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1689 lda r3,X(r11) lda r3,X+2(r11)
1690 extwl r1,r3,r1 extql r1,r3,r1
1691 extwh r2,r3,r2 extqh r2,r3,r2
1692 or r1.r2.r1 or r1,r2,r1
1695 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1696 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1697 lda r3,X(r11) lda r3,X(r11)
1698 extll r1,r3,r1 extll r1,r3,r1
1699 extlh r2,r3,r2 extlh r2,r3,r2
1700 or r1.r2.r1 addl r1,r2,r1
1702 quad: ldq_u r1,X(r11)
1711 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1713 HOST_WIDE_INT size, ofs;
1716 rtx meml, memh, addr, extl, exth;
1717 enum machine_mode mode;
1719 meml = gen_reg_rtx (DImode);
1720 memh = gen_reg_rtx (DImode);
1721 addr = gen_reg_rtx (DImode);
1722 extl = gen_reg_rtx (DImode);
1723 exth = gen_reg_rtx (DImode);
1725 emit_move_insn (meml,
1726 change_address (mem, DImode,
1727 gen_rtx_AND (DImode,
1728 plus_constant (XEXP (mem, 0),
1732 emit_move_insn (memh,
1733 change_address (mem, DImode,
1734 gen_rtx_AND (DImode,
1735 plus_constant (XEXP (mem, 0),
1739 if (sign && size == 2)
1741 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1743 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1744 emit_insn (gen_extqh (exth, memh, addr));
1746 /* We must use tgt here for the target. Alpha-vms port fails if we use
1747 addr for the target, because addr is marked as a pointer and combine
1748 knows that pointers are always sign-extended 32 bit values. */
1749 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1750 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1751 addr, 1, OPTAB_WIDEN);
1755 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1756 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1760 emit_insn (gen_extwh (exth, memh, addr));
1765 emit_insn (gen_extlh (exth, memh, addr));
1770 emit_insn (gen_extqh (exth, memh, addr));
1777 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1778 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1783 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1786 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1789 alpha_expand_unaligned_store (dst, src, size, ofs)
1791 HOST_WIDE_INT size, ofs;
1793 rtx dstl, dsth, addr, insl, insh, meml, memh;
1795 dstl = gen_reg_rtx (DImode);
1796 dsth = gen_reg_rtx (DImode);
1797 insl = gen_reg_rtx (DImode);
1798 insh = gen_reg_rtx (DImode);
1800 meml = change_address (dst, DImode,
1801 gen_rtx_AND (DImode,
1802 plus_constant (XEXP (dst, 0), ofs),
1804 memh = change_address (dst, DImode,
1805 gen_rtx_AND (DImode,
1806 plus_constant (XEXP (dst, 0),
1810 emit_move_insn (dsth, memh);
1811 emit_move_insn (dstl, meml);
1812 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1814 if (src != const0_rtx)
1816 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1817 GEN_INT (size*8), addr));
1822 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1825 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1828 emit_insn (gen_insql (insl, src, addr));
1833 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1838 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1841 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1845 #if HOST_BITS_PER_WIDE_INT == 32
1846 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1848 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1850 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1855 if (src != const0_rtx)
1857 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1858 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1861 /* Must store high before low for degenerate case of aligned. */
1862 emit_move_insn (memh, dsth);
1863 emit_move_insn (meml, dstl);
1866 /* The block move code tries to maximize speed by separating loads and
1867 stores at the expense of register pressure: we load all of the data
1868 before we store it back out. There are two secondary effects worth
1869 mentioning, that this speeds copying to/from aligned and unaligned
1870 buffers, and that it makes the code significantly easier to write. */
1872 #define MAX_MOVE_WORDS 8
1874 /* Load an integral number of consecutive unaligned quadwords. */
1877 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1880 HOST_WIDE_INT words, ofs;
1882 rtx const im8 = GEN_INT (-8);
1883 rtx const i64 = GEN_INT (64);
1884 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1888 /* Generate all the tmp registers we need. */
1889 for (i = 0; i < words; ++i)
1891 data_regs[i] = out_regs[i];
1892 ext_tmps[i] = gen_reg_rtx (DImode);
1894 data_regs[words] = gen_reg_rtx (DImode);
1897 smem = change_address (smem, GET_MODE (smem),
1898 plus_constant (XEXP (smem, 0), ofs));
1900 /* Load up all of the source data. */
1901 for (i = 0; i < words; ++i)
1903 emit_move_insn (data_regs[i],
1904 change_address (smem, DImode,
1905 gen_rtx_AND (DImode,
1906 plus_constant (XEXP(smem,0),
1910 emit_move_insn (data_regs[words],
1911 change_address (smem, DImode,
1912 gen_rtx_AND (DImode,
1913 plus_constant (XEXP(smem,0),
1917 /* Extract the half-word fragments. Unfortunately DEC decided to make
1918 extxh with offset zero a noop instead of zeroing the register, so
1919 we must take care of that edge condition ourselves with cmov. */
1921 sreg = copy_addr_to_reg (XEXP (smem, 0));
1922 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1924 for (i = 0; i < words; ++i)
1926 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1928 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1929 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1930 gen_rtx_IF_THEN_ELSE (DImode,
1931 gen_rtx_EQ (DImode, areg,
1933 const0_rtx, ext_tmps[i])));
1936 /* Merge the half-words into whole words. */
1937 for (i = 0; i < words; ++i)
1939 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1940 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1944 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1945 may be NULL to store zeros. */
1948 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1951 HOST_WIDE_INT words, ofs;
1953 rtx const im8 = GEN_INT (-8);
1954 rtx const i64 = GEN_INT (64);
1955 #if HOST_BITS_PER_WIDE_INT == 32
1956 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1958 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1960 rtx ins_tmps[MAX_MOVE_WORDS];
1961 rtx st_tmp_1, st_tmp_2, dreg;
1962 rtx st_addr_1, st_addr_2;
1965 /* Generate all the tmp registers we need. */
1966 if (data_regs != NULL)
1967 for (i = 0; i < words; ++i)
1968 ins_tmps[i] = gen_reg_rtx(DImode);
1969 st_tmp_1 = gen_reg_rtx(DImode);
1970 st_tmp_2 = gen_reg_rtx(DImode);
1973 dmem = change_address (dmem, GET_MODE (dmem),
1974 plus_constant (XEXP (dmem, 0), ofs));
1977 st_addr_2 = change_address (dmem, DImode,
1978 gen_rtx_AND (DImode,
1979 plus_constant (XEXP(dmem,0),
1982 st_addr_1 = change_address (dmem, DImode,
1983 gen_rtx_AND (DImode,
1987 /* Load up the destination end bits. */
1988 emit_move_insn (st_tmp_2, st_addr_2);
1989 emit_move_insn (st_tmp_1, st_addr_1);
1991 /* Shift the input data into place. */
1992 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1993 if (data_regs != NULL)
1995 for (i = words-1; i >= 0; --i)
1997 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1998 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2000 for (i = words-1; i > 0; --i)
2002 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2003 ins_tmps[i-1], ins_tmps[i-1], 1,
2008 /* Split and merge the ends with the destination data. */
2009 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2010 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2012 if (data_regs != NULL)
2014 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2015 st_tmp_2, 1, OPTAB_WIDEN);
2016 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2017 st_tmp_1, 1, OPTAB_WIDEN);
2021 emit_move_insn (st_addr_2, st_tmp_2);
2022 for (i = words-1; i > 0; --i)
2024 emit_move_insn (change_address (dmem, DImode,
2025 gen_rtx_AND (DImode,
2026 plus_constant(XEXP (dmem,0),
2029 data_regs ? ins_tmps[i-1] : const0_rtx);
2031 emit_move_insn (st_addr_1, st_tmp_1);
2035 /* Expand string/block move operations.
2037 operands[0] is the pointer to the destination.
2038 operands[1] is the pointer to the source.
2039 operands[2] is the number of bytes to move.
2040 operands[3] is the alignment. */
2043 alpha_expand_block_move (operands)
2046 rtx bytes_rtx = operands[2];
2047 rtx align_rtx = operands[3];
2048 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2049 HOST_WIDE_INT bytes = orig_bytes;
2050 HOST_WIDE_INT src_align = INTVAL (align_rtx);
2051 HOST_WIDE_INT dst_align = src_align;
2052 rtx orig_src = operands[1];
2053 rtx orig_dst = operands[0];
2054 rtx data_regs[2*MAX_MOVE_WORDS+16];
2056 int i, words, ofs, nregs = 0;
2060 if (bytes > MAX_MOVE_WORDS*8)
2063 /* Look for additional alignment information from recorded register info. */
2065 tmp = XEXP (orig_src, 0);
2066 if (GET_CODE (tmp) == REG)
2068 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
2069 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
2071 else if (GET_CODE (tmp) == PLUS
2072 && GET_CODE (XEXP (tmp, 0)) == REG
2073 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2075 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2076 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2080 if (a >= 8 && c % 8 == 0)
2082 else if (a >= 4 && c % 4 == 0)
2084 else if (a >= 2 && c % 2 == 0)
2089 tmp = XEXP (orig_dst, 0);
2090 if (GET_CODE (tmp) == REG)
2092 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
2093 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
2095 else if (GET_CODE (tmp) == PLUS
2096 && GET_CODE (XEXP (tmp, 0)) == REG
2097 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2099 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2100 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2104 if (a >= 8 && c % 8 == 0)
2106 else if (a >= 4 && c % 4 == 0)
2108 else if (a >= 2 && c % 2 == 0)
2114 * Load the entire block into registers.
2117 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2119 enum machine_mode mode;
2120 tmp = XEXP (XEXP (orig_src, 0), 0);
2122 /* Don't use the existing register if we're reading more than
2123 is held in the register. Nor if there is not a mode that
2124 handles the exact size. */
2125 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2127 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2131 data_regs[nregs] = gen_lowpart (DImode, tmp);
2132 data_regs[nregs+1] = gen_highpart (DImode, tmp);
2136 data_regs[nregs++] = gen_lowpart (mode, tmp);
2140 /* No appropriate mode; fall back on memory. */
2141 orig_src = change_address (orig_src, GET_MODE (orig_src),
2142 copy_addr_to_reg (XEXP (orig_src, 0)));
2146 if (src_align >= 8 && bytes >= 8)
2150 for (i = 0; i < words; ++i)
2151 data_regs[nregs+i] = gen_reg_rtx(DImode);
2153 for (i = 0; i < words; ++i)
2155 emit_move_insn (data_regs[nregs+i],
2156 change_address (orig_src, DImode,
2157 plus_constant (XEXP (orig_src, 0),
2165 if (src_align >= 4 && bytes >= 4)
2169 for (i = 0; i < words; ++i)
2170 data_regs[nregs+i] = gen_reg_rtx(SImode);
2172 for (i = 0; i < words; ++i)
2174 emit_move_insn (data_regs[nregs+i],
2175 change_address (orig_src, SImode,
2176 plus_constant (XEXP (orig_src, 0),
2188 for (i = 0; i < words+1; ++i)
2189 data_regs[nregs+i] = gen_reg_rtx(DImode);
2191 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2198 if (!TARGET_BWX && bytes >= 8)
2200 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2201 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2205 if (!TARGET_BWX && bytes >= 4)
2207 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2208 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2217 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2218 emit_move_insn (tmp,
2219 change_address (orig_src, HImode,
2220 plus_constant (XEXP (orig_src, 0),
2224 } while (bytes >= 2);
2226 else if (!TARGET_BWX)
2228 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2229 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2236 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2237 emit_move_insn (tmp,
2238 change_address (orig_src, QImode,
2239 plus_constant (XEXP (orig_src, 0),
2246 if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2250 * Now save it back out again.
2255 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2257 enum machine_mode mode;
2258 tmp = XEXP (XEXP (orig_dst, 0), 0);
2260 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2261 if (GET_MODE (tmp) == mode)
2265 emit_move_insn (tmp, data_regs[0]);
2269 else if (nregs == 2 && mode == TImode)
2271 /* Undo the subregging done above when copying between
2272 two TImode registers. */
2273 if (GET_CODE (data_regs[0]) == SUBREG
2274 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
2276 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
2283 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
2284 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
2288 emit_no_conflict_block (seq, tmp, data_regs[0],
2289 data_regs[1], NULL_RTX);
2297 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2298 /* ??? Optimize mode < dst_mode with strict_low_part. */
2300 /* No appropriate mode; fall back on memory. We can speed things
2301 up by recognizing extra alignment information. */
2302 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2303 copy_addr_to_reg (XEXP (orig_dst, 0)));
2304 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2307 /* Write out the data in whatever chunks reading the source allowed. */
2310 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2312 emit_move_insn (change_address (orig_dst, DImode,
2313 plus_constant (XEXP (orig_dst, 0),
2322 /* If the source has remaining DImode regs, write them out in
2324 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2326 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2327 NULL_RTX, 1, OPTAB_WIDEN);
2329 emit_move_insn (change_address (orig_dst, SImode,
2330 plus_constant (XEXP (orig_dst, 0),
2332 gen_lowpart (SImode, data_regs[i]));
2333 emit_move_insn (change_address (orig_dst, SImode,
2334 plus_constant (XEXP (orig_dst, 0),
2336 gen_lowpart (SImode, tmp));
2341 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2343 emit_move_insn (change_address(orig_dst, SImode,
2344 plus_constant (XEXP (orig_dst, 0),
2351 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2353 /* Write out a remaining block of words using unaligned methods. */
2355 for (words = 1; i+words < nregs ; ++words)
2356 if (GET_MODE (data_regs[i+words]) != DImode)
2360 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2362 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2368 /* Due to the above, this won't be aligned. */
2369 /* ??? If we have more than one of these, consider constructing full
2370 words in registers and using alpha_expand_unaligned_store_words. */
2371 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2373 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2379 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2381 emit_move_insn (change_address (orig_dst, HImode,
2382 plus_constant (XEXP (orig_dst, 0),
2389 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2391 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2395 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2397 emit_move_insn (change_address (orig_dst, QImode,
2398 plus_constant (XEXP (orig_dst, 0),
2413 alpha_expand_block_clear (operands)
2416 rtx bytes_rtx = operands[1];
2417 rtx align_rtx = operands[2];
2418 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2419 HOST_WIDE_INT align = INTVAL (align_rtx);
2420 rtx orig_dst = operands[0];
2422 HOST_WIDE_INT i, words, ofs = 0;
2426 if (bytes > MAX_MOVE_WORDS*8)
2429 /* Look for stricter alignment. */
2431 tmp = XEXP (orig_dst, 0);
2432 if (GET_CODE (tmp) == REG)
2434 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2435 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2437 else if (GET_CODE (tmp) == PLUS
2438 && GET_CODE (XEXP (tmp, 0)) == REG
2439 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2441 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2442 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2446 if (a >= 8 && c % 8 == 0)
2448 else if (a >= 4 && c % 4 == 0)
2450 else if (a >= 2 && c % 2 == 0)
2454 else if (GET_CODE (tmp) == ADDRESSOF)
2456 enum machine_mode mode;
2458 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2459 if (GET_MODE (XEXP (tmp, 0)) == mode)
2461 emit_move_insn (XEXP (tmp, 0), const0_rtx);
2465 /* No appropriate mode; fall back on memory. */
2466 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2467 copy_addr_to_reg (tmp));
2468 align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));
2471 /* Handle a block of contiguous words first. */
2473 if (align >= 8 && bytes >= 8)
2477 for (i = 0; i < words; ++i)
2479 emit_move_insn (change_address(orig_dst, DImode,
2480 plus_constant (XEXP (orig_dst, 0),
2488 if (align >= 4 && bytes >= 4)
2492 for (i = 0; i < words; ++i)
2494 emit_move_insn (change_address (orig_dst, SImode,
2495 plus_constant (XEXP (orig_dst, 0),
2507 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2513 /* Next clean up any trailing pieces. We know from the contiguous
2514 block move that there are no aligned SImode or DImode hunks left. */
2516 if (!TARGET_BWX && bytes >= 8)
2518 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2522 if (!TARGET_BWX && bytes >= 4)
2524 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2533 emit_move_insn (change_address (orig_dst, HImode,
2534 plus_constant (XEXP (orig_dst, 0),
2539 } while (bytes >= 2);
2541 else if (!TARGET_BWX)
2543 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2550 emit_move_insn (change_address (orig_dst, QImode,
2551 plus_constant (XEXP (orig_dst, 0),
2562 /* Adjust the cost of a scheduling dependency. Return the new cost of
2563 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2566 alpha_adjust_cost (insn, link, dep_insn, cost)
2573 enum attr_type insn_type, dep_insn_type;
2575 /* If the dependence is an anti-dependence, there is no cost. For an
2576 output dependence, there is sometimes a cost, but it doesn't seem
2577 worth handling those few cases. */
2579 if (REG_NOTE_KIND (link) != 0)
2582 /* If we can't recognize the insns, we can't really do anything. */
2583 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2586 insn_type = get_attr_type (insn);
2587 dep_insn_type = get_attr_type (dep_insn);
2589 /* Bring in the user-defined memory latency. */
2590 if (dep_insn_type == TYPE_ILD
2591 || dep_insn_type == TYPE_FLD
2592 || dep_insn_type == TYPE_LDSYM)
2593 cost += alpha_memory_latency-1;
2598 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2599 being stored, we can sometimes lower the cost. */
2601 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2602 && (set = single_set (dep_insn)) != 0
2603 && GET_CODE (PATTERN (insn)) == SET
2604 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2606 switch (dep_insn_type)
2610 /* No savings here. */
2614 /* In these cases, we save one cycle. */
2618 /* In all other cases, we save two cycles. */
2619 return MAX (0, cost - 2);
2623 /* Another case that needs adjustment is an arithmetic or logical
2624 operation. It's cost is usually one cycle, but we default it to
2625 two in the MD file. The only case that it is actually two is
2626 for the address in loads, stores, and jumps. */
2628 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2643 /* The final case is when a compare feeds into an integer branch;
2644 the cost is only one cycle in that case. */
2646 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2651 /* And the lord DEC saith: "A special bypass provides an effective
2652 latency of 0 cycles for an ICMP or ILOG insn producing the test
2653 operand of an IBR or ICMOV insn." */
2655 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2656 && (set = single_set (dep_insn)) != 0)
2658 /* A branch only has one input. This must be it. */
2659 if (insn_type == TYPE_IBR)
2661 /* A conditional move has three, make sure it is the test. */
2662 if (insn_type == TYPE_ICMOV
2663 && GET_CODE (set_src = PATTERN (insn)) == SET
2664 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2665 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2669 /* "The multiplier is unable to receive data from IEU bypass paths.
2670 The instruction issues at the expected time, but its latency is
2671 increased by the time it takes for the input data to become
2672 available to the multiplier" -- which happens in pipeline stage
2673 six, when results are comitted to the register file. */
2675 if (insn_type == TYPE_IMUL)
2677 switch (dep_insn_type)
2679 /* These insns produce their results in pipeline stage five. */
2686 /* Other integer insns produce results in pipeline stage four. */
2694 /* There is additional latency to move the result of (most) FP
2695 operations anywhere but the FP register file. */
2697 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2698 && (dep_insn_type == TYPE_FADD ||
2699 dep_insn_type == TYPE_FMUL ||
2700 dep_insn_type == TYPE_FCMOV))
2706 /* Otherwise, return the default cost. */
2710 /* Functions to save and restore alpha_return_addr_rtx. */
2713 alpha_init_machine_status (p)
2717 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
2721 alpha_mark_machine_status (p)
2724 struct machine_function *machine = p->machine;
2726 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
2727 ggc_mark_rtx (machine->ra_rtx);
2730 /* Start the ball rolling with RETURN_ADDR_RTX. */
2733 alpha_return_addr (count, frame)
2735 rtx frame ATTRIBUTE_UNUSED;
2742 reg = cfun->machine->ra_rtx;
2745 /* No rtx yet. Invent one, and initialize it from $26 in
2747 reg = gen_reg_rtx (Pmode);
2748 cfun->machine->ra_rtx = reg;
2749 init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
2751 /* Emit the insn to the prologue with the other argument copies. */
2752 push_topmost_sequence ();
2753 emit_insn_after (init, get_insns ());
2754 pop_topmost_sequence ();
2761 alpha_ra_ever_killed ()
2765 #ifdef ASM_OUTPUT_MI_THUNK
2766 if (current_function_is_thunk)
2769 if (!cfun->machine->ra_rtx)
2770 return regs_ever_live[REG_RA];
2772 push_topmost_sequence ();
2774 pop_topmost_sequence ();
2776 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2780 /* Print an operand. Recognize special options, documented below. */
2783 print_operand (file, x, code)
2793 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2794 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2795 mode. alpha_fprm controls which suffix is generated. */
2798 case ALPHA_FPRM_NORM:
2800 case ALPHA_FPRM_MINF:
2803 case ALPHA_FPRM_CHOP:
2806 case ALPHA_FPRM_DYN:
2813 /* Generates trap-mode suffix for instructions that accept the su
2814 suffix only (cmpt et al). */
2815 if (alpha_fptm >= ALPHA_FPTM_SU)
2820 /* Generates trap-mode suffix for instructions that accept the
2821 v and sv suffix. The only instruction that needs this is cvtql. */
2830 case ALPHA_FPTM_SUI:
2837 /* Generates trap-mode suffix for instructions that accept the
2838 v, sv, and svi suffix. The only instruction that needs this
2850 case ALPHA_FPTM_SUI:
2851 fputs ("svi", file);
2857 /* Generates trap-mode suffix for instructions that accept the u, su,
2858 and sui suffix. This is the bulk of the IEEE floating point
2859 instructions (addt et al). */
2870 case ALPHA_FPTM_SUI:
2871 fputs ("sui", file);
2877 /* Generates trap-mode suffix for instructions that accept the sui
2878 suffix (cvtqt and cvtqs). */
2883 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2885 case ALPHA_FPTM_SUI:
2886 fputs ("sui", file);
2892 /* Generates single precision instruction suffix. */
2893 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2897 /* Generates double precision instruction suffix. */
2898 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2902 /* If this operand is the constant zero, write it as "$31". */
2903 if (GET_CODE (x) == REG)
2904 fprintf (file, "%s", reg_names[REGNO (x)]);
2905 else if (x == CONST0_RTX (GET_MODE (x)))
2906 fprintf (file, "$31");
2908 output_operand_lossage ("invalid %%r value");
2913 /* Similar, but for floating-point. */
2914 if (GET_CODE (x) == REG)
2915 fprintf (file, "%s", reg_names[REGNO (x)]);
2916 else if (x == CONST0_RTX (GET_MODE (x)))
2917 fprintf (file, "$f31");
2919 output_operand_lossage ("invalid %%R value");
2924 /* Write the 1's complement of a constant. */
2925 if (GET_CODE (x) != CONST_INT)
2926 output_operand_lossage ("invalid %%N value");
2928 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2932 /* Write 1 << C, for a constant C. */
2933 if (GET_CODE (x) != CONST_INT)
2934 output_operand_lossage ("invalid %%P value");
2936 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2940 /* Write the high-order 16 bits of a constant, sign-extended. */
2941 if (GET_CODE (x) != CONST_INT)
2942 output_operand_lossage ("invalid %%h value");
2944 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2948 /* Write the low-order 16 bits of a constant, sign-extended. */
2949 if (GET_CODE (x) != CONST_INT)
2950 output_operand_lossage ("invalid %%L value");
2952 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2953 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2957 /* Write mask for ZAP insn. */
2958 if (GET_CODE (x) == CONST_DOUBLE)
2960 HOST_WIDE_INT mask = 0;
2961 HOST_WIDE_INT value;
2963 value = CONST_DOUBLE_LOW (x);
2964 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2969 value = CONST_DOUBLE_HIGH (x);
2970 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2973 mask |= (1 << (i + sizeof (int)));
2975 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2978 else if (GET_CODE (x) == CONST_INT)
2980 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2982 for (i = 0; i < 8; i++, value >>= 8)
2986 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2989 output_operand_lossage ("invalid %%m value");
2993 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2994 if (GET_CODE (x) != CONST_INT
2995 || (INTVAL (x) != 8 && INTVAL (x) != 16
2996 && INTVAL (x) != 32 && INTVAL (x) != 64))
2997 output_operand_lossage ("invalid %%M value");
2999 fprintf (file, "%s",
3000 (INTVAL (x) == 8 ? "b"
3001 : INTVAL (x) == 16 ? "w"
3002 : INTVAL (x) == 32 ? "l"
3007 /* Similar, except do it from the mask. */
3008 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3009 fprintf (file, "b");
3010 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3011 fprintf (file, "w");
3012 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3013 fprintf (file, "l");
3014 #if HOST_BITS_PER_WIDE_INT == 32
3015 else if (GET_CODE (x) == CONST_DOUBLE
3016 && CONST_DOUBLE_HIGH (x) == 0
3017 && CONST_DOUBLE_LOW (x) == -1)
3018 fprintf (file, "l");
3019 else if (GET_CODE (x) == CONST_DOUBLE
3020 && CONST_DOUBLE_HIGH (x) == -1
3021 && CONST_DOUBLE_LOW (x) == -1)
3022 fprintf (file, "q");
3024 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3025 fprintf (file, "q");
3026 else if (GET_CODE (x) == CONST_DOUBLE
3027 && CONST_DOUBLE_HIGH (x) == 0
3028 && CONST_DOUBLE_LOW (x) == -1)
3029 fprintf (file, "q");
3032 output_operand_lossage ("invalid %%U value");
3036 /* Write the constant value divided by 8. */
3037 if (GET_CODE (x) != CONST_INT
3038 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3039 && (INTVAL (x) & 7) != 8)
3040 output_operand_lossage ("invalid %%s value");
3042 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3046 /* Same, except compute (64 - c) / 8 */
3048 if (GET_CODE (x) != CONST_INT
3049 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3050 && (INTVAL (x) & 7) != 8)
3051 output_operand_lossage ("invalid %%s value");
3053 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
3056 case 'C': case 'D': case 'c': case 'd':
3057 /* Write out comparison name. */
3059 enum rtx_code c = GET_CODE (x);
3061 if (GET_RTX_CLASS (c) != '<')
3062 output_operand_lossage ("invalid %%C value");
3065 c = reverse_condition (c);
3066 else if (code == 'c')
3067 c = swap_condition (c);
3068 else if (code == 'd')
3069 c = swap_condition (reverse_condition (c));
3072 fprintf (file, "ule");
3074 fprintf (file, "ult");
3076 fprintf (file, "%s", GET_RTX_NAME (c));
3081 /* Write the divide or modulus operator. */
3082 switch (GET_CODE (x))
3085 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
3088 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
3091 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
3094 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
3097 output_operand_lossage ("invalid %%E value");
3103 /* Write "_u" for unaligned access. */
3104 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
3105 fprintf (file, "_u");
3109 if (GET_CODE (x) == REG)
3110 fprintf (file, "%s", reg_names[REGNO (x)]);
3111 else if (GET_CODE (x) == MEM)
3112 output_address (XEXP (x, 0));
3114 output_addr_const (file, x);
3118 output_operand_lossage ("invalid %%xn code");
3123 print_operand_address (file, addr)
3128 HOST_WIDE_INT offset = 0;
3130 if (GET_CODE (addr) == AND)
3131 addr = XEXP (addr, 0);
3133 if (GET_CODE (addr) == PLUS
3134 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3136 offset = INTVAL (XEXP (addr, 1));
3137 addr = XEXP (addr, 0);
3139 if (GET_CODE (addr) == REG)
3140 basereg = REGNO (addr);
3141 else if (GET_CODE (addr) == SUBREG
3142 && GET_CODE (SUBREG_REG (addr)) == REG)
3143 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
3144 else if (GET_CODE (addr) == CONST_INT)
3145 offset = INTVAL (addr);
3149 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
3150 fprintf (file, "($%d)", basereg);
3153 /* Emit RTL insns to initialize the variable parts of a trampoline at
3154 TRAMP. FNADDR is an RTX for the address of the function's pure
3155 code. CXT is an RTX for the static chain value for the function.
3157 The three offset parameters are for the individual template's
3158 layout. A JMPOFS < 0 indicates that the trampoline does not
3159 contain instructions at all.
3161 We assume here that a function will be called many more times than
3162 its address is taken (e.g., it might be passed to qsort), so we
3163 take the trouble to initialize the "hint" field in the JMP insn.
3164 Note that the hint field is PC (new) + 4 * bits 13:0. */
3167 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
3168 rtx tramp, fnaddr, cxt;
3169 int fnofs, cxtofs, jmpofs;
3171 rtx temp, temp1, addr;
3172 /* VMS really uses DImode pointers in memory at this point. */
3173 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
3175 #ifdef POINTERS_EXTEND_UNSIGNED
3176 fnaddr = convert_memory_address (mode, fnaddr);
3177 cxt = convert_memory_address (mode, cxt);
3180 /* Store function address and CXT. */
3181 addr = memory_address (mode, plus_constant (tramp, fnofs));
3182 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
3183 addr = memory_address (mode, plus_constant (tramp, cxtofs));
3184 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
3186 /* This has been disabled since the hint only has a 32k range, and in
3187 no existing OS is the stack within 32k of the text segment. */
3188 if (0 && jmpofs >= 0)
3190 /* Compute hint value. */
3191 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3192 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3194 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3195 build_int_2 (2, 0), NULL_RTX, 1);
3196 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3198 /* Merge in the hint. */
3199 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3200 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
3201 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3202 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3204 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
3207 #ifdef TRANSFER_FROM_TRAMPOLINE
3208 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
3209 0, VOIDmode, 1, addr, Pmode);
3213 emit_insn (gen_imb ());
3217 alpha_build_va_list ()
3219 tree base, ofs, record, type_decl;
3221 if (TARGET_OPEN_VMS)
3222 return ptr_type_node;
3224 record = make_lang_type (RECORD_TYPE);
3225 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
3226 TREE_CHAIN (record) = type_decl;
3227 TYPE_NAME (record) = type_decl;
3229 /* C++? SET_IS_AGGR_TYPE (record, 1); */
3231 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
3233 DECL_FIELD_CONTEXT (ofs) = record;
3235 base = build_decl (FIELD_DECL, get_identifier ("__base"),
3237 DECL_FIELD_CONTEXT (base) = record;
3238 TREE_CHAIN (base) = ofs;
3240 TYPE_FIELDS (record) = base;
3241 layout_type (record);
3247 alpha_va_start (stdarg_p, valist, nextarg)
3250 rtx nextarg ATTRIBUTE_UNUSED;
3252 HOST_WIDE_INT offset;
3253 tree t, offset_field, base_field;
3255 if (TARGET_OPEN_VMS)
3256 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
3258 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
3259 up by 48, storing fp arg registers in the first 48 bytes, and the
3260 integer arg registers in the next 48 bytes. This is only done,
3261 however, if any integer registers need to be stored.
3263 If no integer registers need be stored, then we must subtract 48
3264 in order to account for the integer arg registers which are counted
3265 in argsize above, but which are not actually stored on the stack. */
3267 if (NUM_ARGS <= 5 + stdarg_p)
3268 offset = 6 * UNITS_PER_WORD;
3270 offset = -6 * UNITS_PER_WORD;
3272 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3273 offset_field = TREE_CHAIN (base_field);
3275 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3276 valist, base_field);
3277 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3278 valist, offset_field);
3280 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3281 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
3282 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
3283 TREE_SIDE_EFFECTS (t) = 1;
3284 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3286 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
3287 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
3288 TREE_SIDE_EFFECTS (t) = 1;
3289 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3293 alpha_va_arg (valist, type)
3296 HOST_WIDE_INT tsize;
3299 tree offset_field, base_field, addr_tree, addend;
3300 tree wide_type, wide_ofs;
3302 if (TARGET_OPEN_VMS)
3303 return std_expand_builtin_va_arg (valist, type);
3305 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
3307 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3308 offset_field = TREE_CHAIN (base_field);
3310 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3311 valist, base_field);
3312 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3313 valist, offset_field);
3315 wide_type = make_signed_type (64);
3316 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
3319 if (FLOAT_TYPE_P (type))
3321 tree fpaddend, cond;
3323 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
3324 addend, build_int_2 (-6*8, 0)));
3326 cond = fold (build (LT_EXPR, integer_type_node,
3327 wide_ofs, build_int_2 (6*8, 0)));
3329 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
3333 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
3334 base_field, addend);
3336 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3337 addr = copy_to_reg (addr);
3339 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
3340 build (PLUS_EXPR, TREE_TYPE (offset_field),
3341 offset_field, build_int_2 (tsize, 0)));
3342 TREE_SIDE_EFFECTS (t) = 1;
3343 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3348 /* This page contains routines that are used to determine what the function
3349 prologue and epilogue code will do and write them out. */
3351 /* Compute the size of the save area in the stack. */
3353 /* These variables are used for communication between the following functions.
3354 They indicate various things about the current function being compiled
3355 that are used to tell what kind of prologue, epilogue and procedure
3356 descriptior to generate. */
3358 /* Nonzero if we need a stack procedure. */
3359 static int vms_is_stack_procedure;
3361 /* Register number (either FP or SP) that is used to unwind the frame. */
3362 static int vms_unwind_regno;
3364 /* Register number used to save FP. We need not have one for RA since
3365 we don't modify it for register procedures. This is only defined
3366 for register frame procedures. */
3367 static int vms_save_fp_regno;
3369 /* Register number used to reference objects off our PV. */
3370 static int vms_base_regno;
3372 /* Compute register masks for saved registers. */
3375 alpha_sa_mask (imaskP, fmaskP)
3376 unsigned long *imaskP;
3377 unsigned long *fmaskP;
3379 unsigned long imask = 0;
3380 unsigned long fmask = 0;
3383 #ifdef ASM_OUTPUT_MI_THUNK
3384 if (!current_function_is_thunk)
3387 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3388 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3390 /* One for every register we have to save. */
3391 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3392 if (! fixed_regs[i] && ! call_used_regs[i]
3393 && regs_ever_live[i] && i != REG_RA)
3398 fmask |= (1L << (i - 32));
3401 if (imask || fmask || alpha_ra_ever_killed ())
3402 imask |= (1L << REG_RA);
3415 #ifdef ASM_OUTPUT_MI_THUNK
3416 if (current_function_is_thunk)
3421 /* One for every register we have to save. */
3422 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3423 if (! fixed_regs[i] && ! call_used_regs[i]
3424 && regs_ever_live[i] && i != REG_RA)
3428 if (TARGET_OPEN_VMS)
3430 /* Start by assuming we can use a register procedure if we don't
3431 make any calls (REG_RA not used) or need to save any
3432 registers and a stack procedure if we do. */
3433 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3435 /* Decide whether to refer to objects off our PV via FP or PV.
3436 If we need FP for something else or if we receive a nonlocal
3437 goto (which expects PV to contain the value), we must use PV.
3438 Otherwise, start by assuming we can use FP. */
3439 vms_base_regno = (frame_pointer_needed
3440 || current_function_has_nonlocal_label
3441 || vms_is_stack_procedure
3442 || current_function_outgoing_args_size
3443 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3445 /* If we want to copy PV into FP, we need to find some register
3446 in which to save FP. */
3448 vms_save_fp_regno = -1;
3449 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3450 for (i = 0; i < 32; i++)
3451 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3452 vms_save_fp_regno = i;
3454 if (vms_save_fp_regno == -1)
3455 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3457 /* Stack unwinding should be done via FP unless we use it for PV. */
3458 vms_unwind_regno = (vms_base_regno == REG_PV
3459 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3461 /* If this is a stack procedure, allow space for saving FP and RA. */
3462 if (vms_is_stack_procedure)
3467 /* If some registers were saved but not RA, RA must also be saved,
3468 so leave space for it. */
3469 if (sa_size != 0 || alpha_ra_ever_killed ())
3472 /* Our size must be even (multiple of 16 bytes). */
3481 alpha_pv_save_size ()
3484 return vms_is_stack_procedure ? 8 : 0;
3491 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3495 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3496 tree decl ATTRIBUTE_UNUSED;
3497 tree attributes ATTRIBUTE_UNUSED;
3501 if (is_attribute_p ("overlaid", identifier))
3502 return (args == NULL_TREE);
3507 alpha_does_function_need_gp ()
3511 /* We never need a GP for Windows/NT or VMS. */
3512 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3515 #ifdef TARGET_PROFILING_NEEDS_GP
3520 #ifdef ASM_OUTPUT_MI_THUNK
3521 if (current_function_is_thunk)
3525 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3526 Even if we are a static function, we still need to do this in case
3527 our address is taken and passed to something like qsort. */
3529 push_topmost_sequence ();
3530 insn = get_insns ();
3531 pop_topmost_sequence ();
3533 for (; insn; insn = NEXT_INSN (insn))
3534 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3535 && GET_CODE (PATTERN (insn)) != USE
3536 && GET_CODE (PATTERN (insn)) != CLOBBER)
3538 enum attr_type type = get_attr_type (insn);
3539 if (type == TYPE_LDSYM || type == TYPE_JSR)
3546 /* Write a version stamp. Don't write anything if we are running as a
3547 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3554 alpha_write_verstamp (file)
3555 FILE *file ATTRIBUTE_UNUSED;
3558 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3562 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3566 set_frame_related_p ()
3568 rtx seq = gen_sequence ();
3571 if (GET_CODE (seq) == SEQUENCE)
3573 int i = XVECLEN (seq, 0);
3575 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3576 return emit_insn (seq);
3580 seq = emit_insn (seq);
3581 RTX_FRAME_RELATED_P (seq) = 1;
3586 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3588 /* Write function prologue. */
3590 /* On vms we have two kinds of functions:
3592 - stack frame (PROC_STACK)
3593 these are 'normal' functions with local vars and which are
3594 calling other functions
3595 - register frame (PROC_REGISTER)
3596 keeps all data in registers, needs no stack
3598 We must pass this to the assembler so it can generate the
3599 proper pdsc (procedure descriptor)
3600 This is done with the '.pdesc' command.
3602 On not-vms, we don't really differentiate between the two, as we can
3603 simply allocate stack without saving registers. */
3606 alpha_expand_prologue ()
3608 /* Registers to save. */
3609 unsigned long imask = 0;
3610 unsigned long fmask = 0;
3611 /* Stack space needed for pushing registers clobbered by us. */
3612 HOST_WIDE_INT sa_size;
3613 /* Complete stack size needed. */
3614 HOST_WIDE_INT frame_size;
3615 /* Offset from base reg to register save area. */
3616 HOST_WIDE_INT reg_offset;
3620 sa_size = alpha_sa_size ();
3622 frame_size = get_frame_size ();
3623 if (TARGET_OPEN_VMS)
3624 frame_size = ALPHA_ROUND (sa_size
3625 + (vms_is_stack_procedure ? 8 : 0)
3627 + current_function_pretend_args_size);
3629 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3631 + ALPHA_ROUND (frame_size
3632 + current_function_pretend_args_size));
3634 if (TARGET_OPEN_VMS)
3637 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3639 alpha_sa_mask (&imask, &fmask);
3641 /* Adjust the stack by the frame size. If the frame size is > 4096
3642 bytes, we need to be sure we probe somewhere in the first and last
3643 4096 bytes (we can probably get away without the latter test) and
3644 every 8192 bytes in between. If the frame size is > 32768, we
3645 do this in a loop. Otherwise, we generate the explicit probe
3648 Note that we are only allowed to adjust sp once in the prologue. */
3650 if (frame_size <= 32768)
3652 if (frame_size > 4096)
3657 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3658 while ((probed += 8192) < frame_size);
3660 /* We only have to do this probe if we aren't saving registers. */
3661 if (sa_size == 0 && probed + 4096 < frame_size)
3662 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3665 if (frame_size != 0)
3667 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
3668 GEN_INT (-frame_size))));
3673 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3674 number of 8192 byte blocks to probe. We then probe each block
3675 in the loop and then set SP to the proper location. If the
3676 amount remaining is > 4096, we have to do one more probe if we
3677 are not saving any registers. */
3679 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3680 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3681 rtx ptr = gen_rtx_REG (DImode, 22);
3682 rtx count = gen_rtx_REG (DImode, 23);
3685 emit_move_insn (count, GEN_INT (blocks));
3686 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
3688 /* Because of the difficulty in emitting a new basic block this
3689 late in the compilation, generate the loop as a single insn. */
3690 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3692 if (leftover > 4096 && sa_size == 0)
3694 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3695 MEM_VOLATILE_P (last) = 1;
3696 emit_move_insn (last, const0_rtx);
3699 if (TARGET_WINDOWS_NT)
3701 /* For NT stack unwind (done by 'reverse execution'), it's
3702 not OK to take the result of a loop, even though the value
3703 is already in ptr, so we reload it via a single operation
3704 and subtract it to sp.
3706 Yes, that's correct -- we have to reload the whole constant
3707 into a temporary via ldah+lda then subtract from sp. To
3708 ensure we get ldah+lda, we use a special pattern. */
3710 HOST_WIDE_INT lo, hi;
3711 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3712 hi = frame_size - lo;
3714 emit_move_insn (ptr, GEN_INT (hi));
3715 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
3716 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3721 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
3722 GEN_INT (-leftover)));
3725 /* This alternative is special, because the DWARF code cannot
3726 possibly intuit through the loop above. So we invent this
3727 note it looks at instead. */
3728 RTX_FRAME_RELATED_P (seq) = 1;
3730 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3731 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3732 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3733 GEN_INT (-frame_size))),
3737 /* Cope with very large offsets to the register save area. */
3738 sa_reg = stack_pointer_rtx;
3739 if (reg_offset + sa_size > 0x8000)
3741 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3744 if (low + sa_size <= 0x8000)
3745 bias = reg_offset - low, reg_offset = low;
3747 bias = reg_offset, reg_offset = 0;
3749 sa_reg = gen_rtx_REG (DImode, 24);
3750 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
3753 /* Save regs in stack order. Beginning with VMS PV. */
3754 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3756 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3757 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3758 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3761 /* Save register RA next. */
3762 if (imask & (1L << REG_RA))
3764 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3765 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3766 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3767 imask &= ~(1L << REG_RA);
3771 /* Now save any other registers required to be saved. */
3772 for (i = 0; i < 32; i++)
3773 if (imask & (1L << i))
3775 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3776 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3777 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3781 for (i = 0; i < 32; i++)
3782 if (fmask & (1L << i))
3784 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3785 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3786 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3790 if (TARGET_OPEN_VMS)
3792 if (!vms_is_stack_procedure)
3794 /* Register frame procedures fave the fp. */
3795 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3796 hard_frame_pointer_rtx));
3799 if (vms_base_regno != REG_PV)
3800 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3801 gen_rtx_REG (DImode, REG_PV)));
3803 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3805 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3808 /* If we have to allocate space for outgoing args, do it now. */
3809 if (current_function_outgoing_args_size != 0)
3811 FRP (emit_move_insn (stack_pointer_rtx,
3812 plus_constant (hard_frame_pointer_rtx,
3813 - ALPHA_ROUND (current_function_outgoing_args_size))));
3818 /* If we need a frame pointer, set it from the stack pointer. */
3819 if (frame_pointer_needed)
3821 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3822 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3825 /* This must always be the last instruction in the
3826 prologue, thus we emit a special move + clobber. */
3827 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3828 stack_pointer_rtx, sa_reg)));
3833 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3834 the prologue, for exception handling reasons, we cannot do this for
3835 any insn that might fault. We could prevent this for mems with a
3836 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3837 have to prevent all such scheduling with a blockage.
3839 Linux, on the other hand, never bothered to implement OSF/1's
3840 exception handling, and so doesn't care about such things. Anyone
3841 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3843 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3844 emit_insn (gen_blockage ());
3847 /* Output the textual info surrounding the prologue. */
3850 alpha_start_function (file, fnname, decl)
3853 tree decl ATTRIBUTE_UNUSED;
3855 unsigned long imask = 0;
3856 unsigned long fmask = 0;
3857 /* Stack space needed for pushing registers clobbered by us. */
3858 HOST_WIDE_INT sa_size;
3859 /* Complete stack size needed. */
3860 HOST_WIDE_INT frame_size;
3861 /* Offset from base reg to register save area. */
3862 HOST_WIDE_INT reg_offset;
3863 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3866 sa_size = alpha_sa_size ();
3868 frame_size = get_frame_size ();
3869 if (TARGET_OPEN_VMS)
3870 frame_size = ALPHA_ROUND (sa_size
3871 + (vms_is_stack_procedure ? 8 : 0)
3873 + current_function_pretend_args_size);
3875 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3877 + ALPHA_ROUND (frame_size
3878 + current_function_pretend_args_size));
3880 if (TARGET_OPEN_VMS)
3883 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3885 alpha_sa_mask (&imask, &fmask);
3887 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3888 We have to do that before the .ent directive as we cannot switch
3889 files within procedures with native ecoff because line numbers are
3890 linked to procedure descriptors.
3891 Outputting the lineno helps debugging of one line functions as they
3892 would otherwise get no line number at all. Please note that we would
3893 like to put out last_linenum from final.c, but it is not accessible. */
3895 if (write_symbols == SDB_DEBUG)
3897 ASM_OUTPUT_SOURCE_FILENAME (file,
3898 DECL_SOURCE_FILE (current_function_decl));
3899 if (debug_info_level != DINFO_LEVEL_TERSE)
3900 ASM_OUTPUT_SOURCE_LINE (file,
3901 DECL_SOURCE_LINE (current_function_decl));
3904 /* Issue function start and label. */
3905 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3907 fputs ("\t.ent ", file);
3908 assemble_name (file, fnname);
3912 strcpy (entry_label, fnname);
3913 if (TARGET_OPEN_VMS)
3914 strcat (entry_label, "..en");
3915 ASM_OUTPUT_LABEL (file, entry_label);
3916 inside_function = TRUE;
3918 if (TARGET_OPEN_VMS)
3919 fprintf (file, "\t.base $%d\n", vms_base_regno);
3921 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3922 && !flag_inhibit_size_directive)
3924 /* Set flags in procedure descriptor to request IEEE-conformant
3925 math-library routines. The value we set it to is PDSC_EXC_IEEE
3926 (/usr/include/pdsc.h). */
3927 fputs ("\t.eflag 48\n", file);
3930 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3931 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3932 alpha_arg_offset = -frame_size + 48;
3934 /* Describe our frame. If the frame size is larger than an integer,
3935 print it as zero to avoid an assembler error. We won't be
3936 properly describing such a frame, but that's the best we can do. */
3937 if (TARGET_OPEN_VMS)
3939 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3940 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3941 frame_size >= (1l << 31) ? 0 : frame_size);
3942 fputs (",$26,", file);
3943 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3946 else if (!flag_inhibit_size_directive)
3948 fprintf (file, "\t.frame $%d,",
3949 (frame_pointer_needed
3950 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3951 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3952 frame_size >= (1l << 31) ? 0 : frame_size);
3953 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3956 /* Describe which registers were spilled. */
3957 if (TARGET_OPEN_VMS)
3960 /* ??? Does VMS care if mask contains ra? The old code did'nt
3961 set it, so I don't here. */
3962 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3964 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3965 if (!vms_is_stack_procedure)
3966 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3968 else if (!flag_inhibit_size_directive)
3972 fprintf (file, "\t.mask 0x%lx,", imask);
3973 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3974 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3977 for (i = 0; i < 32; ++i)
3978 if (imask & (1L << i))
3984 fprintf (file, "\t.fmask 0x%lx,", fmask);
3985 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3986 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3991 /* Emit GP related things. It is rather unfortunate about the alignment
3992 issues surrounding a CODE_LABEL that forces us to do the label in
3994 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3996 alpha_function_needs_gp = alpha_does_function_need_gp ();
3997 if (alpha_function_needs_gp)
3998 fputs ("\tldgp $29,0($27)\n", file);
4001 assemble_name (file, fnname);
4002 fputs ("..ng:\n", file);
4006 /* Ifdef'ed cause readonly_section and link_section are only
4008 readonly_section ();
4009 fprintf (file, "\t.align 3\n");
4010 assemble_name (file, fnname); fputs ("..na:\n", file);
4011 fputs ("\t.ascii \"", file);
4012 assemble_name (file, fnname);
4013 fputs ("\\0\"\n", file);
4016 fprintf (file, "\t.align 3\n");
4017 fputs ("\t.name ", file);
4018 assemble_name (file, fnname);
4019 fputs ("..na\n", file);
4020 ASM_OUTPUT_LABEL (file, fnname);
4021 fprintf (file, "\t.pdesc ");
4022 assemble_name (file, fnname);
4023 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
4024 alpha_need_linkage (fnname, 1);
4029 /* Emit the .prologue note at the scheduled end of the prologue. */
4032 output_end_prologue (file)
4035 if (TARGET_OPEN_VMS)
4036 fputs ("\t.prologue\n", file);
4037 else if (TARGET_WINDOWS_NT)
4038 fputs ("\t.prologue 0\n", file);
4039 else if (!flag_inhibit_size_directive)
4040 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
4043 /* Write function epilogue. */
4045 /* ??? At some point we will want to support full unwind, and so will
4046 need to mark the epilogue as well. At the moment, we just confuse
4049 #define FRP(exp) exp
4052 alpha_expand_epilogue ()
4054 /* Registers to save. */
4055 unsigned long imask = 0;
4056 unsigned long fmask = 0;
4057 /* Stack space needed for pushing registers clobbered by us. */
4058 HOST_WIDE_INT sa_size;
4059 /* Complete stack size needed. */
4060 HOST_WIDE_INT frame_size;
4061 /* Offset from base reg to register save area. */
4062 HOST_WIDE_INT reg_offset;
4063 int fp_is_frame_pointer, fp_offset;
4064 rtx sa_reg, sa_reg_exp = NULL;
4065 rtx sp_adj1, sp_adj2, mem;
4069 sa_size = alpha_sa_size ();
4071 frame_size = get_frame_size ();
4072 if (TARGET_OPEN_VMS)
4073 frame_size = ALPHA_ROUND (sa_size
4074 + (vms_is_stack_procedure ? 8 : 0)
4076 + current_function_pretend_args_size);
4078 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4080 + ALPHA_ROUND (frame_size
4081 + current_function_pretend_args_size));
4083 if (TARGET_OPEN_VMS)
4086 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4088 alpha_sa_mask (&imask, &fmask);
4090 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
4091 || (!TARGET_OPEN_VMS && frame_pointer_needed));
4093 eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
4096 /* If we have a frame pointer, restore SP from it. */
4097 if ((TARGET_OPEN_VMS
4098 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4099 || (!TARGET_OPEN_VMS && frame_pointer_needed))
4101 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
4104 /* Cope with very large offsets to the register save area. */
4105 sa_reg = stack_pointer_rtx;
4106 if (reg_offset + sa_size > 0x8000)
4108 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4111 if (low + sa_size <= 0x8000)
4112 bias = reg_offset - low, reg_offset = low;
4114 bias = reg_offset, reg_offset = 0;
4116 sa_reg = gen_rtx_REG (DImode, 22);
4117 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
4119 FRP (emit_move_insn (sa_reg, sa_reg_exp));
4122 /* Restore registers in order, excepting a true frame pointer. */
4126 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4127 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4128 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
4131 imask &= ~(1L << REG_RA);
4133 for (i = 0; i < 32; ++i)
4134 if (imask & (1L << i))
4136 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
4137 fp_offset = reg_offset;
4140 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4141 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4142 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
4147 for (i = 0; i < 32; ++i)
4148 if (fmask & (1L << i))
4150 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
4151 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4152 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
4157 if (frame_size || eh_ofs)
4159 sp_adj1 = stack_pointer_rtx;
4163 sp_adj1 = gen_rtx_REG (DImode, 23);
4164 emit_move_insn (sp_adj1,
4165 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
4168 /* If the stack size is large, begin computation into a temporary
4169 register so as not to interfere with a potential fp restore,
4170 which must be consecutive with an SP restore. */
4171 if (frame_size < 32768)
4172 sp_adj2 = GEN_INT (frame_size);
4173 else if (frame_size < 0x40007fffL)
4175 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4177 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
4178 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
4182 sp_adj1 = gen_rtx_REG (DImode, 23);
4183 FRP (emit_move_insn (sp_adj1, sp_adj2));
4185 sp_adj2 = GEN_INT (low);
4189 rtx tmp = gen_rtx_REG (DImode, 23);
4190 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
4193 /* We can't drop new things to memory this late, afaik,
4194 so build it up by pieces. */
4195 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
4196 -(frame_size < 0)));
4202 /* From now on, things must be in order. So emit blockages. */
4204 /* Restore the frame pointer. */
4205 if (fp_is_frame_pointer)
4207 emit_insn (gen_blockage ());
4208 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
4209 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4210 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
4212 else if (TARGET_OPEN_VMS)
4214 emit_insn (gen_blockage ());
4215 FRP (emit_move_insn (hard_frame_pointer_rtx,
4216 gen_rtx_REG (DImode, vms_save_fp_regno)));
4219 /* Restore the stack pointer. */
4220 emit_insn (gen_blockage ());
4221 FRP (emit_move_insn (stack_pointer_rtx,
4222 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
4226 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4228 emit_insn (gen_blockage ());
4229 FRP (emit_move_insn (hard_frame_pointer_rtx,
4230 gen_rtx_REG (DImode, vms_save_fp_regno)));
4235 emit_jump_insn (gen_return_internal ());
4238 /* Output the rest of the textual info surrounding the epilogue. */
4241 alpha_end_function (file, fnname, decl)
4244 tree decl ATTRIBUTE_UNUSED;
4246 /* End the function. */
4247 if (!flag_inhibit_size_directive)
4249 fputs ("\t.end ", file);
4250 assemble_name (file, fnname);
4253 inside_function = FALSE;
4255 /* Show that we know this function if it is called again.
4257 Don't do this for global functions in object files destined for a
4258 shared library because the function may be overridden by the application
4259 or other libraries. Similarly, don't do this for weak functions. */
4261 if (!DECL_WEAK (current_function_decl)
4262 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4263 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4266 /* Debugging support. */
4270 /* Count the number of sdb related labels are generated (to find block
4271 start and end boundaries). */
4273 int sdb_label_count = 0;
4275 /* Next label # for each statement. */
4277 static int sym_lineno = 0;
4279 /* Count the number of .file directives, so that .loc is up to date. */
4281 static int num_source_filenames = 0;
4283 /* Name of the file containing the current function. */
4285 static const char *current_function_file = "";
4287 /* Offsets to alpha virtual arg/local debugging pointers. */
4289 long alpha_arg_offset;
4290 long alpha_auto_offset;
4292 /* Emit a new filename to a stream. */
4295 alpha_output_filename (stream, name)
4299 static int first_time = TRUE;
4300 char ltext_label_name[100];
4305 ++num_source_filenames;
4306 current_function_file = name;
4307 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4308 output_quoted_string (stream, name);
4309 fprintf (stream, "\n");
4310 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4311 fprintf (stream, "\t#@stabs\n");
4314 else if (write_symbols == DBX_DEBUG)
4316 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4317 fprintf (stream, "%s ", ASM_STABS_OP);
4318 output_quoted_string (stream, name);
4319 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
4322 else if (name != current_function_file
4323 && strcmp (name, current_function_file) != 0)
4325 if (inside_function && ! TARGET_GAS)
4326 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4329 ++num_source_filenames;
4330 current_function_file = name;
4331 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4334 output_quoted_string (stream, name);
4335 fprintf (stream, "\n");
4339 /* Emit a linenumber to a stream. */
4342 alpha_output_lineno (stream, line)
4346 if (write_symbols == DBX_DEBUG)
4348 /* mips-tfile doesn't understand .stabd directives. */
4350 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4351 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4354 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4357 /* Structure to show the current status of registers and memory. */
4359 struct shadow_summary
4362 unsigned long i : 31; /* Mask of int regs */
4363 unsigned long fp : 31; /* Mask of fp regs */
4364 unsigned long mem : 1; /* mem == imem | fpmem */
4368 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
4369 static void alpha_handle_trap_shadows PARAMS ((rtx));
4371 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4372 to the summary structure. SET is nonzero if the insn is setting the
4373 object, otherwise zero. */
4376 summarize_insn (x, sum, set)
4378 struct shadow_summary *sum;
4381 const char *format_ptr;
4387 switch (GET_CODE (x))
4389 /* ??? Note that this case would be incorrect if the Alpha had a
4390 ZERO_EXTRACT in SET_DEST. */
4392 summarize_insn (SET_SRC (x), sum, 0);
4393 summarize_insn (SET_DEST (x), sum, 1);
4397 summarize_insn (XEXP (x, 0), sum, 1);
4401 summarize_insn (XEXP (x, 0), sum, 0);
4405 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4406 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4410 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4411 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4415 summarize_insn (SUBREG_REG (x), sum, 0);
4420 int regno = REGNO (x);
4421 unsigned long mask = 1UL << (regno % 32);
4423 if (regno == 31 || regno == 63)
4429 sum->defd.i |= mask;
4431 sum->defd.fp |= mask;
4436 sum->used.i |= mask;
4438 sum->used.fp |= mask;
4449 /* Find the regs used in memory address computation: */
4450 summarize_insn (XEXP (x, 0), sum, 0);
4453 case CONST_INT: case CONST_DOUBLE:
4454 case SYMBOL_REF: case LABEL_REF: case CONST:
4457 /* Handle common unary and binary ops for efficiency. */
4458 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4459 case MOD: case UDIV: case UMOD: case AND: case IOR:
4460 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4461 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4462 case NE: case EQ: case GE: case GT: case LE:
4463 case LT: case GEU: case GTU: case LEU: case LTU:
4464 summarize_insn (XEXP (x, 0), sum, 0);
4465 summarize_insn (XEXP (x, 1), sum, 0);
4468 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4469 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4470 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4471 case SQRT: case FFS:
4472 summarize_insn (XEXP (x, 0), sum, 0);
4476 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4477 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4478 switch (format_ptr[i])
4481 summarize_insn (XEXP (x, i), sum, 0);
4485 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4486 summarize_insn (XVECEXP (x, i, j), sum, 0);
4498 /* Ensure a sufficient number of `trapb' insns are in the code when
4499 the user requests code with a trap precision of functions or
4502 In naive mode, when the user requests a trap-precision of
4503 "instruction", a trapb is needed after every instruction that may
4504 generate a trap. This ensures that the code is resumption safe but
4507 When optimizations are turned on, we delay issuing a trapb as long
4508 as possible. In this context, a trap shadow is the sequence of
4509 instructions that starts with a (potentially) trap generating
4510 instruction and extends to the next trapb or call_pal instruction
4511 (but GCC never generates call_pal by itself). We can delay (and
4512 therefore sometimes omit) a trapb subject to the following
4515 (a) On entry to the trap shadow, if any Alpha register or memory
4516 location contains a value that is used as an operand value by some
4517 instruction in the trap shadow (live on entry), then no instruction
4518 in the trap shadow may modify the register or memory location.
4520 (b) Within the trap shadow, the computation of the base register
4521 for a memory load or store instruction may not involve using the
4522 result of an instruction that might generate an UNPREDICTABLE
4525 (c) Within the trap shadow, no register may be used more than once
4526 as a destination register. (This is to make life easier for the
4529 (d) The trap shadow may not include any branch instructions. */
4532 alpha_handle_trap_shadows (insns)
4535 struct shadow_summary shadow;
4536 int trap_pending, exception_nesting;
4540 exception_nesting = 0;
4543 shadow.used.mem = 0;
4544 shadow.defd = shadow.used;
4546 for (i = insns; i ; i = NEXT_INSN (i))
4548 if (GET_CODE (i) == NOTE)
4550 switch (NOTE_LINE_NUMBER (i))
4552 case NOTE_INSN_EH_REGION_BEG:
4553 exception_nesting++;
4558 case NOTE_INSN_EH_REGION_END:
4559 exception_nesting--;
4564 case NOTE_INSN_EPILOGUE_BEG:
4565 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4570 else if (trap_pending)
4572 if (alpha_tp == ALPHA_TP_FUNC)
4574 if (GET_CODE (i) == JUMP_INSN
4575 && GET_CODE (PATTERN (i)) == RETURN)
4578 else if (alpha_tp == ALPHA_TP_INSN)
4582 struct shadow_summary sum;
4587 sum.defd = sum.used;
4589 switch (GET_CODE (i))
4592 /* Annoyingly, get_attr_trap will abort on these. */
4593 if (GET_CODE (PATTERN (i)) == USE
4594 || GET_CODE (PATTERN (i)) == CLOBBER)
4597 summarize_insn (PATTERN (i), &sum, 0);
4599 if ((sum.defd.i & shadow.defd.i)
4600 || (sum.defd.fp & shadow.defd.fp))
4602 /* (c) would be violated */
4606 /* Combine shadow with summary of current insn: */
4607 shadow.used.i |= sum.used.i;
4608 shadow.used.fp |= sum.used.fp;
4609 shadow.used.mem |= sum.used.mem;
4610 shadow.defd.i |= sum.defd.i;
4611 shadow.defd.fp |= sum.defd.fp;
4612 shadow.defd.mem |= sum.defd.mem;
4614 if ((sum.defd.i & shadow.used.i)
4615 || (sum.defd.fp & shadow.used.fp)
4616 || (sum.defd.mem & shadow.used.mem))
4618 /* (a) would be violated (also takes care of (b)) */
4619 if (get_attr_trap (i) == TRAP_YES
4620 && ((sum.defd.i & sum.used.i)
4621 || (sum.defd.fp & sum.used.fp)))
4640 n = emit_insn_before (gen_trapb (), i);
4641 PUT_MODE (n, TImode);
4642 PUT_MODE (i, TImode);
4646 shadow.used.mem = 0;
4647 shadow.defd = shadow.used;
4652 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4653 && GET_CODE (i) == INSN
4654 && GET_CODE (PATTERN (i)) != USE
4655 && GET_CODE (PATTERN (i)) != CLOBBER
4656 && get_attr_trap (i) == TRAP_YES)
4658 if (optimize && !trap_pending)
4659 summarize_insn (PATTERN (i), &shadow, 0);
4666 /* Alpha can only issue instruction groups simultaneously if they are
4667 suitibly aligned. This is very processor-specific. */
4669 enum alphaev4_pipe {
4676 enum alphaev5_pipe {
4687 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
4688 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
4689 static rtx alphaev4_next_group PARAMS ((rtx, int*, int*));
4690 static rtx alphaev5_next_group PARAMS ((rtx, int*, int*));
4691 static rtx alphaev4_next_nop PARAMS ((int*));
4692 static rtx alphaev5_next_nop PARAMS ((int*));
4694 static void alpha_align_insns
4695 PARAMS ((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4697 static enum alphaev4_pipe
4698 alphaev4_insn_pipe (insn)
4701 if (recog_memoized (insn) < 0)
4703 if (get_attr_length (insn) != 4)
4706 switch (get_attr_type (insn))
4739 static enum alphaev5_pipe
4740 alphaev5_insn_pipe (insn)
4743 if (recog_memoized (insn) < 0)
4745 if (get_attr_length (insn) != 4)
4748 switch (get_attr_type (insn))
4788 /* IN_USE is a mask of the slots currently filled within the insn group.
4789 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4790 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4792 LEN is, of course, the length of the group in bytes. */
4795 alphaev4_next_group (insn, pin_use, plen)
4797 int *pin_use, *plen;
4803 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4804 || GET_CODE (PATTERN (insn)) == CLOBBER
4805 || GET_CODE (PATTERN (insn)) == USE)
4810 enum alphaev4_pipe pipe;
4812 pipe = alphaev4_insn_pipe (insn);
4816 /* Force complex instructions to start new groups. */
4820 /* If this is a completely unrecognized insn, its an asm.
4821 We don't know how long it is, so record length as -1 to
4822 signal a needed realignment. */
4823 if (recog_memoized (insn) < 0)
4826 len = get_attr_length (insn);
4830 if (in_use & EV4_IB0)
4832 if (in_use & EV4_IB1)
4837 in_use |= EV4_IB0 | EV4_IBX;
4841 if (in_use & EV4_IB0)
4843 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4851 if (in_use & EV4_IB1)
4861 /* Haifa doesn't do well scheduling branches. */
4862 if (GET_CODE (insn) == JUMP_INSN)
4866 insn = next_nonnote_insn (insn);
4868 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4871 /* Let Haifa tell us where it thinks insn group boundaries are. */
4872 if (GET_MODE (insn) == TImode)
4875 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4880 insn = next_nonnote_insn (insn);
4888 /* IN_USE is a mask of the slots currently filled within the insn group.
4889 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4890 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4892 LEN is, of course, the length of the group in bytes. */
4895 alphaev5_next_group (insn, pin_use, plen)
4897 int *pin_use, *plen;
4903 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4904 || GET_CODE (PATTERN (insn)) == CLOBBER
4905 || GET_CODE (PATTERN (insn)) == USE)
4910 enum alphaev5_pipe pipe;
4912 pipe = alphaev5_insn_pipe (insn);
4916 /* Force complex instructions to start new groups. */
4920 /* If this is a completely unrecognized insn, its an asm.
4921 We don't know how long it is, so record length as -1 to
4922 signal a needed realignment. */
4923 if (recog_memoized (insn) < 0)
4926 len = get_attr_length (insn);
4929 /* ??? Most of the places below, we would like to abort, as
4930 it would indicate an error either in Haifa, or in the
4931 scheduling description. Unfortunately, Haifa never
4932 schedules the last instruction of the BB, so we don't
4933 have an accurate TI bit to go off. */
4935 if (in_use & EV5_E0)
4937 if (in_use & EV5_E1)
4942 in_use |= EV5_E0 | EV5_E01;
4946 if (in_use & EV5_E0)
4948 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4956 if (in_use & EV5_E1)
4962 if (in_use & EV5_FA)
4964 if (in_use & EV5_FM)
4969 in_use |= EV5_FA | EV5_FAM;
4973 if (in_use & EV5_FA)
4979 if (in_use & EV5_FM)
4992 /* Haifa doesn't do well scheduling branches. */
4993 /* ??? If this is predicted not-taken, slotting continues, except
4994 that no more IBR, FBR, or JSR insns may be slotted. */
4995 if (GET_CODE (insn) == JUMP_INSN)
4999 insn = next_nonnote_insn (insn);
5001 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
5004 /* Let Haifa tell us where it thinks insn group boundaries are. */
5005 if (GET_MODE (insn) == TImode)
5008 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5013 insn = next_nonnote_insn (insn);
5022 alphaev4_next_nop (pin_use)
5025 int in_use = *pin_use;
5028 if (!(in_use & EV4_IB0))
5033 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
5038 else if (TARGET_FP && !(in_use & EV4_IB1))
5051 alphaev5_next_nop (pin_use)
5054 int in_use = *pin_use;
5057 if (!(in_use & EV5_E1))
5062 else if (TARGET_FP && !(in_use & EV5_FA))
5067 else if (TARGET_FP && !(in_use & EV5_FM))
5079 /* The instruction group alignment main loop. */
5082 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
5085 rtx (*next_group) PARAMS ((rtx, int*, int*));
5086 rtx (*next_nop) PARAMS ((int*));
5089 /* ALIGN is the known alignment for the insn group. */
5091 /* OFS is the offset of the current insn in the insn group. */
5093 int prev_in_use, in_use, len;
5096 /* Let shorten branches care for assigning alignments to code labels. */
5097 shorten_branches (insns);
5099 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
5100 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
5102 /* Account for the initial GP load, which happens before the scheduled
5103 prologue we emitted as RTL. */
5104 ofs = prev_in_use = 0;
5105 if (alpha_does_function_need_gp())
5107 ofs = 8 & (align - 1);
5108 prev_in_use = gp_in_use;
5112 if (GET_CODE (i) == NOTE)
5113 i = next_nonnote_insn (i);
5117 next = (*next_group)(i, &in_use, &len);
5119 /* When we see a label, resync alignment etc. */
5120 if (GET_CODE (i) == CODE_LABEL)
5122 int new_align = 1 << label_to_alignment (i);
5123 if (new_align >= align)
5125 align = new_align < max_align ? new_align : max_align;
5128 else if (ofs & (new_align-1))
5129 ofs = (ofs | (new_align-1)) + 1;
5134 /* Handle complex instructions special. */
5135 else if (in_use == 0)
5137 /* Asms will have length < 0. This is a signal that we have
5138 lost alignment knowledge. Assume, however, that the asm
5139 will not mis-align instructions. */
5148 /* If the known alignment is smaller than the recognized insn group,
5149 realign the output. */
5150 else if (align < len)
5152 int new_log_align = len > 8 ? 4 : 3;
5155 where = prev_nonnote_insn (i);
5156 if (!where || GET_CODE (where) != CODE_LABEL)
5159 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
5160 align = 1 << new_log_align;
5164 /* If the group won't fit in the same INT16 as the previous,
5165 we need to add padding to keep the group together. Rather
5166 than simply leaving the insn filling to the assembler, we
5167 can make use of the knowledge of what sorts of instructions
5168 were issued in the previous group to make sure that all of
5169 the added nops are really free. */
5170 else if (ofs + len > align)
5172 int nop_count = (align - ofs) / 4;
5175 /* Insert nops before labels and branches to truely merge the
5176 execution of the nops with the previous instruction group. */
5177 where = prev_nonnote_insn (i);
5180 if (GET_CODE (where) == CODE_LABEL)
5182 rtx where2 = prev_nonnote_insn (where);
5183 if (where2 && GET_CODE (where2) == JUMP_INSN)
5186 else if (GET_CODE (where) != JUMP_INSN)
5193 emit_insn_before ((*next_nop)(&prev_in_use), where);
5194 while (--nop_count);
5198 ofs = (ofs + len) & (align - 1);
5199 prev_in_use = in_use;
5205 /* Machine dependant reorg pass. */
5211 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
5212 alpha_handle_trap_shadows (insns);
5215 /* Due to the number of extra trapb insns, don't bother fixing up
5216 alignment when trap precision is instruction. Moreover, we can
5217 only do our job when sched2 is run and Haifa is our scheduler. */
5218 if (optimize && !optimize_size
5219 && alpha_tp != ALPHA_TP_INSN
5220 && flag_schedule_insns_after_reload)
5222 if (alpha_cpu == PROCESSOR_EV4)
5223 alpha_align_insns (insns, 8, alphaev4_next_group,
5224 alphaev4_next_nop, EV4_IB0);
5225 else if (alpha_cpu == PROCESSOR_EV5)
5226 alpha_align_insns (insns, 16, alphaev5_next_group,
5227 alphaev5_next_nop, EV5_E01 | EV5_E0);
5233 /* Check a floating-point value for validity for a particular machine mode. */
5235 static const char * const float_strings[] =
5237 /* These are for FLOAT_VAX. */
5238 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5239 "-1.70141173319264430e+38",
5240 "2.93873587705571877e-39", /* 2^-128 */
5241 "-2.93873587705571877e-39",
5242 /* These are for the default broken IEEE mode, which traps
5243 on infinity or denormal numbers. */
5244 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5245 "-3.402823466385288598117e+38",
5246 "1.1754943508222875079687e-38", /* 2^-126 */
5247 "-1.1754943508222875079687e-38",
5250 static REAL_VALUE_TYPE float_values[8];
5251 static int inited_float_values = 0;
5254 check_float_value (mode, d, overflow)
5255 enum machine_mode mode;
5257 int overflow ATTRIBUTE_UNUSED;
5260 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5263 if (inited_float_values == 0)
5266 for (i = 0; i < 8; i++)
5267 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5269 inited_float_values = 1;
5275 REAL_VALUE_TYPE *fvptr;
5277 if (TARGET_FLOAT_VAX)
5278 fvptr = &float_values[0];
5280 fvptr = &float_values[4];
5282 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5283 if (REAL_VALUES_LESS (fvptr[0], r))
5285 bcopy ((char *) &fvptr[0], (char *) d,
5286 sizeof (REAL_VALUE_TYPE));
5289 else if (REAL_VALUES_LESS (r, fvptr[1]))
5291 bcopy ((char *) &fvptr[1], (char *) d,
5292 sizeof (REAL_VALUE_TYPE));
5295 else if (REAL_VALUES_LESS (dconst0, r)
5296 && REAL_VALUES_LESS (r, fvptr[2]))
5298 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5301 else if (REAL_VALUES_LESS (r, dconst0)
5302 && REAL_VALUES_LESS (fvptr[3], r))
5304 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5314 /* Return the VMS argument type corresponding to MODE. */
5317 alpha_arg_type (mode)
5318 enum machine_mode mode;
5323 return TARGET_FLOAT_VAX ? FF : FS;
5325 return TARGET_FLOAT_VAX ? FD : FT;
5331 /* Return an rtx for an integer representing the VMS Argument Information
5335 alpha_arg_info_reg_val (cum)
5336 CUMULATIVE_ARGS cum;
5338 unsigned HOST_WIDE_INT regval = cum.num_args;
5341 for (i = 0; i < 6; i++)
5342 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5344 return GEN_INT (regval);
5347 /* Structure to collect function names for final output
5350 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5353 struct alpha_links {
5354 struct alpha_links *next;
5356 enum links_kind kind;
5359 static struct alpha_links *alpha_links_base = 0;
5361 /* Make (or fake) .linkage entry for function call.
5363 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5366 alpha_need_linkage (name, is_local)
5371 struct alpha_links *lptr, *nptr;
5376 /* Is this name already defined ? */
5378 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5379 if (strcmp (lptr->name, name) == 0)
5383 /* Defined here but external assumed. */
5384 if (lptr->kind == KIND_EXTERN)
5385 lptr->kind = KIND_LOCAL;
5389 /* Used here but unused assumed. */
5390 if (lptr->kind == KIND_UNUSED)
5391 lptr->kind = KIND_LOCAL;
5396 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5397 nptr->next = alpha_links_base;
5398 nptr->name = xstrdup (name);
5400 /* Assume external if no definition. */
5401 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5403 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5404 get_identifier (name);
5406 alpha_links_base = nptr;
5413 alpha_write_linkage (stream)
5416 struct alpha_links *lptr, *nptr;
5418 readonly_section ();
5420 fprintf (stream, "\t.align 3\n");
5422 for (lptr = alpha_links_base; lptr; lptr = nptr)
5426 if (lptr->kind == KIND_UNUSED
5427 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5430 fprintf (stream, "$%s..lk:\n", lptr->name);
5431 if (lptr->kind == KIND_LOCAL)
5433 /* Local and used, build linkage pair. */
5434 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5435 fprintf (stream, "\t.quad %s\n", lptr->name);
5438 /* External and used, request linkage pair. */
5439 fprintf (stream, "\t.linkage %s\n", lptr->name);
5446 alpha_need_linkage (name, is_local)
5447 const char *name ATTRIBUTE_UNUSED;
5448 int is_local ATTRIBUTE_UNUSED;
5452 #endif /* OPEN_VMS */