1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 1997 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. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
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 /* Save the name of the current function as used by the assembler. This
83 is used by the epilogue. */
85 char *alpha_function_name;
87 /* Non-zero if inside of a function, because the Alpha asm can't
88 handle .files inside of functions. */
90 static int inside_function = FALSE;
92 /* Nonzero if the current function needs gp. */
94 int alpha_function_needs_gp;
96 /* If non-null, this rtx holds the return address for the function. */
98 static rtx alpha_return_addr_rtx;
100 /* The number of cycles of latency we should assume on memory reads. */
102 int alpha_memory_latency = 3;
104 /* Declarations of static functions. */
105 static void alpha_set_memflags_1 PROTO((rtx, int, int, int));
106 static rtx alpha_emit_set_const_1 PROTO((rtx, enum machine_mode,
107 HOST_WIDE_INT, int));
108 static void add_long_const PROTO((FILE *, HOST_WIDE_INT, int, int, int));
110 /* Compute the size of the save area in the stack. */
112 static void alpha_sa_mask PROTO((unsigned long *imaskP,
113 unsigned long *fmaskP));
115 /* Get the number of args of a function in one of two ways. */
117 #define NUM_ARGS current_function_args_info.num_args
119 #define NUM_ARGS current_function_args_info
129 /* Parse target option strings. */
134 /* 971208 -- EV6 scheduling parameters are still secret, so don't even
135 pretend and just schedule for an EV5 for now. -- r~ */
137 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
138 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
140 if (alpha_cpu_string)
142 if (! strcmp (alpha_cpu_string, "ev4")
143 || ! strcmp (alpha_cpu_string, "21064"))
145 alpha_cpu = PROCESSOR_EV4;
146 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
148 else if (! strcmp (alpha_cpu_string, "ev5")
149 || ! strcmp (alpha_cpu_string, "21164"))
151 alpha_cpu = PROCESSOR_EV5;
152 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
154 else if (! strcmp (alpha_cpu_string, "ev56")
155 || ! strcmp (alpha_cpu_string, "21164a"))
157 alpha_cpu = PROCESSOR_EV5;
158 target_flags |= MASK_BWX;
159 target_flags &= ~ (MASK_CIX | MASK_MAX);
161 else if (! strcmp (alpha_cpu_string, "pca56")
162 || ! strcmp (alpha_cpu_string, "21164PC")
163 || ! strcmp (alpha_cpu_string, "21164pc"))
165 alpha_cpu = PROCESSOR_EV5;
166 target_flags |= MASK_BWX | MASK_MAX;
167 target_flags &= ~ MASK_CIX;
169 else if (! strcmp (alpha_cpu_string, "ev6")
170 || ! strcmp (alpha_cpu_string, "21264"))
172 alpha_cpu = PROCESSOR_EV6;
173 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
176 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
179 alpha_tp = ALPHA_TP_PROG;
180 alpha_fprm = ALPHA_FPRM_NORM;
181 alpha_fptm = ALPHA_FPTM_N;
185 alpha_tp = ALPHA_TP_INSN;
186 alpha_fptm = ALPHA_FPTM_SU;
189 if (TARGET_IEEE_WITH_INEXACT)
191 alpha_tp = ALPHA_TP_INSN;
192 alpha_fptm = ALPHA_FPTM_SUI;
197 if (! strcmp (alpha_tp_string, "p"))
198 alpha_tp = ALPHA_TP_PROG;
199 else if (! strcmp (alpha_tp_string, "f"))
200 alpha_tp = ALPHA_TP_FUNC;
201 else if (! strcmp (alpha_tp_string, "i"))
202 alpha_tp = ALPHA_TP_INSN;
204 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
207 if (alpha_fprm_string)
209 if (! strcmp (alpha_fprm_string, "n"))
210 alpha_fprm = ALPHA_FPRM_NORM;
211 else if (! strcmp (alpha_fprm_string, "m"))
212 alpha_fprm = ALPHA_FPRM_MINF;
213 else if (! strcmp (alpha_fprm_string, "c"))
214 alpha_fprm = ALPHA_FPRM_CHOP;
215 else if (! strcmp (alpha_fprm_string,"d"))
216 alpha_fprm = ALPHA_FPRM_DYN;
218 error ("bad value `%s' for -mfp-rounding-mode switch",
222 if (alpha_fptm_string)
224 if (strcmp (alpha_fptm_string, "n") == 0)
225 alpha_fptm = ALPHA_FPTM_N;
226 else if (strcmp (alpha_fptm_string, "u") == 0)
227 alpha_fptm = ALPHA_FPTM_U;
228 else if (strcmp (alpha_fptm_string, "su") == 0)
229 alpha_fptm = ALPHA_FPTM_SU;
230 else if (strcmp (alpha_fptm_string, "sui") == 0)
231 alpha_fptm = ALPHA_FPTM_SUI;
233 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
236 /* Do some sanity checks on the above option. */
238 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
239 && alpha_tp != ALPHA_TP_INSN)
241 warning ("fp software completion requires -mtrap-precision=i");
242 alpha_tp = ALPHA_TP_INSN;
245 if (TARGET_FLOAT_VAX)
247 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
249 warning ("rounding mode not supported for VAX floats");
250 alpha_fprm = ALPHA_FPRM_NORM;
252 if (alpha_fptm == ALPHA_FPTM_SUI)
254 warning ("trap mode not supported for VAX floats");
255 alpha_fptm = ALPHA_FPTM_SU;
263 if (!alpha_mlat_string)
264 alpha_mlat_string = "L1";
266 if (isdigit (alpha_mlat_string[0])
267 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
269 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
270 && isdigit (alpha_mlat_string[1])
271 && alpha_mlat_string[2] == '\0')
273 static int const cache_latency[][4] =
275 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
276 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
277 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
280 lat = alpha_mlat_string[1] - '0';
281 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
283 warning ("L%d cache latency unknown for %s",
284 lat, alpha_cpu_name[alpha_cpu]);
288 lat = cache_latency[alpha_cpu][lat-1];
290 else if (! strcmp (alpha_mlat_string, "main"))
292 /* Most current memories have about 370ns latency. This is
293 a reasonable guess for a fast cpu. */
298 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
302 alpha_memory_latency = lat;
306 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
314 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
316 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
322 /* Returns 1 if OP is either the constant zero or a register. If a
323 register, it must be in the proper mode unless MODE is VOIDmode. */
326 reg_or_0_operand (op, mode)
328 enum machine_mode mode;
330 return op == const0_rtx || register_operand (op, mode);
333 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
337 reg_or_6bit_operand (op, mode)
339 enum machine_mode mode;
341 return ((GET_CODE (op) == CONST_INT
342 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
343 || register_operand (op, mode));
347 /* Return 1 if OP is an 8-bit constant or any register. */
350 reg_or_8bit_operand (op, mode)
352 enum machine_mode mode;
354 return ((GET_CODE (op) == CONST_INT
355 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
356 || register_operand (op, mode));
359 /* Return 1 if OP is an 8-bit constant. */
362 cint8_operand (op, mode)
364 enum machine_mode mode;
366 return (GET_CODE (op) == CONST_INT
367 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
370 /* Return 1 if the operand is a valid second operand to an add insn. */
373 add_operand (op, mode)
375 enum machine_mode mode;
377 if (GET_CODE (op) == CONST_INT)
378 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
379 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
380 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
382 return register_operand (op, mode);
385 /* Return 1 if the operand is a valid second operand to a sign-extending
389 sext_add_operand (op, mode)
391 enum machine_mode mode;
393 if (GET_CODE (op) == CONST_INT)
394 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
395 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
397 return register_operand (op, mode);
400 /* Return 1 if OP is the constant 4 or 8. */
403 const48_operand (op, mode)
405 enum machine_mode mode;
407 return (GET_CODE (op) == CONST_INT
408 && (INTVAL (op) == 4 || INTVAL (op) == 8));
411 /* Return 1 if OP is a valid first operand to an AND insn. */
414 and_operand (op, mode)
416 enum machine_mode mode;
418 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
419 return (zap_mask (CONST_DOUBLE_LOW (op))
420 && zap_mask (CONST_DOUBLE_HIGH (op)));
422 if (GET_CODE (op) == CONST_INT)
423 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
424 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
425 || zap_mask (INTVAL (op)));
427 return register_operand (op, mode);
430 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
433 or_operand (op, mode)
435 enum machine_mode mode;
437 if (GET_CODE (op) == CONST_INT)
438 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
439 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
441 return register_operand (op, mode);
444 /* Return 1 if OP is a constant that is the width, in bits, of an integral
445 mode smaller than DImode. */
448 mode_width_operand (op, mode)
450 enum machine_mode mode;
452 return (GET_CODE (op) == CONST_INT
453 && (INTVAL (op) == 8 || INTVAL (op) == 16
454 || INTVAL (op) == 32 || INTVAL (op) == 64));
457 /* Return 1 if OP is a constant that is the width of an integral machine mode
458 smaller than an integer. */
461 mode_mask_operand (op, mode)
463 enum machine_mode mode;
465 #if HOST_BITS_PER_WIDE_INT == 32
466 if (GET_CODE (op) == CONST_DOUBLE)
467 return (CONST_DOUBLE_LOW (op) == -1
468 && (CONST_DOUBLE_HIGH (op) == -1
469 || CONST_DOUBLE_HIGH (op) == 0));
471 if (GET_CODE (op) == CONST_DOUBLE)
472 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
475 return (GET_CODE (op) == CONST_INT
476 && (INTVAL (op) == 0xff
477 || INTVAL (op) == 0xffff
478 #if HOST_BITS_PER_WIDE_INT == 64
479 || INTVAL (op) == 0xffffffff
480 || INTVAL (op) == 0xffffffffffffffff
485 /* Return 1 if OP is a multiple of 8 less than 64. */
488 mul8_operand (op, mode)
490 enum machine_mode mode;
492 return (GET_CODE (op) == CONST_INT
493 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
494 && (INTVAL (op) & 7) == 0);
497 /* Return 1 if OP is the constant zero in floating-point. */
500 fp0_operand (op, mode)
502 enum machine_mode mode;
504 return (GET_MODE (op) == mode
505 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
508 /* Return 1 if OP is the floating-point constant zero or a register. */
511 reg_or_fp0_operand (op, mode)
513 enum machine_mode mode;
515 return fp0_operand (op, mode) || register_operand (op, mode);
518 /* Return 1 if OP is a register or a constant integer. */
522 reg_or_cint_operand (op, mode)
524 enum machine_mode mode;
526 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
529 /* Return 1 if OP is something that can be reloaded into a register;
530 if it is a MEM, it need not be valid. */
533 some_operand (op, mode)
535 enum machine_mode mode;
537 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
540 switch (GET_CODE (op))
542 case REG: case MEM: case CONST_DOUBLE:
543 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
547 return some_operand (SUBREG_REG (op), VOIDmode);
556 /* Return 1 if OP is a valid operand for the source of a move insn. */
559 input_operand (op, mode)
561 enum machine_mode mode;
563 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
566 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
569 switch (GET_CODE (op))
574 /* This handles both the Windows/NT and OSF cases. */
575 return mode == ptr_mode || mode == DImode;
581 if (register_operand (op, mode))
583 /* ... fall through ... */
585 return ((TARGET_BWX || (mode != HImode && mode != QImode))
586 && general_operand (op, mode));
589 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
592 return mode == QImode || mode == HImode || add_operand (op, mode);
601 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
605 current_file_function_operand (op, mode)
607 enum machine_mode mode;
609 return (GET_CODE (op) == SYMBOL_REF
610 && ! profile_flag && ! profile_block_flag
611 && (SYMBOL_REF_FLAG (op)
612 || op == XEXP (DECL_RTL (current_function_decl), 0)));
615 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
618 call_operand (op, mode)
620 enum machine_mode mode;
625 return (GET_CODE (op) == SYMBOL_REF
626 || (GET_CODE (op) == REG
627 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
630 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
631 comparisons are valid in which insn. */
634 alpha_comparison_operator (op, mode)
636 enum machine_mode mode;
638 enum rtx_code code = GET_CODE (op);
640 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
643 return (code == EQ || code == LE || code == LT
644 || (mode == DImode && (code == LEU || code == LTU)));
647 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
650 alpha_swapped_comparison_operator (op, mode)
652 enum machine_mode mode;
654 enum rtx_code code = GET_CODE (op);
656 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
659 code = swap_condition (code);
660 return (code == EQ || code == LE || code == LT
661 || (mode == DImode && (code == LEU || code == LTU)));
664 /* Return 1 if OP is a signed comparison operation. */
667 signed_comparison_operator (op, mode)
669 enum machine_mode mode;
671 switch (GET_CODE (op))
673 case EQ: case NE: case LE: case LT: case GE: case GT:
683 /* Return 1 if this is a divide or modulus operator. */
686 divmod_operator (op, mode)
688 enum machine_mode mode;
690 switch (GET_CODE (op))
692 case DIV: case MOD: case UDIV: case UMOD:
702 /* Return 1 if this memory address is a known aligned register plus
703 a constant. It must be a valid address. This means that we can do
704 this as an aligned reference plus some offset.
706 Take into account what reload will do.
708 We could say that out-of-range stack slots are alignable, but that would
709 complicate get_aligned_mem and it isn't worth the trouble since few
710 functions have large stack space. */
713 aligned_memory_operand (op, mode)
715 enum machine_mode mode;
717 if (GET_CODE (op) == SUBREG)
719 if (GET_MODE (op) != mode)
721 op = SUBREG_REG (op);
722 mode = GET_MODE (op);
725 if (reload_in_progress && GET_CODE (op) == REG
726 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
727 op = reg_equiv_mem[REGNO (op)];
729 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
730 || ! memory_address_p (mode, XEXP (op, 0)))
735 if (GET_CODE (op) == PLUS)
738 return (GET_CODE (op) == REG
739 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
742 /* Similar, but return 1 if OP is a MEM which is not alignable. */
745 unaligned_memory_operand (op, mode)
747 enum machine_mode mode;
749 if (GET_CODE (op) == SUBREG)
751 if (GET_MODE (op) != mode)
753 op = SUBREG_REG (op);
754 mode = GET_MODE (op);
757 if (reload_in_progress && GET_CODE (op) == REG
758 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
759 op = reg_equiv_mem[REGNO (op)];
761 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
766 if (! memory_address_p (mode, op))
769 if (GET_CODE (op) == PLUS)
772 return (GET_CODE (op) != REG
773 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
776 /* Return 1 if OP is either a register or an unaligned memory location. */
779 reg_or_unaligned_mem_operand (op, mode)
781 enum machine_mode mode;
783 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
786 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
789 any_memory_operand (op, mode)
791 enum machine_mode mode;
793 return (GET_CODE (op) == MEM
794 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
795 || (reload_in_progress && GET_CODE (op) == REG
796 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
797 || (reload_in_progress && GET_CODE (op) == SUBREG
798 && GET_CODE (SUBREG_REG (op)) == REG
799 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
802 /* REF is an alignable memory location. Place an aligned SImode
803 reference into *PALIGNED_MEM and the number of bits to shift into
807 get_aligned_mem (ref, paligned_mem, pbitnum)
809 rtx *paligned_mem, *pbitnum;
812 HOST_WIDE_INT offset = 0;
814 if (GET_CODE (ref) == SUBREG)
816 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
817 if (BYTES_BIG_ENDIAN)
818 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
819 - MIN (UNITS_PER_WORD,
820 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
821 ref = SUBREG_REG (ref);
824 if (GET_CODE (ref) == REG)
825 ref = reg_equiv_mem[REGNO (ref)];
827 if (reload_in_progress)
828 base = find_replacement (&XEXP (ref, 0));
830 base = XEXP (ref, 0);
832 if (GET_CODE (base) == PLUS)
833 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
835 *paligned_mem = gen_rtx_MEM (SImode,
836 plus_constant (base, offset & ~3));
837 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
838 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
839 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
841 *pbitnum = GEN_INT ((offset & 3) * 8);
844 /* Similar, but just get the address. Handle the two reload cases.
845 Add EXTRA_OFFSET to the address we return. */
848 get_unaligned_address (ref, extra_offset)
853 HOST_WIDE_INT offset = 0;
855 if (GET_CODE (ref) == SUBREG)
857 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
858 if (BYTES_BIG_ENDIAN)
859 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
860 - MIN (UNITS_PER_WORD,
861 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
862 ref = SUBREG_REG (ref);
865 if (GET_CODE (ref) == REG)
866 ref = reg_equiv_mem[REGNO (ref)];
868 if (reload_in_progress)
869 base = find_replacement (&XEXP (ref, 0));
871 base = XEXP (ref, 0);
873 if (GET_CODE (base) == PLUS)
874 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
876 return plus_constant (base, offset + extra_offset);
879 /* Subfunction of the following function. Update the flags of any MEM
880 found in part of X. */
883 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
885 int in_struct_p, volatile_p, unchanging_p;
889 switch (GET_CODE (x))
893 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
894 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
899 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
904 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
906 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
911 MEM_IN_STRUCT_P (x) = in_struct_p;
912 MEM_VOLATILE_P (x) = volatile_p;
913 RTX_UNCHANGING_P (x) = unchanging_p;
921 /* Given INSN, which is either an INSN or a SEQUENCE generated to
922 perform a memory operation, look for any MEMs in either a SET_DEST or
923 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
924 REF into each of the MEMs found. If REF is not a MEM, don't do
928 alpha_set_memflags (insn, ref)
932 /* Note that it is always safe to get these flags, though they won't
933 be what we think if REF is not a MEM. */
934 int in_struct_p = MEM_IN_STRUCT_P (ref);
935 int volatile_p = MEM_VOLATILE_P (ref);
936 int unchanging_p = RTX_UNCHANGING_P (ref);
938 if (GET_CODE (ref) != MEM
939 || (! in_struct_p && ! volatile_p && ! unchanging_p))
942 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
945 /* Try to output insns to set TARGET equal to the constant C if it can be
946 done in less than N insns. Do all computations in MODE. Returns the place
947 where the output has been placed if it can be done and the insns have been
948 emitted. If it would take more than N insns, zero is returned and no
949 insns and emitted. */
952 alpha_emit_set_const (target, mode, c, n)
954 enum machine_mode mode;
961 /* Try 1 insn, then 2, then up to N. */
962 for (i = 1; i <= n; i++)
963 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
969 /* Internal routine for the above to check for N or below insns. */
972 alpha_emit_set_const_1 (target, mode, c, n)
974 enum machine_mode mode;
978 HOST_WIDE_INT new = c;
980 /* Use a pseudo if highly optimizing and still generating RTL. */
982 = (flag_expensive_optimizations && rtx_equal_function_value_matters
986 #if HOST_BITS_PER_WIDE_INT == 64
987 /* We are only called for SImode and DImode. If this is SImode, ensure that
988 we are sign extended to a full word. This does not make any sense when
989 cross-compiling on a narrow machine. */
992 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
995 /* If this is a sign-extended 32-bit constant, we can do this in at most
996 three insns, so do it if we have enough insns left. We always have
997 a sign-extended 32-bit constant when compiling on a narrow machine. */
999 if (HOST_BITS_PER_WIDE_INT != 64
1000 || c >> 31 == -1 || c >> 31 == 0)
1002 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1003 HOST_WIDE_INT tmp1 = c - low;
1005 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1006 HOST_WIDE_INT extra = 0;
1008 /* If HIGH will be interpreted as negative but the constant is
1009 positive, we must adjust it to do two ldha insns. */
1011 if ((high & 0x8000) != 0 && c >= 0)
1015 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1018 if (c == low || (low == 0 && extra == 0))
1020 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1021 but that meant that we can't handle INT_MIN on 32-bit machines
1022 (like NT/Alpha), because we recurse indefinitely through
1023 emit_move_insn to gen_movdi. So instead, since we know exactly
1024 what we want, create it explicitly. */
1027 target = gen_reg_rtx (mode);
1028 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1031 else if (n >= 2 + (extra != 0))
1033 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1036 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1037 subtarget, 0, OPTAB_WIDEN);
1039 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1040 target, 0, OPTAB_WIDEN);
1044 /* If we couldn't do it that way, try some other methods. But if we have
1045 no instructions left, don't bother. Likewise, if this is SImode and
1046 we can't make pseudos, we can't do anything since the expand_binop
1047 and expand_unop calls will widen and try to make pseudos. */
1050 || (mode == SImode && ! rtx_equal_function_value_matters))
1053 #if HOST_BITS_PER_WIDE_INT == 64
1054 /* First, see if can load a value into the target that is the same as the
1055 constant except that all bytes that are 0 are changed to be 0xff. If we
1056 can, then we can do a ZAPNOT to obtain the desired constant. */
1058 for (i = 0; i < 64; i += 8)
1059 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1060 new |= (HOST_WIDE_INT) 0xff << i;
1062 /* We are only called for SImode and DImode. If this is SImode, ensure that
1063 we are sign extended to a full word. */
1066 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1069 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1070 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1071 target, 0, OPTAB_WIDEN);
1074 /* Next, see if we can load a related constant and then shift and possibly
1075 negate it to get the constant we want. Try this once each increasing
1076 numbers of insns. */
1078 for (i = 1; i < n; i++)
1080 /* First try complementing. */
1081 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1082 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1084 /* Next try to form a constant and do a left shift. We can do this
1085 if some low-order bits are zero; the exact_log2 call below tells
1086 us that information. The bits we are shifting out could be any
1087 value, but here we'll just try the 0- and sign-extended forms of
1088 the constant. To try to increase the chance of having the same
1089 constant in more than one insn, start at the highest number of
1090 bits to shift, but try all possibilities in case a ZAPNOT will
1093 if ((bits = exact_log2 (c & - c)) > 0)
1094 for (; bits > 0; bits--)
1095 if ((temp = (alpha_emit_set_const
1097 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
1098 || ((temp = (alpha_emit_set_const
1100 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1102 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1103 target, 0, OPTAB_WIDEN);
1105 /* Now try high-order zero bits. Here we try the shifted-in bits as
1106 all zero and all ones. Be careful to avoid shifting outside the
1107 mode and to avoid shifting outside the host wide int size. */
1108 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1109 confuse the recursive call and set all of the high 32 bits. */
1111 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1112 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1113 for (; bits > 0; bits--)
1114 if ((temp = alpha_emit_set_const (subtarget, mode,
1116 || ((temp = (alpha_emit_set_const
1118 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1121 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1122 target, 1, OPTAB_WIDEN);
1124 /* Now try high-order 1 bits. We get that with a sign-extension.
1125 But one bit isn't enough here. Be careful to avoid shifting outside
1126 the mode and to avoid shifting outside the host wide int size. */
1128 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1129 - floor_log2 (~ c) - 2)) > 0)
1130 for (; bits > 0; bits--)
1131 if ((temp = alpha_emit_set_const (subtarget, mode,
1133 || ((temp = (alpha_emit_set_const
1135 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1138 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1139 target, 0, OPTAB_WIDEN);
1145 #if HOST_BITS_PER_WIDE_INT == 64
1146 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1147 fall back to a straight forward decomposition. We do this to avoid
1148 exponential run times encountered when looking for longer sequences
1149 with alpha_emit_set_const. */
1152 alpha_emit_set_long_const (target, c)
1156 /* Use a pseudo if highly optimizing and still generating RTL. */
1158 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1160 HOST_WIDE_INT d1, d2, d3, d4;
1163 /* Decompose the entire word */
1164 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1166 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1168 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1170 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1175 /* Construct the high word */
1177 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
1179 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
1181 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1182 subtarget, 0, OPTAB_WIDEN);
1184 /* Shift it into place */
1185 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1186 subtarget, 0, OPTAB_WIDEN);
1188 if (subtarget == 0 && d1 == d3 && d2 == d4)
1189 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1194 /* Add in the low word */
1196 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1197 subtarget, 0, OPTAB_WIDEN);
1199 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1200 subtarget, 0, OPTAB_WIDEN);
1204 r1 = copy_to_suggested_reg(r1, target, DImode);
1208 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1210 /* Rewrite a comparison against zero CMP of the form
1211 (CODE (cc0) (const_int 0)) so it can be written validly in
1212 a conditional move (if_then_else CMP ...).
1213 If both of the operands that set cc0 are non-zero we must emit
1214 an insn to perform the compare (it can't be done within
1215 the conditional move). */
1217 alpha_emit_conditional_move (cmp, mode)
1219 enum machine_mode mode;
1221 enum rtx_code code = GET_CODE (cmp);
1222 enum rtx_code cmov_code = NE;
1223 rtx op0 = alpha_compare_op0;
1224 rtx op1 = alpha_compare_op1;
1225 enum machine_mode cmp_mode
1226 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1227 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1230 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1233 /* We may be able to use a conditional move directly.
1234 This avoids emitting spurious compares. */
1235 if (signed_comparison_operator (cmp, cmp_op_mode)
1236 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1237 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1239 /* We can't put the comparison insides a conditional move;
1240 emit a compare instruction and put that inside the
1241 conditional move. Make sure we emit only comparisons we have;
1242 swap or reverse as necessary. */
1246 case EQ: case LE: case LT: case LEU: case LTU:
1247 /* We have these compares: */
1251 /* This must be reversed. */
1252 code = reverse_condition (code);
1256 case GE: case GT: case GEU: case GTU:
1257 /* These must be swapped. Make sure the new first operand is in
1259 code = swap_condition (code);
1260 tem = op0, op0 = op1, op1 = tem;
1261 op0 = force_reg (cmp_mode, op0);
1268 tem = gen_reg_rtx (cmp_op_mode);
1269 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1270 return gen_rtx_fmt_ee (cmov_code, VOIDmode, tem, CONST0_RTX (cmp_op_mode));
1273 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1277 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1278 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1279 lda r3,X(r11) lda r3,X+2(r11)
1280 extwl r1,r3,r1 extql r1,r3,r1
1281 extwh r2,r3,r2 extqh r2,r3,r2
1282 or r1.r2.r1 or r1,r2,r1
1285 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1286 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1287 lda r3,X(r11) lda r3,X(r11)
1288 extll r1,r3,r1 extll r1,r3,r1
1289 extlh r2,r3,r2 extlh r2,r3,r2
1290 or r1.r2.r1 addl r1,r2,r1
1292 quad: ldq_u r1,X(r11)
1301 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1303 HOST_WIDE_INT size, ofs;
1306 rtx meml, memh, addr, extl, exth;
1308 meml = gen_reg_rtx (DImode);
1309 memh = gen_reg_rtx (DImode);
1310 addr = gen_reg_rtx (DImode);
1311 extl = gen_reg_rtx (DImode);
1312 exth = gen_reg_rtx (DImode);
1314 emit_move_insn (meml,
1315 change_address (mem, DImode,
1316 gen_rtx_AND (DImode,
1317 plus_constant (XEXP (mem, 0),
1321 emit_move_insn (memh,
1322 change_address (mem, DImode,
1323 gen_rtx_AND (DImode,
1324 plus_constant (XEXP (mem, 0),
1328 if (sign && size == 2)
1330 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1332 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1333 emit_insn (gen_extqh (exth, memh, addr));
1335 expand_binop (DImode, ior_optab, extl, exth, addr, 1, OPTAB_WIDEN);
1336 expand_binop (DImode, ashr_optab, addr, GEN_INT (48), addr,
1338 emit_move_insn (tgt, addr);
1342 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1343 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1347 emit_insn (gen_extwh (exth, memh, addr));
1351 emit_insn (gen_extlh (exth, memh, addr));
1355 emit_insn (gen_extqh (exth, memh, addr));
1359 expand_binop (DImode, ior_optab, extl, exth, tgt, sign, OPTAB_WIDEN);
1362 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1365 alpha_expand_unaligned_store (dst, src, size, ofs)
1367 HOST_WIDE_INT size, ofs;
1369 rtx dstl, dsth, addr, insl, insh, meml, memh;
1371 dstl = gen_reg_rtx (DImode);
1372 dsth = gen_reg_rtx (DImode);
1373 insl = gen_reg_rtx (DImode);
1374 insh = gen_reg_rtx (DImode);
1376 meml = change_address (dst, DImode,
1377 gen_rtx_AND (DImode,
1378 plus_constant (XEXP (dst, 0), ofs),
1380 memh = change_address (dst, DImode,
1381 gen_rtx_AND (DImode,
1382 plus_constant (XEXP (dst, 0),
1386 emit_move_insn (dsth, memh);
1387 emit_move_insn (dstl, meml);
1388 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1390 if (src != const0_rtx)
1392 emit_insn (gen_insxh (insh, src, GEN_INT (size*8), addr));
1397 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1400 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1403 emit_insn (gen_insql (insl, src, addr));
1408 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1413 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1416 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1420 #if HOST_BITS_PER_WIDE_INT == 32
1421 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1423 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1425 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1430 if (src != const0_rtx)
1432 expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1433 expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1436 /* Must store high before low for degenerate case of aligned. */
1437 emit_move_insn (memh, dsth);
1438 emit_move_insn (meml, dstl);
1441 /* Load an integral number of consecutive unaligned quadwords. */
1443 #define MAX_MOVE_WORDS 4
1446 alpha_expand_unaligned_load_words (data_regs, src_addr, words)
1447 rtx data_regs[MAX_MOVE_WORDS+1];
1449 HOST_WIDE_INT words;
1451 rtx const im8 = GEN_INT (-8);
1452 rtx const i64 = GEN_INT (64);
1453 rtx ext_tmps[MAX_MOVE_WORDS];
1454 rtx src_reg, and_reg;
1457 /* Generate all the tmp registers we need. */
1458 for (i = 0; i < words; ++i)
1459 ext_tmps[i] = gen_reg_rtx(DImode);
1461 /* Load up all of the source data. */
1462 for (i = 0; i < words; ++i)
1464 emit_move_insn (data_regs[i],
1465 change_address (src_addr, DImode,
1466 gen_rtx_AND (DImode,
1467 plus_constant (XEXP(src_addr,0),
1471 emit_move_insn (data_regs[words],
1472 change_address (src_addr, DImode,
1473 gen_rtx_AND (DImode,
1474 plus_constant (XEXP(src_addr,0),
1478 /* Extract the half-word fragments. Unfortunately DEC decided to make
1479 extxh with offset zero a noop instead of zeroing the register, so
1480 we must take care of that edge condition ourselves with cmov. */
1482 src_reg = copy_addr_to_reg (XEXP (src_addr, 0));
1483 and_reg = expand_binop (DImode, and_optab, src_reg, GEN_INT (7), NULL,
1485 for (i = 0; i < words; ++i)
1487 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, src_reg));
1489 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], src_reg));
1490 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1491 gen_rtx_IF_THEN_ELSE (DImode,
1492 gen_rtx_EQ (DImode, and_reg, const0_rtx),
1493 const0_rtx, ext_tmps[i])));
1496 /* Merge the half-words into whole words. */
1497 for (i = 0; i < words; ++i)
1499 expand_binop (DImode, ior_optab, data_regs[i], ext_tmps[i],
1500 data_regs[i], 1, OPTAB_WIDEN);
1504 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1505 may be NULL to store zeros. */
1508 alpha_expand_unaligned_store_words (data_regs, dst_addr, words)
1511 HOST_WIDE_INT words;
1513 rtx const im8 = GEN_INT (-8);
1514 rtx const i64 = GEN_INT (64);
1515 #if HOST_BITS_PER_WIDE_INT == 32
1516 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1518 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1520 rtx ins_tmps[MAX_MOVE_WORDS];
1521 rtx st_tmp_1, st_tmp_2, dst_reg;
1522 rtx st_addr_1, st_addr_2;
1525 /* Generate all the tmp registers we need. */
1526 if (data_regs != NULL)
1527 for (i = 0; i < words; ++i)
1528 ins_tmps[i] = gen_reg_rtx(DImode);
1529 st_tmp_1 = gen_reg_rtx(DImode);
1530 st_tmp_2 = gen_reg_rtx(DImode);
1532 st_addr_2 = change_address (dst_addr, DImode,
1533 gen_rtx_AND (DImode,
1534 plus_constant (XEXP(dst_addr,0),
1537 st_addr_1 = change_address (dst_addr, DImode,
1538 gen_rtx_AND (DImode,
1542 /* Load up the destination end bits. */
1543 emit_move_insn (st_tmp_2, st_addr_2);
1544 emit_move_insn (st_tmp_1, st_addr_1);
1546 /* Shift the input data into place. */
1547 dst_reg = copy_addr_to_reg (XEXP (dst_addr, 0));
1549 if (data_regs != NULL)
1551 for (i = words-1; i >= 0; --i)
1553 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dst_reg));
1554 emit_insn (gen_insql (data_regs[i], data_regs[i], dst_reg));
1557 for (i = words-1; i > 0; --i)
1559 expand_binop (DImode, ior_optab, data_regs[i], ins_tmps[i-1],
1560 ins_tmps[i-1], 1, OPTAB_WIDEN);
1564 /* Split and merge the ends with the destination data. */
1565 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dst_reg));
1566 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dst_reg));
1568 if (data_regs != NULL)
1570 expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1571 st_tmp_2, 1, OPTAB_WIDEN);
1572 expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1573 st_tmp_1, 1, OPTAB_WIDEN);
1577 emit_move_insn (st_addr_2, st_tmp_2);
1578 for (i = words-1; i > 0; --i)
1580 emit_move_insn (change_address (dst_addr, DImode,
1581 gen_rtx_AND (DImode,
1582 plus_constant(XEXP (dst_addr,0),
1585 data_regs ? ins_tmps[i-1] : const0_rtx);
1587 emit_move_insn (st_addr_1, st_tmp_1);
1591 /* Expand string/block move operations.
1593 operands[0] is the pointer to the destination.
1594 operands[1] is the pointer to the source.
1595 operands[2] is the number of bytes to move.
1596 operands[3] is the alignment. */
1599 alpha_expand_block_move (operands)
1602 rtx bytes_rtx = operands[2];
1603 rtx align_rtx = operands[3];
1604 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1605 HOST_WIDE_INT align = INTVAL (align_rtx);
1606 rtx orig_src = operands[1];
1607 rtx orig_dst = operands[0];
1609 rtx data_regs[2*MAX_MOVE_WORDS];
1610 HOST_WIDE_INT i, words, ofs = 0;
1614 if (bytes > MAX_MOVE_WORDS*8)
1617 /* Handle a block of contiguous words first. */
1619 if (align >= 8 && bytes >= 8)
1623 /* Make some data registers. */
1624 for (i = 0; i < words; ++i)
1625 data_regs[i] = gen_reg_rtx(DImode);
1627 /* Move in aligned hunks. */
1628 for (i = 0; i < words; ++i)
1630 emit_move_insn (data_regs[i],
1631 change_address(orig_src, DImode,
1632 plus_constant (XEXP (orig_src, 0),
1635 for (i = 0; i < words; ++i)
1637 emit_move_insn (change_address(orig_dst, DImode,
1638 plus_constant (XEXP (orig_dst, 0),
1646 if (align >= 4 && bytes >= 4)
1650 /* Make some data registers. */
1651 for (i = 0; i < words; ++i)
1652 data_regs[i] = gen_reg_rtx(SImode);
1654 /* Move in aligned hunks. */
1655 for (i = 0; i < words; ++i)
1657 emit_move_insn (data_regs[i],
1658 change_address(orig_src, SImode,
1659 plus_constant (XEXP (orig_src, 0),
1662 for (i = 0; i < words; ++i)
1664 emit_move_insn (change_address(orig_dst, SImode,
1665 plus_constant (XEXP (orig_dst, 0),
1677 /* Make some data registers. */
1678 for (i = 0; i < words+1; ++i)
1679 data_regs[i] = gen_reg_rtx(DImode);
1681 /* Move in unaligned hunks. */
1682 alpha_expand_unaligned_load_words (data_regs, orig_src, words);
1683 alpha_expand_unaligned_store_words (data_regs, orig_dst, words);
1689 /* Next clean up any trailing pieces. We know from the contiguous
1690 block move that there are no aligned SImode or DImode hunks left. */
1692 if (!TARGET_BWX && bytes >= 8)
1694 tmp = gen_reg_rtx (DImode);
1695 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1696 alpha_expand_unaligned_store (orig_dst, tmp, 8, ofs);
1701 if (!TARGET_BWX && bytes >= 4)
1703 tmp = gen_reg_rtx (DImode);
1704 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1705 alpha_expand_unaligned_store (orig_dst, tmp, 4, ofs);
1715 emit_move_insn (change_address (orig_dst, HImode,
1716 plus_constant (XEXP (orig_dst, 0),
1718 change_address (orig_src, HImode,
1719 plus_constant (XEXP (orig_src, 0),
1723 } while (bytes >= 2);
1725 else if (!TARGET_BWX)
1727 tmp = gen_reg_rtx (DImode);
1728 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1729 alpha_expand_unaligned_store (orig_dst, tmp, 2, ofs);
1736 emit_move_insn (change_address (orig_dst, QImode,
1737 plus_constant (XEXP (orig_dst, 0),
1739 change_address (orig_src, QImode,
1740 plus_constant (XEXP (orig_src, 0),
1750 alpha_expand_block_clear (operands)
1753 rtx bytes_rtx = operands[1];
1754 rtx align_rtx = operands[2];
1755 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1756 HOST_WIDE_INT align = INTVAL (align_rtx);
1757 rtx orig_dst = operands[0];
1758 HOST_WIDE_INT i, words, ofs = 0;
1762 if (bytes > MAX_MOVE_WORDS*8)
1765 /* Handle a block of contiguous words first. */
1767 if (align >= 8 && bytes >= 8)
1771 for (i = 0; i < words; ++i)
1773 emit_move_insn (change_address(orig_dst, DImode,
1774 plus_constant (XEXP (orig_dst, 0),
1782 else if (align >= 4 && bytes >= 4)
1786 for (i = 0; i < words; ++i)
1788 emit_move_insn (change_address(orig_dst, SImode,
1789 plus_constant (XEXP (orig_dst, 0),
1797 else if (bytes >= 16)
1801 alpha_expand_unaligned_store_words (NULL, orig_dst, words);
1807 /* Next clean up any trailing pieces. We know from the contiguous
1808 block move that there are no aligned SImode or DImode hunks left. */
1810 if (!TARGET_BWX && bytes >= 8)
1812 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
1816 if (!TARGET_BWX && bytes >= 4)
1818 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
1827 emit_move_insn (change_address (orig_dst, HImode,
1828 plus_constant (XEXP (orig_dst, 0),
1833 } while (bytes >= 2);
1835 else if (!TARGET_BWX)
1837 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
1844 emit_move_insn (change_address (orig_dst, QImode,
1845 plus_constant (XEXP (orig_dst, 0),
1856 /* Adjust the cost of a scheduling dependency. Return the new cost of
1857 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
1860 alpha_adjust_cost (insn, link, dep_insn, cost)
1867 enum attr_type insn_type, dep_insn_type;
1869 /* If the dependence is an anti-dependence, there is no cost. For an
1870 output dependence, there is sometimes a cost, but it doesn't seem
1871 worth handling those few cases. */
1873 if (REG_NOTE_KIND (link) != 0)
1876 /* If we can't recognize the insns, we can't really do anything. */
1877 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
1880 insn_type = get_attr_type (insn);
1881 dep_insn_type = get_attr_type (dep_insn);
1883 /* Bring in the user-defined memory latency. */
1884 if (dep_insn_type == TYPE_ILD
1885 || dep_insn_type == TYPE_FLD
1886 || dep_insn_type == TYPE_LDSYM)
1887 cost += alpha_memory_latency-1;
1892 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
1893 being stored, we can sometimes lower the cost. */
1895 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
1896 && (set = single_set (dep_insn)) != 0
1897 && GET_CODE (PATTERN (insn)) == SET
1898 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
1900 switch (dep_insn_type)
1904 /* No savings here. */
1908 /* In these cases, we save one cycle. */
1912 /* In all other cases, we save two cycles. */
1913 return MAX (0, cost - 2);
1917 /* Another case that needs adjustment is an arithmetic or logical
1918 operation. It's cost is usually one cycle, but we default it to
1919 two in the MD file. The only case that it is actually two is
1920 for the address in loads, stores, and jumps. */
1922 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
1937 /* The final case is when a compare feeds into an integer branch;
1938 the cost is only one cycle in that case. */
1940 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
1945 /* And the lord DEC saith: "A special bypass provides an effective
1946 latency of 0 cycles for an ICMP or ILOG insn producing the test
1947 operand of an IBR or ICMOV insn." */
1949 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
1950 && (set = single_set (dep_insn)) != 0)
1952 /* A branch only has one input. This must be it. */
1953 if (insn_type == TYPE_IBR)
1955 /* A conditional move has three, make sure it is the test. */
1956 if (insn_type == TYPE_ICMOV
1957 && GET_CODE (set_src = PATTERN (insn)) == SET
1958 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
1959 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
1963 /* "The multiplier is unable to receive data from IEU bypass paths.
1964 The instruction issues at the expected time, but its latency is
1965 increased by the time it takes for the input data to become
1966 available to the multiplier" -- which happens in pipeline stage
1967 six, when results are comitted to the register file. */
1969 if (insn_type == TYPE_IMUL)
1971 switch (dep_insn_type)
1973 /* These insns produce their results in pipeline stage five. */
1980 /* Other integer insns produce results in pipeline stage four. */
1988 /* There is additional latency to move the result of (most) FP
1989 operations anywhere but the FP register file. */
1991 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
1992 && (dep_insn_type == TYPE_FADD ||
1993 dep_insn_type == TYPE_FMUL ||
1994 dep_insn_type == TYPE_FCMOV))
2000 /* Otherwise, return the default cost. */
2004 /* Functions to save and restore alpha_return_addr_rtx. */
2006 struct machine_function
2012 alpha_save_machine_status (p)
2015 struct machine_function *machine =
2016 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2018 p->machine = machine;
2019 machine->ra_rtx = alpha_return_addr_rtx;
2023 alpha_restore_machine_status (p)
2026 struct machine_function *machine = p->machine;
2028 alpha_return_addr_rtx = machine->ra_rtx;
2031 p->machine = (struct machine_function *)0;
2034 /* Do anything needed before RTL is emitted for each function. */
2037 alpha_init_expanders ()
2039 alpha_return_addr_rtx = NULL_RTX;
2041 /* Arrange to save and restore machine status around nested functions. */
2042 save_machine_status = alpha_save_machine_status;
2043 restore_machine_status = alpha_restore_machine_status;
2046 /* Start the ball rolling with RETURN_ADDR_RTX. */
2049 alpha_return_addr (count, frame)
2058 if (alpha_return_addr_rtx)
2059 return alpha_return_addr_rtx;
2061 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2062 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2063 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2064 gen_rtx_REG (Pmode, REG_RA));
2066 /* Emit the insn to the prologue with the other argument copies. */
2067 push_topmost_sequence ();
2068 emit_insn_after (init, get_insns ());
2069 pop_topmost_sequence ();
2071 return alpha_return_addr_rtx;
2075 alpha_ra_ever_killed ()
2079 if (!alpha_return_addr_rtx)
2080 return regs_ever_live[REG_RA];
2082 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2083 get_insns(), NULL_RTX);
2087 /* Print an operand. Recognize special options, documented below. */
2090 print_operand (file, x, code)
2100 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2101 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2102 mode. alpha_fprm controls which suffix is generated. */
2105 case ALPHA_FPRM_NORM:
2107 case ALPHA_FPRM_MINF:
2110 case ALPHA_FPRM_CHOP:
2113 case ALPHA_FPRM_DYN:
2120 /* Generates trap-mode suffix for instructions that accept the su
2121 suffix only (cmpt et al). */
2122 if (alpha_tp == ALPHA_TP_INSN)
2127 /* Generates trap-mode suffix for instructions that accept the u, su,
2128 and sui suffix. This is the bulk of the IEEE floating point
2129 instructions (addt et al). */
2140 case ALPHA_FPTM_SUI:
2141 fputs ("sui", file);
2147 /* Generates trap-mode suffix for instructions that accept the sui
2148 suffix (cvtqt and cvtqs). */
2151 case ALPHA_FPTM_N: case ALPHA_FPTM_U:
2152 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2154 case ALPHA_FPTM_SUI:
2155 fputs ("sui", file);
2161 /* Generates single precision instruction suffix. */
2162 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2166 /* Generates double precision instruction suffix. */
2167 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2171 /* If this operand is the constant zero, write it as "$31". */
2172 if (GET_CODE (x) == REG)
2173 fprintf (file, "%s", reg_names[REGNO (x)]);
2174 else if (x == CONST0_RTX (GET_MODE (x)))
2175 fprintf (file, "$31");
2177 output_operand_lossage ("invalid %%r value");
2182 /* Similar, but for floating-point. */
2183 if (GET_CODE (x) == REG)
2184 fprintf (file, "%s", reg_names[REGNO (x)]);
2185 else if (x == CONST0_RTX (GET_MODE (x)))
2186 fprintf (file, "$f31");
2188 output_operand_lossage ("invalid %%R value");
2193 /* Write the 1's complement of a constant. */
2194 if (GET_CODE (x) != CONST_INT)
2195 output_operand_lossage ("invalid %%N value");
2197 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2201 /* Write 1 << C, for a constant C. */
2202 if (GET_CODE (x) != CONST_INT)
2203 output_operand_lossage ("invalid %%P value");
2205 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2209 /* Write the high-order 16 bits of a constant, sign-extended. */
2210 if (GET_CODE (x) != CONST_INT)
2211 output_operand_lossage ("invalid %%h value");
2213 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2217 /* Write the low-order 16 bits of a constant, sign-extended. */
2218 if (GET_CODE (x) != CONST_INT)
2219 output_operand_lossage ("invalid %%L value");
2221 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2222 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2226 /* Write mask for ZAP insn. */
2227 if (GET_CODE (x) == CONST_DOUBLE)
2229 HOST_WIDE_INT mask = 0;
2230 HOST_WIDE_INT value;
2232 value = CONST_DOUBLE_LOW (x);
2233 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2238 value = CONST_DOUBLE_HIGH (x);
2239 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2242 mask |= (1 << (i + sizeof (int)));
2244 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2247 else if (GET_CODE (x) == CONST_INT)
2249 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2251 for (i = 0; i < 8; i++, value >>= 8)
2255 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2258 output_operand_lossage ("invalid %%m value");
2262 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2263 if (GET_CODE (x) != CONST_INT
2264 || (INTVAL (x) != 8 && INTVAL (x) != 16
2265 && INTVAL (x) != 32 && INTVAL (x) != 64))
2266 output_operand_lossage ("invalid %%M value");
2268 fprintf (file, "%s",
2269 (INTVAL (x) == 8 ? "b"
2270 : INTVAL (x) == 16 ? "w"
2271 : INTVAL (x) == 32 ? "l"
2276 /* Similar, except do it from the mask. */
2277 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2278 fprintf (file, "b");
2279 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2280 fprintf (file, "w");
2281 #if HOST_BITS_PER_WIDE_INT == 32
2282 else if (GET_CODE (x) == CONST_DOUBLE
2283 && CONST_DOUBLE_HIGH (x) == 0
2284 && CONST_DOUBLE_LOW (x) == -1)
2285 fprintf (file, "l");
2286 else if (GET_CODE (x) == CONST_DOUBLE
2287 && CONST_DOUBLE_HIGH (x) == -1
2288 && CONST_DOUBLE_LOW (x) == -1)
2289 fprintf (file, "q");
2291 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2292 fprintf (file, "l");
2293 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2294 fprintf (file, "q");
2295 else if (GET_CODE (x) == CONST_DOUBLE
2296 && CONST_DOUBLE_HIGH (x) == 0
2297 && CONST_DOUBLE_LOW (x) == -1)
2298 fprintf (file, "q");
2301 output_operand_lossage ("invalid %%U value");
2305 /* Write the constant value divided by 8. */
2306 if (GET_CODE (x) != CONST_INT
2307 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2308 && (INTVAL (x) & 7) != 8)
2309 output_operand_lossage ("invalid %%s value");
2311 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2315 /* Same, except compute (64 - c) / 8 */
2317 if (GET_CODE (x) != CONST_INT
2318 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2319 && (INTVAL (x) & 7) != 8)
2320 output_operand_lossage ("invalid %%s value");
2322 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2325 case 'C': case 'D': case 'c': case 'd':
2326 /* Write out comparison name. */
2328 enum rtx_code c = GET_CODE (x);
2330 if (GET_RTX_CLASS (c) != '<')
2331 output_operand_lossage ("invalid %%C value");
2334 c = reverse_condition (c);
2335 else if (code == 'c')
2336 c = swap_condition (c);
2337 else if (code == 'd')
2338 c = swap_condition (reverse_condition (c));
2341 fprintf (file, "ule");
2343 fprintf (file, "ult");
2345 fprintf (file, "%s", GET_RTX_NAME (c));
2350 /* Write the divide or modulus operator. */
2351 switch (GET_CODE (x))
2354 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2357 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2360 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2363 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2366 output_operand_lossage ("invalid %%E value");
2372 /* Write "_u" for unaligned access. */
2373 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2374 fprintf (file, "_u");
2378 if (GET_CODE (x) == REG)
2379 fprintf (file, "%s", reg_names[REGNO (x)]);
2380 else if (GET_CODE (x) == MEM)
2381 output_address (XEXP (x, 0));
2383 output_addr_const (file, x);
2387 output_operand_lossage ("invalid %%xn code");
2391 /* Do what is necessary for `va_start'. The argument is ignored;
2392 We look at the current function to determine if stdarg or varargs
2393 is used and fill in an initial va_list. A pointer to this constructor
2397 alpha_builtin_saveregs (arglist)
2400 rtx block, addr, dest, argsize;
2401 tree fntype = TREE_TYPE (current_function_decl);
2402 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2403 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2404 != void_type_node));
2406 /* Compute the current position into the args, taking into account
2407 both registers and memory. Both of these are already included in
2410 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2412 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2413 storing fp arg registers in the first 48 bytes, and the integer arg
2414 registers in the next 48 bytes. This is only done, however, if any
2415 integer registers need to be stored.
2417 If no integer registers need be stored, then we must subtract 48 in
2418 order to account for the integer arg registers which are counted in
2419 argsize above, but which are not actually stored on the stack. */
2421 if (TARGET_OPEN_VMS)
2422 addr = plus_constant (virtual_incoming_args_rtx,
2423 NUM_ARGS <= 5 + stdarg
2424 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2426 addr = (NUM_ARGS <= 5 + stdarg
2427 ? plus_constant (virtual_incoming_args_rtx,
2429 : plus_constant (virtual_incoming_args_rtx,
2430 - (6 * UNITS_PER_WORD)));
2432 /* For VMS, we include the argsize, while on Unix, it's handled as
2433 a separate field. */
2434 if (TARGET_OPEN_VMS)
2435 addr = plus_constant (addr, INTVAL (argsize));
2437 addr = force_operand (addr, NULL_RTX);
2439 #ifdef POINTERS_EXTEND_UNSIGNED
2440 addr = convert_memory_address (ptr_mode, addr);
2443 if (TARGET_OPEN_VMS)
2447 /* Allocate the va_list constructor */
2448 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2449 RTX_UNCHANGING_P (block) = 1;
2450 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2452 /* Store the address of the first integer register in the __base
2455 dest = change_address (block, ptr_mode, XEXP (block, 0));
2456 emit_move_insn (dest, addr);
2458 if (flag_check_memory_usage)
2459 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2461 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2462 TYPE_MODE (sizetype),
2463 GEN_INT (MEMORY_USE_RW),
2464 TYPE_MODE (integer_type_node));
2466 /* Store the argsize as the __va_offset member. */
2467 dest = change_address (block, TYPE_MODE (integer_type_node),
2468 plus_constant (XEXP (block, 0),
2469 POINTER_SIZE/BITS_PER_UNIT));
2470 emit_move_insn (dest, argsize);
2472 if (flag_check_memory_usage)
2473 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2475 GEN_INT (GET_MODE_SIZE
2476 (TYPE_MODE (integer_type_node))),
2477 TYPE_MODE (sizetype),
2478 GEN_INT (MEMORY_USE_RW),
2479 TYPE_MODE (integer_type_node));
2481 /* Return the address of the va_list constructor, but don't put it in a
2482 register. Doing so would fail when not optimizing and produce worse
2483 code when optimizing. */
2484 return XEXP (block, 0);
2488 /* This page contains routines that are used to determine what the function
2489 prologue and epilogue code will do and write them out. */
2491 /* Compute the size of the save area in the stack. */
2495 /* These variables are used for communication between the following functions.
2496 They indicate various things about the current function being compiled
2497 that are used to tell what kind of prologue, epilogue and procedure
2498 descriptior to generate. */
2500 /* Nonzero if we need a stack procedure. */
2501 static int is_stack_procedure;
2503 /* Register number (either FP or SP) that is used to unwind the frame. */
2504 static int unwind_regno;
2506 /* Register number used to save FP. We need not have one for RA since
2507 we don't modify it for register procedures. This is only defined
2508 for register frame procedures. */
2509 static int save_fp_regno;
2511 /* Register number used to reference objects off our PV. */
2512 static int base_regno;
2514 /* Compute register masks for saved registers. */
2517 alpha_sa_mask (imaskP, fmaskP)
2518 unsigned long *imaskP;
2519 unsigned long *fmaskP;
2521 unsigned long imask = 0;
2522 unsigned long fmask = 0;
2525 if (is_stack_procedure)
2526 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2528 /* One for every register we have to save. */
2530 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2531 if (! fixed_regs[i] && ! call_used_regs[i]
2532 && regs_ever_live[i] && i != REG_RA)
2537 fmask |= (1L << (i - 32));
2550 HOST_WIDE_INT stack_needed;
2553 /* One for every register we have to save. */
2555 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2556 if (! fixed_regs[i] && ! call_used_regs[i]
2557 && regs_ever_live[i] && i != REG_RA)
2560 /* Start by assuming we can use a register procedure if we don't make any
2561 calls (REG_RA not used) or need to save any registers and a stack
2562 procedure if we do. */
2563 is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2565 /* Decide whether to refer to objects off our PV via FP or PV.
2566 If we need need FP for something else or if we receive a nonlocal
2567 goto (which expects PV to contain the value), we must use PV.
2568 Otherwise, start by assuming we can use FP. */
2569 base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
2570 || is_stack_procedure
2571 || current_function_outgoing_args_size
2572 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
2574 /* If we want to copy PV into FP, we need to find some register in which to
2579 if (base_regno == HARD_FRAME_POINTER_REGNUM)
2580 for (i = 0; i < 32; i++)
2581 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
2584 if (save_fp_regno == -1)
2585 base_regno = REG_PV, is_stack_procedure = 1;
2587 /* Stack unwinding should be done via FP unless we use it for PV. */
2589 = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
2591 /* If this is a stack procedure, allow space for saving FP and RA. */
2592 if (is_stack_procedure)
2599 alpha_pv_save_size ()
2602 return is_stack_procedure ? 8 : 0;
2609 return unwind_regno == HARD_FRAME_POINTER_REGNUM;
2612 #else /* ! OPEN_VMS */
2620 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2621 if (! fixed_regs[i] && ! call_used_regs[i]
2622 && regs_ever_live[i] && i != REG_RA)
2625 /* If some registers were saved but not reg 26, reg 26 must also
2626 be saved, so leave space for it. */
2627 if (size != 0 || alpha_ra_ever_killed ())
2630 /* Our size must be even (multiple of 16 bytes). */
2637 #endif /* ! OPEN_VMS */
2639 /* Return 1 if this function can directly return via $26. */
2644 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
2645 && get_frame_size () == 0
2646 && current_function_outgoing_args_size == 0
2647 && current_function_pretend_args_size == 0);
2650 /* Write a version stamp. Don't write anything if we are running as a
2651 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
2653 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__) && !defined(VMS)
2658 alpha_write_verstamp (file)
2662 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
2666 /* Write code to add constant C to register number IN_REG (possibly 31)
2667 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
2668 usually this will be OUT_REG, but should not be if OUT_REG is
2669 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
2670 Write the code to FILE. */
2673 add_long_const (file, c, in_reg, out_reg, temp_reg)
2676 int in_reg, out_reg, temp_reg;
2678 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
2679 HOST_WIDE_INT tmp1 = c - low;
2680 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
2681 HOST_WIDE_INT extra = 0;
2683 /* We don't have code to write out constants larger than 32 bits. */
2684 #if HOST_BITS_PER_LONG_INT == 64
2685 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
2689 /* If HIGH will be interpreted as negative, we must adjust it to do two
2690 ldha insns. Note that we will never be building a negative constant
2697 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
2702 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
2704 if (low >= 0 && low < 255)
2705 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
2707 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
2709 in_reg = result_reg;
2714 int result_reg = (high == 0) ? out_reg : temp_reg;
2716 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
2717 in_reg = result_reg;
2721 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
2724 /* Write function prologue. */
2728 /* On vms we have two kinds of functions:
2730 - stack frame (PROC_STACK)
2731 these are 'normal' functions with local vars and which are
2732 calling other functions
2733 - register frame (PROC_REGISTER)
2734 keeps all data in registers, needs no stack
2736 We must pass this to the assembler so it can generate the
2737 proper pdsc (procedure descriptor)
2738 This is done with the '.pdesc' command.
2740 size is the stack size needed for local variables. */
2743 output_prolog (file, size)
2747 unsigned long imask = 0;
2748 unsigned long fmask = 0;
2749 /* Stack space needed for pushing registers clobbered by us. */
2750 HOST_WIDE_INT sa_size;
2751 /* Complete stack size needed. */
2752 HOST_WIDE_INT frame_size;
2753 /* Offset from base reg to register save area. */
2755 /* Offset during register save. */
2757 /* Label for the procedure entry. */
2758 char *entry_label = (char *) alloca (strlen (alpha_function_name) + 6);
2761 sa_size = alpha_sa_size ();
2763 = ALPHA_ROUND (sa_size
2764 + (is_stack_procedure ? 8 : 0)
2765 + size + current_function_pretend_args_size);
2767 /* Issue function start and label. */
2768 fprintf (file, "\t.ent ");
2769 assemble_name (file, alpha_function_name);
2770 fprintf (file, "\n");
2771 sprintf (entry_label, "$%s..en", alpha_function_name);
2772 ASM_OUTPUT_LABEL (file, entry_label);
2773 inside_function = TRUE;
2775 fprintf (file, "\t.base $%d\n", base_regno);
2777 /* Calculate register masks for clobbered registers. */
2779 if (is_stack_procedure)
2780 alpha_sa_mask (&imask, &fmask);
2782 /* Adjust the stack by the frame size. If the frame size is > 4096
2783 bytes, we need to be sure we probe somewhere in the first and last
2784 4096 bytes (we can probably get away without the latter test) and
2785 every 8192 bytes in between. If the frame size is > 32768, we
2786 do this in a loop. Otherwise, we generate the explicit probe
2789 Note that we are only allowed to adjust sp once in the prologue. */
2791 if (frame_size < 32768)
2793 if (frame_size > 4096)
2797 fprintf (file, "\tstq $31,-%d($30)\n", probed);
2799 while (probed + 8192 < frame_size)
2800 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
2802 /* We only have to do this probe if we aren't saving registers. */
2803 if (sa_size == 0 && probed + 4096 < frame_size)
2804 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
2807 if (frame_size != 0)
2808 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
2812 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
2813 number of 8192 byte blocks to probe. We then probe each block
2814 in the loop and then set SP to the proper location. If the
2815 amount remaining is > 4096, we have to do one more probe if we
2816 are not saving any registers. */
2818 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
2819 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
2821 add_long_const (file, blocks, 31, 23, 23);
2823 fprintf (file, "\tlda $22,4096($30)\n");
2826 assemble_name (file, alpha_function_name);
2827 fprintf (file, "..sc:\n");
2829 fprintf (file, "\tstq $31,-8192($22)\n");
2830 fprintf (file, "\tsubq $23,1,$23\n");
2831 fprintf (file, "\tlda $22,-8192($22)\n");
2833 fprintf (file, "\tbne $23,$");
2834 assemble_name (file, alpha_function_name);
2835 fprintf (file, "..sc\n");
2837 if (leftover > 4096 && sa_size == 0)
2838 fprintf (file, "\tstq $31,-%d($22)\n", leftover);
2840 fprintf (file, "\tlda $30,-%d($22)\n", leftover);
2843 if (is_stack_procedure)
2845 int reg_offset = rsa_offset;
2847 /* Store R26 (RA) first. */
2848 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
2851 /* Store integer regs. according to mask. */
2852 for (i = 0; i < 32; i++)
2853 if (imask & (1L<<i))
2855 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
2859 /* Print the register mask and do floating-point saves. */
2862 fprintf (file, "\t.mask 0x%x,0\n", imask);
2864 for (i = 0; i < 32; i++)
2866 if (fmask & (1L << i))
2868 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
2873 /* Print the floating-point mask, if we've saved any fp register. */
2875 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
2877 fprintf (file, "\tstq $27,0($30)\n");
2881 fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
2882 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
2883 HARD_FRAME_POINTER_REGNUM, save_fp_regno);
2886 if (base_regno != REG_PV)
2887 fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
2889 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
2890 fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
2891 STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
2893 /* Describe our frame. */
2894 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
2895 unwind_regno, frame_size, rsa_offset);
2897 /* If we have to allocate space for outgoing args, do it now. */
2898 if (current_function_outgoing_args_size != 0)
2899 fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
2900 - ALPHA_ROUND (current_function_outgoing_args_size),
2901 HARD_FRAME_POINTER_REGNUM);
2903 fprintf (file, "\t.prologue\n");
2906 fprintf (file, "\t.align 3\n");
2907 ASM_OUTPUT_LABEL (file, alpha_function_name);
2908 fprintf (file, "\t.pdesc $");
2909 assemble_name (file, alpha_function_name);
2910 fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
2911 alpha_need_linkage (alpha_function_name, 1);
2917 /* Write function epilogue. */
2920 output_epilog (file, size)
2924 unsigned long imask = 0;
2925 unsigned long fmask = 0;
2926 /* Stack space needed for pushing registers clobbered by us. */
2927 HOST_WIDE_INT sa_size = alpha_sa_size ();
2928 /* Complete stack size needed. */
2929 HOST_WIDE_INT frame_size
2930 = ALPHA_ROUND (sa_size
2931 + (is_stack_procedure ? 8 : 0)
2932 + size + current_function_pretend_args_size);
2934 rtx insn = get_last_insn ();
2936 /* If the last insn was a BARRIER, we don't have to write anything except
2937 the .end pseudo-op. */
2939 if (GET_CODE (insn) == NOTE)
2940 insn = prev_nonnote_insn (insn);
2942 if (insn == 0 || GET_CODE (insn) != BARRIER)
2944 /* Restore clobbered registers, load FP last. */
2946 if (is_stack_procedure)
2952 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
2953 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
2954 HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
2956 alpha_sa_mask (&imask, &fmask);
2958 /* Start reloading registers after RA. */
2959 reg_offset = rsa_offset + 8;
2961 for (i = 0; i < 32; i++)
2962 if (imask & (1L<<i))
2964 if (i == HARD_FRAME_POINTER_REGNUM)
2965 fp_offset = reg_offset;
2967 fprintf (file, "\tldq $%d,%d($30)\n",
2972 for (i = 0; i < 32; i++)
2973 if (fmask & (1L << i))
2975 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
2979 /* Restore R26 (RA). */
2980 fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
2982 /* Restore R29 (FP). */
2983 fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
2986 fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
2987 HARD_FRAME_POINTER_REGNUM);
2989 if (frame_size != 0)
2991 if (frame_size < 32768)
2992 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
2995 long high = frame_size >> 16;
2996 long low = frame_size & 0xffff;
3000 low = -32768 + (low & 0x7fff);
3002 fprintf (file, "\tldah $2,%ld($31)\n", high);
3003 fprintf (file, "\tlda $2,%ld($2)\n", low);
3004 fprintf (file, "\taddq $30,$2,$30\n");
3008 /* Finally return to the caller. */
3009 fprintf (file, "\tret $31,($26),1\n");
3012 /* End the function. */
3013 fprintf (file, "\t.end ");
3014 assemble_name (file, alpha_function_name);
3015 fprintf (file, "\n");
3016 inside_function = FALSE;
3018 /* Show that we know this function if it is called again. */
3019 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3023 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3029 if (is_attribute_p ("overlaid", identifier))
3030 return (args == NULL_TREE);
3034 #else /* !OPEN_VMS */
3037 alpha_does_function_need_gp ()
3041 /* We never need a GP for Windows/NT. */
3042 if (TARGET_WINDOWS_NT)
3045 #ifdef TARGET_PROFILING_NEEDS_GP
3050 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3051 Even if we are a static function, we still need to do this in case
3052 our address is taken and passed to something like qsort. */
3054 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3055 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3056 && GET_CODE (PATTERN (insn)) != USE
3057 && GET_CODE (PATTERN (insn)) != CLOBBER)
3059 enum attr_type type = get_attr_type (insn);
3060 if (type == TYPE_LDSYM || type == TYPE_JSR)
3068 output_prolog (file, size)
3072 HOST_WIDE_INT out_args_size
3073 = ALPHA_ROUND (current_function_outgoing_args_size);
3074 HOST_WIDE_INT sa_size = alpha_sa_size ();
3075 HOST_WIDE_INT frame_size
3076 = (out_args_size + sa_size
3077 + ALPHA_ROUND (size + current_function_pretend_args_size));
3078 HOST_WIDE_INT reg_offset = out_args_size;
3079 HOST_WIDE_INT start_reg_offset = reg_offset;
3080 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
3081 int int_reg_save_area_size = 0;
3082 unsigned reg_mask = 0;
3085 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3086 We have to do that before the .ent directive as we cannot switch
3087 files within procedures with native ecoff because line numbers are
3088 linked to procedure descriptors.
3089 Outputting the lineno helps debugging of one line functions as they
3090 would otherwise get no line number at all. Please note that we would
3091 like to put out last_linenum from final.c, but it is not accessible. */
3093 if (write_symbols == SDB_DEBUG)
3095 ASM_OUTPUT_SOURCE_FILENAME (file,
3096 DECL_SOURCE_FILE (current_function_decl));
3097 if (debug_info_level != DINFO_LEVEL_TERSE)
3098 ASM_OUTPUT_SOURCE_LINE (file,
3099 DECL_SOURCE_LINE (current_function_decl));
3102 /* The assembly language programmer's guide states that the second argument
3103 to the .ent directive, the lex_level, is ignored by the assembler,
3104 so we might as well omit it. */
3106 if (!flag_inhibit_size_directive)
3108 fprintf (file, "\t.ent ");
3109 assemble_name (file, alpha_function_name);
3110 fprintf (file, "\n");
3112 ASM_OUTPUT_LABEL (file, alpha_function_name);
3113 inside_function = TRUE;
3115 if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
3116 /* Set flags in procedure descriptor to request IEEE-conformant
3117 math-library routines. The value we set it to is PDSC_EXC_IEEE
3118 (/usr/include/pdsc.h). */
3119 fprintf (file, "\t.eflag 48\n");
3121 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3123 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3124 alpha_arg_offset = -frame_size + 48;
3126 alpha_function_needs_gp = alpha_does_function_need_gp ();
3128 if (TARGET_WINDOWS_NT == 0)
3130 if (alpha_function_needs_gp)
3131 fprintf (file, "\tldgp $29,0($27)\n");
3133 /* Put a label after the GP load so we can enter the function at it. */
3135 assemble_name (file, alpha_function_name);
3136 fprintf (file, "..ng:\n");
3139 /* Adjust the stack by the frame size. If the frame size is > 4096
3140 bytes, we need to be sure we probe somewhere in the first and last
3141 4096 bytes (we can probably get away without the latter test) and
3142 every 8192 bytes in between. If the frame size is > 32768, we
3143 do this in a loop. Otherwise, we generate the explicit probe
3146 Note that we are only allowed to adjust sp once in the prologue. */
3148 if (frame_size < 32768)
3150 if (frame_size > 4096)
3154 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3156 while (probed + 8192 < frame_size)
3157 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3159 /* We only have to do this probe if we aren't saving registers. */
3160 if (sa_size == 0 && probed + 4096 < frame_size)
3161 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3164 if (frame_size != 0)
3165 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3169 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
3170 number of 8192 byte blocks to probe. We then probe each block
3171 in the loop and then set SP to the proper location. If the
3172 amount remaining is > 4096, we have to do one more probe if we
3173 are not saving any registers. */
3175 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3176 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3178 add_long_const (file, blocks, 31, 5, 5);
3180 fprintf (file, "\tlda $4,4096($30)\n");
3183 assemble_name (file, alpha_function_name);
3184 fprintf (file, "..sc:\n");
3186 fprintf (file, "\tstq $31,-8192($4)\n");
3187 fprintf (file, "\tsubq $5,1,$5\n");
3188 fprintf (file, "\tlda $4,-8192($4)\n");
3190 fprintf (file, "\tbne $5,$");
3191 assemble_name (file, alpha_function_name);
3192 fprintf (file, "..sc\n");
3194 if (leftover > 4096 && sa_size == 0)
3195 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
3197 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
3200 /* Describe our frame. */
3201 if (!flag_inhibit_size_directive)
3203 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
3204 (frame_pointer_needed
3205 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
3206 frame_size, current_function_pretend_args_size);
3209 /* Cope with very large offsets to the register save area. */
3211 if (reg_offset + sa_size > 0x8000)
3213 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3214 if (low + sa_size <= 0x8000)
3216 add_long_const (file, reg_offset - low, 30, 24, 24);
3221 add_long_const (file, reg_offset, 30, 24, 24);
3227 /* Save register RA if any other register needs to be saved. */
3230 reg_mask |= 1 << REG_RA;
3231 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
3233 int_reg_save_area_size += 8;
3236 /* Now save any other used integer registers required to be saved. */
3237 for (i = 0; i < 32; i++)
3238 if (! fixed_regs[i] && ! call_used_regs[i]
3239 && regs_ever_live[i] && i != REG_RA)
3242 fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3244 int_reg_save_area_size += 8;
3247 /* Print the register mask and do floating-point saves. */
3248 if (reg_mask && !flag_inhibit_size_directive)
3249 fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
3250 actual_start_reg_offset - frame_size);
3252 start_reg_offset = reg_offset;
3255 for (i = 0; i < 32; i++)
3256 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3257 && regs_ever_live[i + 32])
3260 fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3264 /* Print the floating-point mask, if we've saved any fp register. */
3265 if (reg_mask && !flag_inhibit_size_directive)
3266 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
3267 actual_start_reg_offset - frame_size + int_reg_save_area_size);
3269 /* If we need a frame pointer, set it from the stack pointer. Note that
3270 this must always be the last instruction in the prologue. */
3271 if (frame_pointer_needed)
3272 fprintf (file, "\tbis $30,$30,$15\n");
3274 /* End the prologue and say if we used gp. */
3275 if (!flag_inhibit_size_directive)
3276 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3279 /* Write function epilogue. */
3282 output_epilog (file, size)
3286 rtx insn = get_last_insn ();
3287 HOST_WIDE_INT out_args_size
3288 = ALPHA_ROUND (current_function_outgoing_args_size);
3289 HOST_WIDE_INT sa_size = alpha_sa_size ();
3290 HOST_WIDE_INT frame_size
3291 = (out_args_size + sa_size
3292 + ALPHA_ROUND (size + current_function_pretend_args_size));
3293 HOST_WIDE_INT reg_offset = out_args_size;
3294 HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
3296 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
3299 /* If the last insn was a BARRIER, we don't have to write anything except
3300 the .end pseudo-op. */
3301 if (GET_CODE (insn) == NOTE)
3302 insn = prev_nonnote_insn (insn);
3303 if (insn == 0 || GET_CODE (insn) != BARRIER)
3308 /* If we have a frame pointer, restore SP from it. */
3309 if (frame_pointer_needed)
3310 fprintf (file, "\tbis $15,$15,$30\n");
3312 /* Cope with large offsets to the register save area. */
3314 if (reg_offset + sa_size > 0x8000)
3316 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3317 if (low + sa_size <= 0x8000)
3319 add_long_const (file, reg_offset - low, 30, 24, 24);
3324 add_long_const (file, reg_offset, 30, 24, 24);
3330 /* Restore all the registers, starting with the return address
3334 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
3338 /* Now restore any other used integer registers that that we saved,
3339 except for FP if it is being used as FP, since it must be
3342 for (i = 0; i < 32; i++)
3343 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
3346 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3347 fp_offset = reg_offset;
3349 fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3353 for (i = 0; i < 32; i++)
3354 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3355 && regs_ever_live[i + 32])
3357 fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3361 /* If the stack size is large and we have a frame pointer, compute the
3362 size of the stack into a register because the old FP restore, stack
3363 pointer adjust, and return are required to be consecutive
3365 if (frame_size > 32767 && restore_fp)
3366 add_long_const (file, frame_size, 31, 1, 1);
3368 /* If we needed a frame pointer and we have to restore it, do it
3369 now. This must be done in one instruction immediately
3370 before the SP update. */
3371 if (restore_fp && fp_offset)
3372 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
3374 /* Now update the stack pointer, if needed. Only one instruction must
3375 modify the stack pointer. It must be the last instruction in the
3376 sequence and must be an ADDQ or LDA instruction. If the frame
3377 pointer was loaded above, we may only put one instruction here. */
3379 if (frame_size > 32768 && restore_fp)
3380 fprintf (file, "\taddq $1,$30,$30\n");
3382 add_long_const (file, frame_size, 30, 30, 1);
3384 /* Finally return to the caller. */
3385 fprintf (file, "\tret $31,($26),1\n");
3388 /* End the function. */
3389 if (!flag_inhibit_size_directive)
3391 fprintf (file, "\t.end ");
3392 assemble_name (file, alpha_function_name);
3393 fprintf (file, "\n");
3395 inside_function = FALSE;
3397 /* Show that we know this function if it is called again. */
3398 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3400 #endif /* !OPEN_VMS */
3402 /* Debugging support. */
3406 /* Count the number of sdb related labels are generated (to find block
3407 start and end boundaries). */
3409 int sdb_label_count = 0;
3411 /* Next label # for each statement. */
3413 static int sym_lineno = 0;
3415 /* Count the number of .file directives, so that .loc is up to date. */
3417 static int num_source_filenames = 0;
3419 /* Name of the file containing the current function. */
3421 static char *current_function_file = "";
3423 /* Offsets to alpha virtual arg/local debugging pointers. */
3425 long alpha_arg_offset;
3426 long alpha_auto_offset;
3428 /* Emit a new filename to a stream. */
3431 alpha_output_filename (stream, name)
3435 static int first_time = TRUE;
3436 char ltext_label_name[100];
3441 ++num_source_filenames;
3442 current_function_file = name;
3443 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3444 output_quoted_string (stream, name);
3445 fprintf (stream, "\n");
3446 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3447 fprintf (stream, "\t#@stabs\n");
3450 else if (write_symbols == DBX_DEBUG)
3452 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3453 fprintf (stream, "%s ", ASM_STABS_OP);
3454 output_quoted_string (stream, name);
3455 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3458 else if (name != current_function_file
3459 && strcmp (name, current_function_file) != 0)
3461 if (inside_function && ! TARGET_GAS)
3462 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3465 ++num_source_filenames;
3466 current_function_file = name;
3467 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3470 output_quoted_string (stream, name);
3471 fprintf (stream, "\n");
3475 /* Emit a linenumber to a stream. */
3478 alpha_output_lineno (stream, line)
3482 if (write_symbols == DBX_DEBUG)
3484 /* mips-tfile doesn't understand .stabd directives. */
3486 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3487 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3490 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3493 /* Structure to show the current status of registers and memory. */
3495 struct shadow_summary
3498 unsigned long i : 31; /* Mask of int regs */
3499 unsigned long fp : 31; /* Mask of fp regs */
3500 unsigned long mem : 1; /* mem == imem | fpmem */
3504 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3505 to the summary structure. SET is nonzero if the insn is setting the
3506 object, otherwise zero. */
3509 summarize_insn (x, sum, set)
3511 struct shadow_summary *sum;
3520 switch (GET_CODE (x))
3522 /* ??? Note that this case would be incorrect if the Alpha had a
3523 ZERO_EXTRACT in SET_DEST. */
3525 summarize_insn (SET_SRC (x), sum, 0);
3526 summarize_insn (SET_DEST (x), sum, 1);
3530 summarize_insn (XEXP (x, 0), sum, 1);
3534 summarize_insn (XEXP (x, 0), sum, 0);
3538 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3539 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3543 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3544 summarize_insn (XVECEXP (x, 0, i), sum, 0);
3553 int regno = REGNO (x);
3554 unsigned long mask = 1UL << (regno % 32);
3556 if (regno == 31 || regno == 63)
3562 sum->defd.i |= mask;
3564 sum->defd.fp |= mask;
3569 sum->used.i |= mask;
3571 sum->used.fp |= mask;
3582 /* Find the regs used in memory address computation: */
3583 summarize_insn (XEXP (x, 0), sum, 0);
3586 case CONST_INT: case CONST_DOUBLE:
3587 case SYMBOL_REF: case LABEL_REF: case CONST:
3590 /* Handle common unary and binary ops for efficiency. */
3591 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
3592 case MOD: case UDIV: case UMOD: case AND: case IOR:
3593 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
3594 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
3595 case NE: case EQ: case GE: case GT: case LE:
3596 case LT: case GEU: case GTU: case LEU: case LTU:
3597 summarize_insn (XEXP (x, 0), sum, 0);
3598 summarize_insn (XEXP (x, 1), sum, 0);
3601 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
3602 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
3603 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
3604 case SQRT: case FFS:
3605 summarize_insn (XEXP (x, 0), sum, 0);
3609 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
3610 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3611 switch (format_ptr[i])
3614 summarize_insn (XEXP (x, i), sum, 0);
3618 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3619 summarize_insn (XVECEXP (x, i, j), sum, 0);
3628 /* Ensure a sufficient number of `trapb' insns are in the code when the user
3629 requests code with a trap precision of functions or instructions.
3631 In naive mode, when the user requests a trap-precision of "instruction", a
3632 trapb is needed after every instruction that may generate a trap (and after
3633 jsr/bsr instructions, because called functions may import a trap from the
3634 caller). This ensures that the code is resumption safe but it is also slow.
3636 When optimizations are turned on, we delay issuing a trapb as long as
3637 possible. In this context, a trap shadow is the sequence of instructions
3638 that starts with a (potentially) trap generating instruction and extends to
3639 the next trapb or call_pal instruction (but GCC never generates call_pal by
3640 itself). We can delay (and therefore sometimes omit) a trapb subject to the
3641 following conditions:
3643 (a) On entry to the trap shadow, if any Alpha register or memory location
3644 contains a value that is used as an operand value by some instruction in
3645 the trap shadow (live on entry), then no instruction in the trap shadow
3646 may modify the register or memory location.
3648 (b) Within the trap shadow, the computation of the base register for a
3649 memory load or store instruction may not involve using the result
3650 of an instruction that might generate an UNPREDICTABLE result.
3652 (c) Within the trap shadow, no register may be used more than once as a
3653 destination register. (This is to make life easier for the trap-handler.)
3655 (d) The trap shadow may not include any branch instructions. */
3658 alpha_handle_trap_shadows (insns)
3661 struct shadow_summary shadow;
3662 int trap_pending, exception_nesting;
3665 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
3669 exception_nesting = 0;
3672 shadow.used.mem = 0;
3673 shadow.defd = shadow.used;
3675 for (i = insns; i ; i = NEXT_INSN (i))
3677 if (GET_CODE (i) == NOTE)
3679 switch (NOTE_LINE_NUMBER (i))
3681 case NOTE_INSN_EH_REGION_BEG:
3682 exception_nesting++;
3687 case NOTE_INSN_EH_REGION_END:
3688 exception_nesting--;
3693 case NOTE_INSN_EPILOGUE_BEG:
3694 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
3699 else if (trap_pending)
3701 if (alpha_tp == ALPHA_TP_FUNC)
3703 if (GET_CODE (i) == JUMP_INSN
3704 && GET_CODE (PATTERN (i)) == RETURN)
3707 else if (alpha_tp == ALPHA_TP_INSN)
3711 struct shadow_summary sum;
3716 sum.defd = sum.used;
3718 switch (GET_CODE (i))
3721 /* Annoyingly, get_attr_trap will abort on USE. */
3722 if (GET_CODE (PATTERN (i)) == USE)
3725 summarize_insn (PATTERN (i), &sum, 0);
3727 if ((sum.defd.i & shadow.defd.i)
3728 || (sum.defd.fp & shadow.defd.fp))
3730 /* (c) would be violated */
3734 /* Combine shadow with summary of current insn: */
3735 shadow.used.i |= sum.used.i;
3736 shadow.used.fp |= sum.used.fp;
3737 shadow.used.mem |= sum.used.mem;
3738 shadow.defd.i |= sum.defd.i;
3739 shadow.defd.fp |= sum.defd.fp;
3740 shadow.defd.mem |= sum.defd.mem;
3742 if ((sum.defd.i & shadow.used.i)
3743 || (sum.defd.fp & shadow.used.fp)
3744 || (sum.defd.mem & shadow.used.mem))
3746 /* (a) would be violated (also takes care of (b)) */
3747 if (get_attr_trap (i) == TRAP_YES
3748 && ((sum.defd.i & sum.used.i)
3749 || (sum.defd.fp & sum.used.fp)))
3768 emit_insn_before (gen_trapb (), i);
3772 shadow.used.mem = 0;
3773 shadow.defd = shadow.used;
3778 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
3779 && GET_CODE (i) == INSN
3780 && GET_CODE (PATTERN (i)) != USE
3781 && GET_CODE (PATTERN (i)) != CLOBBER
3782 && get_attr_trap (i) == TRAP_YES)
3784 if (optimize && !trap_pending)
3785 summarize_insn (PATTERN (i), &shadow, 0);
3791 /* Machine dependant reorg pass. */
3797 alpha_handle_trap_shadows (insns);
3801 /* Check a floating-point value for validity for a particular machine mode. */
3803 static char *float_strings[] =
3805 /* These are for FLOAT_VAX. */
3806 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
3807 "-1.70141173319264430e+38",
3808 "2.93873587705571877e-39", /* 2^-128 */
3809 "-2.93873587705571877e-39",
3810 /* These are for the default broken IEEE mode, which traps
3811 on infinity or denormal numbers. */
3812 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
3813 "-3.402823466385288598117e+38",
3814 "1.1754943508222875079687e-38", /* 2^-126 */
3815 "-1.1754943508222875079687e-38",
3818 static REAL_VALUE_TYPE float_values[8];
3819 static int inited_float_values = 0;
3822 check_float_value (mode, d, overflow)
3823 enum machine_mode mode;
3828 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
3831 if (inited_float_values == 0)
3834 for (i = 0; i < 8; i++)
3835 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
3837 inited_float_values = 1;
3843 REAL_VALUE_TYPE *fvptr;
3845 if (TARGET_FLOAT_VAX)
3846 fvptr = &float_values[0];
3848 fvptr = &float_values[4];
3850 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
3851 if (REAL_VALUES_LESS (fvptr[0], r))
3853 bcopy ((char *) &fvptr[0], (char *) d,
3854 sizeof (REAL_VALUE_TYPE));
3857 else if (REAL_VALUES_LESS (r, fvptr[1]))
3859 bcopy ((char *) &fvptr[1], (char *) d,
3860 sizeof (REAL_VALUE_TYPE));
3863 else if (REAL_VALUES_LESS (dconst0, r)
3864 && REAL_VALUES_LESS (r, fvptr[2]))
3866 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
3869 else if (REAL_VALUES_LESS (r, dconst0)
3870 && REAL_VALUES_LESS (fvptr[3], r))
3872 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
3882 /* Return the VMS argument type corresponding to MODE. */
3885 alpha_arg_type (mode)
3886 enum machine_mode mode;
3891 return TARGET_FLOAT_VAX ? FF : FS;
3893 return TARGET_FLOAT_VAX ? FD : FT;
3899 /* Return an rtx for an integer representing the VMS Argument Information
3903 alpha_arg_info_reg_val (cum)
3904 CUMULATIVE_ARGS cum;
3906 unsigned HOST_WIDE_INT regval = cum.num_args;
3909 for (i = 0; i < 6; i++)
3910 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
3912 return GEN_INT (regval);
3915 /* Structure to collect function names for final output
3918 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
3921 struct alpha_links {
3922 struct alpha_links *next;
3924 enum links_kind kind;
3927 static struct alpha_links *alpha_links_base = 0;
3929 /* Make (or fake) .linkage entry for function call.
3931 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
3934 alpha_need_linkage (name, is_local)
3939 struct alpha_links *lptr, *nptr;
3944 /* Is this name already defined ? */
3946 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
3947 if (strcmp (lptr->name, name) == 0)
3951 /* Defined here but external assumed. */
3952 if (lptr->kind == KIND_EXTERN)
3953 lptr->kind = KIND_LOCAL;
3957 /* Used here but unused assumed. */
3958 if (lptr->kind == KIND_UNUSED)
3959 lptr->kind = KIND_LOCAL;
3964 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
3965 nptr->next = alpha_links_base;
3966 nptr->name = xstrdup (name);
3968 /* Assume external if no definition. */
3969 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
3971 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
3972 get_identifier (name);
3974 alpha_links_base = nptr;
3981 alpha_write_linkage (stream)
3984 struct alpha_links *lptr, *nptr;
3986 readonly_section ();
3988 fprintf (stream, "\t.align 3\n");
3990 for (lptr = alpha_links_base; lptr; lptr = nptr)
3994 if (lptr->kind == KIND_UNUSED
3995 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
3998 fprintf (stream, "$%s..lk:\n", lptr->name);
3999 if (lptr->kind == KIND_LOCAL)
4001 /* Local and used, build linkage pair. */
4002 fprintf (stream, "\t.quad $%s..en\n", lptr->name);
4003 fprintf (stream, "\t.quad %s\n", lptr->name);
4006 /* External and used, request linkage pair. */
4007 fprintf (stream, "\t.linkage %s\n", lptr->name);
4014 alpha_need_linkage (name, is_local)
4020 #endif /* OPEN_VMS */