1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93-98, 1999 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"
45 extern char *version_string;
46 extern int rtx_equal_function_value_matters;
48 /* Specify which cpu to schedule for. */
50 enum processor_type alpha_cpu;
51 static const char * const alpha_cpu_name[] =
56 /* Specify how accurate floating-point traps need to be. */
58 enum alpha_trap_precision alpha_tp;
60 /* Specify the floating-point rounding mode. */
62 enum alpha_fp_rounding_mode alpha_fprm;
64 /* Specify which things cause traps. */
66 enum alpha_fp_trap_mode alpha_fptm;
68 /* Strings decoded into the above options. */
70 const char *alpha_cpu_string; /* -mcpu= */
71 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
72 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
73 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
74 const char *alpha_mlat_string; /* -mmemory-latency= */
76 /* Save information from a "cmpxx" operation until the branch or scc is
79 rtx alpha_compare_op0, alpha_compare_op1;
80 int alpha_compare_fp_p;
82 /* Define the information needed to modify the epilogue for EH. */
84 rtx alpha_eh_epilogue_sp_ofs;
86 /* Non-zero if inside of a function, because the Alpha asm can't
87 handle .files inside of functions. */
89 static int inside_function = FALSE;
91 /* If non-null, this rtx holds the return address for the function. */
93 static rtx alpha_return_addr_rtx;
95 /* The number of cycles of latency we should assume on memory reads. */
97 int alpha_memory_latency = 3;
99 /* Whether the function needs the GP. */
101 static int alpha_function_needs_gp;
103 /* The alias set for prologue/epilogue register save/restore. */
105 static int alpha_sr_alias_set;
107 /* Declarations of static functions. */
108 static void alpha_set_memflags_1
109 PROTO((rtx, int, int, int));
110 static rtx alpha_emit_set_const_1
111 PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int));
112 static void alpha_expand_unaligned_load_words
113 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
114 static void alpha_expand_unaligned_store_words
115 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
116 static void alpha_sa_mask
117 PROTO((unsigned long *imaskP, unsigned long *fmaskP));
118 static int alpha_does_function_need_gp
122 /* Get the number of args of a function in one of two ways. */
124 #define NUM_ARGS current_function_args_info.num_args
126 #define NUM_ARGS current_function_args_info
132 /* Parse target option strings. */
138 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
139 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
141 if (alpha_cpu_string)
143 if (! strcmp (alpha_cpu_string, "ev4")
144 || ! strcmp (alpha_cpu_string, "21064"))
146 alpha_cpu = PROCESSOR_EV4;
147 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
149 else if (! strcmp (alpha_cpu_string, "ev5")
150 || ! strcmp (alpha_cpu_string, "21164"))
152 alpha_cpu = PROCESSOR_EV5;
153 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
155 else if (! strcmp (alpha_cpu_string, "ev56")
156 || ! strcmp (alpha_cpu_string, "21164a"))
158 alpha_cpu = PROCESSOR_EV5;
159 target_flags |= MASK_BWX;
160 target_flags &= ~ (MASK_CIX | MASK_MAX);
162 else if (! strcmp (alpha_cpu_string, "pca56")
163 || ! strcmp (alpha_cpu_string, "21164PC")
164 || ! strcmp (alpha_cpu_string, "21164pc"))
166 alpha_cpu = PROCESSOR_EV5;
167 target_flags |= MASK_BWX | MASK_MAX;
168 target_flags &= ~ MASK_CIX;
170 else if (! strcmp (alpha_cpu_string, "ev6")
171 || ! strcmp (alpha_cpu_string, "21264"))
173 alpha_cpu = PROCESSOR_EV6;
174 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
177 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
180 alpha_tp = ALPHA_TP_PROG;
181 alpha_fprm = ALPHA_FPRM_NORM;
182 alpha_fptm = ALPHA_FPTM_N;
186 alpha_tp = ALPHA_TP_INSN;
187 alpha_fptm = ALPHA_FPTM_SU;
190 if (TARGET_IEEE_WITH_INEXACT)
192 alpha_tp = ALPHA_TP_INSN;
193 alpha_fptm = ALPHA_FPTM_SUI;
198 if (! strcmp (alpha_tp_string, "p"))
199 alpha_tp = ALPHA_TP_PROG;
200 else if (! strcmp (alpha_tp_string, "f"))
201 alpha_tp = ALPHA_TP_FUNC;
202 else if (! strcmp (alpha_tp_string, "i"))
203 alpha_tp = ALPHA_TP_INSN;
205 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
208 if (alpha_fprm_string)
210 if (! strcmp (alpha_fprm_string, "n"))
211 alpha_fprm = ALPHA_FPRM_NORM;
212 else if (! strcmp (alpha_fprm_string, "m"))
213 alpha_fprm = ALPHA_FPRM_MINF;
214 else if (! strcmp (alpha_fprm_string, "c"))
215 alpha_fprm = ALPHA_FPRM_CHOP;
216 else if (! strcmp (alpha_fprm_string,"d"))
217 alpha_fprm = ALPHA_FPRM_DYN;
219 error ("bad value `%s' for -mfp-rounding-mode switch",
223 if (alpha_fptm_string)
225 if (strcmp (alpha_fptm_string, "n") == 0)
226 alpha_fptm = ALPHA_FPTM_N;
227 else if (strcmp (alpha_fptm_string, "u") == 0)
228 alpha_fptm = ALPHA_FPTM_U;
229 else if (strcmp (alpha_fptm_string, "su") == 0)
230 alpha_fptm = ALPHA_FPTM_SU;
231 else if (strcmp (alpha_fptm_string, "sui") == 0)
232 alpha_fptm = ALPHA_FPTM_SUI;
234 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
237 /* Do some sanity checks on the above option. */
239 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
240 && alpha_tp != ALPHA_TP_INSN)
242 warning ("fp software completion requires -mtrap-precision=i");
243 alpha_tp = ALPHA_TP_INSN;
246 if (TARGET_FLOAT_VAX)
248 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
250 warning ("rounding mode not supported for VAX floats");
251 alpha_fprm = ALPHA_FPRM_NORM;
253 if (alpha_fptm == ALPHA_FPTM_SUI)
255 warning ("trap mode not supported for VAX floats");
256 alpha_fptm = ALPHA_FPTM_SU;
264 if (!alpha_mlat_string)
265 alpha_mlat_string = "L1";
267 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
268 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
270 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
271 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
272 && alpha_mlat_string[2] == '\0')
274 static int const cache_latency[][4] =
276 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
277 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
278 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
281 lat = alpha_mlat_string[1] - '0';
282 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
284 warning ("L%d cache latency unknown for %s",
285 lat, alpha_cpu_name[alpha_cpu]);
289 lat = cache_latency[alpha_cpu][lat-1];
291 else if (! strcmp (alpha_mlat_string, "main"))
293 /* Most current memories have about 370ns latency. This is
294 a reasonable guess for a fast cpu. */
299 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
303 alpha_memory_latency = lat;
306 /* Default the definition of "small data" to 8 bytes. */
310 /* Acquire a unique set number for our register saves and restores. */
311 alpha_sr_alias_set = new_alias_set ();
314 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
322 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
324 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
330 /* Returns 1 if OP is either the constant zero or a register. If a
331 register, it must be in the proper mode unless MODE is VOIDmode. */
334 reg_or_0_operand (op, mode)
336 enum machine_mode mode;
338 return op == const0_rtx || register_operand (op, mode);
341 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
345 reg_or_6bit_operand (op, mode)
347 enum machine_mode mode;
349 return ((GET_CODE (op) == CONST_INT
350 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
351 || register_operand (op, mode));
355 /* Return 1 if OP is an 8-bit constant or any register. */
358 reg_or_8bit_operand (op, mode)
360 enum machine_mode mode;
362 return ((GET_CODE (op) == CONST_INT
363 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
364 || register_operand (op, mode));
367 /* Return 1 if OP is an 8-bit constant. */
370 cint8_operand (op, mode)
372 enum machine_mode mode ATTRIBUTE_UNUSED;
374 return ((GET_CODE (op) == CONST_INT
375 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
378 /* Return 1 if the operand is a valid second operand to an add insn. */
381 add_operand (op, mode)
383 enum machine_mode mode;
385 if (GET_CODE (op) == CONST_INT)
386 /* Constraints I, J, O and P are covered by K. */
387 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
388 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
390 return register_operand (op, mode);
393 /* Return 1 if the operand is a valid second operand to a sign-extending
397 sext_add_operand (op, mode)
399 enum machine_mode mode;
401 if (GET_CODE (op) == CONST_INT)
402 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
403 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
405 return register_operand (op, mode);
408 /* Return 1 if OP is the constant 4 or 8. */
411 const48_operand (op, mode)
413 enum machine_mode mode ATTRIBUTE_UNUSED;
415 return (GET_CODE (op) == CONST_INT
416 && (INTVAL (op) == 4 || INTVAL (op) == 8));
419 /* Return 1 if OP is a valid first operand to an AND insn. */
422 and_operand (op, mode)
424 enum machine_mode mode;
426 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
427 return (zap_mask (CONST_DOUBLE_LOW (op))
428 && zap_mask (CONST_DOUBLE_HIGH (op)));
430 if (GET_CODE (op) == CONST_INT)
431 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
432 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
433 || zap_mask (INTVAL (op)));
435 return register_operand (op, mode);
438 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
441 or_operand (op, mode)
443 enum machine_mode mode;
445 if (GET_CODE (op) == CONST_INT)
446 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
447 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
449 return register_operand (op, mode);
452 /* Return 1 if OP is a constant that is the width, in bits, of an integral
453 mode smaller than DImode. */
456 mode_width_operand (op, mode)
458 enum machine_mode mode ATTRIBUTE_UNUSED;
460 return (GET_CODE (op) == CONST_INT
461 && (INTVAL (op) == 8 || INTVAL (op) == 16
462 || INTVAL (op) == 32 || INTVAL (op) == 64));
465 /* Return 1 if OP is a constant that is the width of an integral machine mode
466 smaller than an integer. */
469 mode_mask_operand (op, mode)
471 enum machine_mode mode ATTRIBUTE_UNUSED;
473 #if HOST_BITS_PER_WIDE_INT == 32
474 if (GET_CODE (op) == CONST_DOUBLE)
475 return (CONST_DOUBLE_LOW (op) == -1
476 && (CONST_DOUBLE_HIGH (op) == -1
477 || CONST_DOUBLE_HIGH (op) == 0));
479 if (GET_CODE (op) == CONST_DOUBLE)
480 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
483 return (GET_CODE (op) == CONST_INT
484 && (INTVAL (op) == 0xff
485 || INTVAL (op) == 0xffff
486 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
487 #if HOST_BITS_PER_WIDE_INT == 64
493 /* Return 1 if OP is a multiple of 8 less than 64. */
496 mul8_operand (op, mode)
498 enum machine_mode mode ATTRIBUTE_UNUSED;
500 return (GET_CODE (op) == CONST_INT
501 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
502 && (INTVAL (op) & 7) == 0);
505 /* Return 1 if OP is the constant zero in floating-point. */
508 fp0_operand (op, mode)
510 enum machine_mode mode;
512 return (GET_MODE (op) == mode
513 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
516 /* Return 1 if OP is the floating-point constant zero or a register. */
519 reg_or_fp0_operand (op, mode)
521 enum machine_mode mode;
523 return fp0_operand (op, mode) || register_operand (op, mode);
526 /* Return 1 if OP is a hard floating-point register. */
529 hard_fp_register_operand (op, mode)
531 enum machine_mode mode;
533 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
534 || (GET_CODE (op) == SUBREG
535 && hard_fp_register_operand (SUBREG_REG (op), mode)));
538 /* Return 1 if OP is a register or a constant integer. */
542 reg_or_cint_operand (op, mode)
544 enum machine_mode mode;
546 return (GET_CODE (op) == CONST_INT
547 || register_operand (op, mode));
550 /* Return 1 if OP is something that can be reloaded into a register;
551 if it is a MEM, it need not be valid. */
554 some_operand (op, mode)
556 enum machine_mode mode;
558 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
561 switch (GET_CODE (op))
563 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
564 case SYMBOL_REF: case CONST:
568 return some_operand (SUBREG_REG (op), VOIDmode);
577 /* Return 1 if OP is a valid operand for the source of a move insn. */
580 input_operand (op, mode)
582 enum machine_mode mode;
584 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
587 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
590 switch (GET_CODE (op))
595 /* This handles both the Windows/NT and OSF cases. */
596 return mode == ptr_mode || mode == DImode;
602 if (register_operand (op, mode))
604 /* ... fall through ... */
606 return ((TARGET_BWX || (mode != HImode && mode != QImode))
607 && general_operand (op, mode));
610 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
613 return mode == QImode || mode == HImode || add_operand (op, mode);
625 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
629 current_file_function_operand (op, mode)
631 enum machine_mode mode ATTRIBUTE_UNUSED;
633 return (GET_CODE (op) == SYMBOL_REF
634 && ! profile_flag && ! profile_block_flag
635 && (SYMBOL_REF_FLAG (op)
636 || op == XEXP (DECL_RTL (current_function_decl), 0)));
639 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
642 call_operand (op, mode)
644 enum machine_mode mode;
649 return (GET_CODE (op) == SYMBOL_REF
650 || (GET_CODE (op) == REG
651 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
654 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
655 comparisons are valid in which insn. */
658 alpha_comparison_operator (op, mode)
660 enum machine_mode mode;
662 enum rtx_code code = GET_CODE (op);
664 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
667 return (code == EQ || code == LE || code == LT
668 || (mode == DImode && (code == LEU || code == LTU)));
671 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
674 alpha_swapped_comparison_operator (op, mode)
676 enum machine_mode mode;
678 enum rtx_code code = GET_CODE (op);
680 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
683 code = swap_condition (code);
684 return (code == EQ || code == LE || code == LT
685 || (mode == DImode && (code == LEU || code == LTU)));
688 /* Return 1 if OP is a signed comparison operation. */
691 signed_comparison_operator (op, mode)
693 enum machine_mode mode ATTRIBUTE_UNUSED;
695 switch (GET_CODE (op))
697 case EQ: case NE: case LE: case LT: case GE: case GT:
707 /* Return 1 if this is a divide or modulus operator. */
710 divmod_operator (op, mode)
712 enum machine_mode mode ATTRIBUTE_UNUSED;
714 switch (GET_CODE (op))
716 case DIV: case MOD: case UDIV: case UMOD:
726 /* Return 1 if this memory address is a known aligned register plus
727 a constant. It must be a valid address. This means that we can do
728 this as an aligned reference plus some offset.
730 Take into account what reload will do. */
733 aligned_memory_operand (op, mode)
735 enum machine_mode mode;
739 if (reload_in_progress)
742 if (GET_CODE (tmp) == SUBREG)
743 tmp = SUBREG_REG (tmp);
744 if (GET_CODE (tmp) == REG
745 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
747 op = reg_equiv_memory_loc[REGNO (tmp)];
753 if (GET_CODE (op) != MEM
754 || GET_MODE (op) != mode)
758 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
759 sorts of constructs. Dig for the real base register. */
760 if (reload_in_progress
761 && GET_CODE (op) == PLUS
762 && GET_CODE (XEXP (op, 0)) == PLUS)
763 base = XEXP (XEXP (op, 0), 0);
766 if (! memory_address_p (mode, op))
768 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
771 return (GET_CODE (base) == REG
772 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
775 /* Similar, but return 1 if OP is a MEM which is not alignable. */
778 unaligned_memory_operand (op, mode)
780 enum machine_mode mode;
784 if (reload_in_progress)
787 if (GET_CODE (tmp) == SUBREG)
788 tmp = SUBREG_REG (tmp);
789 if (GET_CODE (tmp) == REG
790 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
792 op = reg_equiv_memory_loc[REGNO (tmp)];
798 if (GET_CODE (op) != MEM
799 || GET_MODE (op) != mode)
803 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
804 sorts of constructs. Dig for the real base register. */
805 if (reload_in_progress
806 && GET_CODE (op) == PLUS
807 && GET_CODE (XEXP (op, 0)) == PLUS)
808 base = XEXP (XEXP (op, 0), 0);
811 if (! memory_address_p (mode, op))
813 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
816 return (GET_CODE (base) == REG
817 && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
820 /* Return 1 if OP is either a register or an unaligned memory location. */
823 reg_or_unaligned_mem_operand (op, mode)
825 enum machine_mode mode;
827 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
830 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
833 any_memory_operand (op, mode)
835 enum machine_mode mode ATTRIBUTE_UNUSED;
837 return (GET_CODE (op) == MEM
838 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
839 || (reload_in_progress && GET_CODE (op) == REG
840 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
841 || (reload_in_progress && GET_CODE (op) == SUBREG
842 && GET_CODE (SUBREG_REG (op)) == REG
843 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
846 /* Returns 1 if OP is not an eliminable register.
848 This exists to cure a pathological abort in the s8addq (et al) patterns,
850 long foo () { long t; bar(); return (long) &t * 26107; }
852 which run afoul of a hack in reload to cure a (presumably) similar
853 problem with lea-type instructions on other targets. But there is
854 one of us and many of them, so work around the problem by selectively
855 preventing combine from making the optimization. */
858 reg_not_elim_operand (op, mode)
860 enum machine_mode mode;
863 if (GET_CODE (op) == SUBREG)
864 inner = SUBREG_REG (op);
865 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
868 return register_operand (op, mode);
871 /* Return 1 is OP is a memory location that is not a reference (using
872 an AND) to an unaligned location. Take into account what reload
876 normal_memory_operand (op, mode)
878 enum machine_mode mode ATTRIBUTE_UNUSED;
880 if (reload_in_progress)
883 if (GET_CODE (tmp) == SUBREG)
884 tmp = SUBREG_REG (tmp);
885 if (GET_CODE (tmp) == REG
886 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
888 op = reg_equiv_memory_loc[REGNO (tmp)];
890 /* This may not have been assigned an equivalent address if it will
891 be eliminated. In that case, it doesn't matter what we do. */
897 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
900 /* Accept a register, but not a subreg of any kind. This allows us to
901 avoid pathological cases in reload wrt data movement common in
902 int->fp conversion. */
905 reg_no_subreg_operand (op, mode)
907 enum machine_mode mode;
909 if (GET_CODE (op) == SUBREG)
911 return register_operand (op, mode);
914 /* Return 1 if this function can directly return via $26. */
919 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
920 && get_frame_size () == 0
921 && current_function_outgoing_args_size == 0
922 && current_function_pretend_args_size == 0);
925 /* REF is an alignable memory location. Place an aligned SImode
926 reference into *PALIGNED_MEM and the number of bits to shift into
927 *PBITNUM. SCRATCH is a free register for use in reloading out
928 of range stack slots. */
931 get_aligned_mem (ref, paligned_mem, pbitnum)
933 rtx *paligned_mem, *pbitnum;
936 HOST_WIDE_INT offset = 0;
938 if (GET_CODE (ref) != MEM)
941 if (reload_in_progress
942 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
944 base = find_replacement (&XEXP (ref, 0));
946 if (! memory_address_p (GET_MODE (ref), base))
951 base = XEXP (ref, 0);
954 if (GET_CODE (base) == PLUS)
955 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
957 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
958 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
959 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
961 /* Sadly, we cannot use alias sets here because we may overlap other
962 data in a different alias set. */
963 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
965 *pbitnum = GEN_INT ((offset & 3) * 8);
968 /* Similar, but just get the address. Handle the two reload cases.
969 Add EXTRA_OFFSET to the address we return. */
972 get_unaligned_address (ref, extra_offset)
977 HOST_WIDE_INT offset = 0;
979 if (GET_CODE (ref) != MEM)
982 if (reload_in_progress
983 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
985 base = find_replacement (&XEXP (ref, 0));
987 if (! memory_address_p (GET_MODE (ref), base))
992 base = XEXP (ref, 0);
995 if (GET_CODE (base) == PLUS)
996 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
998 return plus_constant (base, offset + extra_offset);
1001 /* Subfunction of the following function. Update the flags of any MEM
1002 found in part of X. */
1005 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1007 int in_struct_p, volatile_p, unchanging_p;
1011 switch (GET_CODE (x))
1015 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1016 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1021 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1026 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1028 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1033 MEM_IN_STRUCT_P (x) = in_struct_p;
1034 MEM_VOLATILE_P (x) = volatile_p;
1035 RTX_UNCHANGING_P (x) = unchanging_p;
1036 /* Sadly, we cannot use alias sets because the extra aliasing
1037 produced by the AND interferes. Given that two-byte quantities
1038 are the only thing we would be able to differentiate anyway,
1039 there does not seem to be any point in convoluting the early
1040 out of the alias check. */
1041 /* MEM_ALIAS_SET (x) = alias_set; */
1049 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1050 perform a memory operation, look for any MEMs in either a SET_DEST or
1051 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1052 REF into each of the MEMs found. If REF is not a MEM, don't do
1056 alpha_set_memflags (insn, ref)
1060 int in_struct_p, volatile_p, unchanging_p;
1062 if (GET_CODE (ref) != MEM)
1065 in_struct_p = MEM_IN_STRUCT_P (ref);
1066 volatile_p = MEM_VOLATILE_P (ref);
1067 unchanging_p = RTX_UNCHANGING_P (ref);
1069 /* This is only called from alpha.md, after having had something
1070 generated from one of the insn patterns. So if everything is
1071 zero, the pattern is already up-to-date. */
1072 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1075 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1078 /* Try to output insns to set TARGET equal to the constant C if it can be
1079 done in less than N insns. Do all computations in MODE. Returns the place
1080 where the output has been placed if it can be done and the insns have been
1081 emitted. If it would take more than N insns, zero is returned and no
1082 insns and emitted. */
1085 alpha_emit_set_const (target, mode, c, n)
1087 enum machine_mode mode;
1094 /* Try 1 insn, then 2, then up to N. */
1095 for (i = 1; i <= n; i++)
1096 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1102 /* Internal routine for the above to check for N or below insns. */
1105 alpha_emit_set_const_1 (target, mode, c, n)
1107 enum machine_mode mode;
1111 HOST_WIDE_INT new = c;
1113 /* Use a pseudo if highly optimizing and still generating RTL. */
1115 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1119 #if HOST_BITS_PER_WIDE_INT == 64
1120 /* We are only called for SImode and DImode. If this is SImode, ensure that
1121 we are sign extended to a full word. This does not make any sense when
1122 cross-compiling on a narrow machine. */
1125 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1128 /* If this is a sign-extended 32-bit constant, we can do this in at most
1129 three insns, so do it if we have enough insns left. We always have
1130 a sign-extended 32-bit constant when compiling on a narrow machine. */
1132 if (HOST_BITS_PER_WIDE_INT != 64
1133 || c >> 31 == -1 || c >> 31 == 0)
1135 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1136 HOST_WIDE_INT tmp1 = c - low;
1138 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1139 HOST_WIDE_INT extra = 0;
1141 /* If HIGH will be interpreted as negative but the constant is
1142 positive, we must adjust it to do two ldha insns. */
1144 if ((high & 0x8000) != 0 && c >= 0)
1148 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1151 if (c == low || (low == 0 && extra == 0))
1153 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1154 but that meant that we can't handle INT_MIN on 32-bit machines
1155 (like NT/Alpha), because we recurse indefinitely through
1156 emit_move_insn to gen_movdi. So instead, since we know exactly
1157 what we want, create it explicitly. */
1160 target = gen_reg_rtx (mode);
1161 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1164 else if (n >= 2 + (extra != 0))
1166 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1169 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1170 subtarget, 0, OPTAB_WIDEN);
1172 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1173 target, 0, OPTAB_WIDEN);
1177 /* If we couldn't do it that way, try some other methods. But if we have
1178 no instructions left, don't bother. Likewise, if this is SImode and
1179 we can't make pseudos, we can't do anything since the expand_binop
1180 and expand_unop calls will widen and try to make pseudos. */
1183 || (mode == SImode && ! rtx_equal_function_value_matters))
1186 #if HOST_BITS_PER_WIDE_INT == 64
1187 /* First, see if can load a value into the target that is the same as the
1188 constant except that all bytes that are 0 are changed to be 0xff. If we
1189 can, then we can do a ZAPNOT to obtain the desired constant. */
1191 for (i = 0; i < 64; i += 8)
1192 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1193 new |= (HOST_WIDE_INT) 0xff << i;
1195 /* We are only called for SImode and DImode. If this is SImode, ensure that
1196 we are sign extended to a full word. */
1199 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1202 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1203 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1204 target, 0, OPTAB_WIDEN);
1207 /* Next, see if we can load a related constant and then shift and possibly
1208 negate it to get the constant we want. Try this once each increasing
1209 numbers of insns. */
1211 for (i = 1; i < n; i++)
1213 /* First try complementing. */
1214 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1215 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1217 /* Next try to form a constant and do a left shift. We can do this
1218 if some low-order bits are zero; the exact_log2 call below tells
1219 us that information. The bits we are shifting out could be any
1220 value, but here we'll just try the 0- and sign-extended forms of
1221 the constant. To try to increase the chance of having the same
1222 constant in more than one insn, start at the highest number of
1223 bits to shift, but try all possibilities in case a ZAPNOT will
1226 if ((bits = exact_log2 (c & - c)) > 0)
1227 for (; bits > 0; bits--)
1228 if ((temp = (alpha_emit_set_const
1230 (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1231 || ((temp = (alpha_emit_set_const
1233 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1235 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1236 target, 0, OPTAB_WIDEN);
1238 /* Now try high-order zero bits. Here we try the shifted-in bits as
1239 all zero and all ones. Be careful to avoid shifting outside the
1240 mode and to avoid shifting outside the host wide int size. */
1241 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1242 confuse the recursive call and set all of the high 32 bits. */
1244 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1245 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1246 for (; bits > 0; bits--)
1247 if ((temp = alpha_emit_set_const (subtarget, mode,
1249 || ((temp = (alpha_emit_set_const
1251 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1254 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1255 target, 1, OPTAB_WIDEN);
1257 /* Now try high-order 1 bits. We get that with a sign-extension.
1258 But one bit isn't enough here. Be careful to avoid shifting outside
1259 the mode and to avoid shifting outside the host wide int size. */
1261 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1262 - floor_log2 (~ c) - 2)) > 0)
1263 for (; bits > 0; bits--)
1264 if ((temp = alpha_emit_set_const (subtarget, mode,
1266 || ((temp = (alpha_emit_set_const
1268 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1271 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1272 target, 0, OPTAB_WIDEN);
1278 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1279 fall back to a straight forward decomposition. We do this to avoid
1280 exponential run times encountered when looking for longer sequences
1281 with alpha_emit_set_const. */
1284 alpha_emit_set_long_const (target, c1, c2)
1286 HOST_WIDE_INT c1, c2;
1288 HOST_WIDE_INT d1, d2, d3, d4;
1290 /* Decompose the entire word */
1291 #if HOST_BITS_PER_WIDE_INT >= 64
1292 if (c2 != -(c1 < 0))
1294 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1296 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1297 c1 = (c1 - d2) >> 32;
1298 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1300 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1304 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1306 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1310 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1312 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1317 /* Construct the high word */
1320 emit_move_insn (target, GEN_INT (d4));
1322 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1325 emit_move_insn (target, GEN_INT (d3));
1327 /* Shift it into place */
1328 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1330 /* Add in the low bits. */
1332 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1334 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1339 /* Generate the comparison for a conditional branch. */
1342 alpha_emit_conditional_branch (code)
1345 enum rtx_code cmp_code, branch_code;
1346 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1347 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1350 /* The general case: fold the comparison code to the types of compares
1351 that we have, choosing the branch as necessary. */
1354 case EQ: case LE: case LT: case LEU: case LTU:
1355 /* We have these compares: */
1356 cmp_code = code, branch_code = NE;
1360 /* This must be reversed. */
1361 cmp_code = EQ, branch_code = EQ;
1364 case GE: case GT: case GEU: case GTU:
1365 /* For FP, we swap them, for INT, we reverse them. */
1366 if (alpha_compare_fp_p)
1368 cmp_code = swap_condition (code);
1370 tem = op0, op0 = op1, op1 = tem;
1374 cmp_code = reverse_condition (code);
1383 if (alpha_compare_fp_p)
1388 /* When we are not as concerned about non-finite values, and we
1389 are comparing against zero, we can branch directly. */
1390 if (op1 == CONST0_RTX (DFmode))
1391 cmp_code = NIL, branch_code = code;
1392 else if (op0 == CONST0_RTX (DFmode))
1394 /* Undo the swap we probably did just above. */
1395 tem = op0, op0 = op1, op1 = tem;
1396 branch_code = swap_condition (cmp_code);
1402 /* ??? We mark the the branch mode to be CCmode to prevent the
1403 compare and branch from being combined, since the compare
1404 insn follows IEEE rules that the branch does not. */
1405 branch_mode = CCmode;
1412 /* The following optimizations are only for signed compares. */
1413 if (code != LEU && code != LTU && code != GEU && code != GTU)
1415 /* Whee. Compare and branch against 0 directly. */
1416 if (op1 == const0_rtx)
1417 cmp_code = NIL, branch_code = code;
1419 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1420 bypass between logicals and br/cmov on EV5. But we don't want to
1421 force valid immediate constants into registers needlessly. */
1422 else if (GET_CODE (op1) == CONST_INT)
1424 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1426 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1427 && (CONST_OK_FOR_LETTER_P (n, 'K')
1428 || CONST_OK_FOR_LETTER_P (n, 'L')))
1430 cmp_code = PLUS, branch_code = code;
1437 /* Force op0 into a register. */
1438 if (GET_CODE (op0) != REG)
1439 op0 = force_reg (cmp_mode, op0);
1441 /* Emit an initial compare instruction, if necessary. */
1443 if (cmp_code != NIL)
1445 tem = gen_reg_rtx (cmp_mode);
1446 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1449 /* Return the branch comparison. */
1450 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1454 /* Rewrite a comparison against zero CMP of the form
1455 (CODE (cc0) (const_int 0)) so it can be written validly in
1456 a conditional move (if_then_else CMP ...).
1457 If both of the operands that set cc0 are non-zero we must emit
1458 an insn to perform the compare (it can't be done within
1459 the conditional move). */
1461 alpha_emit_conditional_move (cmp, mode)
1463 enum machine_mode mode;
1465 enum rtx_code code = GET_CODE (cmp);
1466 enum rtx_code cmov_code = NE;
1467 rtx op0 = alpha_compare_op0;
1468 rtx op1 = alpha_compare_op1;
1469 enum machine_mode cmp_mode
1470 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1471 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1472 enum machine_mode cmov_mode = VOIDmode;
1475 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1478 /* We may be able to use a conditional move directly.
1479 This avoids emitting spurious compares. */
1480 if (signed_comparison_operator (cmp, cmp_op_mode)
1481 && (!alpha_compare_fp_p || flag_fast_math)
1482 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1483 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1485 /* We can't put the comparison insides a conditional move;
1486 emit a compare instruction and put that inside the
1487 conditional move. Make sure we emit only comparisons we have;
1488 swap or reverse as necessary. */
1492 case EQ: case LE: case LT: case LEU: case LTU:
1493 /* We have these compares: */
1497 /* This must be reversed. */
1498 code = reverse_condition (code);
1502 case GE: case GT: case GEU: case GTU:
1503 /* These must be swapped. Make sure the new first operand is in
1505 code = swap_condition (code);
1506 tem = op0, op0 = op1, op1 = tem;
1507 op0 = force_reg (cmp_mode, op0);
1514 /* ??? We mark the branch mode to be CCmode to prevent the compare
1515 and cmov from being combined, since the compare insn follows IEEE
1516 rules that the cmov does not. */
1517 if (alpha_compare_fp_p && !flag_fast_math)
1520 tem = gen_reg_rtx (cmp_op_mode);
1521 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1522 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1525 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1529 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1530 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1531 lda r3,X(r11) lda r3,X+2(r11)
1532 extwl r1,r3,r1 extql r1,r3,r1
1533 extwh r2,r3,r2 extqh r2,r3,r2
1534 or r1.r2.r1 or r1,r2,r1
1537 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1538 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1539 lda r3,X(r11) lda r3,X(r11)
1540 extll r1,r3,r1 extll r1,r3,r1
1541 extlh r2,r3,r2 extlh r2,r3,r2
1542 or r1.r2.r1 addl r1,r2,r1
1544 quad: ldq_u r1,X(r11)
1553 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1555 HOST_WIDE_INT size, ofs;
1558 rtx meml, memh, addr, extl, exth;
1559 enum machine_mode mode;
1561 meml = gen_reg_rtx (DImode);
1562 memh = gen_reg_rtx (DImode);
1563 addr = gen_reg_rtx (DImode);
1564 extl = gen_reg_rtx (DImode);
1565 exth = gen_reg_rtx (DImode);
1567 emit_move_insn (meml,
1568 change_address (mem, DImode,
1569 gen_rtx_AND (DImode,
1570 plus_constant (XEXP (mem, 0),
1574 emit_move_insn (memh,
1575 change_address (mem, DImode,
1576 gen_rtx_AND (DImode,
1577 plus_constant (XEXP (mem, 0),
1581 if (sign && size == 2)
1583 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1585 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1586 emit_insn (gen_extqh (exth, memh, addr));
1588 /* We must use tgt here for the target. Alpha-vms port fails if we use
1589 addr for the target, because addr is marked as a pointer and combine
1590 knows that pointers are always sign-extended 32 bit values. */
1591 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1592 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1593 addr, 1, OPTAB_WIDEN);
1597 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1598 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1602 emit_insn (gen_extwh (exth, memh, addr));
1607 emit_insn (gen_extlh (exth, memh, addr));
1612 emit_insn (gen_extqh (exth, memh, addr));
1619 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1620 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1625 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1628 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1631 alpha_expand_unaligned_store (dst, src, size, ofs)
1633 HOST_WIDE_INT size, ofs;
1635 rtx dstl, dsth, addr, insl, insh, meml, memh;
1637 dstl = gen_reg_rtx (DImode);
1638 dsth = gen_reg_rtx (DImode);
1639 insl = gen_reg_rtx (DImode);
1640 insh = gen_reg_rtx (DImode);
1642 meml = change_address (dst, DImode,
1643 gen_rtx_AND (DImode,
1644 plus_constant (XEXP (dst, 0), ofs),
1646 memh = change_address (dst, DImode,
1647 gen_rtx_AND (DImode,
1648 plus_constant (XEXP (dst, 0),
1652 emit_move_insn (dsth, memh);
1653 emit_move_insn (dstl, meml);
1654 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1656 if (src != const0_rtx)
1658 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1659 GEN_INT (size*8), addr));
1664 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1667 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1670 emit_insn (gen_insql (insl, src, addr));
1675 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1680 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1683 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1687 #if HOST_BITS_PER_WIDE_INT == 32
1688 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1690 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1692 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1697 if (src != const0_rtx)
1699 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1700 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1703 /* Must store high before low for degenerate case of aligned. */
1704 emit_move_insn (memh, dsth);
1705 emit_move_insn (meml, dstl);
1708 /* The block move code tries to maximize speed by separating loads and
1709 stores at the expense of register pressure: we load all of the data
1710 before we store it back out. There are two secondary effects worth
1711 mentioning, that this speeds copying to/from aligned and unaligned
1712 buffers, and that it makes the code significantly easier to write. */
1714 #define MAX_MOVE_WORDS 8
1716 /* Load an integral number of consecutive unaligned quadwords. */
1719 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1722 HOST_WIDE_INT words, ofs;
1724 rtx const im8 = GEN_INT (-8);
1725 rtx const i64 = GEN_INT (64);
1726 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1730 /* Generate all the tmp registers we need. */
1731 for (i = 0; i < words; ++i)
1733 data_regs[i] = out_regs[i];
1734 ext_tmps[i] = gen_reg_rtx (DImode);
1736 data_regs[words] = gen_reg_rtx (DImode);
1739 smem = change_address (smem, GET_MODE (smem),
1740 plus_constant (XEXP (smem, 0), ofs));
1742 /* Load up all of the source data. */
1743 for (i = 0; i < words; ++i)
1745 emit_move_insn (data_regs[i],
1746 change_address (smem, DImode,
1747 gen_rtx_AND (DImode,
1748 plus_constant (XEXP(smem,0),
1752 emit_move_insn (data_regs[words],
1753 change_address (smem, DImode,
1754 gen_rtx_AND (DImode,
1755 plus_constant (XEXP(smem,0),
1759 /* Extract the half-word fragments. Unfortunately DEC decided to make
1760 extxh with offset zero a noop instead of zeroing the register, so
1761 we must take care of that edge condition ourselves with cmov. */
1763 sreg = copy_addr_to_reg (XEXP (smem, 0));
1764 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1766 for (i = 0; i < words; ++i)
1768 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1770 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1771 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1772 gen_rtx_IF_THEN_ELSE (DImode,
1773 gen_rtx_EQ (DImode, areg,
1775 const0_rtx, ext_tmps[i])));
1778 /* Merge the half-words into whole words. */
1779 for (i = 0; i < words; ++i)
1781 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1782 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1786 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1787 may be NULL to store zeros. */
1790 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1793 HOST_WIDE_INT words, ofs;
1795 rtx const im8 = GEN_INT (-8);
1796 rtx const i64 = GEN_INT (64);
1797 #if HOST_BITS_PER_WIDE_INT == 32
1798 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1800 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1802 rtx ins_tmps[MAX_MOVE_WORDS];
1803 rtx st_tmp_1, st_tmp_2, dreg;
1804 rtx st_addr_1, st_addr_2;
1807 /* Generate all the tmp registers we need. */
1808 if (data_regs != NULL)
1809 for (i = 0; i < words; ++i)
1810 ins_tmps[i] = gen_reg_rtx(DImode);
1811 st_tmp_1 = gen_reg_rtx(DImode);
1812 st_tmp_2 = gen_reg_rtx(DImode);
1815 dmem = change_address (dmem, GET_MODE (dmem),
1816 plus_constant (XEXP (dmem, 0), ofs));
1819 st_addr_2 = change_address (dmem, DImode,
1820 gen_rtx_AND (DImode,
1821 plus_constant (XEXP(dmem,0),
1824 st_addr_1 = change_address (dmem, DImode,
1825 gen_rtx_AND (DImode,
1829 /* Load up the destination end bits. */
1830 emit_move_insn (st_tmp_2, st_addr_2);
1831 emit_move_insn (st_tmp_1, st_addr_1);
1833 /* Shift the input data into place. */
1834 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1835 if (data_regs != NULL)
1837 for (i = words-1; i >= 0; --i)
1839 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1840 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1842 for (i = words-1; i > 0; --i)
1844 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1845 ins_tmps[i-1], ins_tmps[i-1], 1,
1850 /* Split and merge the ends with the destination data. */
1851 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1852 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1854 if (data_regs != NULL)
1856 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1857 st_tmp_2, 1, OPTAB_WIDEN);
1858 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1859 st_tmp_1, 1, OPTAB_WIDEN);
1863 emit_move_insn (st_addr_2, st_tmp_2);
1864 for (i = words-1; i > 0; --i)
1866 emit_move_insn (change_address (dmem, DImode,
1867 gen_rtx_AND (DImode,
1868 plus_constant(XEXP (dmem,0),
1871 data_regs ? ins_tmps[i-1] : const0_rtx);
1873 emit_move_insn (st_addr_1, st_tmp_1);
1877 /* Expand string/block move operations.
1879 operands[0] is the pointer to the destination.
1880 operands[1] is the pointer to the source.
1881 operands[2] is the number of bytes to move.
1882 operands[3] is the alignment. */
1885 alpha_expand_block_move (operands)
1888 rtx bytes_rtx = operands[2];
1889 rtx align_rtx = operands[3];
1890 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
1891 HOST_WIDE_INT bytes = orig_bytes;
1892 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1893 HOST_WIDE_INT dst_align = src_align;
1894 rtx orig_src = operands[1];
1895 rtx orig_dst = operands[0];
1896 rtx data_regs[2*MAX_MOVE_WORDS+16];
1898 int i, words, ofs, nregs = 0;
1902 if (bytes > MAX_MOVE_WORDS*8)
1905 /* Look for additional alignment information from recorded register info. */
1907 tmp = XEXP (orig_src, 0);
1908 if (GET_CODE (tmp) == REG)
1910 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1911 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1913 else if (GET_CODE (tmp) == PLUS
1914 && GET_CODE (XEXP (tmp, 0)) == REG
1915 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1917 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1918 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1922 if (a >= 8 && c % 8 == 0)
1924 else if (a >= 4 && c % 4 == 0)
1926 else if (a >= 2 && c % 2 == 0)
1931 tmp = XEXP (orig_dst, 0);
1932 if (GET_CODE (tmp) == REG)
1934 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1935 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1937 else if (GET_CODE (tmp) == PLUS
1938 && GET_CODE (XEXP (tmp, 0)) == REG
1939 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1941 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1942 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1946 if (a >= 8 && c % 8 == 0)
1948 else if (a >= 4 && c % 4 == 0)
1950 else if (a >= 2 && c % 2 == 0)
1956 * Load the entire block into registers.
1959 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1961 enum machine_mode mode;
1962 tmp = XEXP (XEXP (orig_src, 0), 0);
1964 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
1966 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1968 /* Whee! Optimize the load to use the existing register. */
1969 data_regs[nregs++] = gen_lowpart (mode, tmp);
1973 /* ??? We could potentially be copying 3 bytes or whatnot from
1974 a wider reg. Probably not worth worrying about. */
1975 /* No appropriate mode; fall back on memory. */
1976 orig_src = change_address (orig_src, GET_MODE (orig_src),
1977 copy_addr_to_reg (XEXP (orig_src, 0)));
1981 if (src_align >= 8 && bytes >= 8)
1985 for (i = 0; i < words; ++i)
1986 data_regs[nregs+i] = gen_reg_rtx(DImode);
1988 for (i = 0; i < words; ++i)
1990 emit_move_insn (data_regs[nregs+i],
1991 change_address(orig_src, DImode,
1992 plus_constant (XEXP (orig_src, 0),
2000 if (src_align >= 4 && bytes >= 4)
2004 for (i = 0; i < words; ++i)
2005 data_regs[nregs+i] = gen_reg_rtx(SImode);
2007 for (i = 0; i < words; ++i)
2009 emit_move_insn (data_regs[nregs+i],
2010 change_address(orig_src, SImode,
2011 plus_constant (XEXP (orig_src, 0),
2023 for (i = 0; i < words+1; ++i)
2024 data_regs[nregs+i] = gen_reg_rtx(DImode);
2026 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
2032 if (!TARGET_BWX && bytes >= 8)
2034 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2035 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2039 if (!TARGET_BWX && bytes >= 4)
2041 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2042 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2051 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2052 emit_move_insn (tmp,
2053 change_address (orig_src, HImode,
2054 plus_constant (XEXP (orig_src, 0),
2058 } while (bytes >= 2);
2060 else if (!TARGET_BWX)
2062 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2063 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2070 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2071 emit_move_insn (tmp,
2072 change_address (orig_src, QImode,
2073 plus_constant (XEXP (orig_src, 0),
2080 if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2084 * Now save it back out again.
2089 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2091 enum machine_mode mode;
2092 tmp = XEXP (XEXP (orig_dst, 0), 0);
2094 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2095 if (GET_MODE (tmp) == mode && nregs == 1)
2097 emit_move_insn (tmp, data_regs[0]);
2102 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2103 /* ??? Optimize mode < dst_mode with strict_low_part. */
2105 /* No appropriate mode; fall back on memory. We can speed things
2106 up by recognizing extra alignment information. */
2107 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2108 copy_addr_to_reg (XEXP (orig_dst, 0)));
2109 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2112 /* Write out the data in whatever chunks reading the source allowed. */
2115 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2117 emit_move_insn (change_address(orig_dst, DImode,
2118 plus_constant (XEXP (orig_dst, 0),
2127 /* If the source has remaining DImode regs, write them out in
2129 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2131 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2132 NULL_RTX, 1, OPTAB_WIDEN);
2134 emit_move_insn (change_address(orig_dst, SImode,
2135 plus_constant (XEXP (orig_dst, 0),
2137 gen_lowpart (SImode, data_regs[i]));
2138 emit_move_insn (change_address(orig_dst, SImode,
2139 plus_constant (XEXP (orig_dst, 0),
2141 gen_lowpart (SImode, tmp));
2146 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2148 emit_move_insn (change_address(orig_dst, SImode,
2149 plus_constant (XEXP (orig_dst, 0),
2156 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2158 /* Write out a remaining block of words using unaligned methods. */
2160 for (words = 1; i+words < nregs ; ++words)
2161 if (GET_MODE (data_regs[i+words]) != DImode)
2165 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2167 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2173 /* Due to the above, this won't be aligned. */
2174 /* ??? If we have more than one of these, consider constructing full
2175 words in registers and using alpha_expand_unaligned_store_words. */
2176 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2178 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2184 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2186 emit_move_insn (change_address (orig_dst, HImode,
2187 plus_constant (XEXP (orig_dst, 0),
2194 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2196 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2200 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2202 emit_move_insn (change_address (orig_dst, QImode,
2203 plus_constant (XEXP (orig_dst, 0),
2218 alpha_expand_block_clear (operands)
2221 rtx bytes_rtx = operands[1];
2222 rtx align_rtx = operands[2];
2223 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2224 HOST_WIDE_INT align = INTVAL (align_rtx);
2225 rtx orig_dst = operands[0];
2227 HOST_WIDE_INT i, words, ofs = 0;
2231 if (bytes > MAX_MOVE_WORDS*8)
2234 /* Look for stricter alignment. */
2236 tmp = XEXP (orig_dst, 0);
2237 if (GET_CODE (tmp) == REG)
2239 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2240 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2242 else if (GET_CODE (tmp) == PLUS
2243 && GET_CODE (XEXP (tmp, 0)) == REG
2244 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2246 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2247 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2251 if (a >= 8 && c % 8 == 0)
2253 else if (a >= 4 && c % 4 == 0)
2255 else if (a >= 2 && c % 2 == 0)
2260 /* Handle a block of contiguous words first. */
2262 if (align >= 8 && bytes >= 8)
2266 for (i = 0; i < words; ++i)
2268 emit_move_insn (change_address(orig_dst, DImode,
2269 plus_constant (XEXP (orig_dst, 0),
2277 if (align >= 4 && bytes >= 4)
2281 for (i = 0; i < words; ++i)
2283 emit_move_insn (change_address(orig_dst, SImode,
2284 plus_constant (XEXP (orig_dst, 0),
2296 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2302 /* Next clean up any trailing pieces. We know from the contiguous
2303 block move that there are no aligned SImode or DImode hunks left. */
2305 if (!TARGET_BWX && bytes >= 8)
2307 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2311 if (!TARGET_BWX && bytes >= 4)
2313 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2322 emit_move_insn (change_address (orig_dst, HImode,
2323 plus_constant (XEXP (orig_dst, 0),
2328 } while (bytes >= 2);
2330 else if (!TARGET_BWX)
2332 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2339 emit_move_insn (change_address (orig_dst, QImode,
2340 plus_constant (XEXP (orig_dst, 0),
2351 /* Adjust the cost of a scheduling dependency. Return the new cost of
2352 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2355 alpha_adjust_cost (insn, link, dep_insn, cost)
2362 enum attr_type insn_type, dep_insn_type;
2364 /* If the dependence is an anti-dependence, there is no cost. For an
2365 output dependence, there is sometimes a cost, but it doesn't seem
2366 worth handling those few cases. */
2368 if (REG_NOTE_KIND (link) != 0)
2371 /* If we can't recognize the insns, we can't really do anything. */
2372 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2375 insn_type = get_attr_type (insn);
2376 dep_insn_type = get_attr_type (dep_insn);
2378 /* Bring in the user-defined memory latency. */
2379 if (dep_insn_type == TYPE_ILD
2380 || dep_insn_type == TYPE_FLD
2381 || dep_insn_type == TYPE_LDSYM)
2382 cost += alpha_memory_latency-1;
2387 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2388 being stored, we can sometimes lower the cost. */
2390 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2391 && (set = single_set (dep_insn)) != 0
2392 && GET_CODE (PATTERN (insn)) == SET
2393 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2395 switch (dep_insn_type)
2399 /* No savings here. */
2403 /* In these cases, we save one cycle. */
2407 /* In all other cases, we save two cycles. */
2408 return MAX (0, cost - 2);
2412 /* Another case that needs adjustment is an arithmetic or logical
2413 operation. It's cost is usually one cycle, but we default it to
2414 two in the MD file. The only case that it is actually two is
2415 for the address in loads, stores, and jumps. */
2417 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2432 /* The final case is when a compare feeds into an integer branch;
2433 the cost is only one cycle in that case. */
2435 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2440 /* And the lord DEC saith: "A special bypass provides an effective
2441 latency of 0 cycles for an ICMP or ILOG insn producing the test
2442 operand of an IBR or ICMOV insn." */
2444 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2445 && (set = single_set (dep_insn)) != 0)
2447 /* A branch only has one input. This must be it. */
2448 if (insn_type == TYPE_IBR)
2450 /* A conditional move has three, make sure it is the test. */
2451 if (insn_type == TYPE_ICMOV
2452 && GET_CODE (set_src = PATTERN (insn)) == SET
2453 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2454 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2458 /* "The multiplier is unable to receive data from IEU bypass paths.
2459 The instruction issues at the expected time, but its latency is
2460 increased by the time it takes for the input data to become
2461 available to the multiplier" -- which happens in pipeline stage
2462 six, when results are comitted to the register file. */
2464 if (insn_type == TYPE_IMUL)
2466 switch (dep_insn_type)
2468 /* These insns produce their results in pipeline stage five. */
2475 /* Other integer insns produce results in pipeline stage four. */
2483 /* There is additional latency to move the result of (most) FP
2484 operations anywhere but the FP register file. */
2486 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2487 && (dep_insn_type == TYPE_FADD ||
2488 dep_insn_type == TYPE_FMUL ||
2489 dep_insn_type == TYPE_FCMOV))
2495 /* Otherwise, return the default cost. */
2499 /* Functions to save and restore alpha_return_addr_rtx. */
2501 struct machine_function
2507 alpha_save_machine_status (p)
2510 struct machine_function *machine =
2511 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2513 p->machine = machine;
2514 machine->ra_rtx = alpha_return_addr_rtx;
2518 alpha_restore_machine_status (p)
2521 struct machine_function *machine = p->machine;
2523 alpha_return_addr_rtx = machine->ra_rtx;
2526 p->machine = (struct machine_function *)0;
2529 /* Do anything needed before RTL is emitted for each function. */
2532 alpha_init_expanders ()
2534 alpha_return_addr_rtx = NULL_RTX;
2535 alpha_eh_epilogue_sp_ofs = NULL_RTX;
2537 /* Arrange to save and restore machine status around nested functions. */
2538 save_machine_status = alpha_save_machine_status;
2539 restore_machine_status = alpha_restore_machine_status;
2542 /* Start the ball rolling with RETURN_ADDR_RTX. */
2545 alpha_return_addr (count, frame)
2547 rtx frame ATTRIBUTE_UNUSED;
2554 if (alpha_return_addr_rtx)
2555 return alpha_return_addr_rtx;
2557 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2558 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2559 init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
2560 gen_rtx_REG (Pmode, REG_RA));
2562 /* Emit the insn to the prologue with the other argument copies. */
2563 push_topmost_sequence ();
2564 emit_insn_after (init, get_insns ());
2565 pop_topmost_sequence ();
2567 return alpha_return_addr_rtx;
2571 alpha_ra_ever_killed ()
2575 #ifdef ASM_OUTPUT_MI_THUNK
2576 if (current_function_is_thunk)
2579 if (!alpha_return_addr_rtx)
2580 return regs_ever_live[REG_RA];
2582 push_topmost_sequence ();
2584 pop_topmost_sequence ();
2586 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2590 /* Print an operand. Recognize special options, documented below. */
2593 print_operand (file, x, code)
2603 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2604 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2605 mode. alpha_fprm controls which suffix is generated. */
2608 case ALPHA_FPRM_NORM:
2610 case ALPHA_FPRM_MINF:
2613 case ALPHA_FPRM_CHOP:
2616 case ALPHA_FPRM_DYN:
2623 /* Generates trap-mode suffix for instructions that accept the su
2624 suffix only (cmpt et al). */
2625 if (alpha_tp == ALPHA_TP_INSN)
2630 /* Generates trap-mode suffix for instructions that accept the
2631 v and sv suffix. The only instruction that needs this is cvtql. */
2640 case ALPHA_FPTM_SUI:
2647 /* Generates trap-mode suffix for instructions that accept the
2648 v, sv, and svi suffix. The only instruction that needs this
2660 case ALPHA_FPTM_SUI:
2661 fputs ("svi", file);
2667 /* Generates trap-mode suffix for instructions that accept the u, su,
2668 and sui suffix. This is the bulk of the IEEE floating point
2669 instructions (addt et al). */
2680 case ALPHA_FPTM_SUI:
2681 fputs ("sui", file);
2687 /* Generates trap-mode suffix for instructions that accept the sui
2688 suffix (cvtqt and cvtqs). */
2693 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2695 case ALPHA_FPTM_SUI:
2696 fputs ("sui", file);
2702 /* Generates single precision instruction suffix. */
2703 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2707 /* Generates double precision instruction suffix. */
2708 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2712 /* If this operand is the constant zero, write it as "$31". */
2713 if (GET_CODE (x) == REG)
2714 fprintf (file, "%s", reg_names[REGNO (x)]);
2715 else if (x == CONST0_RTX (GET_MODE (x)))
2716 fprintf (file, "$31");
2718 output_operand_lossage ("invalid %%r value");
2723 /* Similar, but for floating-point. */
2724 if (GET_CODE (x) == REG)
2725 fprintf (file, "%s", reg_names[REGNO (x)]);
2726 else if (x == CONST0_RTX (GET_MODE (x)))
2727 fprintf (file, "$f31");
2729 output_operand_lossage ("invalid %%R value");
2734 /* Write the 1's complement of a constant. */
2735 if (GET_CODE (x) != CONST_INT)
2736 output_operand_lossage ("invalid %%N value");
2738 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2742 /* Write 1 << C, for a constant C. */
2743 if (GET_CODE (x) != CONST_INT)
2744 output_operand_lossage ("invalid %%P value");
2746 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2750 /* Write the high-order 16 bits of a constant, sign-extended. */
2751 if (GET_CODE (x) != CONST_INT)
2752 output_operand_lossage ("invalid %%h value");
2754 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2758 /* Write the low-order 16 bits of a constant, sign-extended. */
2759 if (GET_CODE (x) != CONST_INT)
2760 output_operand_lossage ("invalid %%L value");
2762 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2763 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2767 /* Write mask for ZAP insn. */
2768 if (GET_CODE (x) == CONST_DOUBLE)
2770 HOST_WIDE_INT mask = 0;
2771 HOST_WIDE_INT value;
2773 value = CONST_DOUBLE_LOW (x);
2774 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2779 value = CONST_DOUBLE_HIGH (x);
2780 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2783 mask |= (1 << (i + sizeof (int)));
2785 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2788 else if (GET_CODE (x) == CONST_INT)
2790 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2792 for (i = 0; i < 8; i++, value >>= 8)
2796 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2799 output_operand_lossage ("invalid %%m value");
2803 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2804 if (GET_CODE (x) != CONST_INT
2805 || (INTVAL (x) != 8 && INTVAL (x) != 16
2806 && INTVAL (x) != 32 && INTVAL (x) != 64))
2807 output_operand_lossage ("invalid %%M value");
2809 fprintf (file, "%s",
2810 (INTVAL (x) == 8 ? "b"
2811 : INTVAL (x) == 16 ? "w"
2812 : INTVAL (x) == 32 ? "l"
2817 /* Similar, except do it from the mask. */
2818 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2819 fprintf (file, "b");
2820 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2821 fprintf (file, "w");
2822 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2823 fprintf (file, "l");
2824 #if HOST_BITS_PER_WIDE_INT == 32
2825 else if (GET_CODE (x) == CONST_DOUBLE
2826 && CONST_DOUBLE_HIGH (x) == 0
2827 && CONST_DOUBLE_LOW (x) == -1)
2828 fprintf (file, "l");
2829 else if (GET_CODE (x) == CONST_DOUBLE
2830 && CONST_DOUBLE_HIGH (x) == -1
2831 && CONST_DOUBLE_LOW (x) == -1)
2832 fprintf (file, "q");
2834 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
2835 fprintf (file, "q");
2836 else if (GET_CODE (x) == CONST_DOUBLE
2837 && CONST_DOUBLE_HIGH (x) == 0
2838 && CONST_DOUBLE_LOW (x) == -1)
2839 fprintf (file, "q");
2842 output_operand_lossage ("invalid %%U value");
2846 /* Write the constant value divided by 8. */
2847 if (GET_CODE (x) != CONST_INT
2848 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2849 && (INTVAL (x) & 7) != 8)
2850 output_operand_lossage ("invalid %%s value");
2852 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2856 /* Same, except compute (64 - c) / 8 */
2858 if (GET_CODE (x) != CONST_INT
2859 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2860 && (INTVAL (x) & 7) != 8)
2861 output_operand_lossage ("invalid %%s value");
2863 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2866 case 'C': case 'D': case 'c': case 'd':
2867 /* Write out comparison name. */
2869 enum rtx_code c = GET_CODE (x);
2871 if (GET_RTX_CLASS (c) != '<')
2872 output_operand_lossage ("invalid %%C value");
2875 c = reverse_condition (c);
2876 else if (code == 'c')
2877 c = swap_condition (c);
2878 else if (code == 'd')
2879 c = swap_condition (reverse_condition (c));
2882 fprintf (file, "ule");
2884 fprintf (file, "ult");
2886 fprintf (file, "%s", GET_RTX_NAME (c));
2891 /* Write the divide or modulus operator. */
2892 switch (GET_CODE (x))
2895 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2898 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2901 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2904 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2907 output_operand_lossage ("invalid %%E value");
2913 /* Write "_u" for unaligned access. */
2914 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2915 fprintf (file, "_u");
2919 if (GET_CODE (x) == REG)
2920 fprintf (file, "%s", reg_names[REGNO (x)]);
2921 else if (GET_CODE (x) == MEM)
2922 output_address (XEXP (x, 0));
2924 output_addr_const (file, x);
2928 output_operand_lossage ("invalid %%xn code");
2933 print_operand_address (file, addr)
2938 HOST_WIDE_INT offset = 0;
2940 if (GET_CODE (addr) == AND)
2941 addr = XEXP (addr, 0);
2943 if (GET_CODE (addr) == PLUS
2944 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2946 offset = INTVAL (XEXP (addr, 1));
2947 addr = XEXP (addr, 0);
2949 if (GET_CODE (addr) == REG)
2950 basereg = REGNO (addr);
2951 else if (GET_CODE (addr) == SUBREG
2952 && GET_CODE (SUBREG_REG (addr)) == REG)
2953 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
2954 else if (GET_CODE (addr) == CONST_INT)
2955 offset = INTVAL (addr);
2959 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
2960 fprintf (file, "($%d)", basereg);
2963 /* Emit RTL insns to initialize the variable parts of a trampoline at
2964 TRAMP. FNADDR is an RTX for the address of the function's pure
2965 code. CXT is an RTX for the static chain value for the function.
2967 The three offset parameters are for the individual template's
2968 layout. A JMPOFS < 0 indicates that the trampoline does not
2969 contain instructions at all.
2971 We assume here that a function will be called many more times than
2972 its address is taken (e.g., it might be passed to qsort), so we
2973 take the trouble to initialize the "hint" field in the JMP insn.
2974 Note that the hint field is PC (new) + 4 * bits 13:0. */
2977 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2978 rtx tramp, fnaddr, cxt;
2979 int fnofs, cxtofs, jmpofs;
2981 rtx temp, temp1, addr;
2982 /* VMS really uses DImode pointers in memory at this point. */
2983 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2985 #ifdef POINTERS_EXTEND_UNSIGNED
2986 fnaddr = convert_memory_address (mode, fnaddr);
2987 cxt = convert_memory_address (mode, cxt);
2990 /* Store function address and CXT. */
2991 addr = memory_address (mode, plus_constant (tramp, fnofs));
2992 emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2993 addr = memory_address (mode, plus_constant (tramp, cxtofs));
2994 emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2996 /* This has been disabled since the hint only has a 32k range, and in
2997 no existing OS is the stack within 32k of the text segment. */
2998 if (0 && jmpofs >= 0)
3000 /* Compute hint value. */
3001 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3002 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3004 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3005 build_int_2 (2, 0), NULL_RTX, 1);
3006 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3008 /* Merge in the hint. */
3009 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3010 temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
3011 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3012 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3014 emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
3017 #ifdef TRANSFER_FROM_TRAMPOLINE
3018 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
3019 0, VOIDmode, 1, addr, Pmode);
3023 emit_insn (gen_imb ());
3026 /* Do what is necessary for `va_start'. The argument is ignored;
3027 We look at the current function to determine if stdarg or varargs
3028 is used and fill in an initial va_list. A pointer to this constructor
3032 alpha_builtin_saveregs (arglist)
3033 tree arglist ATTRIBUTE_UNUSED;
3035 rtx block, addr, dest, argsize;
3036 tree fntype = TREE_TYPE (current_function_decl);
3037 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
3038 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3039 != void_type_node));
3041 /* Compute the current position into the args, taking into account
3042 both registers and memory. Both of these are already included in
3045 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
3047 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
3048 storing fp arg registers in the first 48 bytes, and the integer arg
3049 registers in the next 48 bytes. This is only done, however, if any
3050 integer registers need to be stored.
3052 If no integer registers need be stored, then we must subtract 48 in
3053 order to account for the integer arg registers which are counted in
3054 argsize above, but which are not actually stored on the stack. */
3056 if (TARGET_OPEN_VMS)
3057 addr = plus_constant (virtual_incoming_args_rtx,
3058 NUM_ARGS <= 5 + stdarg
3059 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
3061 addr = (NUM_ARGS <= 5 + stdarg
3062 ? plus_constant (virtual_incoming_args_rtx,
3064 : plus_constant (virtual_incoming_args_rtx,
3065 - (6 * UNITS_PER_WORD)));
3067 /* For VMS, we include the argsize, while on Unix, it's handled as
3068 a separate field. */
3069 if (TARGET_OPEN_VMS)
3070 addr = plus_constant (addr, INTVAL (argsize));
3072 addr = force_operand (addr, NULL_RTX);
3074 #ifdef POINTERS_EXTEND_UNSIGNED
3075 addr = convert_memory_address (ptr_mode, addr);
3078 if (TARGET_OPEN_VMS)
3082 /* Allocate the va_list constructor */
3083 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
3084 RTX_UNCHANGING_P (block) = 1;
3085 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
3087 /* Store the address of the first integer register in the __base
3090 dest = change_address (block, ptr_mode, XEXP (block, 0));
3091 emit_move_insn (dest, addr);
3093 if (current_function_check_memory_usage)
3094 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3096 GEN_INT (GET_MODE_SIZE (ptr_mode)),
3097 TYPE_MODE (sizetype),
3098 GEN_INT (MEMORY_USE_RW),
3099 TYPE_MODE (integer_type_node));
3101 /* Store the argsize as the __va_offset member. */
3102 dest = change_address (block, TYPE_MODE (integer_type_node),
3103 plus_constant (XEXP (block, 0),
3104 POINTER_SIZE/BITS_PER_UNIT));
3105 emit_move_insn (dest, argsize);
3107 if (current_function_check_memory_usage)
3108 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3110 GEN_INT (GET_MODE_SIZE
3111 (TYPE_MODE (integer_type_node))),
3112 TYPE_MODE (sizetype),
3113 GEN_INT (MEMORY_USE_RW),
3114 TYPE_MODE (integer_type_node));
3116 /* Return the address of the va_list constructor, but don't put it in a
3117 register. Doing so would fail when not optimizing and produce worse
3118 code when optimizing. */
3119 return XEXP (block, 0);
3123 /* This page contains routines that are used to determine what the function
3124 prologue and epilogue code will do and write them out. */
3126 /* Compute the size of the save area in the stack. */
3128 /* These variables are used for communication between the following functions.
3129 They indicate various things about the current function being compiled
3130 that are used to tell what kind of prologue, epilogue and procedure
3131 descriptior to generate. */
3133 /* Nonzero if we need a stack procedure. */
3134 static int vms_is_stack_procedure;
3136 /* Register number (either FP or SP) that is used to unwind the frame. */
3137 static int vms_unwind_regno;
3139 /* Register number used to save FP. We need not have one for RA since
3140 we don't modify it for register procedures. This is only defined
3141 for register frame procedures. */
3142 static int vms_save_fp_regno;
3144 /* Register number used to reference objects off our PV. */
3145 static int vms_base_regno;
3147 /* Compute register masks for saved registers. */
3150 alpha_sa_mask (imaskP, fmaskP)
3151 unsigned long *imaskP;
3152 unsigned long *fmaskP;
3154 unsigned long imask = 0;
3155 unsigned long fmask = 0;
3158 #ifdef ASM_OUTPUT_MI_THUNK
3159 if (!current_function_is_thunk)
3162 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3163 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3165 /* One for every register we have to save. */
3166 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3167 if (! fixed_regs[i] && ! call_used_regs[i]
3168 && regs_ever_live[i] && i != REG_RA)
3173 fmask |= (1L << (i - 32));
3176 if (imask || fmask || alpha_ra_ever_killed ())
3177 imask |= (1L << REG_RA);
3190 #ifdef ASM_OUTPUT_MI_THUNK
3191 if (current_function_is_thunk)
3196 /* One for every register we have to save. */
3197 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3198 if (! fixed_regs[i] && ! call_used_regs[i]
3199 && regs_ever_live[i] && i != REG_RA)
3203 if (TARGET_OPEN_VMS)
3205 /* Start by assuming we can use a register procedure if we don't
3206 make any calls (REG_RA not used) or need to save any
3207 registers and a stack procedure if we do. */
3208 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3210 /* Decide whether to refer to objects off our PV via FP or PV.
3211 If we need FP for something else or if we receive a nonlocal
3212 goto (which expects PV to contain the value), we must use PV.
3213 Otherwise, start by assuming we can use FP. */
3214 vms_base_regno = (frame_pointer_needed
3215 || current_function_has_nonlocal_label
3216 || vms_is_stack_procedure
3217 || current_function_outgoing_args_size
3218 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3220 /* If we want to copy PV into FP, we need to find some register
3221 in which to save FP. */
3223 vms_save_fp_regno = -1;
3224 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3225 for (i = 0; i < 32; i++)
3226 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3227 vms_save_fp_regno = i;
3229 if (vms_save_fp_regno == -1)
3230 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3232 /* Stack unwinding should be done via FP unless we use it for PV. */
3233 vms_unwind_regno = (vms_base_regno == REG_PV
3234 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3236 /* If this is a stack procedure, allow space for saving FP and RA. */
3237 if (vms_is_stack_procedure)
3242 /* If some registers were saved but not RA, RA must also be saved,
3243 so leave space for it. */
3244 if (sa_size != 0 || alpha_ra_ever_killed ())
3247 /* Our size must be even (multiple of 16 bytes). */
3256 alpha_pv_save_size ()
3259 return vms_is_stack_procedure ? 8 : 0;
3266 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3270 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3271 tree decl ATTRIBUTE_UNUSED;
3272 tree attributes ATTRIBUTE_UNUSED;
3276 if (is_attribute_p ("overlaid", identifier))
3277 return (args == NULL_TREE);
3282 alpha_does_function_need_gp ()
3286 /* We never need a GP for Windows/NT or VMS. */
3287 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3290 #ifdef TARGET_PROFILING_NEEDS_GP
3295 #ifdef ASM_OUTPUT_MI_THUNK
3296 if (current_function_is_thunk)
3300 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3301 Even if we are a static function, we still need to do this in case
3302 our address is taken and passed to something like qsort. */
3304 push_topmost_sequence ();
3305 insn = get_insns ();
3306 pop_topmost_sequence ();
3308 for (; insn; insn = NEXT_INSN (insn))
3309 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3310 && GET_CODE (PATTERN (insn)) != USE
3311 && GET_CODE (PATTERN (insn)) != CLOBBER)
3313 enum attr_type type = get_attr_type (insn);
3314 if (type == TYPE_LDSYM || type == TYPE_JSR)
3321 /* Write a version stamp. Don't write anything if we are running as a
3322 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3329 alpha_write_verstamp (file)
3330 FILE *file ATTRIBUTE_UNUSED;
3333 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3337 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3341 set_frame_related_p ()
3343 rtx seq = gen_sequence ();
3346 if (GET_CODE (seq) == SEQUENCE)
3348 int i = XVECLEN (seq, 0);
3350 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3351 return emit_insn (seq);
3355 seq = emit_insn (seq);
3356 RTX_FRAME_RELATED_P (seq) = 1;
3361 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3363 /* Write function prologue. */
3365 /* On vms we have two kinds of functions:
3367 - stack frame (PROC_STACK)
3368 these are 'normal' functions with local vars and which are
3369 calling other functions
3370 - register frame (PROC_REGISTER)
3371 keeps all data in registers, needs no stack
3373 We must pass this to the assembler so it can generate the
3374 proper pdsc (procedure descriptor)
3375 This is done with the '.pdesc' command.
3377 On not-vms, we don't really differentiate between the two, as we can
3378 simply allocate stack without saving registers. */
3381 alpha_expand_prologue ()
3383 /* Registers to save. */
3384 unsigned long imask = 0;
3385 unsigned long fmask = 0;
3386 /* Stack space needed for pushing registers clobbered by us. */
3387 HOST_WIDE_INT sa_size;
3388 /* Complete stack size needed. */
3389 HOST_WIDE_INT frame_size;
3390 /* Offset from base reg to register save area. */
3391 HOST_WIDE_INT reg_offset;
3395 sa_size = alpha_sa_size ();
3397 frame_size = get_frame_size ();
3398 if (TARGET_OPEN_VMS)
3399 frame_size = ALPHA_ROUND (sa_size
3400 + (vms_is_stack_procedure ? 8 : 0)
3402 + current_function_pretend_args_size);
3404 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3406 + ALPHA_ROUND (frame_size
3407 + current_function_pretend_args_size));
3409 if (TARGET_OPEN_VMS)
3412 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3414 alpha_sa_mask (&imask, &fmask);
3416 /* Adjust the stack by the frame size. If the frame size is > 4096
3417 bytes, we need to be sure we probe somewhere in the first and last
3418 4096 bytes (we can probably get away without the latter test) and
3419 every 8192 bytes in between. If the frame size is > 32768, we
3420 do this in a loop. Otherwise, we generate the explicit probe
3423 Note that we are only allowed to adjust sp once in the prologue. */
3425 if (frame_size <= 32768)
3427 if (frame_size > 4096)
3432 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3433 while ((probed += 8192) < frame_size);
3435 /* We only have to do this probe if we aren't saving registers. */
3436 if (sa_size == 0 && probed + 4096 < frame_size)
3437 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3440 if (frame_size != 0)
3442 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
3443 GEN_INT (-frame_size))));
3448 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3449 number of 8192 byte blocks to probe. We then probe each block
3450 in the loop and then set SP to the proper location. If the
3451 amount remaining is > 4096, we have to do one more probe if we
3452 are not saving any registers. */
3454 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3455 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3456 rtx ptr = gen_rtx_REG (DImode, 22);
3457 rtx count = gen_rtx_REG (DImode, 23);
3460 emit_move_insn (count, GEN_INT (blocks));
3461 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
3463 /* Because of the difficulty in emitting a new basic block this
3464 late in the compilation, generate the loop as a single insn. */
3465 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3467 if (leftover > 4096 && sa_size == 0)
3469 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3470 MEM_VOLATILE_P (last) = 1;
3471 emit_move_insn (last, const0_rtx);
3474 if (TARGET_WINDOWS_NT)
3476 /* For NT stack unwind (done by 'reverse execution'), it's
3477 not OK to take the result of a loop, even though the value
3478 is already in ptr, so we reload it via a single operation
3479 and subtract it to sp.
3481 Yes, that's correct -- we have to reload the whole constant
3482 into a temporary via ldah+lda then subtract from sp. To
3483 ensure we get ldah+lda, we use a special pattern. */
3485 HOST_WIDE_INT lo, hi;
3486 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3487 hi = frame_size - lo;
3489 emit_move_insn (ptr, GEN_INT (hi));
3490 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
3491 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3496 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
3497 GEN_INT (-leftover)));
3500 /* This alternative is special, because the DWARF code cannot
3501 possibly intuit through the loop above. So we invent this
3502 note it looks at instead. */
3503 RTX_FRAME_RELATED_P (seq) = 1;
3505 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3506 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3507 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3508 GEN_INT (-frame_size))),
3512 /* Cope with very large offsets to the register save area. */
3513 sa_reg = stack_pointer_rtx;
3514 if (reg_offset + sa_size > 0x8000)
3516 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3519 if (low + sa_size <= 0x8000)
3520 bias = reg_offset - low, reg_offset = low;
3522 bias = reg_offset, reg_offset = 0;
3524 sa_reg = gen_rtx_REG (DImode, 24);
3525 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
3528 /* Save regs in stack order. Beginning with VMS PV. */
3529 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3531 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3532 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3533 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3536 /* Save register RA next. */
3537 if (imask & (1L << REG_RA))
3539 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3540 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3541 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3542 imask &= ~(1L << REG_RA);
3546 /* Now save any other registers required to be saved. */
3547 for (i = 0; i < 32; i++)
3548 if (imask & (1L << i))
3550 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3551 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3552 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3556 for (i = 0; i < 32; i++)
3557 if (fmask & (1L << i))
3559 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3560 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3561 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3565 if (TARGET_OPEN_VMS)
3567 if (!vms_is_stack_procedure)
3569 /* Register frame procedures fave the fp. */
3570 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3571 hard_frame_pointer_rtx));
3574 if (vms_base_regno != REG_PV)
3575 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3576 gen_rtx_REG (DImode, REG_PV)));
3578 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3580 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3583 /* If we have to allocate space for outgoing args, do it now. */
3584 if (current_function_outgoing_args_size != 0)
3586 FRP (emit_move_insn (stack_pointer_rtx,
3587 plus_constant (hard_frame_pointer_rtx,
3588 - ALPHA_ROUND (current_function_outgoing_args_size))));
3593 /* If we need a frame pointer, set it from the stack pointer. */
3594 if (frame_pointer_needed)
3596 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3597 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3600 /* This must always be the last instruction in the
3601 prologue, thus we emit a special move + clobber. */
3602 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3603 stack_pointer_rtx, sa_reg)));
3608 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3609 the prologue, for exception handling reasons, we cannot do this for
3610 any insn that might fault. We could prevent this for mems with a
3611 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3612 have to prevent all such scheduling with a blockage.
3614 Linux, on the other hand, never bothered to implement OSF/1's
3615 exception handling, and so doesn't care about such things. Anyone
3616 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3618 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3619 emit_insn (gen_blockage ());
3622 /* Output the textual info surrounding the prologue. */
3625 alpha_start_function (file, fnname, decl)
3628 tree decl ATTRIBUTE_UNUSED;
3630 unsigned long imask = 0;
3631 unsigned long fmask = 0;
3632 /* Stack space needed for pushing registers clobbered by us. */
3633 HOST_WIDE_INT sa_size;
3634 /* Complete stack size needed. */
3635 HOST_WIDE_INT frame_size;
3636 /* Offset from base reg to register save area. */
3637 HOST_WIDE_INT reg_offset;
3638 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3641 sa_size = alpha_sa_size ();
3643 frame_size = get_frame_size ();
3644 if (TARGET_OPEN_VMS)
3645 frame_size = ALPHA_ROUND (sa_size
3646 + (vms_is_stack_procedure ? 8 : 0)
3648 + current_function_pretend_args_size);
3650 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3652 + ALPHA_ROUND (frame_size
3653 + current_function_pretend_args_size));
3655 if (TARGET_OPEN_VMS)
3658 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3660 alpha_sa_mask (&imask, &fmask);
3662 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3663 We have to do that before the .ent directive as we cannot switch
3664 files within procedures with native ecoff because line numbers are
3665 linked to procedure descriptors.
3666 Outputting the lineno helps debugging of one line functions as they
3667 would otherwise get no line number at all. Please note that we would
3668 like to put out last_linenum from final.c, but it is not accessible. */
3670 if (write_symbols == SDB_DEBUG)
3672 ASM_OUTPUT_SOURCE_FILENAME (file,
3673 DECL_SOURCE_FILE (current_function_decl));
3674 if (debug_info_level != DINFO_LEVEL_TERSE)
3675 ASM_OUTPUT_SOURCE_LINE (file,
3676 DECL_SOURCE_LINE (current_function_decl));
3679 /* Issue function start and label. */
3680 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3682 fputs ("\t.ent ", file);
3683 assemble_name (file, fnname);
3687 strcpy (entry_label, fnname);
3688 if (TARGET_OPEN_VMS)
3689 strcat (entry_label, "..en");
3690 ASM_OUTPUT_LABEL (file, entry_label);
3691 inside_function = TRUE;
3693 if (TARGET_OPEN_VMS)
3694 fprintf (file, "\t.base $%d\n", vms_base_regno);
3696 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3697 && !flag_inhibit_size_directive)
3699 /* Set flags in procedure descriptor to request IEEE-conformant
3700 math-library routines. The value we set it to is PDSC_EXC_IEEE
3701 (/usr/include/pdsc.h). */
3702 fputs ("\t.eflag 48\n", file);
3705 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3706 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3707 alpha_arg_offset = -frame_size + 48;
3709 /* Describe our frame. If the frame size is larger than an integer,
3710 print it as zero to avoid an assembler error. We won't be
3711 properly describing such a frame, but that's the best we can do. */
3712 if (TARGET_OPEN_VMS)
3714 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3715 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3716 frame_size >= (1l << 31) ? 0 : frame_size);
3717 fputs (",$26,", file);
3718 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3721 else if (!flag_inhibit_size_directive)
3723 fprintf (file, "\t.frame $%d,",
3724 (frame_pointer_needed
3725 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3726 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3727 frame_size >= (1l << 31) ? 0 : frame_size);
3728 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3731 /* Describe which registers were spilled. */
3732 if (TARGET_OPEN_VMS)
3735 /* ??? Does VMS care if mask contains ra? The old code did'nt
3736 set it, so I don't here. */
3737 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3739 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3740 if (!vms_is_stack_procedure)
3741 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3743 else if (!flag_inhibit_size_directive)
3747 fprintf (file, "\t.mask 0x%lx,", imask);
3748 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3749 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3752 for (i = 0; i < 32; ++i)
3753 if (imask & (1L << i))
3759 fprintf (file, "\t.fmask 0x%lx,", fmask);
3760 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3761 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3766 /* Emit GP related things. It is rather unfortunate about the alignment
3767 issues surrounding a CODE_LABEL that forces us to do the label in
3769 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3771 alpha_function_needs_gp = alpha_does_function_need_gp ();
3772 if (alpha_function_needs_gp)
3773 fputs ("\tldgp $29,0($27)\n", file);
3776 assemble_name (file, fnname);
3777 fputs ("..ng:\n", file);
3781 /* Ifdef'ed cause readonly_section and link_section are only
3783 readonly_section ();
3784 fprintf (file, "\t.align 3\n");
3785 assemble_name (file, fnname); fputs ("..na:\n", file);
3786 fputs ("\t.ascii \"", file);
3787 assemble_name (file, fnname);
3788 fputs ("\\0\"\n", file);
3791 fprintf (file, "\t.align 3\n");
3792 fputs ("\t.name ", file);
3793 assemble_name (file, fnname);
3794 fputs ("..na\n", file);
3795 ASM_OUTPUT_LABEL (file, fnname);
3796 fprintf (file, "\t.pdesc ");
3797 assemble_name (file, fnname);
3798 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3799 alpha_need_linkage (fnname, 1);
3804 /* Emit the .prologue note at the scheduled end of the prologue. */
3807 output_end_prologue (file)
3810 if (TARGET_OPEN_VMS)
3811 fputs ("\t.prologue\n", file);
3812 else if (TARGET_WINDOWS_NT)
3813 fputs ("\t.prologue 0\n", file);
3814 else if (!flag_inhibit_size_directive)
3815 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3818 /* Write function epilogue. */
3820 /* ??? At some point we will want to support full unwind, and so will
3821 need to mark the epilogue as well. At the moment, we just confuse
3824 #define FRP(exp) exp
3827 alpha_expand_epilogue ()
3829 /* Registers to save. */
3830 unsigned long imask = 0;
3831 unsigned long fmask = 0;
3832 /* Stack space needed for pushing registers clobbered by us. */
3833 HOST_WIDE_INT sa_size;
3834 /* Complete stack size needed. */
3835 HOST_WIDE_INT frame_size;
3836 /* Offset from base reg to register save area. */
3837 HOST_WIDE_INT reg_offset;
3838 int fp_is_frame_pointer, fp_offset;
3839 rtx sa_reg, sa_reg_exp = NULL;
3840 rtx sp_adj1, sp_adj2, mem;
3843 sa_size = alpha_sa_size ();
3845 frame_size = get_frame_size ();
3846 if (TARGET_OPEN_VMS)
3847 frame_size = ALPHA_ROUND (sa_size
3848 + (vms_is_stack_procedure ? 8 : 0)
3850 + current_function_pretend_args_size);
3852 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3854 + ALPHA_ROUND (frame_size
3855 + current_function_pretend_args_size));
3857 if (TARGET_OPEN_VMS)
3860 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3862 alpha_sa_mask (&imask, &fmask);
3864 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3865 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3869 /* If we have a frame pointer, restore SP from it. */
3870 if ((TARGET_OPEN_VMS
3871 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3872 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3874 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
3877 /* Cope with very large offsets to the register save area. */
3878 sa_reg = stack_pointer_rtx;
3879 if (reg_offset + sa_size > 0x8000)
3881 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3884 if (low + sa_size <= 0x8000)
3885 bias = reg_offset - low, reg_offset = low;
3887 bias = reg_offset, reg_offset = 0;
3889 sa_reg = gen_rtx_REG (DImode, 22);
3890 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3892 FRP (emit_move_insn (sa_reg, sa_reg_exp));
3895 /* Restore registers in order, excepting a true frame pointer. */
3897 if (! alpha_eh_epilogue_sp_ofs)
3899 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3900 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3901 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
3904 imask &= ~(1L << REG_RA);
3906 for (i = 0; i < 32; ++i)
3907 if (imask & (1L << i))
3909 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3910 fp_offset = reg_offset;
3913 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3914 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3915 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
3920 for (i = 0; i < 32; ++i)
3921 if (fmask & (1L << i))
3923 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
3924 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3925 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
3930 if (frame_size || alpha_eh_epilogue_sp_ofs)
3932 sp_adj1 = stack_pointer_rtx;
3934 if (alpha_eh_epilogue_sp_ofs)
3936 sp_adj1 = gen_rtx_REG (DImode, 23);
3937 emit_move_insn (sp_adj1,
3938 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3939 alpha_eh_epilogue_sp_ofs));
3942 /* If the stack size is large, begin computation into a temporary
3943 register so as not to interfere with a potential fp restore,
3944 which must be consecutive with an SP restore. */
3945 if (frame_size < 32768)
3946 sp_adj2 = GEN_INT (frame_size);
3947 else if (frame_size < 0x40007fffL)
3949 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3951 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
3952 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3956 sp_adj1 = gen_rtx_REG (DImode, 23);
3957 FRP (emit_move_insn (sp_adj1, sp_adj2));
3959 sp_adj2 = GEN_INT (low);
3963 rtx tmp = gen_rtx_REG (DImode, 23);
3964 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
3967 /* We can't drop new things to memory this late, afaik,
3968 so build it up by pieces. */
3969 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
3970 -(frame_size < 0)));
3976 /* From now on, things must be in order. So emit blockages. */
3978 /* Restore the frame pointer. */
3979 if (fp_is_frame_pointer)
3981 emit_insn (gen_blockage ());
3982 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
3983 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3984 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
3986 else if (TARGET_OPEN_VMS)
3988 emit_insn (gen_blockage ());
3989 FRP (emit_move_insn (hard_frame_pointer_rtx,
3990 gen_rtx_REG (DImode, vms_save_fp_regno)));
3993 /* Restore the stack pointer. */
3994 emit_insn (gen_blockage ());
3995 FRP (emit_move_insn (stack_pointer_rtx,
3996 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
4000 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4002 emit_insn (gen_blockage ());
4003 FRP (emit_move_insn (hard_frame_pointer_rtx,
4004 gen_rtx_REG (DImode, vms_save_fp_regno)));
4009 emit_jump_insn (gen_return_internal ());
4012 /* Output the rest of the textual info surrounding the epilogue. */
4015 alpha_end_function (file, fnname, decl)
4018 tree decl ATTRIBUTE_UNUSED;
4020 /* End the function. */
4021 if (!flag_inhibit_size_directive)
4023 fputs ("\t.end ", file);
4024 assemble_name (file, fnname);
4027 inside_function = FALSE;
4029 /* Show that we know this function if it is called again.
4031 Don't do this for global functions in object files destined for a
4032 shared library because the function may be overridden by the application
4033 or other libraries. Similarly, don't do this for weak functions. */
4035 if (!DECL_WEAK (current_function_decl)
4036 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4037 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4040 /* Debugging support. */
4044 /* Count the number of sdb related labels are generated (to find block
4045 start and end boundaries). */
4047 int sdb_label_count = 0;
4049 /* Next label # for each statement. */
4051 static int sym_lineno = 0;
4053 /* Count the number of .file directives, so that .loc is up to date. */
4055 static int num_source_filenames = 0;
4057 /* Name of the file containing the current function. */
4059 static const char *current_function_file = "";
4061 /* Offsets to alpha virtual arg/local debugging pointers. */
4063 long alpha_arg_offset;
4064 long alpha_auto_offset;
4066 /* Emit a new filename to a stream. */
4069 alpha_output_filename (stream, name)
4073 static int first_time = TRUE;
4074 char ltext_label_name[100];
4079 ++num_source_filenames;
4080 current_function_file = name;
4081 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4082 output_quoted_string (stream, name);
4083 fprintf (stream, "\n");
4084 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4085 fprintf (stream, "\t#@stabs\n");
4088 else if (write_symbols == DBX_DEBUG)
4090 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4091 fprintf (stream, "%s ", ASM_STABS_OP);
4092 output_quoted_string (stream, name);
4093 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
4096 else if (name != current_function_file
4097 && strcmp (name, current_function_file) != 0)
4099 if (inside_function && ! TARGET_GAS)
4100 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4103 ++num_source_filenames;
4104 current_function_file = name;
4105 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4108 output_quoted_string (stream, name);
4109 fprintf (stream, "\n");
4113 /* Emit a linenumber to a stream. */
4116 alpha_output_lineno (stream, line)
4120 if (write_symbols == DBX_DEBUG)
4122 /* mips-tfile doesn't understand .stabd directives. */
4124 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4125 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4128 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4131 /* Structure to show the current status of registers and memory. */
4133 struct shadow_summary
4136 unsigned long i : 31; /* Mask of int regs */
4137 unsigned long fp : 31; /* Mask of fp regs */
4138 unsigned long mem : 1; /* mem == imem | fpmem */
4142 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
4143 static void alpha_handle_trap_shadows PROTO((rtx));
4145 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4146 to the summary structure. SET is nonzero if the insn is setting the
4147 object, otherwise zero. */
4150 summarize_insn (x, sum, set)
4152 struct shadow_summary *sum;
4161 switch (GET_CODE (x))
4163 /* ??? Note that this case would be incorrect if the Alpha had a
4164 ZERO_EXTRACT in SET_DEST. */
4166 summarize_insn (SET_SRC (x), sum, 0);
4167 summarize_insn (SET_DEST (x), sum, 1);
4171 summarize_insn (XEXP (x, 0), sum, 1);
4175 summarize_insn (XEXP (x, 0), sum, 0);
4179 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4180 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4184 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4185 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4189 summarize_insn (SUBREG_REG (x), sum, 0);
4194 int regno = REGNO (x);
4195 unsigned long mask = 1UL << (regno % 32);
4197 if (regno == 31 || regno == 63)
4203 sum->defd.i |= mask;
4205 sum->defd.fp |= mask;
4210 sum->used.i |= mask;
4212 sum->used.fp |= mask;
4223 /* Find the regs used in memory address computation: */
4224 summarize_insn (XEXP (x, 0), sum, 0);
4227 case CONST_INT: case CONST_DOUBLE:
4228 case SYMBOL_REF: case LABEL_REF: case CONST:
4231 /* Handle common unary and binary ops for efficiency. */
4232 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4233 case MOD: case UDIV: case UMOD: case AND: case IOR:
4234 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4235 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4236 case NE: case EQ: case GE: case GT: case LE:
4237 case LT: case GEU: case GTU: case LEU: case LTU:
4238 summarize_insn (XEXP (x, 0), sum, 0);
4239 summarize_insn (XEXP (x, 1), sum, 0);
4242 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4243 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4244 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4245 case SQRT: case FFS:
4246 summarize_insn (XEXP (x, 0), sum, 0);
4250 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4251 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4252 switch (format_ptr[i])
4255 summarize_insn (XEXP (x, i), sum, 0);
4259 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4260 summarize_insn (XVECEXP (x, i, j), sum, 0);
4272 /* Ensure a sufficient number of `trapb' insns are in the code when
4273 the user requests code with a trap precision of functions or
4276 In naive mode, when the user requests a trap-precision of
4277 "instruction", a trapb is needed after every instruction that may
4278 generate a trap. This ensures that the code is resumption safe but
4281 When optimizations are turned on, we delay issuing a trapb as long
4282 as possible. In this context, a trap shadow is the sequence of
4283 instructions that starts with a (potentially) trap generating
4284 instruction and extends to the next trapb or call_pal instruction
4285 (but GCC never generates call_pal by itself). We can delay (and
4286 therefore sometimes omit) a trapb subject to the following
4289 (a) On entry to the trap shadow, if any Alpha register or memory
4290 location contains a value that is used as an operand value by some
4291 instruction in the trap shadow (live on entry), then no instruction
4292 in the trap shadow may modify the register or memory location.
4294 (b) Within the trap shadow, the computation of the base register
4295 for a memory load or store instruction may not involve using the
4296 result of an instruction that might generate an UNPREDICTABLE
4299 (c) Within the trap shadow, no register may be used more than once
4300 as a destination register. (This is to make life easier for the
4303 (d) The trap shadow may not include any branch instructions. */
4306 alpha_handle_trap_shadows (insns)
4309 struct shadow_summary shadow;
4310 int trap_pending, exception_nesting;
4314 exception_nesting = 0;
4317 shadow.used.mem = 0;
4318 shadow.defd = shadow.used;
4320 for (i = insns; i ; i = NEXT_INSN (i))
4322 if (GET_CODE (i) == NOTE)
4324 switch (NOTE_LINE_NUMBER (i))
4326 case NOTE_INSN_EH_REGION_BEG:
4327 exception_nesting++;
4332 case NOTE_INSN_EH_REGION_END:
4333 exception_nesting--;
4338 case NOTE_INSN_EPILOGUE_BEG:
4339 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4344 else if (trap_pending)
4346 if (alpha_tp == ALPHA_TP_FUNC)
4348 if (GET_CODE (i) == JUMP_INSN
4349 && GET_CODE (PATTERN (i)) == RETURN)
4352 else if (alpha_tp == ALPHA_TP_INSN)
4356 struct shadow_summary sum;
4361 sum.defd = sum.used;
4363 switch (GET_CODE (i))
4366 /* Annoyingly, get_attr_trap will abort on these. */
4367 if (GET_CODE (PATTERN (i)) == USE
4368 || GET_CODE (PATTERN (i)) == CLOBBER)
4371 summarize_insn (PATTERN (i), &sum, 0);
4373 if ((sum.defd.i & shadow.defd.i)
4374 || (sum.defd.fp & shadow.defd.fp))
4376 /* (c) would be violated */
4380 /* Combine shadow with summary of current insn: */
4381 shadow.used.i |= sum.used.i;
4382 shadow.used.fp |= sum.used.fp;
4383 shadow.used.mem |= sum.used.mem;
4384 shadow.defd.i |= sum.defd.i;
4385 shadow.defd.fp |= sum.defd.fp;
4386 shadow.defd.mem |= sum.defd.mem;
4388 if ((sum.defd.i & shadow.used.i)
4389 || (sum.defd.fp & shadow.used.fp)
4390 || (sum.defd.mem & shadow.used.mem))
4392 /* (a) would be violated (also takes care of (b)) */
4393 if (get_attr_trap (i) == TRAP_YES
4394 && ((sum.defd.i & sum.used.i)
4395 || (sum.defd.fp & sum.used.fp)))
4414 n = emit_insn_before (gen_trapb (), i);
4415 PUT_MODE (n, TImode);
4416 PUT_MODE (i, TImode);
4420 shadow.used.mem = 0;
4421 shadow.defd = shadow.used;
4426 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4427 && GET_CODE (i) == INSN
4428 && GET_CODE (PATTERN (i)) != USE
4429 && GET_CODE (PATTERN (i)) != CLOBBER
4430 && get_attr_trap (i) == TRAP_YES)
4432 if (optimize && !trap_pending)
4433 summarize_insn (PATTERN (i), &shadow, 0);
4440 /* Alpha can only issue instruction groups simultaneously if they are
4441 suitibly aligned. This is very processor-specific. */
4443 enum alphaev4_pipe {
4450 enum alphaev5_pipe {
4461 static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx));
4462 static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx));
4463 static rtx alphaev4_next_group PROTO((rtx, int*, int*));
4464 static rtx alphaev5_next_group PROTO((rtx, int*, int*));
4465 static rtx alphaev4_next_nop PROTO((int*));
4466 static rtx alphaev5_next_nop PROTO((int*));
4468 static void alpha_align_insns
4469 PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4471 static enum alphaev4_pipe
4472 alphaev4_insn_pipe (insn)
4475 if (recog_memoized (insn) < 0)
4477 if (get_attr_length (insn) != 4)
4480 switch (get_attr_type (insn))
4513 static enum alphaev5_pipe
4514 alphaev5_insn_pipe (insn)
4517 if (recog_memoized (insn) < 0)
4519 if (get_attr_length (insn) != 4)
4522 switch (get_attr_type (insn))
4562 /* IN_USE is a mask of the slots currently filled within the insn group.
4563 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4564 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4566 LEN is, of course, the length of the group in bytes. */
4569 alphaev4_next_group (insn, pin_use, plen)
4571 int *pin_use, *plen;
4577 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4578 || GET_CODE (PATTERN (insn)) == CLOBBER
4579 || GET_CODE (PATTERN (insn)) == USE)
4584 enum alphaev4_pipe pipe;
4586 pipe = alphaev4_insn_pipe (insn);
4590 /* Force complex instructions to start new groups. */
4594 /* If this is a completely unrecognized insn, its an asm.
4595 We don't know how long it is, so record length as -1 to
4596 signal a needed realignment. */
4597 if (recog_memoized (insn) < 0)
4600 len = get_attr_length (insn);
4604 if (in_use & EV4_IB0)
4606 if (in_use & EV4_IB1)
4611 in_use |= EV4_IB0 | EV4_IBX;
4615 if (in_use & EV4_IB0)
4617 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4625 if (in_use & EV4_IB1)
4635 /* Haifa doesn't do well scheduling branches. */
4636 if (GET_CODE (insn) == JUMP_INSN)
4640 insn = next_nonnote_insn (insn);
4642 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4645 /* Let Haifa tell us where it thinks insn group boundaries are. */
4646 if (GET_MODE (insn) == TImode)
4649 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4654 insn = next_nonnote_insn (insn);
4662 /* IN_USE is a mask of the slots currently filled within the insn group.
4663 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4664 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4666 LEN is, of course, the length of the group in bytes. */
4669 alphaev5_next_group (insn, pin_use, plen)
4671 int *pin_use, *plen;
4677 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4678 || GET_CODE (PATTERN (insn)) == CLOBBER
4679 || GET_CODE (PATTERN (insn)) == USE)
4684 enum alphaev5_pipe pipe;
4686 pipe = alphaev5_insn_pipe (insn);
4690 /* Force complex instructions to start new groups. */
4694 /* If this is a completely unrecognized insn, its an asm.
4695 We don't know how long it is, so record length as -1 to
4696 signal a needed realignment. */
4697 if (recog_memoized (insn) < 0)
4700 len = get_attr_length (insn);
4703 /* ??? Most of the places below, we would like to abort, as
4704 it would indicate an error either in Haifa, or in the
4705 scheduling description. Unfortunately, Haifa never
4706 schedules the last instruction of the BB, so we don't
4707 have an accurate TI bit to go off. */
4709 if (in_use & EV5_E0)
4711 if (in_use & EV5_E1)
4716 in_use |= EV5_E0 | EV5_E01;
4720 if (in_use & EV5_E0)
4722 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4730 if (in_use & EV5_E1)
4736 if (in_use & EV5_FA)
4738 if (in_use & EV5_FM)
4743 in_use |= EV5_FA | EV5_FAM;
4747 if (in_use & EV5_FA)
4753 if (in_use & EV5_FM)
4766 /* Haifa doesn't do well scheduling branches. */
4767 /* ??? If this is predicted not-taken, slotting continues, except
4768 that no more IBR, FBR, or JSR insns may be slotted. */
4769 if (GET_CODE (insn) == JUMP_INSN)
4773 insn = next_nonnote_insn (insn);
4775 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4778 /* Let Haifa tell us where it thinks insn group boundaries are. */
4779 if (GET_MODE (insn) == TImode)
4782 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4787 insn = next_nonnote_insn (insn);
4796 alphaev4_next_nop (pin_use)
4799 int in_use = *pin_use;
4802 if (!(in_use & EV4_IB0))
4807 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
4812 else if (TARGET_FP && !(in_use & EV4_IB1))
4825 alphaev5_next_nop (pin_use)
4828 int in_use = *pin_use;
4831 if (!(in_use & EV5_E1))
4836 else if (TARGET_FP && !(in_use & EV5_FA))
4841 else if (TARGET_FP && !(in_use & EV5_FM))
4853 /* The instruction group alignment main loop. */
4856 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
4859 rtx (*next_group) PROTO((rtx, int*, int*));
4860 rtx (*next_nop) PROTO((int*));
4863 /* ALIGN is the known alignment for the insn group. */
4865 /* OFS is the offset of the current insn in the insn group. */
4867 int prev_in_use, in_use, len;
4870 /* Let shorten branches care for assigning alignments to code labels. */
4871 shorten_branches (insns);
4873 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
4874 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
4876 /* Account for the initial GP load, which happens before the scheduled
4877 prologue we emitted as RTL. */
4878 ofs = prev_in_use = 0;
4879 if (alpha_does_function_need_gp())
4881 ofs = 8 & (align - 1);
4882 prev_in_use = gp_in_use;
4886 if (GET_CODE (i) == NOTE)
4887 i = next_nonnote_insn (i);
4891 next = (*next_group)(i, &in_use, &len);
4893 /* When we see a label, resync alignment etc. */
4894 if (GET_CODE (i) == CODE_LABEL)
4896 int new_align = 1 << label_to_alignment (i);
4897 if (new_align >= align)
4899 align = new_align < max_align ? new_align : max_align;
4902 else if (ofs & (new_align-1))
4903 ofs = (ofs | (new_align-1)) + 1;
4908 /* Handle complex instructions special. */
4909 else if (in_use == 0)
4911 /* Asms will have length < 0. This is a signal that we have
4912 lost alignment knowledge. Assume, however, that the asm
4913 will not mis-align instructions. */
4922 /* If the known alignment is smaller than the recognized insn group,
4923 realign the output. */
4924 else if (align < len)
4926 int new_log_align = len > 8 ? 4 : 3;
4929 where = prev_nonnote_insn (i);
4930 if (!where || GET_CODE (where) != CODE_LABEL)
4933 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4934 align = 1 << new_log_align;
4938 /* If the group won't fit in the same INT16 as the previous,
4939 we need to add padding to keep the group together. Rather
4940 than simply leaving the insn filling to the assembler, we
4941 can make use of the knowledge of what sorts of instructions
4942 were issued in the previous group to make sure that all of
4943 the added nops are really free. */
4944 else if (ofs + len > align)
4946 int nop_count = (align - ofs) / 4;
4949 /* Insert nops before labels and branches to truely merge the
4950 execution of the nops with the previous instruction group. */
4951 where = prev_nonnote_insn (i);
4954 if (GET_CODE (where) == CODE_LABEL)
4956 rtx where2 = prev_nonnote_insn (where);
4957 if (where2 && GET_CODE (where2) == JUMP_INSN)
4960 else if (GET_CODE (where) != JUMP_INSN)
4967 emit_insn_before ((*next_nop)(&prev_in_use), where);
4968 while (--nop_count);
4972 ofs = (ofs + len) & (align - 1);
4973 prev_in_use = in_use;
4979 /* Machine dependant reorg pass. */
4985 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4986 alpha_handle_trap_shadows (insns);
4989 /* Due to the number of extra trapb insns, don't bother fixing up
4990 alignment when trap precision is instruction. Moreover, we can
4991 only do our job when sched2 is run and Haifa is our scheduler. */
4992 if (optimize && !optimize_size
4993 && alpha_tp != ALPHA_TP_INSN
4994 && flag_schedule_insns_after_reload)
4996 if (alpha_cpu == PROCESSOR_EV4)
4997 alpha_align_insns (insns, 8, alphaev4_next_group,
4998 alphaev4_next_nop, EV4_IB0);
4999 else if (alpha_cpu == PROCESSOR_EV5)
5000 alpha_align_insns (insns, 16, alphaev5_next_group,
5001 alphaev5_next_nop, EV5_E01 | EV5_E0);
5007 /* Check a floating-point value for validity for a particular machine mode. */
5009 static char * const float_strings[] =
5011 /* These are for FLOAT_VAX. */
5012 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5013 "-1.70141173319264430e+38",
5014 "2.93873587705571877e-39", /* 2^-128 */
5015 "-2.93873587705571877e-39",
5016 /* These are for the default broken IEEE mode, which traps
5017 on infinity or denormal numbers. */
5018 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5019 "-3.402823466385288598117e+38",
5020 "1.1754943508222875079687e-38", /* 2^-126 */
5021 "-1.1754943508222875079687e-38",
5024 static REAL_VALUE_TYPE float_values[8];
5025 static int inited_float_values = 0;
5028 check_float_value (mode, d, overflow)
5029 enum machine_mode mode;
5031 int overflow ATTRIBUTE_UNUSED;
5034 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5037 if (inited_float_values == 0)
5040 for (i = 0; i < 8; i++)
5041 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5043 inited_float_values = 1;
5049 REAL_VALUE_TYPE *fvptr;
5051 if (TARGET_FLOAT_VAX)
5052 fvptr = &float_values[0];
5054 fvptr = &float_values[4];
5056 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5057 if (REAL_VALUES_LESS (fvptr[0], r))
5059 bcopy ((char *) &fvptr[0], (char *) d,
5060 sizeof (REAL_VALUE_TYPE));
5063 else if (REAL_VALUES_LESS (r, fvptr[1]))
5065 bcopy ((char *) &fvptr[1], (char *) d,
5066 sizeof (REAL_VALUE_TYPE));
5069 else if (REAL_VALUES_LESS (dconst0, r)
5070 && REAL_VALUES_LESS (r, fvptr[2]))
5072 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5075 else if (REAL_VALUES_LESS (r, dconst0)
5076 && REAL_VALUES_LESS (fvptr[3], r))
5078 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5088 /* Return the VMS argument type corresponding to MODE. */
5091 alpha_arg_type (mode)
5092 enum machine_mode mode;
5097 return TARGET_FLOAT_VAX ? FF : FS;
5099 return TARGET_FLOAT_VAX ? FD : FT;
5105 /* Return an rtx for an integer representing the VMS Argument Information
5109 alpha_arg_info_reg_val (cum)
5110 CUMULATIVE_ARGS cum;
5112 unsigned HOST_WIDE_INT regval = cum.num_args;
5115 for (i = 0; i < 6; i++)
5116 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5118 return GEN_INT (regval);
5121 /* Structure to collect function names for final output
5124 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5127 struct alpha_links {
5128 struct alpha_links *next;
5130 enum links_kind kind;
5133 static struct alpha_links *alpha_links_base = 0;
5135 /* Make (or fake) .linkage entry for function call.
5137 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5140 alpha_need_linkage (name, is_local)
5145 struct alpha_links *lptr, *nptr;
5150 /* Is this name already defined ? */
5152 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5153 if (strcmp (lptr->name, name) == 0)
5157 /* Defined here but external assumed. */
5158 if (lptr->kind == KIND_EXTERN)
5159 lptr->kind = KIND_LOCAL;
5163 /* Used here but unused assumed. */
5164 if (lptr->kind == KIND_UNUSED)
5165 lptr->kind = KIND_LOCAL;
5170 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5171 nptr->next = alpha_links_base;
5172 nptr->name = xstrdup (name);
5174 /* Assume external if no definition. */
5175 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5177 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5178 get_identifier (name);
5180 alpha_links_base = nptr;
5187 alpha_write_linkage (stream)
5190 struct alpha_links *lptr, *nptr;
5192 readonly_section ();
5194 fprintf (stream, "\t.align 3\n");
5196 for (lptr = alpha_links_base; lptr; lptr = nptr)
5200 if (lptr->kind == KIND_UNUSED
5201 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5204 fprintf (stream, "$%s..lk:\n", lptr->name);
5205 if (lptr->kind == KIND_LOCAL)
5207 /* Local and used, build linkage pair. */
5208 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5209 fprintf (stream, "\t.quad %s\n", lptr->name);
5212 /* External and used, request linkage pair. */
5213 fprintf (stream, "\t.linkage %s\n", lptr->name);
5220 alpha_need_linkage (name, is_local)
5221 char *name ATTRIBUTE_UNUSED;
5222 int is_local ATTRIBUTE_UNUSED;
5226 #endif /* OPEN_VMS */