1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 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 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 char *alpha_cpu_string; /* -mcpu= */
71 char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
72 char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
73 char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
74 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);
622 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
626 current_file_function_operand (op, mode)
628 enum machine_mode mode ATTRIBUTE_UNUSED;
630 return (GET_CODE (op) == SYMBOL_REF
631 && ! profile_flag && ! profile_block_flag
632 && (SYMBOL_REF_FLAG (op)
633 || op == XEXP (DECL_RTL (current_function_decl), 0)));
636 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
639 call_operand (op, mode)
641 enum machine_mode mode;
646 return (GET_CODE (op) == SYMBOL_REF
647 || (GET_CODE (op) == REG
648 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
651 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
652 comparisons are valid in which insn. */
655 alpha_comparison_operator (op, mode)
657 enum machine_mode mode;
659 enum rtx_code code = GET_CODE (op);
661 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
664 return (code == EQ || code == LE || code == LT
665 || (mode == DImode && (code == LEU || code == LTU)));
668 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
671 alpha_swapped_comparison_operator (op, mode)
673 enum machine_mode mode;
675 enum rtx_code code = GET_CODE (op);
677 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
680 code = swap_condition (code);
681 return (code == EQ || code == LE || code == LT
682 || (mode == DImode && (code == LEU || code == LTU)));
685 /* Return 1 if OP is a signed comparison operation. */
688 signed_comparison_operator (op, mode)
690 enum machine_mode mode ATTRIBUTE_UNUSED;
692 switch (GET_CODE (op))
694 case EQ: case NE: case LE: case LT: case GE: case GT:
704 /* Return 1 if this is a divide or modulus operator. */
707 divmod_operator (op, mode)
709 enum machine_mode mode ATTRIBUTE_UNUSED;
711 switch (GET_CODE (op))
713 case DIV: case MOD: case UDIV: case UMOD:
723 /* Return 1 if this memory address is a known aligned register plus
724 a constant. It must be a valid address. This means that we can do
725 this as an aligned reference plus some offset.
727 Take into account what reload will do.
729 We could say that out-of-range stack slots are alignable, but that would
730 complicate get_aligned_mem and it isn't worth the trouble since few
731 functions have large stack space. */
734 aligned_memory_operand (op, mode)
736 enum machine_mode mode;
738 if (GET_CODE (op) == SUBREG)
740 if (GET_MODE (op) != mode)
742 op = SUBREG_REG (op);
743 mode = GET_MODE (op);
746 if (reload_in_progress && GET_CODE (op) == REG
747 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
748 op = reg_equiv_mem[REGNO (op)];
750 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
751 || ! memory_address_p (mode, XEXP (op, 0)))
756 if (GET_CODE (op) == PLUS)
759 return (GET_CODE (op) == REG
760 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
763 /* Similar, but return 1 if OP is a MEM which is not alignable. */
766 unaligned_memory_operand (op, mode)
768 enum machine_mode mode;
770 if (GET_CODE (op) == SUBREG)
772 if (GET_MODE (op) != mode)
774 op = SUBREG_REG (op);
775 mode = GET_MODE (op);
778 if (reload_in_progress && GET_CODE (op) == REG
779 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
780 op = reg_equiv_mem[REGNO (op)];
782 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
787 if (! memory_address_p (mode, op))
790 if (GET_CODE (op) == PLUS)
793 return (GET_CODE (op) != REG
794 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
797 /* Return 1 if OP is either a register or an unaligned memory location. */
800 reg_or_unaligned_mem_operand (op, mode)
802 enum machine_mode mode;
804 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
807 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
810 any_memory_operand (op, mode)
812 enum machine_mode mode ATTRIBUTE_UNUSED;
814 return (GET_CODE (op) == MEM
815 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
816 || (reload_in_progress && GET_CODE (op) == REG
817 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
818 || (reload_in_progress && GET_CODE (op) == SUBREG
819 && GET_CODE (SUBREG_REG (op)) == REG
820 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
823 /* Returns 1 if OP is not an eliminable register.
825 This exists to cure a pathological abort in the s8addq (et al) patterns,
827 long foo () { long t; bar(); return (long) &t * 26107; }
829 which run afoul of a hack in reload to cure a (presumably) similar
830 problem with lea-type instructions on other targets. But there is
831 one of us and many of them, so work around the problem by selectively
832 preventing combine from making the optimization. */
835 reg_not_elim_operand (op, mode)
837 enum machine_mode mode;
840 if (GET_CODE (op) == SUBREG)
841 inner = SUBREG_REG (op);
842 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
845 return register_operand (op, mode);
848 /* Return 1 if this function can directly return via $26. */
853 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
854 && get_frame_size () == 0
855 && current_function_outgoing_args_size == 0
856 && current_function_pretend_args_size == 0);
859 /* REF is an alignable memory location. Place an aligned SImode
860 reference into *PALIGNED_MEM and the number of bits to shift into
864 get_aligned_mem (ref, paligned_mem, pbitnum)
866 rtx *paligned_mem, *pbitnum;
869 HOST_WIDE_INT offset = 0;
871 if (GET_CODE (ref) == SUBREG)
873 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
874 if (BYTES_BIG_ENDIAN)
875 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
876 - MIN (UNITS_PER_WORD,
877 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
878 ref = SUBREG_REG (ref);
881 if (GET_CODE (ref) == REG)
882 ref = reg_equiv_mem[REGNO (ref)];
884 if (reload_in_progress)
885 base = find_replacement (&XEXP (ref, 0));
887 base = XEXP (ref, 0);
889 if (GET_CODE (base) == PLUS)
890 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
892 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
893 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
894 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
895 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
897 /* Sadly, we cannot use alias sets here because we may overlap other
898 data in a different alias set. */
899 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
901 *pbitnum = GEN_INT ((offset & 3) * 8);
904 /* Similar, but just get the address. Handle the two reload cases.
905 Add EXTRA_OFFSET to the address we return. */
908 get_unaligned_address (ref, extra_offset)
913 HOST_WIDE_INT offset = 0;
915 if (GET_CODE (ref) == SUBREG)
917 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
918 if (BYTES_BIG_ENDIAN)
919 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
920 - MIN (UNITS_PER_WORD,
921 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
922 ref = SUBREG_REG (ref);
925 if (GET_CODE (ref) == REG)
926 ref = reg_equiv_mem[REGNO (ref)];
928 if (reload_in_progress)
929 base = find_replacement (&XEXP (ref, 0));
931 base = XEXP (ref, 0);
933 if (GET_CODE (base) == PLUS)
934 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
936 return plus_constant (base, offset + extra_offset);
939 /* Subfunction of the following function. Update the flags of any MEM
940 found in part of X. */
943 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
945 int in_struct_p, volatile_p, unchanging_p;
949 switch (GET_CODE (x))
953 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
954 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
959 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
964 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
966 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
971 MEM_IN_STRUCT_P (x) = in_struct_p;
972 MEM_VOLATILE_P (x) = volatile_p;
973 RTX_UNCHANGING_P (x) = unchanging_p;
974 /* Sadly, we cannot use alias sets because the extra aliasing
975 produced by the AND interferes. Given that two-byte quantities
976 are the only thing we would be able to differentiate anyway,
977 there does not seem to be any point in convoluting the early
978 out of the alias check. */
979 /* MEM_ALIAS_SET (x) = alias_set; */
987 /* Given INSN, which is either an INSN or a SEQUENCE generated to
988 perform a memory operation, look for any MEMs in either a SET_DEST or
989 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
990 REF into each of the MEMs found. If REF is not a MEM, don't do
994 alpha_set_memflags (insn, ref)
998 int in_struct_p, volatile_p, unchanging_p;
1000 if (GET_CODE (ref) != MEM)
1003 in_struct_p = MEM_IN_STRUCT_P (ref);
1004 volatile_p = MEM_VOLATILE_P (ref);
1005 unchanging_p = RTX_UNCHANGING_P (ref);
1007 /* This is only called from alpha.md, after having had something
1008 generated from one of the insn patterns. So if everything is
1009 zero, the pattern is already up-to-date. */
1010 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1013 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1016 /* Try to output insns to set TARGET equal to the constant C if it can be
1017 done in less than N insns. Do all computations in MODE. Returns the place
1018 where the output has been placed if it can be done and the insns have been
1019 emitted. If it would take more than N insns, zero is returned and no
1020 insns and emitted. */
1023 alpha_emit_set_const (target, mode, c, n)
1025 enum machine_mode mode;
1032 /* Try 1 insn, then 2, then up to N. */
1033 for (i = 1; i <= n; i++)
1034 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1040 /* Internal routine for the above to check for N or below insns. */
1043 alpha_emit_set_const_1 (target, mode, c, n)
1045 enum machine_mode mode;
1049 HOST_WIDE_INT new = c;
1051 /* Use a pseudo if highly optimizing and still generating RTL. */
1053 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1057 #if HOST_BITS_PER_WIDE_INT == 64
1058 /* We are only called for SImode and DImode. If this is SImode, ensure that
1059 we are sign extended to a full word. This does not make any sense when
1060 cross-compiling on a narrow machine. */
1063 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1066 /* If this is a sign-extended 32-bit constant, we can do this in at most
1067 three insns, so do it if we have enough insns left. We always have
1068 a sign-extended 32-bit constant when compiling on a narrow machine. */
1070 if (HOST_BITS_PER_WIDE_INT != 64
1071 || c >> 31 == -1 || c >> 31 == 0)
1073 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1074 HOST_WIDE_INT tmp1 = c - low;
1076 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1077 HOST_WIDE_INT extra = 0;
1079 /* If HIGH will be interpreted as negative but the constant is
1080 positive, we must adjust it to do two ldha insns. */
1082 if ((high & 0x8000) != 0 && c >= 0)
1086 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1089 if (c == low || (low == 0 && extra == 0))
1091 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1092 but that meant that we can't handle INT_MIN on 32-bit machines
1093 (like NT/Alpha), because we recurse indefinitely through
1094 emit_move_insn to gen_movdi. So instead, since we know exactly
1095 what we want, create it explicitly. */
1098 target = gen_reg_rtx (mode);
1099 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1102 else if (n >= 2 + (extra != 0))
1104 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1107 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1108 subtarget, 0, OPTAB_WIDEN);
1110 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1111 target, 0, OPTAB_WIDEN);
1115 /* If we couldn't do it that way, try some other methods. But if we have
1116 no instructions left, don't bother. Likewise, if this is SImode and
1117 we can't make pseudos, we can't do anything since the expand_binop
1118 and expand_unop calls will widen and try to make pseudos. */
1121 || (mode == SImode && ! rtx_equal_function_value_matters))
1124 #if HOST_BITS_PER_WIDE_INT == 64
1125 /* First, see if can load a value into the target that is the same as the
1126 constant except that all bytes that are 0 are changed to be 0xff. If we
1127 can, then we can do a ZAPNOT to obtain the desired constant. */
1129 for (i = 0; i < 64; i += 8)
1130 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1131 new |= (HOST_WIDE_INT) 0xff << i;
1133 /* We are only called for SImode and DImode. If this is SImode, ensure that
1134 we are sign extended to a full word. */
1137 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1140 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1141 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1142 target, 0, OPTAB_WIDEN);
1145 /* Next, see if we can load a related constant and then shift and possibly
1146 negate it to get the constant we want. Try this once each increasing
1147 numbers of insns. */
1149 for (i = 1; i < n; i++)
1151 /* First try complementing. */
1152 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1153 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1155 /* Next try to form a constant and do a left shift. We can do this
1156 if some low-order bits are zero; the exact_log2 call below tells
1157 us that information. The bits we are shifting out could be any
1158 value, but here we'll just try the 0- and sign-extended forms of
1159 the constant. To try to increase the chance of having the same
1160 constant in more than one insn, start at the highest number of
1161 bits to shift, but try all possibilities in case a ZAPNOT will
1164 if ((bits = exact_log2 (c & - c)) > 0)
1165 for (; bits > 0; bits--)
1166 if ((temp = (alpha_emit_set_const
1168 (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1169 || ((temp = (alpha_emit_set_const
1171 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1173 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1174 target, 0, OPTAB_WIDEN);
1176 /* Now try high-order zero bits. Here we try the shifted-in bits as
1177 all zero and all ones. Be careful to avoid shifting outside the
1178 mode and to avoid shifting outside the host wide int size. */
1179 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1180 confuse the recursive call and set all of the high 32 bits. */
1182 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1183 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1184 for (; bits > 0; bits--)
1185 if ((temp = alpha_emit_set_const (subtarget, mode,
1187 || ((temp = (alpha_emit_set_const
1189 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1192 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1193 target, 1, OPTAB_WIDEN);
1195 /* Now try high-order 1 bits. We get that with a sign-extension.
1196 But one bit isn't enough here. Be careful to avoid shifting outside
1197 the mode and to avoid shifting outside the host wide int size. */
1199 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1200 - floor_log2 (~ c) - 2)) > 0)
1201 for (; bits > 0; bits--)
1202 if ((temp = alpha_emit_set_const (subtarget, mode,
1204 || ((temp = (alpha_emit_set_const
1206 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1209 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1210 target, 0, OPTAB_WIDEN);
1216 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1217 fall back to a straight forward decomposition. We do this to avoid
1218 exponential run times encountered when looking for longer sequences
1219 with alpha_emit_set_const. */
1222 alpha_emit_set_long_const (target, c1, c2)
1224 HOST_WIDE_INT c1, c2;
1226 HOST_WIDE_INT d1, d2, d3, d4;
1228 /* Decompose the entire word */
1229 #if HOST_BITS_PER_WIDE_INT >= 64
1230 if (c2 != -(c1 < 0))
1232 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1234 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1235 c1 = (c1 - d2) >> 32;
1236 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1238 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1242 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1244 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1248 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1250 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1255 /* Construct the high word */
1258 emit_move_insn (target, GEN_INT (d4));
1260 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1263 emit_move_insn (target, GEN_INT (d3));
1265 /* Shift it into place */
1266 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1268 /* Add in the low bits. */
1270 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1272 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1277 /* Generate the comparison for a conditional branch. */
1280 alpha_emit_conditional_branch (code)
1283 enum rtx_code cmp_code, branch_code;
1284 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1285 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1288 /* The general case: fold the comparison code to the types of compares
1289 that we have, choosing the branch as necessary. */
1292 case EQ: case LE: case LT: case LEU: case LTU:
1293 /* We have these compares: */
1294 cmp_code = code, branch_code = NE;
1298 /* This must be reversed. */
1299 cmp_code = EQ, branch_code = EQ;
1302 case GE: case GT: case GEU: case GTU:
1303 /* For FP, we swap them, for INT, we reverse them. */
1304 if (alpha_compare_fp_p)
1306 cmp_code = swap_condition (code);
1308 tem = op0, op0 = op1, op1 = tem;
1312 cmp_code = reverse_condition (code);
1321 if (alpha_compare_fp_p)
1326 /* When we are not as concerned about non-finite values, and we
1327 are comparing against zero, we can branch directly. */
1328 if (op1 == CONST0_RTX (DFmode))
1329 cmp_code = NIL, branch_code = code;
1330 else if (op0 == CONST0_RTX (DFmode))
1332 /* Undo the swap we probably did just above. */
1333 tem = op0, op0 = op1, op1 = tem;
1334 branch_code = swap_condition (cmp_code);
1340 /* ??? We mark the the branch mode to be CCmode to prevent the
1341 compare and branch from being combined, since the compare
1342 insn follows IEEE rules that the branch does not. */
1343 branch_mode = CCmode;
1350 /* The following optimizations are only for signed compares. */
1351 if (code != LEU && code != LTU && code != GEU && code != GTU)
1353 /* Whee. Compare and branch against 0 directly. */
1354 if (op1 == const0_rtx)
1355 cmp_code = NIL, branch_code = code;
1357 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1358 bypass between logicals and br/cmov on EV5. But we don't want to
1359 force valid immediate constants into registers needlessly. */
1360 else if (GET_CODE (op1) == CONST_INT)
1362 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1364 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1365 && (CONST_OK_FOR_LETTER_P (n, 'K')
1366 || CONST_OK_FOR_LETTER_P (n, 'L')))
1368 cmp_code = PLUS, branch_code = code;
1375 /* Force op0 into a register. */
1376 if (GET_CODE (op0) != REG)
1377 op0 = force_reg (cmp_mode, op0);
1379 /* Emit an initial compare instruction, if necessary. */
1381 if (cmp_code != NIL)
1383 tem = gen_reg_rtx (cmp_mode);
1384 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1387 /* Return the branch comparison. */
1388 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1392 /* Rewrite a comparison against zero CMP of the form
1393 (CODE (cc0) (const_int 0)) so it can be written validly in
1394 a conditional move (if_then_else CMP ...).
1395 If both of the operands that set cc0 are non-zero we must emit
1396 an insn to perform the compare (it can't be done within
1397 the conditional move). */
1399 alpha_emit_conditional_move (cmp, mode)
1401 enum machine_mode mode;
1403 enum rtx_code code = GET_CODE (cmp);
1404 enum rtx_code cmov_code = NE;
1405 rtx op0 = alpha_compare_op0;
1406 rtx op1 = alpha_compare_op1;
1407 enum machine_mode cmp_mode
1408 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1409 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1410 enum machine_mode cmov_mode = VOIDmode;
1413 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1416 /* We may be able to use a conditional move directly.
1417 This avoids emitting spurious compares. */
1418 if (signed_comparison_operator (cmp, cmp_op_mode)
1419 && (!alpha_compare_fp_p || flag_fast_math)
1420 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1421 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1423 /* We can't put the comparison insides a conditional move;
1424 emit a compare instruction and put that inside the
1425 conditional move. Make sure we emit only comparisons we have;
1426 swap or reverse as necessary. */
1430 case EQ: case LE: case LT: case LEU: case LTU:
1431 /* We have these compares: */
1435 /* This must be reversed. */
1436 code = reverse_condition (code);
1440 case GE: case GT: case GEU: case GTU:
1441 /* These must be swapped. Make sure the new first operand is in
1443 code = swap_condition (code);
1444 tem = op0, op0 = op1, op1 = tem;
1445 op0 = force_reg (cmp_mode, op0);
1452 /* ??? We mark the branch mode to be CCmode to prevent the compare
1453 and cmov from being combined, since the compare insn follows IEEE
1454 rules that the cmov does not. */
1455 if (alpha_compare_fp_p && !flag_fast_math)
1458 tem = gen_reg_rtx (cmp_op_mode);
1459 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1460 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1463 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1467 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1468 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1469 lda r3,X(r11) lda r3,X+2(r11)
1470 extwl r1,r3,r1 extql r1,r3,r1
1471 extwh r2,r3,r2 extqh r2,r3,r2
1472 or r1.r2.r1 or r1,r2,r1
1475 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1476 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1477 lda r3,X(r11) lda r3,X(r11)
1478 extll r1,r3,r1 extll r1,r3,r1
1479 extlh r2,r3,r2 extlh r2,r3,r2
1480 or r1.r2.r1 addl r1,r2,r1
1482 quad: ldq_u r1,X(r11)
1491 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1493 HOST_WIDE_INT size, ofs;
1496 rtx meml, memh, addr, extl, exth;
1497 enum machine_mode mode;
1499 meml = gen_reg_rtx (DImode);
1500 memh = gen_reg_rtx (DImode);
1501 addr = gen_reg_rtx (DImode);
1502 extl = gen_reg_rtx (DImode);
1503 exth = gen_reg_rtx (DImode);
1505 emit_move_insn (meml,
1506 change_address (mem, DImode,
1507 gen_rtx_AND (DImode,
1508 plus_constant (XEXP (mem, 0),
1512 emit_move_insn (memh,
1513 change_address (mem, DImode,
1514 gen_rtx_AND (DImode,
1515 plus_constant (XEXP (mem, 0),
1519 if (sign && size == 2)
1521 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1523 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1524 emit_insn (gen_extqh (exth, memh, addr));
1526 /* We must use tgt here for the target. Alpha-vms port fails if we use
1527 addr for the target, because addr is marked as a pointer and combine
1528 knows that pointers are always sign-extended 32 bit values. */
1529 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1530 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1531 addr, 1, OPTAB_WIDEN);
1535 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1536 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1540 emit_insn (gen_extwh (exth, memh, addr));
1545 emit_insn (gen_extlh (exth, memh, addr));
1550 emit_insn (gen_extqh (exth, memh, addr));
1555 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1556 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1561 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1564 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1567 alpha_expand_unaligned_store (dst, src, size, ofs)
1569 HOST_WIDE_INT size, ofs;
1571 rtx dstl, dsth, addr, insl, insh, meml, memh;
1573 dstl = gen_reg_rtx (DImode);
1574 dsth = gen_reg_rtx (DImode);
1575 insl = gen_reg_rtx (DImode);
1576 insh = gen_reg_rtx (DImode);
1578 meml = change_address (dst, DImode,
1579 gen_rtx_AND (DImode,
1580 plus_constant (XEXP (dst, 0), ofs),
1582 memh = change_address (dst, DImode,
1583 gen_rtx_AND (DImode,
1584 plus_constant (XEXP (dst, 0),
1588 emit_move_insn (dsth, memh);
1589 emit_move_insn (dstl, meml);
1590 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1592 if (src != const0_rtx)
1594 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1595 GEN_INT (size*8), addr));
1600 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1603 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1606 emit_insn (gen_insql (insl, src, addr));
1611 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1616 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1619 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1623 #if HOST_BITS_PER_WIDE_INT == 32
1624 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1626 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1628 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1633 if (src != const0_rtx)
1635 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1636 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1639 /* Must store high before low for degenerate case of aligned. */
1640 emit_move_insn (memh, dsth);
1641 emit_move_insn (meml, dstl);
1644 /* The block move code tries to maximize speed by separating loads and
1645 stores at the expense of register pressure: we load all of the data
1646 before we store it back out. There are two secondary effects worth
1647 mentioning, that this speeds copying to/from aligned and unaligned
1648 buffers, and that it makes the code significantly easier to write. */
1650 #define MAX_MOVE_WORDS 8
1652 /* Load an integral number of consecutive unaligned quadwords. */
1655 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1658 HOST_WIDE_INT words, ofs;
1660 rtx const im8 = GEN_INT (-8);
1661 rtx const i64 = GEN_INT (64);
1662 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1666 /* Generate all the tmp registers we need. */
1667 for (i = 0; i < words; ++i)
1669 data_regs[i] = out_regs[i];
1670 ext_tmps[i] = gen_reg_rtx (DImode);
1672 data_regs[words] = gen_reg_rtx (DImode);
1675 smem = change_address (smem, GET_MODE (smem),
1676 plus_constant (XEXP (smem, 0), ofs));
1678 /* Load up all of the source data. */
1679 for (i = 0; i < words; ++i)
1681 emit_move_insn (data_regs[i],
1682 change_address (smem, DImode,
1683 gen_rtx_AND (DImode,
1684 plus_constant (XEXP(smem,0),
1688 emit_move_insn (data_regs[words],
1689 change_address (smem, DImode,
1690 gen_rtx_AND (DImode,
1691 plus_constant (XEXP(smem,0),
1695 /* Extract the half-word fragments. Unfortunately DEC decided to make
1696 extxh with offset zero a noop instead of zeroing the register, so
1697 we must take care of that edge condition ourselves with cmov. */
1699 sreg = copy_addr_to_reg (XEXP (smem, 0));
1700 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1702 for (i = 0; i < words; ++i)
1704 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1706 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1707 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1708 gen_rtx_IF_THEN_ELSE (DImode,
1709 gen_rtx_EQ (DImode, areg,
1711 const0_rtx, ext_tmps[i])));
1714 /* Merge the half-words into whole words. */
1715 for (i = 0; i < words; ++i)
1717 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1718 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1722 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1723 may be NULL to store zeros. */
1726 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1729 HOST_WIDE_INT words, ofs;
1731 rtx const im8 = GEN_INT (-8);
1732 rtx const i64 = GEN_INT (64);
1733 #if HOST_BITS_PER_WIDE_INT == 32
1734 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1736 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1738 rtx ins_tmps[MAX_MOVE_WORDS];
1739 rtx st_tmp_1, st_tmp_2, dreg;
1740 rtx st_addr_1, st_addr_2;
1743 /* Generate all the tmp registers we need. */
1744 if (data_regs != NULL)
1745 for (i = 0; i < words; ++i)
1746 ins_tmps[i] = gen_reg_rtx(DImode);
1747 st_tmp_1 = gen_reg_rtx(DImode);
1748 st_tmp_2 = gen_reg_rtx(DImode);
1751 dmem = change_address (dmem, GET_MODE (dmem),
1752 plus_constant (XEXP (dmem, 0), ofs));
1755 st_addr_2 = change_address (dmem, DImode,
1756 gen_rtx_AND (DImode,
1757 plus_constant (XEXP(dmem,0),
1760 st_addr_1 = change_address (dmem, DImode,
1761 gen_rtx_AND (DImode,
1765 /* Load up the destination end bits. */
1766 emit_move_insn (st_tmp_2, st_addr_2);
1767 emit_move_insn (st_tmp_1, st_addr_1);
1769 /* Shift the input data into place. */
1770 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1771 if (data_regs != NULL)
1773 for (i = words-1; i >= 0; --i)
1775 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1776 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1778 for (i = words-1; i > 0; --i)
1780 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1781 ins_tmps[i-1], ins_tmps[i-1], 1,
1786 /* Split and merge the ends with the destination data. */
1787 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1788 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1790 if (data_regs != NULL)
1792 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1793 st_tmp_2, 1, OPTAB_WIDEN);
1794 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1795 st_tmp_1, 1, OPTAB_WIDEN);
1799 emit_move_insn (st_addr_2, st_tmp_2);
1800 for (i = words-1; i > 0; --i)
1802 emit_move_insn (change_address (dmem, DImode,
1803 gen_rtx_AND (DImode,
1804 plus_constant(XEXP (dmem,0),
1807 data_regs ? ins_tmps[i-1] : const0_rtx);
1809 emit_move_insn (st_addr_1, st_tmp_1);
1813 /* Expand string/block move operations.
1815 operands[0] is the pointer to the destination.
1816 operands[1] is the pointer to the source.
1817 operands[2] is the number of bytes to move.
1818 operands[3] is the alignment. */
1821 alpha_expand_block_move (operands)
1824 rtx bytes_rtx = operands[2];
1825 rtx align_rtx = operands[3];
1826 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
1827 HOST_WIDE_INT bytes = orig_bytes;
1828 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1829 HOST_WIDE_INT dst_align = src_align;
1830 rtx orig_src = operands[1];
1831 rtx orig_dst = operands[0];
1832 rtx data_regs[2*MAX_MOVE_WORDS+16];
1834 int i, words, ofs, nregs = 0;
1838 if (bytes > MAX_MOVE_WORDS*8)
1841 /* Look for additional alignment information from recorded register info. */
1843 tmp = XEXP (orig_src, 0);
1844 if (GET_CODE (tmp) == REG)
1846 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1847 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1849 else if (GET_CODE (tmp) == PLUS
1850 && GET_CODE (XEXP (tmp, 0)) == REG
1851 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1853 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1854 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1858 if (a >= 8 && c % 8 == 0)
1860 else if (a >= 4 && c % 4 == 0)
1862 else if (a >= 2 && c % 2 == 0)
1867 tmp = XEXP (orig_dst, 0);
1868 if (GET_CODE (tmp) == REG)
1870 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1871 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1873 else if (GET_CODE (tmp) == PLUS
1874 && GET_CODE (XEXP (tmp, 0)) == REG
1875 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1877 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1878 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1882 if (a >= 8 && c % 8 == 0)
1884 else if (a >= 4 && c % 4 == 0)
1886 else if (a >= 2 && c % 2 == 0)
1892 * Load the entire block into registers.
1895 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1897 enum machine_mode mode;
1898 tmp = XEXP (XEXP (orig_src, 0), 0);
1900 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
1902 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1904 /* Whee! Optimize the load to use the existing register. */
1905 data_regs[nregs++] = gen_lowpart (mode, tmp);
1909 /* ??? We could potentially be copying 3 bytes or whatnot from
1910 a wider reg. Probably not worth worrying about. */
1911 /* No appropriate mode; fall back on memory. */
1912 orig_src = change_address (orig_src, GET_MODE (orig_src),
1913 copy_addr_to_reg (XEXP (orig_src, 0)));
1917 if (src_align >= 8 && bytes >= 8)
1921 for (i = 0; i < words; ++i)
1922 data_regs[nregs+i] = gen_reg_rtx(DImode);
1924 for (i = 0; i < words; ++i)
1926 emit_move_insn (data_regs[nregs+i],
1927 change_address(orig_src, DImode,
1928 plus_constant (XEXP (orig_src, 0),
1936 if (src_align >= 4 && bytes >= 4)
1940 for (i = 0; i < words; ++i)
1941 data_regs[nregs+i] = gen_reg_rtx(SImode);
1943 for (i = 0; i < words; ++i)
1945 emit_move_insn (data_regs[nregs+i],
1946 change_address(orig_src, SImode,
1947 plus_constant (XEXP (orig_src, 0),
1959 for (i = 0; i < words+1; ++i)
1960 data_regs[nregs+i] = gen_reg_rtx(DImode);
1962 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1968 if (!TARGET_BWX && bytes >= 8)
1970 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1971 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1975 if (!TARGET_BWX && bytes >= 4)
1977 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1978 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1987 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1988 emit_move_insn (tmp,
1989 change_address (orig_src, HImode,
1990 plus_constant (XEXP (orig_src, 0),
1994 } while (bytes >= 2);
1996 else if (!TARGET_BWX)
1998 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1999 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2006 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2007 emit_move_insn (tmp,
2008 change_address (orig_src, QImode,
2009 plus_constant (XEXP (orig_src, 0),
2016 if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2020 * Now save it back out again.
2025 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2027 enum machine_mode mode;
2028 tmp = XEXP (XEXP (orig_dst, 0), 0);
2030 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2031 if (GET_MODE (tmp) == mode && nregs == 1)
2033 emit_move_insn (tmp, data_regs[0]);
2038 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2039 /* ??? Optimize mode < dst_mode with strict_low_part. */
2041 /* No appropriate mode; fall back on memory. We can speed things
2042 up by recognizing extra alignment information. */
2043 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2044 copy_addr_to_reg (XEXP (orig_dst, 0)));
2045 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2048 /* Write out the data in whatever chunks reading the source allowed. */
2051 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2053 emit_move_insn (change_address(orig_dst, DImode,
2054 plus_constant (XEXP (orig_dst, 0),
2063 /* If the source has remaining DImode regs, write them out in
2065 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2067 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2068 NULL_RTX, 1, OPTAB_WIDEN);
2070 emit_move_insn (change_address(orig_dst, SImode,
2071 plus_constant (XEXP (orig_dst, 0),
2073 gen_lowpart (SImode, data_regs[i]));
2074 emit_move_insn (change_address(orig_dst, SImode,
2075 plus_constant (XEXP (orig_dst, 0),
2077 gen_lowpart (SImode, tmp));
2082 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2084 emit_move_insn (change_address(orig_dst, SImode,
2085 plus_constant (XEXP (orig_dst, 0),
2092 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2094 /* Write out a remaining block of words using unaligned methods. */
2096 for (words = 1; i+words < nregs ; ++words)
2097 if (GET_MODE (data_regs[i+words]) != DImode)
2101 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2103 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2109 /* Due to the above, this won't be aligned. */
2110 /* ??? If we have more than one of these, consider constructing full
2111 words in registers and using alpha_expand_unaligned_store_words. */
2112 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2114 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2120 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2122 emit_move_insn (change_address (orig_dst, HImode,
2123 plus_constant (XEXP (orig_dst, 0),
2130 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2132 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2136 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2138 emit_move_insn (change_address (orig_dst, QImode,
2139 plus_constant (XEXP (orig_dst, 0),
2154 alpha_expand_block_clear (operands)
2157 rtx bytes_rtx = operands[1];
2158 rtx align_rtx = operands[2];
2159 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2160 HOST_WIDE_INT align = INTVAL (align_rtx);
2161 rtx orig_dst = operands[0];
2163 HOST_WIDE_INT i, words, ofs = 0;
2167 if (bytes > MAX_MOVE_WORDS*8)
2170 /* Look for stricter alignment. */
2172 tmp = XEXP (orig_dst, 0);
2173 if (GET_CODE (tmp) == REG)
2175 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2176 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2178 else if (GET_CODE (tmp) == PLUS
2179 && GET_CODE (XEXP (tmp, 0)) == REG
2180 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2182 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2183 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2187 if (a >= 8 && c % 8 == 0)
2189 else if (a >= 4 && c % 4 == 0)
2191 else if (a >= 2 && c % 2 == 0)
2196 /* Handle a block of contiguous words first. */
2198 if (align >= 8 && bytes >= 8)
2202 for (i = 0; i < words; ++i)
2204 emit_move_insn (change_address(orig_dst, DImode,
2205 plus_constant (XEXP (orig_dst, 0),
2213 if (align >= 4 && bytes >= 4)
2217 for (i = 0; i < words; ++i)
2219 emit_move_insn (change_address(orig_dst, SImode,
2220 plus_constant (XEXP (orig_dst, 0),
2232 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2238 /* Next clean up any trailing pieces. We know from the contiguous
2239 block move that there are no aligned SImode or DImode hunks left. */
2241 if (!TARGET_BWX && bytes >= 8)
2243 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2247 if (!TARGET_BWX && bytes >= 4)
2249 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2258 emit_move_insn (change_address (orig_dst, HImode,
2259 plus_constant (XEXP (orig_dst, 0),
2264 } while (bytes >= 2);
2266 else if (!TARGET_BWX)
2268 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2275 emit_move_insn (change_address (orig_dst, QImode,
2276 plus_constant (XEXP (orig_dst, 0),
2287 /* Adjust the cost of a scheduling dependency. Return the new cost of
2288 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2291 alpha_adjust_cost (insn, link, dep_insn, cost)
2298 enum attr_type insn_type, dep_insn_type;
2300 /* If the dependence is an anti-dependence, there is no cost. For an
2301 output dependence, there is sometimes a cost, but it doesn't seem
2302 worth handling those few cases. */
2304 if (REG_NOTE_KIND (link) != 0)
2307 /* If we can't recognize the insns, we can't really do anything. */
2308 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2311 insn_type = get_attr_type (insn);
2312 dep_insn_type = get_attr_type (dep_insn);
2314 /* Bring in the user-defined memory latency. */
2315 if (dep_insn_type == TYPE_ILD
2316 || dep_insn_type == TYPE_FLD
2317 || dep_insn_type == TYPE_LDSYM)
2318 cost += alpha_memory_latency-1;
2323 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2324 being stored, we can sometimes lower the cost. */
2326 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2327 && (set = single_set (dep_insn)) != 0
2328 && GET_CODE (PATTERN (insn)) == SET
2329 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2331 switch (dep_insn_type)
2335 /* No savings here. */
2339 /* In these cases, we save one cycle. */
2343 /* In all other cases, we save two cycles. */
2344 return MAX (0, cost - 2);
2348 /* Another case that needs adjustment is an arithmetic or logical
2349 operation. It's cost is usually one cycle, but we default it to
2350 two in the MD file. The only case that it is actually two is
2351 for the address in loads, stores, and jumps. */
2353 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2368 /* The final case is when a compare feeds into an integer branch;
2369 the cost is only one cycle in that case. */
2371 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2376 /* And the lord DEC saith: "A special bypass provides an effective
2377 latency of 0 cycles for an ICMP or ILOG insn producing the test
2378 operand of an IBR or ICMOV insn." */
2380 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2381 && (set = single_set (dep_insn)) != 0)
2383 /* A branch only has one input. This must be it. */
2384 if (insn_type == TYPE_IBR)
2386 /* A conditional move has three, make sure it is the test. */
2387 if (insn_type == TYPE_ICMOV
2388 && GET_CODE (set_src = PATTERN (insn)) == SET
2389 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2390 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2394 /* "The multiplier is unable to receive data from IEU bypass paths.
2395 The instruction issues at the expected time, but its latency is
2396 increased by the time it takes for the input data to become
2397 available to the multiplier" -- which happens in pipeline stage
2398 six, when results are comitted to the register file. */
2400 if (insn_type == TYPE_IMUL)
2402 switch (dep_insn_type)
2404 /* These insns produce their results in pipeline stage five. */
2411 /* Other integer insns produce results in pipeline stage four. */
2419 /* There is additional latency to move the result of (most) FP
2420 operations anywhere but the FP register file. */
2422 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2423 && (dep_insn_type == TYPE_FADD ||
2424 dep_insn_type == TYPE_FMUL ||
2425 dep_insn_type == TYPE_FCMOV))
2431 /* Otherwise, return the default cost. */
2435 /* Functions to save and restore alpha_return_addr_rtx. */
2437 struct machine_function
2443 alpha_save_machine_status (p)
2446 struct machine_function *machine =
2447 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2449 p->machine = machine;
2450 machine->ra_rtx = alpha_return_addr_rtx;
2454 alpha_restore_machine_status (p)
2457 struct machine_function *machine = p->machine;
2459 alpha_return_addr_rtx = machine->ra_rtx;
2462 p->machine = (struct machine_function *)0;
2465 /* Do anything needed before RTL is emitted for each function. */
2468 alpha_init_expanders ()
2470 alpha_return_addr_rtx = NULL_RTX;
2471 alpha_eh_epilogue_sp_ofs = NULL_RTX;
2473 /* Arrange to save and restore machine status around nested functions. */
2474 save_machine_status = alpha_save_machine_status;
2475 restore_machine_status = alpha_restore_machine_status;
2478 /* Start the ball rolling with RETURN_ADDR_RTX. */
2481 alpha_return_addr (count, frame)
2483 rtx frame ATTRIBUTE_UNUSED;
2490 if (alpha_return_addr_rtx)
2491 return alpha_return_addr_rtx;
2493 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2494 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2495 init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
2496 gen_rtx_REG (Pmode, REG_RA));
2498 /* Emit the insn to the prologue with the other argument copies. */
2499 push_topmost_sequence ();
2500 emit_insn_after (init, get_insns ());
2501 pop_topmost_sequence ();
2503 return alpha_return_addr_rtx;
2507 alpha_ra_ever_killed ()
2511 #ifdef ASM_OUTPUT_MI_THUNK
2512 if (current_function_is_thunk)
2515 if (!alpha_return_addr_rtx)
2516 return regs_ever_live[REG_RA];
2518 push_topmost_sequence ();
2520 pop_topmost_sequence ();
2522 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2526 /* Print an operand. Recognize special options, documented below. */
2529 print_operand (file, x, code)
2539 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2540 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2541 mode. alpha_fprm controls which suffix is generated. */
2544 case ALPHA_FPRM_NORM:
2546 case ALPHA_FPRM_MINF:
2549 case ALPHA_FPRM_CHOP:
2552 case ALPHA_FPRM_DYN:
2559 /* Generates trap-mode suffix for instructions that accept the su
2560 suffix only (cmpt et al). */
2561 if (alpha_tp == ALPHA_TP_INSN)
2566 /* Generates trap-mode suffix for instructions that accept the
2567 v and sv suffix. The only instruction that needs this is cvtql. */
2576 case ALPHA_FPTM_SUI:
2583 /* Generates trap-mode suffix for instructions that accept the
2584 v, sv, and svi suffix. The only instruction that needs this
2596 case ALPHA_FPTM_SUI:
2597 fputs ("svi", file);
2603 /* Generates trap-mode suffix for instructions that accept the u, su,
2604 and sui suffix. This is the bulk of the IEEE floating point
2605 instructions (addt et al). */
2616 case ALPHA_FPTM_SUI:
2617 fputs ("sui", file);
2623 /* Generates trap-mode suffix for instructions that accept the sui
2624 suffix (cvtqt and cvtqs). */
2629 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2631 case ALPHA_FPTM_SUI:
2632 fputs ("sui", file);
2638 /* Generates single precision instruction suffix. */
2639 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2643 /* Generates double precision instruction suffix. */
2644 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2648 /* If this operand is the constant zero, write it as "$31". */
2649 if (GET_CODE (x) == REG)
2650 fprintf (file, "%s", reg_names[REGNO (x)]);
2651 else if (x == CONST0_RTX (GET_MODE (x)))
2652 fprintf (file, "$31");
2654 output_operand_lossage ("invalid %%r value");
2659 /* Similar, but for floating-point. */
2660 if (GET_CODE (x) == REG)
2661 fprintf (file, "%s", reg_names[REGNO (x)]);
2662 else if (x == CONST0_RTX (GET_MODE (x)))
2663 fprintf (file, "$f31");
2665 output_operand_lossage ("invalid %%R value");
2670 /* Write the 1's complement of a constant. */
2671 if (GET_CODE (x) != CONST_INT)
2672 output_operand_lossage ("invalid %%N value");
2674 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2678 /* Write 1 << C, for a constant C. */
2679 if (GET_CODE (x) != CONST_INT)
2680 output_operand_lossage ("invalid %%P value");
2682 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2686 /* Write the high-order 16 bits of a constant, sign-extended. */
2687 if (GET_CODE (x) != CONST_INT)
2688 output_operand_lossage ("invalid %%h value");
2690 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2694 /* Write the low-order 16 bits of a constant, sign-extended. */
2695 if (GET_CODE (x) != CONST_INT)
2696 output_operand_lossage ("invalid %%L value");
2698 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2699 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2703 /* Write mask for ZAP insn. */
2704 if (GET_CODE (x) == CONST_DOUBLE)
2706 HOST_WIDE_INT mask = 0;
2707 HOST_WIDE_INT value;
2709 value = CONST_DOUBLE_LOW (x);
2710 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2715 value = CONST_DOUBLE_HIGH (x);
2716 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2719 mask |= (1 << (i + sizeof (int)));
2721 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2724 else if (GET_CODE (x) == CONST_INT)
2726 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2728 for (i = 0; i < 8; i++, value >>= 8)
2732 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2735 output_operand_lossage ("invalid %%m value");
2739 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2740 if (GET_CODE (x) != CONST_INT
2741 || (INTVAL (x) != 8 && INTVAL (x) != 16
2742 && INTVAL (x) != 32 && INTVAL (x) != 64))
2743 output_operand_lossage ("invalid %%M value");
2745 fprintf (file, "%s",
2746 (INTVAL (x) == 8 ? "b"
2747 : INTVAL (x) == 16 ? "w"
2748 : INTVAL (x) == 32 ? "l"
2753 /* Similar, except do it from the mask. */
2754 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2755 fprintf (file, "b");
2756 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2757 fprintf (file, "w");
2758 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2759 fprintf (file, "l");
2760 #if HOST_BITS_PER_WIDE_INT == 32
2761 else if (GET_CODE (x) == CONST_DOUBLE
2762 && CONST_DOUBLE_HIGH (x) == 0
2763 && CONST_DOUBLE_LOW (x) == -1)
2764 fprintf (file, "l");
2765 else if (GET_CODE (x) == CONST_DOUBLE
2766 && CONST_DOUBLE_HIGH (x) == -1
2767 && CONST_DOUBLE_LOW (x) == -1)
2768 fprintf (file, "q");
2770 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
2771 fprintf (file, "q");
2772 else if (GET_CODE (x) == CONST_DOUBLE
2773 && CONST_DOUBLE_HIGH (x) == 0
2774 && CONST_DOUBLE_LOW (x) == -1)
2775 fprintf (file, "q");
2778 output_operand_lossage ("invalid %%U value");
2782 /* Write the constant value divided by 8. */
2783 if (GET_CODE (x) != CONST_INT
2784 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2785 && (INTVAL (x) & 7) != 8)
2786 output_operand_lossage ("invalid %%s value");
2788 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2792 /* Same, except compute (64 - c) / 8 */
2794 if (GET_CODE (x) != CONST_INT
2795 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2796 && (INTVAL (x) & 7) != 8)
2797 output_operand_lossage ("invalid %%s value");
2799 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2802 case 'C': case 'D': case 'c': case 'd':
2803 /* Write out comparison name. */
2805 enum rtx_code c = GET_CODE (x);
2807 if (GET_RTX_CLASS (c) != '<')
2808 output_operand_lossage ("invalid %%C value");
2811 c = reverse_condition (c);
2812 else if (code == 'c')
2813 c = swap_condition (c);
2814 else if (code == 'd')
2815 c = swap_condition (reverse_condition (c));
2818 fprintf (file, "ule");
2820 fprintf (file, "ult");
2822 fprintf (file, "%s", GET_RTX_NAME (c));
2827 /* Write the divide or modulus operator. */
2828 switch (GET_CODE (x))
2831 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2834 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2837 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2840 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2843 output_operand_lossage ("invalid %%E value");
2849 /* Write "_u" for unaligned access. */
2850 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2851 fprintf (file, "_u");
2855 if (GET_CODE (x) == REG)
2856 fprintf (file, "%s", reg_names[REGNO (x)]);
2857 else if (GET_CODE (x) == MEM)
2858 output_address (XEXP (x, 0));
2860 output_addr_const (file, x);
2864 output_operand_lossage ("invalid %%xn code");
2868 /* Emit RTL insns to initialize the variable parts of a trampoline at
2869 TRAMP. FNADDR is an RTX for the address of the function's pure
2870 code. CXT is an RTX for the static chain value for the function.
2872 The three offset parameters are for the individual template's
2873 layout. A JMPOFS < 0 indicates that the trampoline does not
2874 contain instructions at all.
2876 We assume here that a function will be called many more times than
2877 its address is taken (e.g., it might be passed to qsort), so we
2878 take the trouble to initialize the "hint" field in the JMP insn.
2879 Note that the hint field is PC (new) + 4 * bits 13:0. */
2882 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2883 rtx tramp, fnaddr, cxt;
2884 int fnofs, cxtofs, jmpofs;
2886 rtx temp, temp1, addr;
2887 /* ??? Something is wrong with VMS codegen in that we get aborts when
2888 using ptr_mode. Hack around it for now. */
2889 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2891 /* Store function address and CXT. */
2892 addr = memory_address (mode, plus_constant (tramp, fnofs));
2893 emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2894 addr = memory_address (mode, plus_constant (tramp, cxtofs));
2895 emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2897 /* This has been disabled since the hint only has a 32k range, and in
2898 no existing OS is the stack within 32k of the text segment. */
2899 if (0 && jmpofs >= 0)
2901 /* Compute hint value. */
2902 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
2903 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
2905 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
2906 build_int_2 (2, 0), NULL_RTX, 1);
2907 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
2909 /* Merge in the hint. */
2910 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
2911 temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
2912 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
2913 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
2915 emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
2918 #ifdef TRANSFER_FROM_TRAMPOLINE
2919 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
2920 0, VOIDmode, 1, addr, Pmode);
2924 emit_insn (gen_imb ());
2927 /* Do what is necessary for `va_start'. The argument is ignored;
2928 We look at the current function to determine if stdarg or varargs
2929 is used and fill in an initial va_list. A pointer to this constructor
2933 alpha_builtin_saveregs (arglist)
2934 tree arglist ATTRIBUTE_UNUSED;
2936 rtx block, addr, dest, argsize;
2937 tree fntype = TREE_TYPE (current_function_decl);
2938 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2939 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2940 != void_type_node));
2942 /* Compute the current position into the args, taking into account
2943 both registers and memory. Both of these are already included in
2946 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2948 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2949 storing fp arg registers in the first 48 bytes, and the integer arg
2950 registers in the next 48 bytes. This is only done, however, if any
2951 integer registers need to be stored.
2953 If no integer registers need be stored, then we must subtract 48 in
2954 order to account for the integer arg registers which are counted in
2955 argsize above, but which are not actually stored on the stack. */
2957 if (TARGET_OPEN_VMS)
2958 addr = plus_constant (virtual_incoming_args_rtx,
2959 NUM_ARGS <= 5 + stdarg
2960 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2962 addr = (NUM_ARGS <= 5 + stdarg
2963 ? plus_constant (virtual_incoming_args_rtx,
2965 : plus_constant (virtual_incoming_args_rtx,
2966 - (6 * UNITS_PER_WORD)));
2968 /* For VMS, we include the argsize, while on Unix, it's handled as
2969 a separate field. */
2970 if (TARGET_OPEN_VMS)
2971 addr = plus_constant (addr, INTVAL (argsize));
2973 addr = force_operand (addr, NULL_RTX);
2975 #ifdef POINTERS_EXTEND_UNSIGNED
2976 addr = convert_memory_address (ptr_mode, addr);
2979 if (TARGET_OPEN_VMS)
2983 /* Allocate the va_list constructor */
2984 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2985 RTX_UNCHANGING_P (block) = 1;
2986 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2988 /* Store the address of the first integer register in the __base
2991 dest = change_address (block, ptr_mode, XEXP (block, 0));
2992 emit_move_insn (dest, addr);
2994 if (current_function_check_memory_usage)
2995 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2997 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2998 TYPE_MODE (sizetype),
2999 GEN_INT (MEMORY_USE_RW),
3000 TYPE_MODE (integer_type_node));
3002 /* Store the argsize as the __va_offset member. */
3003 dest = change_address (block, TYPE_MODE (integer_type_node),
3004 plus_constant (XEXP (block, 0),
3005 POINTER_SIZE/BITS_PER_UNIT));
3006 emit_move_insn (dest, argsize);
3008 if (current_function_check_memory_usage)
3009 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3011 GEN_INT (GET_MODE_SIZE
3012 (TYPE_MODE (integer_type_node))),
3013 TYPE_MODE (sizetype),
3014 GEN_INT (MEMORY_USE_RW),
3015 TYPE_MODE (integer_type_node));
3017 /* Return the address of the va_list constructor, but don't put it in a
3018 register. Doing so would fail when not optimizing and produce worse
3019 code when optimizing. */
3020 return XEXP (block, 0);
3024 /* This page contains routines that are used to determine what the function
3025 prologue and epilogue code will do and write them out. */
3027 /* Compute the size of the save area in the stack. */
3029 /* These variables are used for communication between the following functions.
3030 They indicate various things about the current function being compiled
3031 that are used to tell what kind of prologue, epilogue and procedure
3032 descriptior to generate. */
3034 /* Nonzero if we need a stack procedure. */
3035 static int vms_is_stack_procedure;
3037 /* Register number (either FP or SP) that is used to unwind the frame. */
3038 static int vms_unwind_regno;
3040 /* Register number used to save FP. We need not have one for RA since
3041 we don't modify it for register procedures. This is only defined
3042 for register frame procedures. */
3043 static int vms_save_fp_regno;
3045 /* Register number used to reference objects off our PV. */
3046 static int vms_base_regno;
3048 /* Compute register masks for saved registers. */
3051 alpha_sa_mask (imaskP, fmaskP)
3052 unsigned long *imaskP;
3053 unsigned long *fmaskP;
3055 unsigned long imask = 0;
3056 unsigned long fmask = 0;
3059 #ifdef ASM_OUTPUT_MI_THUNK
3060 if (!current_function_is_thunk)
3063 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3064 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3066 /* One for every register we have to save. */
3067 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3068 if (! fixed_regs[i] && ! call_used_regs[i]
3069 && regs_ever_live[i] && i != REG_RA)
3074 fmask |= (1L << (i - 32));
3077 if (imask || fmask || alpha_ra_ever_killed ())
3078 imask |= (1L << REG_RA);
3091 #ifdef ASM_OUTPUT_MI_THUNK
3092 if (current_function_is_thunk)
3097 /* One for every register we have to save. */
3098 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3099 if (! fixed_regs[i] && ! call_used_regs[i]
3100 && regs_ever_live[i] && i != REG_RA)
3104 if (TARGET_OPEN_VMS)
3106 /* Start by assuming we can use a register procedure if we don't
3107 make any calls (REG_RA not used) or need to save any
3108 registers and a stack procedure if we do. */
3109 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3111 /* Decide whether to refer to objects off our PV via FP or PV.
3112 If we need FP for something else or if we receive a nonlocal
3113 goto (which expects PV to contain the value), we must use PV.
3114 Otherwise, start by assuming we can use FP. */
3115 vms_base_regno = (frame_pointer_needed
3116 || current_function_has_nonlocal_label
3117 || vms_is_stack_procedure
3118 || current_function_outgoing_args_size
3119 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3121 /* If we want to copy PV into FP, we need to find some register
3122 in which to save FP. */
3124 vms_save_fp_regno = -1;
3125 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3126 for (i = 0; i < 32; i++)
3127 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3128 vms_save_fp_regno = i;
3130 if (vms_save_fp_regno == -1)
3131 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3133 /* Stack unwinding should be done via FP unless we use it for PV. */
3134 vms_unwind_regno = (vms_base_regno == REG_PV
3135 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3137 /* If this is a stack procedure, allow space for saving FP and RA. */
3138 if (vms_is_stack_procedure)
3143 /* If some registers were saved but not RA, RA must also be saved,
3144 so leave space for it. */
3145 if (sa_size != 0 || alpha_ra_ever_killed ())
3148 /* Our size must be even (multiple of 16 bytes). */
3157 alpha_pv_save_size ()
3160 return vms_is_stack_procedure ? 8 : 0;
3167 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3171 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3172 tree decl ATTRIBUTE_UNUSED;
3173 tree attributes ATTRIBUTE_UNUSED;
3177 if (is_attribute_p ("overlaid", identifier))
3178 return (args == NULL_TREE);
3183 alpha_does_function_need_gp ()
3187 /* We never need a GP for Windows/NT or VMS. */
3188 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3191 #ifdef TARGET_PROFILING_NEEDS_GP
3196 #ifdef ASM_OUTPUT_MI_THUNK
3197 if (current_function_is_thunk)
3201 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3202 Even if we are a static function, we still need to do this in case
3203 our address is taken and passed to something like qsort. */
3205 push_topmost_sequence ();
3206 insn = get_insns ();
3207 pop_topmost_sequence ();
3209 for (; insn; insn = NEXT_INSN (insn))
3210 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3211 && GET_CODE (PATTERN (insn)) != USE
3212 && GET_CODE (PATTERN (insn)) != CLOBBER)
3214 enum attr_type type = get_attr_type (insn);
3215 if (type == TYPE_LDSYM || type == TYPE_JSR)
3222 /* Write a version stamp. Don't write anything if we are running as a
3223 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3230 alpha_write_verstamp (file)
3234 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3238 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3242 set_frame_related_p ()
3244 rtx seq = gen_sequence ();
3247 if (GET_CODE (seq) == SEQUENCE)
3249 int i = XVECLEN (seq, 0);
3251 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3252 return emit_insn (seq);
3256 seq = emit_insn (seq);
3257 RTX_FRAME_RELATED_P (seq) = 1;
3262 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3264 /* Write function prologue. */
3266 /* On vms we have two kinds of functions:
3268 - stack frame (PROC_STACK)
3269 these are 'normal' functions with local vars and which are
3270 calling other functions
3271 - register frame (PROC_REGISTER)
3272 keeps all data in registers, needs no stack
3274 We must pass this to the assembler so it can generate the
3275 proper pdsc (procedure descriptor)
3276 This is done with the '.pdesc' command.
3278 On not-vms, we don't really differentiate between the two, as we can
3279 simply allocate stack without saving registers. */
3282 alpha_expand_prologue ()
3284 /* Registers to save. */
3285 unsigned long imask = 0;
3286 unsigned long fmask = 0;
3287 /* Stack space needed for pushing registers clobbered by us. */
3288 HOST_WIDE_INT sa_size;
3289 /* Complete stack size needed. */
3290 HOST_WIDE_INT frame_size;
3291 /* Offset from base reg to register save area. */
3292 HOST_WIDE_INT reg_offset;
3296 sa_size = alpha_sa_size ();
3298 frame_size = get_frame_size ();
3299 if (TARGET_OPEN_VMS)
3300 frame_size = ALPHA_ROUND (sa_size
3301 + (vms_is_stack_procedure ? 8 : 0)
3303 + current_function_pretend_args_size);
3305 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3307 + ALPHA_ROUND (frame_size
3308 + current_function_pretend_args_size));
3310 if (TARGET_OPEN_VMS)
3313 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3315 alpha_sa_mask (&imask, &fmask);
3317 /* Adjust the stack by the frame size. If the frame size is > 4096
3318 bytes, we need to be sure we probe somewhere in the first and last
3319 4096 bytes (we can probably get away without the latter test) and
3320 every 8192 bytes in between. If the frame size is > 32768, we
3321 do this in a loop. Otherwise, we generate the explicit probe
3324 Note that we are only allowed to adjust sp once in the prologue. */
3326 if (frame_size <= 32768)
3328 if (frame_size > 4096)
3333 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3334 while ((probed += 8192) < frame_size);
3336 /* We only have to do this probe if we aren't saving registers. */
3337 if (sa_size == 0 && probed + 4096 < frame_size)
3338 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3341 if (frame_size != 0)
3343 FRP (emit_move_insn (stack_pointer_rtx,
3344 plus_constant (stack_pointer_rtx, -frame_size)));
3349 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3350 number of 8192 byte blocks to probe. We then probe each block
3351 in the loop and then set SP to the proper location. If the
3352 amount remaining is > 4096, we have to do one more probe if we
3353 are not saving any registers. */
3355 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3356 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3357 rtx ptr = gen_rtx_REG (DImode, 22);
3358 rtx count = gen_rtx_REG (DImode, 23);
3360 emit_move_insn (count, GEN_INT (blocks));
3361 emit_move_insn (ptr, plus_constant (stack_pointer_rtx, 4096));
3363 /* Because of the difficulty in emitting a new basic block this
3364 late in the compilation, generate the loop as a single insn. */
3365 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3367 if (leftover > 4096 && sa_size == 0)
3369 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3370 MEM_VOLATILE_P (last) = 1;
3371 emit_move_insn (last, const0_rtx);
3374 ptr = emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
3376 /* This alternative is special, because the DWARF code cannot possibly
3377 intuit through the loop above. So we invent this note it looks at
3379 RTX_FRAME_RELATED_P (ptr) = 1;
3381 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3382 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3383 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3384 GEN_INT (-frame_size))),
3388 /* Cope with very large offsets to the register save area. */
3389 sa_reg = stack_pointer_rtx;
3390 if (reg_offset + sa_size > 0x8000)
3392 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3395 if (low + sa_size <= 0x8000)
3396 bias = reg_offset - low, reg_offset = low;
3398 bias = reg_offset, reg_offset = 0;
3400 sa_reg = gen_rtx_REG (DImode, 24);
3401 FRP (emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias)));
3404 /* Save regs in stack order. Beginning with VMS PV. */
3405 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3407 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3408 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3409 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3412 /* Save register RA next. */
3413 if (imask & (1L << REG_RA))
3415 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3416 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3417 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3418 imask &= ~(1L << REG_RA);
3422 /* Now save any other registers required to be saved. */
3423 for (i = 0; i < 32; i++)
3424 if (imask & (1L << i))
3426 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3427 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3428 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3432 for (i = 0; i < 32; i++)
3433 if (fmask & (1L << i))
3435 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3436 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3437 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3441 if (TARGET_OPEN_VMS)
3443 if (!vms_is_stack_procedure)
3445 /* Register frame procedures fave the fp. */
3446 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3447 hard_frame_pointer_rtx));
3450 if (vms_base_regno != REG_PV)
3451 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3452 gen_rtx_REG (DImode, REG_PV)));
3454 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3456 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3459 /* If we have to allocate space for outgoing args, do it now. */
3460 if (current_function_outgoing_args_size != 0)
3462 FRP (emit_move_insn (stack_pointer_rtx,
3463 plus_constant (hard_frame_pointer_rtx,
3464 - ALPHA_ROUND (current_function_outgoing_args_size))));
3469 /* If we need a frame pointer, set it from the stack pointer. */
3470 if (frame_pointer_needed)
3472 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3473 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3476 /* This must always be the last instruction in the
3477 prologue, thus we emit a special move + clobber. */
3478 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3479 stack_pointer_rtx, sa_reg)));
3484 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3485 the prologue, for exception handling reasons, we cannot do this for
3486 any insn that might fault. We could prevent this for mems with a
3487 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3488 have to prevent all such scheduling with a blockage.
3490 Linux, on the other hand, never bothered to implement OSF/1's
3491 exception handling, and so doesn't care about such things. Anyone
3492 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3494 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3495 emit_insn (gen_blockage ());
3498 /* Output the textual info surrounding the prologue. */
3501 alpha_start_function (file, fnname, decl)
3504 tree decl ATTRIBUTE_UNUSED;
3506 unsigned long imask = 0;
3507 unsigned long fmask = 0;
3508 /* Stack space needed for pushing registers clobbered by us. */
3509 HOST_WIDE_INT sa_size;
3510 /* Complete stack size needed. */
3511 HOST_WIDE_INT frame_size;
3512 /* Offset from base reg to register save area. */
3513 HOST_WIDE_INT reg_offset;
3514 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3517 sa_size = alpha_sa_size ();
3519 frame_size = get_frame_size ();
3520 if (TARGET_OPEN_VMS)
3521 frame_size = ALPHA_ROUND (sa_size
3522 + (vms_is_stack_procedure ? 8 : 0)
3524 + current_function_pretend_args_size);
3526 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3528 + ALPHA_ROUND (frame_size
3529 + current_function_pretend_args_size));
3531 if (TARGET_OPEN_VMS)
3534 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3536 alpha_sa_mask (&imask, &fmask);
3538 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3539 We have to do that before the .ent directive as we cannot switch
3540 files within procedures with native ecoff because line numbers are
3541 linked to procedure descriptors.
3542 Outputting the lineno helps debugging of one line functions as they
3543 would otherwise get no line number at all. Please note that we would
3544 like to put out last_linenum from final.c, but it is not accessible. */
3546 if (write_symbols == SDB_DEBUG)
3548 ASM_OUTPUT_SOURCE_FILENAME (file,
3549 DECL_SOURCE_FILE (current_function_decl));
3550 if (debug_info_level != DINFO_LEVEL_TERSE)
3551 ASM_OUTPUT_SOURCE_LINE (file,
3552 DECL_SOURCE_LINE (current_function_decl));
3555 /* Issue function start and label. */
3556 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3558 fputs ("\t.ent ", file);
3559 assemble_name (file, fnname);
3563 strcpy (entry_label, fnname);
3564 if (TARGET_OPEN_VMS)
3565 strcat (entry_label, "..en");
3566 ASM_OUTPUT_LABEL (file, entry_label);
3567 inside_function = TRUE;
3569 if (TARGET_OPEN_VMS)
3570 fprintf (file, "\t.base $%d\n", vms_base_regno);
3572 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3573 && !flag_inhibit_size_directive)
3575 /* Set flags in procedure descriptor to request IEEE-conformant
3576 math-library routines. The value we set it to is PDSC_EXC_IEEE
3577 (/usr/include/pdsc.h). */
3578 fputs ("\t.eflag 48\n", file);
3581 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3582 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3583 alpha_arg_offset = -frame_size + 48;
3585 /* Describe our frame. If the frame size is larger than an integer,
3586 print it as zero to avoid an assembler error. We won't be
3587 properly describing such a frame, but that's the best we can do. */
3588 if (TARGET_OPEN_VMS)
3590 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3591 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3592 frame_size >= (1l << 31) ? 0 : frame_size);
3593 fputs (",$26,", file);
3594 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3597 else if (!flag_inhibit_size_directive)
3599 fprintf (file, "\t.frame $%d,",
3600 (frame_pointer_needed
3601 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3602 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3603 frame_size >= (1l << 31) ? 0 : frame_size);
3604 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3607 /* Describe which registers were spilled. */
3608 if (TARGET_OPEN_VMS)
3611 /* ??? Does VMS care if mask contains ra? The old code did'nt
3612 set it, so I don't here. */
3613 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3615 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3616 if (!vms_is_stack_procedure)
3617 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3619 else if (!flag_inhibit_size_directive)
3623 fprintf (file, "\t.mask 0x%lx,", imask);
3624 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3625 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3628 for (i = 0; i < 32; ++i)
3629 if (imask & (1L << i))
3635 fprintf (file, "\t.fmask 0x%lx,", fmask);
3636 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3637 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3642 /* Emit GP related things. It is rather unfortunate about the alignment
3643 issues surrounding a CODE_LABEL that forces us to do the label in
3645 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3647 alpha_function_needs_gp = alpha_does_function_need_gp ();
3648 if (alpha_function_needs_gp)
3649 fputs ("\tldgp $29,0($27)\n", file);
3652 assemble_name (file, fnname);
3653 fputs ("..ng:\n", file);
3657 /* Ifdef'ed cause readonly_section and link_section are only
3659 readonly_section ();
3660 fprintf (file, "\t.align 3\n");
3661 assemble_name (file, fnname); fputs ("..na:\n", file);
3662 fputs ("\t.ascii \"", file);
3663 assemble_name (file, fnname);
3664 fputs ("\\0\"\n", file);
3667 fprintf (file, "\t.align 3\n");
3668 fputs ("\t.name ", file);
3669 assemble_name (file, fnname);
3670 fputs ("..na\n", file);
3671 ASM_OUTPUT_LABEL (file, fnname);
3672 fprintf (file, "\t.pdesc ");
3673 assemble_name (file, fnname);
3674 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3675 alpha_need_linkage (fnname, 1);
3680 /* Emit the .prologue note at the scheduled end of the prologue. */
3683 output_end_prologue (file)
3686 if (TARGET_OPEN_VMS)
3687 fputs ("\t.prologue\n", file);
3688 else if (TARGET_WINDOWS_NT)
3689 fputs ("\t.prologue 0\n", file);
3690 else if (!flag_inhibit_size_directive)
3691 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3694 /* Write function epilogue. */
3696 /* ??? At some point we will want to support full unwind, and so will
3697 need to mark the epilogue as well. At the moment, we just confuse
3700 #define FRP(exp) exp
3703 alpha_expand_epilogue ()
3705 /* Registers to save. */
3706 unsigned long imask = 0;
3707 unsigned long fmask = 0;
3708 /* Stack space needed for pushing registers clobbered by us. */
3709 HOST_WIDE_INT sa_size;
3710 /* Complete stack size needed. */
3711 HOST_WIDE_INT frame_size;
3712 /* Offset from base reg to register save area. */
3713 HOST_WIDE_INT reg_offset;
3714 int fp_is_frame_pointer, fp_offset;
3715 rtx sa_reg, sa_reg_exp = NULL;
3716 rtx sp_adj1, sp_adj2, mem;
3719 sa_size = alpha_sa_size ();
3721 frame_size = get_frame_size ();
3722 if (TARGET_OPEN_VMS)
3723 frame_size = ALPHA_ROUND (sa_size
3724 + (vms_is_stack_procedure ? 8 : 0)
3726 + current_function_pretend_args_size);
3728 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3730 + ALPHA_ROUND (frame_size
3731 + current_function_pretend_args_size));
3733 if (TARGET_OPEN_VMS)
3736 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3738 alpha_sa_mask (&imask, &fmask);
3740 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3741 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3745 /* If we have a frame pointer, restore SP from it. */
3746 if ((TARGET_OPEN_VMS
3747 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3748 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3750 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
3753 /* Cope with very large offsets to the register save area. */
3754 sa_reg = stack_pointer_rtx;
3755 if (reg_offset + sa_size > 0x8000)
3757 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3760 if (low + sa_size <= 0x8000)
3761 bias = reg_offset - low, reg_offset = low;
3763 bias = reg_offset, reg_offset = 0;
3765 sa_reg = gen_rtx_REG (DImode, 22);
3766 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3768 FRP (emit_move_insn (sa_reg, sa_reg_exp));
3771 /* Restore registers in order, excepting a true frame pointer. */
3773 if (! alpha_eh_epilogue_sp_ofs)
3775 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3776 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3777 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
3780 imask &= ~(1L << REG_RA);
3782 for (i = 0; i < 32; ++i)
3783 if (imask & (1L << i))
3785 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3786 fp_offset = reg_offset;
3789 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3790 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3791 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
3796 for (i = 0; i < 32; ++i)
3797 if (fmask & (1L << i))
3799 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
3800 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3801 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
3806 if (frame_size || alpha_eh_epilogue_sp_ofs)
3808 sp_adj1 = stack_pointer_rtx;
3810 if (alpha_eh_epilogue_sp_ofs)
3812 sp_adj1 = gen_rtx_REG (DImode, 23);
3813 emit_move_insn (sp_adj1,
3814 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3815 alpha_eh_epilogue_sp_ofs));
3818 /* If the stack size is large, begin computation into a temporary
3819 register so as not to interfere with a potential fp restore,
3820 which must be consecutive with an SP restore. */
3821 if (frame_size < 32768)
3822 sp_adj2 = GEN_INT (frame_size);
3823 else if (frame_size < 0x40007fffL)
3825 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3827 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
3828 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3832 sp_adj1 = gen_rtx_REG (DImode, 23);
3833 FRP (emit_move_insn (sp_adj1, sp_adj2));
3835 sp_adj2 = GEN_INT (low);
3839 rtx tmp = gen_rtx_REG (DImode, 23);
3840 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
3843 /* We can't drop new things to memory this late, afaik,
3844 so build it up by pieces. */
3845 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
3846 -(frame_size < 0)));
3852 /* From now on, things must be in order. So emit blockages. */
3854 /* Restore the frame pointer. */
3855 if (fp_is_frame_pointer)
3857 emit_insn (gen_blockage ());
3858 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
3859 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3860 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
3862 else if (TARGET_OPEN_VMS)
3864 emit_insn (gen_blockage ());
3865 FRP (emit_move_insn (hard_frame_pointer_rtx,
3866 gen_rtx_REG (DImode, vms_save_fp_regno)));
3869 /* Restore the stack pointer. */
3870 emit_insn (gen_blockage ());
3871 FRP (emit_move_insn (stack_pointer_rtx,
3872 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
3876 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
3878 emit_insn (gen_blockage ());
3879 FRP (emit_move_insn (hard_frame_pointer_rtx,
3880 gen_rtx_REG (DImode, vms_save_fp_regno)));
3885 emit_jump_insn (gen_return_internal ());
3888 /* Output the rest of the textual info surrounding the epilogue. */
3891 alpha_end_function (file, fnname, decl)
3894 tree decl ATTRIBUTE_UNUSED;
3896 /* End the function. */
3897 if (!flag_inhibit_size_directive)
3899 fputs ("\t.end ", file);
3900 assemble_name (file, fnname);
3903 inside_function = FALSE;
3905 /* Show that we know this function if it is called again.
3907 Don't do this for global functions in object files destined for a
3908 shared library because the function may be overridden by the application
3910 ??? Is this just ELF? */
3912 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3913 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3916 /* Debugging support. */
3920 /* Count the number of sdb related labels are generated (to find block
3921 start and end boundaries). */
3923 int sdb_label_count = 0;
3925 /* Next label # for each statement. */
3927 static int sym_lineno = 0;
3929 /* Count the number of .file directives, so that .loc is up to date. */
3931 static int num_source_filenames = 0;
3933 /* Name of the file containing the current function. */
3935 static char *current_function_file = "";
3937 /* Offsets to alpha virtual arg/local debugging pointers. */
3939 long alpha_arg_offset;
3940 long alpha_auto_offset;
3942 /* Emit a new filename to a stream. */
3945 alpha_output_filename (stream, name)
3949 static int first_time = TRUE;
3950 char ltext_label_name[100];
3955 ++num_source_filenames;
3956 current_function_file = name;
3957 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3958 output_quoted_string (stream, name);
3959 fprintf (stream, "\n");
3960 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3961 fprintf (stream, "\t#@stabs\n");
3964 else if (write_symbols == DBX_DEBUG)
3966 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3967 fprintf (stream, "%s ", ASM_STABS_OP);
3968 output_quoted_string (stream, name);
3969 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3972 else if (name != current_function_file
3973 && strcmp (name, current_function_file) != 0)
3975 if (inside_function && ! TARGET_GAS)
3976 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3979 ++num_source_filenames;
3980 current_function_file = name;
3981 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3984 output_quoted_string (stream, name);
3985 fprintf (stream, "\n");
3989 /* Emit a linenumber to a stream. */
3992 alpha_output_lineno (stream, line)
3996 if (write_symbols == DBX_DEBUG)
3998 /* mips-tfile doesn't understand .stabd directives. */
4000 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4001 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4004 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4007 /* Structure to show the current status of registers and memory. */
4009 struct shadow_summary
4012 unsigned long i : 31; /* Mask of int regs */
4013 unsigned long fp : 31; /* Mask of fp regs */
4014 unsigned long mem : 1; /* mem == imem | fpmem */
4018 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
4019 static void alpha_handle_trap_shadows PROTO((rtx));
4021 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4022 to the summary structure. SET is nonzero if the insn is setting the
4023 object, otherwise zero. */
4026 summarize_insn (x, sum, set)
4028 struct shadow_summary *sum;
4037 switch (GET_CODE (x))
4039 /* ??? Note that this case would be incorrect if the Alpha had a
4040 ZERO_EXTRACT in SET_DEST. */
4042 summarize_insn (SET_SRC (x), sum, 0);
4043 summarize_insn (SET_DEST (x), sum, 1);
4047 summarize_insn (XEXP (x, 0), sum, 1);
4051 summarize_insn (XEXP (x, 0), sum, 0);
4055 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4056 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4060 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4061 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4065 summarize_insn (SUBREG_REG (x), sum, 0);
4070 int regno = REGNO (x);
4071 unsigned long mask = 1UL << (regno % 32);
4073 if (regno == 31 || regno == 63)
4079 sum->defd.i |= mask;
4081 sum->defd.fp |= mask;
4086 sum->used.i |= mask;
4088 sum->used.fp |= mask;
4099 /* Find the regs used in memory address computation: */
4100 summarize_insn (XEXP (x, 0), sum, 0);
4103 case CONST_INT: case CONST_DOUBLE:
4104 case SYMBOL_REF: case LABEL_REF: case CONST:
4107 /* Handle common unary and binary ops for efficiency. */
4108 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4109 case MOD: case UDIV: case UMOD: case AND: case IOR:
4110 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4111 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4112 case NE: case EQ: case GE: case GT: case LE:
4113 case LT: case GEU: case GTU: case LEU: case LTU:
4114 summarize_insn (XEXP (x, 0), sum, 0);
4115 summarize_insn (XEXP (x, 1), sum, 0);
4118 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4119 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4120 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4121 case SQRT: case FFS:
4122 summarize_insn (XEXP (x, 0), sum, 0);
4126 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4127 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4128 switch (format_ptr[i])
4131 summarize_insn (XEXP (x, i), sum, 0);
4135 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4136 summarize_insn (XVECEXP (x, i, j), sum, 0);
4148 /* Ensure a sufficient number of `trapb' insns are in the code when
4149 the user requests code with a trap precision of functions or
4152 In naive mode, when the user requests a trap-precision of
4153 "instruction", a trapb is needed after every instruction that may
4154 generate a trap. This ensures that the code is resumption safe but
4157 When optimizations are turned on, we delay issuing a trapb as long
4158 as possible. In this context, a trap shadow is the sequence of
4159 instructions that starts with a (potentially) trap generating
4160 instruction and extends to the next trapb or call_pal instruction
4161 (but GCC never generates call_pal by itself). We can delay (and
4162 therefore sometimes omit) a trapb subject to the following
4165 (a) On entry to the trap shadow, if any Alpha register or memory
4166 location contains a value that is used as an operand value by some
4167 instruction in the trap shadow (live on entry), then no instruction
4168 in the trap shadow may modify the register or memory location.
4170 (b) Within the trap shadow, the computation of the base register
4171 for a memory load or store instruction may not involve using the
4172 result of an instruction that might generate an UNPREDICTABLE
4175 (c) Within the trap shadow, no register may be used more than once
4176 as a destination register. (This is to make life easier for the
4179 (d) The trap shadow may not include any branch instructions. */
4182 alpha_handle_trap_shadows (insns)
4185 struct shadow_summary shadow;
4186 int trap_pending, exception_nesting;
4190 exception_nesting = 0;
4193 shadow.used.mem = 0;
4194 shadow.defd = shadow.used;
4196 for (i = insns; i ; i = NEXT_INSN (i))
4198 if (GET_CODE (i) == NOTE)
4200 switch (NOTE_LINE_NUMBER (i))
4202 case NOTE_INSN_EH_REGION_BEG:
4203 exception_nesting++;
4208 case NOTE_INSN_EH_REGION_END:
4209 exception_nesting--;
4214 case NOTE_INSN_EPILOGUE_BEG:
4215 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4220 else if (trap_pending)
4222 if (alpha_tp == ALPHA_TP_FUNC)
4224 if (GET_CODE (i) == JUMP_INSN
4225 && GET_CODE (PATTERN (i)) == RETURN)
4228 else if (alpha_tp == ALPHA_TP_INSN)
4232 struct shadow_summary sum;
4237 sum.defd = sum.used;
4239 switch (GET_CODE (i))
4242 /* Annoyingly, get_attr_trap will abort on these. */
4243 if (GET_CODE (PATTERN (i)) == USE
4244 || GET_CODE (PATTERN (i)) == CLOBBER)
4247 summarize_insn (PATTERN (i), &sum, 0);
4249 if ((sum.defd.i & shadow.defd.i)
4250 || (sum.defd.fp & shadow.defd.fp))
4252 /* (c) would be violated */
4256 /* Combine shadow with summary of current insn: */
4257 shadow.used.i |= sum.used.i;
4258 shadow.used.fp |= sum.used.fp;
4259 shadow.used.mem |= sum.used.mem;
4260 shadow.defd.i |= sum.defd.i;
4261 shadow.defd.fp |= sum.defd.fp;
4262 shadow.defd.mem |= sum.defd.mem;
4264 if ((sum.defd.i & shadow.used.i)
4265 || (sum.defd.fp & shadow.used.fp)
4266 || (sum.defd.mem & shadow.used.mem))
4268 /* (a) would be violated (also takes care of (b)) */
4269 if (get_attr_trap (i) == TRAP_YES
4270 && ((sum.defd.i & sum.used.i)
4271 || (sum.defd.fp & sum.used.fp)))
4290 n = emit_insn_before (gen_trapb (), i);
4291 PUT_MODE (n, TImode);
4292 PUT_MODE (i, TImode);
4296 shadow.used.mem = 0;
4297 shadow.defd = shadow.used;
4302 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4303 && GET_CODE (i) == INSN
4304 && GET_CODE (PATTERN (i)) != USE
4305 && GET_CODE (PATTERN (i)) != CLOBBER
4306 && get_attr_trap (i) == TRAP_YES)
4308 if (optimize && !trap_pending)
4309 summarize_insn (PATTERN (i), &shadow, 0);
4316 /* Alpha can only issue instruction groups simultaneously if they are
4317 suitibly aligned. This is very processor-specific. */
4319 enum alphaev4_pipe {
4326 enum alphaev5_pipe {
4337 static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx));
4338 static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx));
4339 static rtx alphaev4_next_group PROTO((rtx, int*, int*));
4340 static rtx alphaev5_next_group PROTO((rtx, int*, int*));
4341 static rtx alphaev4_next_nop PROTO((int*));
4342 static rtx alphaev5_next_nop PROTO((int*));
4344 static void alpha_align_insns
4345 PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4347 static enum alphaev4_pipe
4348 alphaev4_insn_pipe (insn)
4351 if (recog_memoized (insn) < 0)
4353 if (get_attr_length (insn) != 4)
4356 switch (get_attr_type (insn))
4389 static enum alphaev5_pipe
4390 alphaev5_insn_pipe (insn)
4393 if (recog_memoized (insn) < 0)
4395 if (get_attr_length (insn) != 4)
4398 switch (get_attr_type (insn))
4438 /* IN_USE is a mask of the slots currently filled within the insn group.
4439 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4440 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4442 LEN is, of course, the length of the group in bytes. */
4445 alphaev4_next_group (insn, pin_use, plen)
4447 int *pin_use, *plen;
4453 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4454 || GET_CODE (PATTERN (insn)) == CLOBBER
4455 || GET_CODE (PATTERN (insn)) == USE)
4460 enum alphaev4_pipe pipe;
4462 pipe = alphaev4_insn_pipe (insn);
4466 /* Force complex instructions to start new groups. */
4470 /* If this is a completely unrecognized insn, its an asm.
4471 We don't know how long it is, so record length as -1 to
4472 signal a needed realignment. */
4473 if (recog_memoized (insn) < 0)
4476 len = get_attr_length (insn);
4480 if (in_use & EV4_IB0)
4482 if (in_use & EV4_IB1)
4487 in_use |= EV4_IB0 | EV4_IBX;
4491 if (in_use & EV4_IB0)
4493 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4501 if (in_use & EV4_IB1)
4511 /* Haifa doesn't do well scheduling branches. */
4512 if (GET_CODE (insn) == JUMP_INSN)
4516 insn = next_nonnote_insn (insn);
4518 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4521 /* Let Haifa tell us where it thinks insn group boundaries are. */
4522 if (GET_MODE (insn) == TImode)
4525 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4530 insn = next_nonnote_insn (insn);
4538 /* IN_USE is a mask of the slots currently filled within the insn group.
4539 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4540 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4542 LEN is, of course, the length of the group in bytes. */
4545 alphaev5_next_group (insn, pin_use, plen)
4547 int *pin_use, *plen;
4553 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4554 || GET_CODE (PATTERN (insn)) == CLOBBER
4555 || GET_CODE (PATTERN (insn)) == USE)
4560 enum alphaev5_pipe pipe;
4562 pipe = alphaev5_insn_pipe (insn);
4566 /* Force complex instructions to start new groups. */
4570 /* If this is a completely unrecognized insn, its an asm.
4571 We don't know how long it is, so record length as -1 to
4572 signal a needed realignment. */
4573 if (recog_memoized (insn) < 0)
4576 len = get_attr_length (insn);
4579 /* ??? Most of the places below, we would like to abort, as
4580 it would indicate an error either in Haifa, or in the
4581 scheduling description. Unfortunately, Haifa never
4582 schedules the last instruction of the BB, so we don't
4583 have an accurate TI bit to go off. */
4585 if (in_use & EV5_E0)
4587 if (in_use & EV5_E1)
4592 in_use |= EV5_E0 | EV5_E01;
4596 if (in_use & EV5_E0)
4598 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4606 if (in_use & EV5_E1)
4612 if (in_use & EV5_FA)
4614 if (in_use & EV5_FM)
4619 in_use |= EV5_FA | EV5_FAM;
4623 if (in_use & EV5_FA)
4629 if (in_use & EV5_FM)
4642 /* Haifa doesn't do well scheduling branches. */
4643 /* ??? If this is predicted not-taken, slotting continues, except
4644 that no more IBR, FBR, or JSR insns may be slotted. */
4645 if (GET_CODE (insn) == JUMP_INSN)
4649 insn = next_nonnote_insn (insn);
4651 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4654 /* Let Haifa tell us where it thinks insn group boundaries are. */
4655 if (GET_MODE (insn) == TImode)
4658 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4663 insn = next_nonnote_insn (insn);
4672 alphaev4_next_nop (pin_use)
4675 int in_use = *pin_use;
4678 if (!(in_use & EV4_IB0))
4683 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
4688 else if (TARGET_FP && !(in_use & EV4_IB1))
4701 alphaev5_next_nop (pin_use)
4704 int in_use = *pin_use;
4707 if (!(in_use & EV5_E1))
4712 else if (TARGET_FP && !(in_use & EV5_FA))
4717 else if (TARGET_FP && !(in_use & EV5_FM))
4729 /* The instruction group alignment main loop. */
4732 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
4735 rtx (*next_group) PROTO((rtx, int*, int*));
4736 rtx (*next_nop) PROTO((int*));
4739 /* ALIGN is the known alignment for the insn group. */
4741 /* OFS is the offset of the current insn in the insn group. */
4743 int prev_in_use, in_use, len;
4746 /* Let shorten branches care for assigning alignments to code labels. */
4747 shorten_branches (insns);
4749 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
4750 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
4752 /* Account for the initial GP load, which happens before the scheduled
4753 prologue we emitted as RTL. */
4754 ofs = prev_in_use = 0;
4755 if (alpha_does_function_need_gp())
4757 ofs = 8 & (align - 1);
4758 prev_in_use = gp_in_use;
4762 if (GET_CODE (i) == NOTE)
4763 i = next_nonnote_insn (i);
4767 next = (*next_group)(i, &in_use, &len);
4769 /* When we see a label, resync alignment etc. */
4770 if (GET_CODE (i) == CODE_LABEL)
4772 int new_align = 1 << label_to_alignment (i);
4773 if (new_align >= align)
4775 align = new_align < max_align ? new_align : max_align;
4778 else if (ofs & (new_align-1))
4779 ofs = (ofs | (new_align-1)) + 1;
4784 /* Handle complex instructions special. */
4785 else if (in_use == 0)
4787 /* Asms will have length < 0. This is a signal that we have
4788 lost alignment knowledge. Assume, however, that the asm
4789 will not mis-align instructions. */
4798 /* If the known alignment is smaller than the recognized insn group,
4799 realign the output. */
4800 else if (align < len)
4802 int new_log_align = len > 8 ? 4 : 3;
4805 where = prev_nonnote_insn (i);
4806 if (!where || GET_CODE (where) != CODE_LABEL)
4809 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4810 align = 1 << new_log_align;
4814 /* If the group won't fit in the same INT16 as the previous,
4815 we need to add padding to keep the group together. Rather
4816 than simply leaving the insn filling to the assembler, we
4817 can make use of the knowledge of what sorts of instructions
4818 were issued in the previous group to make sure that all of
4819 the added nops are really free. */
4820 else if (ofs + len > align)
4822 int nop_count = (align - ofs) / 4;
4825 /* Insert nops before labels and branches to truely merge the
4826 execution of the nops with the previous instruction group. */
4827 where = prev_nonnote_insn (i);
4830 if (GET_CODE (where) == CODE_LABEL)
4832 rtx where2 = prev_nonnote_insn (where);
4833 if (where2 && GET_CODE (where2) == JUMP_INSN)
4836 else if (GET_CODE (where) != JUMP_INSN)
4843 emit_insn_before ((*next_nop)(&prev_in_use), where);
4844 while (--nop_count);
4848 ofs = (ofs + len) & (align - 1);
4849 prev_in_use = in_use;
4855 /* Machine dependant reorg pass. */
4861 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4862 alpha_handle_trap_shadows (insns);
4865 /* Due to the number of extra trapb insns, don't bother fixing up
4866 alignment when trap precision is instruction. Moreover, we can
4867 only do our job when sched2 is run and Haifa is our scheduler. */
4868 if (optimize && !optimize_size
4869 && alpha_tp != ALPHA_TP_INSN
4870 && flag_schedule_insns_after_reload)
4872 if (alpha_cpu == PROCESSOR_EV4)
4873 alpha_align_insns (insns, 8, alphaev4_next_group,
4874 alphaev4_next_nop, EV4_IB0);
4875 else if (alpha_cpu == PROCESSOR_EV5)
4876 alpha_align_insns (insns, 16, alphaev5_next_group,
4877 alphaev5_next_nop, EV5_E01 | EV5_E0);
4883 /* Check a floating-point value for validity for a particular machine mode. */
4885 static char * const float_strings[] =
4887 /* These are for FLOAT_VAX. */
4888 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4889 "-1.70141173319264430e+38",
4890 "2.93873587705571877e-39", /* 2^-128 */
4891 "-2.93873587705571877e-39",
4892 /* These are for the default broken IEEE mode, which traps
4893 on infinity or denormal numbers. */
4894 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4895 "-3.402823466385288598117e+38",
4896 "1.1754943508222875079687e-38", /* 2^-126 */
4897 "-1.1754943508222875079687e-38",
4900 static REAL_VALUE_TYPE float_values[8];
4901 static int inited_float_values = 0;
4904 check_float_value (mode, d, overflow)
4905 enum machine_mode mode;
4907 int overflow ATTRIBUTE_UNUSED;
4910 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4913 if (inited_float_values == 0)
4916 for (i = 0; i < 8; i++)
4917 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4919 inited_float_values = 1;
4925 REAL_VALUE_TYPE *fvptr;
4927 if (TARGET_FLOAT_VAX)
4928 fvptr = &float_values[0];
4930 fvptr = &float_values[4];
4932 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4933 if (REAL_VALUES_LESS (fvptr[0], r))
4935 bcopy ((char *) &fvptr[0], (char *) d,
4936 sizeof (REAL_VALUE_TYPE));
4939 else if (REAL_VALUES_LESS (r, fvptr[1]))
4941 bcopy ((char *) &fvptr[1], (char *) d,
4942 sizeof (REAL_VALUE_TYPE));
4945 else if (REAL_VALUES_LESS (dconst0, r)
4946 && REAL_VALUES_LESS (r, fvptr[2]))
4948 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4951 else if (REAL_VALUES_LESS (r, dconst0)
4952 && REAL_VALUES_LESS (fvptr[3], r))
4954 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4964 /* Return the VMS argument type corresponding to MODE. */
4967 alpha_arg_type (mode)
4968 enum machine_mode mode;
4973 return TARGET_FLOAT_VAX ? FF : FS;
4975 return TARGET_FLOAT_VAX ? FD : FT;
4981 /* Return an rtx for an integer representing the VMS Argument Information
4985 alpha_arg_info_reg_val (cum)
4986 CUMULATIVE_ARGS cum;
4988 unsigned HOST_WIDE_INT regval = cum.num_args;
4991 for (i = 0; i < 6; i++)
4992 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4994 return GEN_INT (regval);
4997 /* Structure to collect function names for final output
5000 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5003 struct alpha_links {
5004 struct alpha_links *next;
5006 enum links_kind kind;
5009 static struct alpha_links *alpha_links_base = 0;
5011 /* Make (or fake) .linkage entry for function call.
5013 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5016 alpha_need_linkage (name, is_local)
5021 struct alpha_links *lptr, *nptr;
5026 /* Is this name already defined ? */
5028 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5029 if (strcmp (lptr->name, name) == 0)
5033 /* Defined here but external assumed. */
5034 if (lptr->kind == KIND_EXTERN)
5035 lptr->kind = KIND_LOCAL;
5039 /* Used here but unused assumed. */
5040 if (lptr->kind == KIND_UNUSED)
5041 lptr->kind = KIND_LOCAL;
5046 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5047 nptr->next = alpha_links_base;
5048 nptr->name = xstrdup (name);
5050 /* Assume external if no definition. */
5051 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5053 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5054 get_identifier (name);
5056 alpha_links_base = nptr;
5063 alpha_write_linkage (stream)
5066 struct alpha_links *lptr, *nptr;
5068 readonly_section ();
5070 fprintf (stream, "\t.align 3\n");
5072 for (lptr = alpha_links_base; lptr; lptr = nptr)
5076 if (lptr->kind == KIND_UNUSED
5077 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5080 fprintf (stream, "$%s..lk:\n", lptr->name);
5081 if (lptr->kind == KIND_LOCAL)
5083 /* Local and used, build linkage pair. */
5084 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5085 fprintf (stream, "\t.quad %s\n", lptr->name);
5088 /* External and used, request linkage pair. */
5089 fprintf (stream, "\t.linkage %s\n", lptr->name);
5096 alpha_need_linkage (name, is_local)
5097 char *name ATTRIBUTE_UNUSED;
5098 int is_local ATTRIBUTE_UNUSED;
5102 #endif /* OPEN_VMS */