1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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;
305 /* Default the definition of "small data" to 8 bytes. */
310 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
318 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
320 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
326 /* Returns 1 if OP is either the constant zero or a register. If a
327 register, it must be in the proper mode unless MODE is VOIDmode. */
330 reg_or_0_operand (op, mode)
332 enum machine_mode mode;
334 return op == const0_rtx || register_operand (op, mode);
337 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
341 reg_or_6bit_operand (op, mode)
343 enum machine_mode mode;
345 return ((GET_CODE (op) == CONST_INT
346 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
347 || register_operand (op, mode));
351 /* Return 1 if OP is an 8-bit constant or any register. */
354 reg_or_8bit_operand (op, mode)
356 enum machine_mode mode;
358 return ((GET_CODE (op) == CONST_INT
359 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
360 || register_operand (op, mode));
363 /* Return 1 if OP is an 8-bit constant. */
366 cint8_operand (op, mode)
368 enum machine_mode mode;
370 return (GET_CODE (op) == CONST_INT
371 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
374 /* Return 1 if the operand is a valid second operand to an add insn. */
377 add_operand (op, mode)
379 enum machine_mode mode;
381 if (GET_CODE (op) == CONST_INT)
382 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
383 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
384 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
386 return register_operand (op, mode);
389 /* Return 1 if the operand is a valid second operand to a sign-extending
393 sext_add_operand (op, mode)
395 enum machine_mode mode;
397 if (GET_CODE (op) == CONST_INT)
398 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
399 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
401 return register_operand (op, mode);
404 /* Return 1 if OP is the constant 4 or 8. */
407 const48_operand (op, mode)
409 enum machine_mode mode;
411 return (GET_CODE (op) == CONST_INT
412 && (INTVAL (op) == 4 || INTVAL (op) == 8));
415 /* Return 1 if OP is a valid first operand to an AND insn. */
418 and_operand (op, mode)
420 enum machine_mode mode;
422 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
423 return (zap_mask (CONST_DOUBLE_LOW (op))
424 && zap_mask (CONST_DOUBLE_HIGH (op)));
426 if (GET_CODE (op) == CONST_INT)
427 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
428 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
429 || zap_mask (INTVAL (op)));
431 return register_operand (op, mode);
434 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
437 or_operand (op, mode)
439 enum machine_mode mode;
441 if (GET_CODE (op) == CONST_INT)
442 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
443 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
445 return register_operand (op, mode);
448 /* Return 1 if OP is a constant that is the width, in bits, of an integral
449 mode smaller than DImode. */
452 mode_width_operand (op, mode)
454 enum machine_mode mode;
456 return (GET_CODE (op) == CONST_INT
457 && (INTVAL (op) == 8 || INTVAL (op) == 16
458 || INTVAL (op) == 32 || INTVAL (op) == 64));
461 /* Return 1 if OP is a constant that is the width of an integral machine mode
462 smaller than an integer. */
465 mode_mask_operand (op, mode)
467 enum machine_mode mode;
469 #if HOST_BITS_PER_WIDE_INT == 32
470 if (GET_CODE (op) == CONST_DOUBLE)
471 return (CONST_DOUBLE_LOW (op) == -1
472 && (CONST_DOUBLE_HIGH (op) == -1
473 || CONST_DOUBLE_HIGH (op) == 0));
475 if (GET_CODE (op) == CONST_DOUBLE)
476 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
479 return (GET_CODE (op) == CONST_INT
480 && (INTVAL (op) == 0xff
481 || INTVAL (op) == 0xffff
482 || INTVAL (op) == 0xffffffff
483 #if HOST_BITS_PER_WIDE_INT == 64
484 || INTVAL (op) == 0xffffffffffffffff
489 /* Return 1 if OP is a multiple of 8 less than 64. */
492 mul8_operand (op, mode)
494 enum machine_mode mode;
496 return (GET_CODE (op) == CONST_INT
497 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
498 && (INTVAL (op) & 7) == 0);
501 /* Return 1 if OP is the constant zero in floating-point. */
504 fp0_operand (op, mode)
506 enum machine_mode mode;
508 return (GET_MODE (op) == mode
509 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
512 /* Return 1 if OP is the floating-point constant zero or a register. */
515 reg_or_fp0_operand (op, mode)
517 enum machine_mode mode;
519 return fp0_operand (op, mode) || register_operand (op, mode);
522 /* Return 1 if OP is a hard floating-point register. */
525 hard_fp_register_operand (op, mode)
527 enum machine_mode mode;
529 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
530 || (GET_CODE (op) == SUBREG
531 && hard_fp_register_operand (SUBREG_REG (op), mode)));
534 /* Return 1 if OP is a register or a constant integer. */
538 reg_or_cint_operand (op, mode)
540 enum machine_mode mode;
542 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
545 /* Return 1 if OP is something that can be reloaded into a register;
546 if it is a MEM, it need not be valid. */
549 some_operand (op, mode)
551 enum machine_mode mode;
553 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
556 switch (GET_CODE (op))
558 case REG: case MEM: case CONST_DOUBLE:
559 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
563 return some_operand (SUBREG_REG (op), VOIDmode);
572 /* Return 1 if OP is a valid operand for the source of a move insn. */
575 input_operand (op, mode)
577 enum machine_mode mode;
579 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
582 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
585 switch (GET_CODE (op))
590 /* This handles both the Windows/NT and OSF cases. */
591 return mode == ptr_mode || mode == DImode;
597 if (register_operand (op, mode))
599 /* ... fall through ... */
601 return ((TARGET_BWX || (mode != HImode && mode != QImode))
602 && general_operand (op, mode));
605 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
608 return mode == QImode || mode == HImode || add_operand (op, mode);
617 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
621 current_file_function_operand (op, mode)
623 enum machine_mode mode;
625 return (GET_CODE (op) == SYMBOL_REF
626 && ! profile_flag && ! profile_block_flag
627 && (SYMBOL_REF_FLAG (op)
628 || op == XEXP (DECL_RTL (current_function_decl), 0)));
631 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
634 call_operand (op, mode)
636 enum machine_mode mode;
641 return (GET_CODE (op) == SYMBOL_REF
642 || (GET_CODE (op) == REG
643 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
646 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
647 comparisons are valid in which insn. */
650 alpha_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 return (code == EQ || code == LE || code == LT
660 || (mode == DImode && (code == LEU || code == LTU)));
663 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
666 alpha_swapped_comparison_operator (op, mode)
668 enum machine_mode mode;
670 enum rtx_code code = GET_CODE (op);
672 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
675 code = swap_condition (code);
676 return (code == EQ || code == LE || code == LT
677 || (mode == DImode && (code == LEU || code == LTU)));
680 /* Return 1 if OP is a signed comparison operation. */
683 signed_comparison_operator (op, mode)
685 enum machine_mode mode;
687 switch (GET_CODE (op))
689 case EQ: case NE: case LE: case LT: case GE: case GT:
699 /* Return 1 if this is a divide or modulus operator. */
702 divmod_operator (op, mode)
704 enum machine_mode mode;
706 switch (GET_CODE (op))
708 case DIV: case MOD: case UDIV: case UMOD:
718 /* Return 1 if this memory address is a known aligned register plus
719 a constant. It must be a valid address. This means that we can do
720 this as an aligned reference plus some offset.
722 Take into account what reload will do.
724 We could say that out-of-range stack slots are alignable, but that would
725 complicate get_aligned_mem and it isn't worth the trouble since few
726 functions have large stack space. */
729 aligned_memory_operand (op, mode)
731 enum machine_mode mode;
733 if (GET_CODE (op) == SUBREG)
735 if (GET_MODE (op) != mode)
737 op = SUBREG_REG (op);
738 mode = GET_MODE (op);
741 if (reload_in_progress && GET_CODE (op) == REG
742 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
743 op = reg_equiv_mem[REGNO (op)];
745 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
746 || ! memory_address_p (mode, XEXP (op, 0)))
751 if (GET_CODE (op) == PLUS)
754 return (GET_CODE (op) == REG
755 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
758 /* Similar, but return 1 if OP is a MEM which is not alignable. */
761 unaligned_memory_operand (op, mode)
763 enum machine_mode mode;
765 if (GET_CODE (op) == SUBREG)
767 if (GET_MODE (op) != mode)
769 op = SUBREG_REG (op);
770 mode = GET_MODE (op);
773 if (reload_in_progress && GET_CODE (op) == REG
774 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
775 op = reg_equiv_mem[REGNO (op)];
777 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
782 if (! memory_address_p (mode, op))
785 if (GET_CODE (op) == PLUS)
788 return (GET_CODE (op) != REG
789 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
792 /* Return 1 if OP is either a register or an unaligned memory location. */
795 reg_or_unaligned_mem_operand (op, mode)
797 enum machine_mode mode;
799 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
802 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
805 any_memory_operand (op, mode)
807 enum machine_mode mode;
809 return (GET_CODE (op) == MEM
810 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
811 || (reload_in_progress && GET_CODE (op) == REG
812 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
813 || (reload_in_progress && GET_CODE (op) == SUBREG
814 && GET_CODE (SUBREG_REG (op)) == REG
815 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
818 /* REF is an alignable memory location. Place an aligned SImode
819 reference into *PALIGNED_MEM and the number of bits to shift into
823 get_aligned_mem (ref, paligned_mem, pbitnum)
825 rtx *paligned_mem, *pbitnum;
828 HOST_WIDE_INT offset = 0;
830 if (GET_CODE (ref) == SUBREG)
832 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
833 if (BYTES_BIG_ENDIAN)
834 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
835 - MIN (UNITS_PER_WORD,
836 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
837 ref = SUBREG_REG (ref);
840 if (GET_CODE (ref) == REG)
841 ref = reg_equiv_mem[REGNO (ref)];
843 if (reload_in_progress)
844 base = find_replacement (&XEXP (ref, 0));
846 base = XEXP (ref, 0);
848 if (GET_CODE (base) == PLUS)
849 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
851 *paligned_mem = gen_rtx_MEM (SImode,
852 plus_constant (base, offset & ~3));
853 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
854 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
855 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
857 *pbitnum = GEN_INT ((offset & 3) * 8);
860 /* Similar, but just get the address. Handle the two reload cases.
861 Add EXTRA_OFFSET to the address we return. */
864 get_unaligned_address (ref, extra_offset)
869 HOST_WIDE_INT offset = 0;
871 if (GET_CODE (ref) == SUBREG)
873 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
874 if (BYTES_BIG_ENDIAN)
875 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
876 - MIN (UNITS_PER_WORD,
877 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
878 ref = SUBREG_REG (ref);
881 if (GET_CODE (ref) == REG)
882 ref = reg_equiv_mem[REGNO (ref)];
884 if (reload_in_progress)
885 base = find_replacement (&XEXP (ref, 0));
887 base = XEXP (ref, 0);
889 if (GET_CODE (base) == PLUS)
890 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
892 return plus_constant (base, offset + extra_offset);
895 /* Subfunction of the following function. Update the flags of any MEM
896 found in part of X. */
899 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
901 int in_struct_p, volatile_p, unchanging_p;
905 switch (GET_CODE (x))
909 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
910 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
915 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
920 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
922 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
927 MEM_IN_STRUCT_P (x) = in_struct_p;
928 MEM_VOLATILE_P (x) = volatile_p;
929 RTX_UNCHANGING_P (x) = unchanging_p;
937 /* Given INSN, which is either an INSN or a SEQUENCE generated to
938 perform a memory operation, look for any MEMs in either a SET_DEST or
939 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
940 REF into each of the MEMs found. If REF is not a MEM, don't do
944 alpha_set_memflags (insn, ref)
948 /* Note that it is always safe to get these flags, though they won't
949 be what we think if REF is not a MEM. */
950 int in_struct_p = MEM_IN_STRUCT_P (ref);
951 int volatile_p = MEM_VOLATILE_P (ref);
952 int unchanging_p = RTX_UNCHANGING_P (ref);
954 if (GET_CODE (ref) != MEM
955 || (! in_struct_p && ! volatile_p && ! unchanging_p))
958 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
961 /* Try to output insns to set TARGET equal to the constant C if it can be
962 done in less than N insns. Do all computations in MODE. Returns the place
963 where the output has been placed if it can be done and the insns have been
964 emitted. If it would take more than N insns, zero is returned and no
965 insns and emitted. */
968 alpha_emit_set_const (target, mode, c, n)
970 enum machine_mode mode;
977 /* Try 1 insn, then 2, then up to N. */
978 for (i = 1; i <= n; i++)
979 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
985 /* Internal routine for the above to check for N or below insns. */
988 alpha_emit_set_const_1 (target, mode, c, n)
990 enum machine_mode mode;
994 HOST_WIDE_INT new = c;
996 /* Use a pseudo if highly optimizing and still generating RTL. */
998 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1002 #if HOST_BITS_PER_WIDE_INT == 64
1003 /* We are only called for SImode and DImode. If this is SImode, ensure that
1004 we are sign extended to a full word. This does not make any sense when
1005 cross-compiling on a narrow machine. */
1008 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1011 /* If this is a sign-extended 32-bit constant, we can do this in at most
1012 three insns, so do it if we have enough insns left. We always have
1013 a sign-extended 32-bit constant when compiling on a narrow machine. */
1015 if (HOST_BITS_PER_WIDE_INT != 64
1016 || c >> 31 == -1 || c >> 31 == 0)
1018 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1019 HOST_WIDE_INT tmp1 = c - low;
1021 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1022 HOST_WIDE_INT extra = 0;
1024 /* If HIGH will be interpreted as negative but the constant is
1025 positive, we must adjust it to do two ldha insns. */
1027 if ((high & 0x8000) != 0 && c >= 0)
1031 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1034 if (c == low || (low == 0 && extra == 0))
1036 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1037 but that meant that we can't handle INT_MIN on 32-bit machines
1038 (like NT/Alpha), because we recurse indefinitely through
1039 emit_move_insn to gen_movdi. So instead, since we know exactly
1040 what we want, create it explicitly. */
1043 target = gen_reg_rtx (mode);
1044 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1047 else if (n >= 2 + (extra != 0))
1049 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1052 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1053 subtarget, 0, OPTAB_WIDEN);
1055 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1056 target, 0, OPTAB_WIDEN);
1060 /* If we couldn't do it that way, try some other methods. But if we have
1061 no instructions left, don't bother. Likewise, if this is SImode and
1062 we can't make pseudos, we can't do anything since the expand_binop
1063 and expand_unop calls will widen and try to make pseudos. */
1066 || (mode == SImode && ! rtx_equal_function_value_matters))
1069 #if HOST_BITS_PER_WIDE_INT == 64
1070 /* First, see if can load a value into the target that is the same as the
1071 constant except that all bytes that are 0 are changed to be 0xff. If we
1072 can, then we can do a ZAPNOT to obtain the desired constant. */
1074 for (i = 0; i < 64; i += 8)
1075 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1076 new |= (HOST_WIDE_INT) 0xff << i;
1078 /* We are only called for SImode and DImode. If this is SImode, ensure that
1079 we are sign extended to a full word. */
1082 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1085 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1086 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1087 target, 0, OPTAB_WIDEN);
1090 /* Next, see if we can load a related constant and then shift and possibly
1091 negate it to get the constant we want. Try this once each increasing
1092 numbers of insns. */
1094 for (i = 1; i < n; i++)
1096 /* First try complementing. */
1097 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1098 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1100 /* Next try to form a constant and do a left shift. We can do this
1101 if some low-order bits are zero; the exact_log2 call below tells
1102 us that information. The bits we are shifting out could be any
1103 value, but here we'll just try the 0- and sign-extended forms of
1104 the constant. To try to increase the chance of having the same
1105 constant in more than one insn, start at the highest number of
1106 bits to shift, but try all possibilities in case a ZAPNOT will
1109 if ((bits = exact_log2 (c & - c)) > 0)
1110 for (; bits > 0; bits--)
1111 if ((temp = (alpha_emit_set_const
1113 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
1114 || ((temp = (alpha_emit_set_const
1116 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1118 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1119 target, 0, OPTAB_WIDEN);
1121 /* Now try high-order zero bits. Here we try the shifted-in bits as
1122 all zero and all ones. Be careful to avoid shifting outside the
1123 mode and to avoid shifting outside the host wide int size. */
1124 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1125 confuse the recursive call and set all of the high 32 bits. */
1127 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1128 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1129 for (; bits > 0; bits--)
1130 if ((temp = alpha_emit_set_const (subtarget, mode,
1132 || ((temp = (alpha_emit_set_const
1134 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1137 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1138 target, 1, OPTAB_WIDEN);
1140 /* Now try high-order 1 bits. We get that with a sign-extension.
1141 But one bit isn't enough here. Be careful to avoid shifting outside
1142 the mode and to avoid shifting outside the host wide int size. */
1144 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1145 - floor_log2 (~ c) - 2)) > 0)
1146 for (; bits > 0; bits--)
1147 if ((temp = alpha_emit_set_const (subtarget, mode,
1149 || ((temp = (alpha_emit_set_const
1151 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1154 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1155 target, 0, OPTAB_WIDEN);
1161 #if HOST_BITS_PER_WIDE_INT == 64
1162 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1163 fall back to a straight forward decomposition. We do this to avoid
1164 exponential run times encountered when looking for longer sequences
1165 with alpha_emit_set_const. */
1168 alpha_emit_set_long_const (target, c)
1172 /* Use a pseudo if highly optimizing and still generating RTL. */
1174 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1176 HOST_WIDE_INT d1, d2, d3, d4;
1179 /* Decompose the entire word */
1180 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1182 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1184 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1186 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1191 /* Construct the high word */
1193 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
1195 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
1197 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1198 subtarget, 0, OPTAB_WIDEN);
1200 /* Shift it into place */
1201 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1202 subtarget, 0, OPTAB_WIDEN);
1204 if (subtarget == 0 && d1 == d3 && d2 == d4)
1205 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1210 /* Add in the low word */
1212 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1213 subtarget, 0, OPTAB_WIDEN);
1215 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1216 subtarget, 0, OPTAB_WIDEN);
1220 r1 = copy_to_suggested_reg(r1, target, DImode);
1224 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1226 /* Generate the comparison for a conditional branch. */
1229 alpha_emit_conditional_branch (code)
1232 enum rtx_code cmp_code, branch_code;
1233 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1234 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1237 /* The general case: fold the comparison code to the types of compares
1238 that we have, choosing the branch as necessary. */
1241 case EQ: case LE: case LT: case LEU: case LTU:
1242 /* We have these compares: */
1243 cmp_code = code, branch_code = NE;
1247 /* This must be reversed. */
1248 cmp_code = EQ, branch_code = EQ;
1251 case GE: case GT: case GEU: case GTU:
1252 /* For FP, we swap them, for INT, we reverse them. */
1253 if (alpha_compare_fp_p)
1255 cmp_code = swap_condition (code);
1257 tem = op0, op0 = op1, op1 = tem;
1261 cmp_code = reverse_condition (code);
1270 if (alpha_compare_fp_p)
1275 /* When we are not as concerned about non-finite values, and we
1276 are comparing against zero, we can branch directly. */
1277 if (op1 == CONST0_RTX (DFmode))
1278 cmp_code = NIL, branch_code = code;
1279 else if (op0 == CONST0_RTX (DFmode))
1281 /* Undo the swap we probably did just above. */
1282 tem = op0, op0 = op1, op1 = tem;
1283 cmp_code = NIL, branch_code = swap_condition (cmp_code);
1288 /* ??? We mark the the branch mode to be CCmode to prevent the
1289 compare and branch from being combined, since the compare
1290 insn follows IEEE rules that the branch does not. */
1291 branch_mode = CCmode;
1298 /* The following optimizations are only for signed compares. */
1299 if (code != LEU && code != LTU && code != GEU && code != GTU)
1301 /* Whee. Compare and branch against 0 directly. */
1302 if (op1 == const0_rtx)
1303 cmp_code = NIL, branch_code = code;
1305 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1306 bypass between logicals and br/cmov on EV5. But we don't want to
1307 force valid immediate constants into registers needlessly. */
1308 else if (GET_CODE (op1) == CONST_INT)
1310 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1312 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1313 && (CONST_OK_FOR_LETTER_P (n, 'K')
1314 || CONST_OK_FOR_LETTER_P (n, 'L')))
1316 cmp_code = PLUS, branch_code = code;
1323 /* Force op0 into a register. */
1324 if (GET_CODE (op0) != REG)
1325 op0 = force_reg (cmp_mode, op0);
1327 /* Emit an initial compare instruction, if necessary. */
1329 if (cmp_code != NIL)
1331 tem = gen_reg_rtx (cmp_mode);
1332 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1335 /* Return the branch comparison. */
1336 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1340 /* Rewrite a comparison against zero CMP of the form
1341 (CODE (cc0) (const_int 0)) so it can be written validly in
1342 a conditional move (if_then_else CMP ...).
1343 If both of the operands that set cc0 are non-zero we must emit
1344 an insn to perform the compare (it can't be done within
1345 the conditional move). */
1347 alpha_emit_conditional_move (cmp, mode)
1349 enum machine_mode mode;
1351 enum rtx_code code = GET_CODE (cmp);
1352 enum rtx_code cmov_code = NE;
1353 rtx op0 = alpha_compare_op0;
1354 rtx op1 = alpha_compare_op1;
1355 enum machine_mode cmp_mode
1356 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1357 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1358 enum machine_mode cmov_mode = VOIDmode;
1361 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1364 /* We may be able to use a conditional move directly.
1365 This avoids emitting spurious compares. */
1366 if (signed_comparison_operator (cmp, cmp_op_mode)
1367 && (!alpha_compare_fp_p || flag_fast_math)
1368 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1369 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1371 /* We can't put the comparison insides a conditional move;
1372 emit a compare instruction and put that inside the
1373 conditional move. Make sure we emit only comparisons we have;
1374 swap or reverse as necessary. */
1378 case EQ: case LE: case LT: case LEU: case LTU:
1379 /* We have these compares: */
1383 /* This must be reversed. */
1384 code = reverse_condition (code);
1388 case GE: case GT: case GEU: case GTU:
1389 /* These must be swapped. Make sure the new first operand is in
1391 code = swap_condition (code);
1392 tem = op0, op0 = op1, op1 = tem;
1393 op0 = force_reg (cmp_mode, op0);
1400 /* ??? We mark the the branch mode to be CCmode to prevent the compare
1401 and cmov from being combined, since the compare insn follows IEEE
1402 rules that the cmov does not. */
1403 if (alpha_compare_fp_p && !flag_fast_math)
1406 tem = gen_reg_rtx (cmp_op_mode);
1407 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1408 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1411 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1415 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1416 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1417 lda r3,X(r11) lda r3,X+2(r11)
1418 extwl r1,r3,r1 extql r1,r3,r1
1419 extwh r2,r3,r2 extqh r2,r3,r2
1420 or r1.r2.r1 or r1,r2,r1
1423 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1424 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1425 lda r3,X(r11) lda r3,X(r11)
1426 extll r1,r3,r1 extll r1,r3,r1
1427 extlh r2,r3,r2 extlh r2,r3,r2
1428 or r1.r2.r1 addl r1,r2,r1
1430 quad: ldq_u r1,X(r11)
1439 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1441 HOST_WIDE_INT size, ofs;
1444 rtx meml, memh, addr, extl, exth;
1445 enum machine_mode mode;
1447 meml = gen_reg_rtx (DImode);
1448 memh = gen_reg_rtx (DImode);
1449 addr = gen_reg_rtx (DImode);
1450 extl = gen_reg_rtx (DImode);
1451 exth = gen_reg_rtx (DImode);
1453 emit_move_insn (meml,
1454 change_address (mem, DImode,
1455 gen_rtx_AND (DImode,
1456 plus_constant (XEXP (mem, 0),
1460 emit_move_insn (memh,
1461 change_address (mem, DImode,
1462 gen_rtx_AND (DImode,
1463 plus_constant (XEXP (mem, 0),
1467 if (sign && size == 2)
1469 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1471 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1472 emit_insn (gen_extqh (exth, memh, addr));
1474 /* We must use tgt here for the target. Alpha-vms port fails if we use
1475 addr for the target, because addr is marked as a pointer and combine
1476 knows that pointers are always sign-extended 32 bit values. */
1477 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1478 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1479 addr, 1, OPTAB_WIDEN);
1483 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1484 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1488 emit_insn (gen_extwh (exth, memh, addr));
1493 emit_insn (gen_extlh (exth, memh, addr));
1498 emit_insn (gen_extqh (exth, memh, addr));
1503 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1504 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1509 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1512 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1515 alpha_expand_unaligned_store (dst, src, size, ofs)
1517 HOST_WIDE_INT size, ofs;
1519 rtx dstl, dsth, addr, insl, insh, meml, memh;
1521 dstl = gen_reg_rtx (DImode);
1522 dsth = gen_reg_rtx (DImode);
1523 insl = gen_reg_rtx (DImode);
1524 insh = gen_reg_rtx (DImode);
1526 meml = change_address (dst, DImode,
1527 gen_rtx_AND (DImode,
1528 plus_constant (XEXP (dst, 0), ofs),
1530 memh = change_address (dst, DImode,
1531 gen_rtx_AND (DImode,
1532 plus_constant (XEXP (dst, 0),
1536 emit_move_insn (dsth, memh);
1537 emit_move_insn (dstl, meml);
1538 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1540 if (src != const0_rtx)
1542 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1543 GEN_INT (size*8), addr));
1548 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1551 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1554 emit_insn (gen_insql (insl, src, addr));
1559 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1564 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1567 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1571 #if HOST_BITS_PER_WIDE_INT == 32
1572 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1574 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1576 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1581 if (src != const0_rtx)
1583 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1584 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1587 /* Must store high before low for degenerate case of aligned. */
1588 emit_move_insn (memh, dsth);
1589 emit_move_insn (meml, dstl);
1592 /* The block move code tries to maximize speed by separating loads and
1593 stores at the expense of register pressure: we load all of the data
1594 before we store it back out. There are two secondary effects worth
1595 mentioning, that this speeds copying to/from aligned and unaligned
1596 buffers, and that it makes the code significantly easier to write. */
1598 #define MAX_MOVE_WORDS 8
1600 /* Load an integral number of consecutive unaligned quadwords. */
1603 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1606 HOST_WIDE_INT words, ofs;
1608 rtx const im8 = GEN_INT (-8);
1609 rtx const i64 = GEN_INT (64);
1610 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1614 /* Generate all the tmp registers we need. */
1615 for (i = 0; i < words; ++i)
1617 data_regs[i] = out_regs[i];
1618 ext_tmps[i] = gen_reg_rtx (DImode);
1620 data_regs[words] = gen_reg_rtx (DImode);
1623 smem = change_address (smem, GET_MODE (smem),
1624 plus_constant (XEXP (smem, 0), ofs));
1626 /* Load up all of the source data. */
1627 for (i = 0; i < words; ++i)
1629 emit_move_insn (data_regs[i],
1630 change_address (smem, DImode,
1631 gen_rtx_AND (DImode,
1632 plus_constant (XEXP(smem,0),
1636 emit_move_insn (data_regs[words],
1637 change_address (smem, DImode,
1638 gen_rtx_AND (DImode,
1639 plus_constant (XEXP(smem,0),
1643 /* Extract the half-word fragments. Unfortunately DEC decided to make
1644 extxh with offset zero a noop instead of zeroing the register, so
1645 we must take care of that edge condition ourselves with cmov. */
1647 sreg = copy_addr_to_reg (XEXP (smem, 0));
1648 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1650 for (i = 0; i < words; ++i)
1652 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1654 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1655 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1656 gen_rtx_IF_THEN_ELSE (DImode,
1657 gen_rtx_EQ (DImode, areg,
1659 const0_rtx, ext_tmps[i])));
1662 /* Merge the half-words into whole words. */
1663 for (i = 0; i < words; ++i)
1665 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1666 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1670 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1671 may be NULL to store zeros. */
1674 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1677 HOST_WIDE_INT words, ofs;
1679 rtx const im8 = GEN_INT (-8);
1680 rtx const i64 = GEN_INT (64);
1681 #if HOST_BITS_PER_WIDE_INT == 32
1682 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1684 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1686 rtx ins_tmps[MAX_MOVE_WORDS];
1687 rtx st_tmp_1, st_tmp_2, dreg;
1688 rtx st_addr_1, st_addr_2;
1691 /* Generate all the tmp registers we need. */
1692 if (data_regs != NULL)
1693 for (i = 0; i < words; ++i)
1694 ins_tmps[i] = gen_reg_rtx(DImode);
1695 st_tmp_1 = gen_reg_rtx(DImode);
1696 st_tmp_2 = gen_reg_rtx(DImode);
1699 dmem = change_address (dmem, GET_MODE (dmem),
1700 plus_constant (XEXP (dmem, 0), ofs));
1703 st_addr_2 = change_address (dmem, DImode,
1704 gen_rtx_AND (DImode,
1705 plus_constant (XEXP(dmem,0),
1708 st_addr_1 = change_address (dmem, DImode,
1709 gen_rtx_AND (DImode,
1713 /* Load up the destination end bits. */
1714 emit_move_insn (st_tmp_2, st_addr_2);
1715 emit_move_insn (st_tmp_1, st_addr_1);
1717 /* Shift the input data into place. */
1718 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1719 if (data_regs != NULL)
1721 for (i = words-1; i >= 0; --i)
1723 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1724 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1726 for (i = words-1; i > 0; --i)
1728 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1729 ins_tmps[i-1], ins_tmps[i-1], 1,
1734 /* Split and merge the ends with the destination data. */
1735 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1736 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1738 if (data_regs != NULL)
1740 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1741 st_tmp_2, 1, OPTAB_WIDEN);
1742 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1743 st_tmp_1, 1, OPTAB_WIDEN);
1747 emit_move_insn (st_addr_2, st_tmp_2);
1748 for (i = words-1; i > 0; --i)
1750 emit_move_insn (change_address (dmem, DImode,
1751 gen_rtx_AND (DImode,
1752 plus_constant(XEXP (dmem,0),
1755 data_regs ? ins_tmps[i-1] : const0_rtx);
1757 emit_move_insn (st_addr_1, st_tmp_1);
1761 /* Expand string/block move operations.
1763 operands[0] is the pointer to the destination.
1764 operands[1] is the pointer to the source.
1765 operands[2] is the number of bytes to move.
1766 operands[3] is the alignment. */
1769 alpha_expand_block_move (operands)
1772 rtx bytes_rtx = operands[2];
1773 rtx align_rtx = operands[3];
1774 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1775 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1776 HOST_WIDE_INT dst_align = src_align;
1777 rtx orig_src = operands[1];
1778 rtx orig_dst = operands[0];
1779 rtx data_regs[2*MAX_MOVE_WORDS+16];
1781 int i, words, ofs, nregs = 0;
1785 if (bytes > MAX_MOVE_WORDS*8)
1788 /* Look for additional alignment information from recorded register info. */
1790 tmp = XEXP (orig_src, 0);
1791 if (GET_CODE (tmp) == REG)
1793 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1794 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1796 else if (GET_CODE (tmp) == PLUS
1797 && GET_CODE (XEXP (tmp, 0)) == REG
1798 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1800 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1801 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1805 if (a >= 8 && c % 8 == 0)
1807 else if (a >= 4 && c % 4 == 0)
1809 else if (a >= 2 && c % 2 == 0)
1814 tmp = XEXP (orig_dst, 0);
1815 if (GET_CODE (tmp) == REG)
1817 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1818 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1820 else if (GET_CODE (tmp) == PLUS
1821 && GET_CODE (XEXP (tmp, 0)) == REG
1822 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1824 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1825 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1829 if (a >= 8 && c % 8 == 0)
1831 else if (a >= 4 && c % 4 == 0)
1833 else if (a >= 2 && c % 2 == 0)
1839 * Load the entire block into registers.
1842 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1844 enum machine_mode mode;
1845 tmp = XEXP (XEXP (orig_src, 0), 0);
1847 mode = mode_for_size (bytes, MODE_INT, 1);
1849 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1851 /* Whee! Optimize the load to use the existing register. */
1852 data_regs[nregs++] = gen_lowpart (mode, tmp);
1856 /* ??? We could potentially be copying 3 bytes or whatnot from
1857 a wider reg. Probably not worth worrying about. */
1858 /* No appropriate mode; fall back on memory. */
1859 orig_src = change_address (orig_src, GET_MODE (orig_src),
1860 copy_addr_to_reg (XEXP (orig_src, 0)));
1864 if (src_align >= 8 && bytes >= 8)
1868 for (i = 0; i < words; ++i)
1869 data_regs[nregs+i] = gen_reg_rtx(DImode);
1871 for (i = 0; i < words; ++i)
1873 emit_move_insn (data_regs[nregs+i],
1874 change_address(orig_src, DImode,
1875 plus_constant (XEXP (orig_src, 0),
1883 if (src_align >= 4 && bytes >= 4)
1887 for (i = 0; i < words; ++i)
1888 data_regs[nregs+i] = gen_reg_rtx(SImode);
1890 for (i = 0; i < words; ++i)
1892 emit_move_insn (data_regs[nregs+i],
1893 change_address(orig_src, SImode,
1894 plus_constant (XEXP (orig_src, 0),
1906 for (i = 0; i < words+1; ++i)
1907 data_regs[nregs+i] = gen_reg_rtx(DImode);
1909 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1915 if (!TARGET_BWX && bytes >= 8)
1917 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1918 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1922 if (!TARGET_BWX && bytes >= 4)
1924 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1925 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1934 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1935 emit_move_insn (tmp,
1936 change_address (orig_src, HImode,
1937 plus_constant (XEXP (orig_src, 0),
1941 } while (bytes >= 2);
1943 else if (!TARGET_BWX)
1945 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1946 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1953 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1954 emit_move_insn (tmp,
1955 change_address (orig_src, QImode,
1956 plus_constant (XEXP (orig_src, 0),
1963 if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1967 * Now save it back out again.
1972 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1974 enum machine_mode mode;
1975 tmp = XEXP (XEXP (orig_dst, 0), 0);
1977 mode = mode_for_size (bytes, MODE_INT, 1);
1978 if (GET_MODE (tmp) == mode && nregs == 1)
1980 emit_move_insn (tmp, data_regs[0]);
1985 /* ??? If nregs > 1, consider reconstructing the word in regs. */
1986 /* ??? Optimize mode < dst_mode with strict_low_part. */
1987 /* No appropriate mode; fall back on memory. */
1988 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
1989 copy_addr_to_reg (XEXP (orig_dst, 0)));
1992 /* Write out the data in whatever chunks reading the source allowed. */
1995 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
1997 emit_move_insn (change_address(orig_dst, DImode,
1998 plus_constant (XEXP (orig_dst, 0),
2007 /* If the source has remaining DImode regs, write them out in
2009 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2011 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2012 NULL_RTX, 1, OPTAB_WIDEN);
2014 emit_move_insn (change_address(orig_dst, SImode,
2015 plus_constant (XEXP (orig_dst, 0),
2017 gen_lowpart (SImode, data_regs[i]));
2018 emit_move_insn (change_address(orig_dst, SImode,
2019 plus_constant (XEXP (orig_dst, 0),
2021 gen_lowpart (SImode, tmp));
2026 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2028 emit_move_insn (change_address(orig_dst, SImode,
2029 plus_constant (XEXP (orig_dst, 0),
2036 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2038 /* Write out a remaining block of words using unaligned methods. */
2040 for (words = 1; i+words < nregs ; ++words)
2041 if (GET_MODE (data_regs[i+words]) != DImode)
2045 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2047 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2053 /* Due to the above, this won't be aligned. */
2054 /* ??? If we have more than one of these, consider constructing full
2055 words in registers and using alpha_expand_unaligned_store_words. */
2056 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2058 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2064 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2066 emit_move_insn (change_address (orig_dst, HImode,
2067 plus_constant (XEXP (orig_dst, 0),
2074 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2076 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2080 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2082 emit_move_insn (change_address (orig_dst, QImode,
2083 plus_constant (XEXP (orig_dst, 0),
2098 alpha_expand_block_clear (operands)
2101 rtx bytes_rtx = operands[1];
2102 rtx align_rtx = operands[2];
2103 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2104 HOST_WIDE_INT align = INTVAL (align_rtx);
2105 rtx orig_dst = operands[0];
2107 HOST_WIDE_INT i, words, ofs = 0;
2111 if (bytes > MAX_MOVE_WORDS*8)
2114 /* Look for stricter alignment. */
2116 tmp = XEXP (orig_dst, 0);
2117 if (GET_CODE (tmp) == REG)
2119 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2120 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2122 else if (GET_CODE (tmp) == PLUS
2123 && GET_CODE (XEXP (tmp, 0)) == REG
2124 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2126 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2127 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2131 if (a >= 8 && c % 8 == 0)
2133 else if (a >= 4 && c % 4 == 0)
2135 else if (a >= 2 && c % 2 == 0)
2140 /* Handle a block of contiguous words first. */
2142 if (align >= 8 && bytes >= 8)
2146 for (i = 0; i < words; ++i)
2148 emit_move_insn (change_address(orig_dst, DImode,
2149 plus_constant (XEXP (orig_dst, 0),
2157 if (align >= 4 && bytes >= 4)
2161 for (i = 0; i < words; ++i)
2163 emit_move_insn (change_address(orig_dst, SImode,
2164 plus_constant (XEXP (orig_dst, 0),
2176 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2182 /* Next clean up any trailing pieces. We know from the contiguous
2183 block move that there are no aligned SImode or DImode hunks left. */
2185 if (!TARGET_BWX && bytes >= 8)
2187 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2191 if (!TARGET_BWX && bytes >= 4)
2193 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2202 emit_move_insn (change_address (orig_dst, HImode,
2203 plus_constant (XEXP (orig_dst, 0),
2208 } while (bytes >= 2);
2210 else if (!TARGET_BWX)
2212 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2219 emit_move_insn (change_address (orig_dst, QImode,
2220 plus_constant (XEXP (orig_dst, 0),
2231 /* Adjust the cost of a scheduling dependency. Return the new cost of
2232 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2235 alpha_adjust_cost (insn, link, dep_insn, cost)
2242 enum attr_type insn_type, dep_insn_type;
2244 /* If the dependence is an anti-dependence, there is no cost. For an
2245 output dependence, there is sometimes a cost, but it doesn't seem
2246 worth handling those few cases. */
2248 if (REG_NOTE_KIND (link) != 0)
2251 /* If we can't recognize the insns, we can't really do anything. */
2252 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2255 insn_type = get_attr_type (insn);
2256 dep_insn_type = get_attr_type (dep_insn);
2258 /* Bring in the user-defined memory latency. */
2259 if (dep_insn_type == TYPE_ILD
2260 || dep_insn_type == TYPE_FLD
2261 || dep_insn_type == TYPE_LDSYM)
2262 cost += alpha_memory_latency-1;
2267 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2268 being stored, we can sometimes lower the cost. */
2270 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2271 && (set = single_set (dep_insn)) != 0
2272 && GET_CODE (PATTERN (insn)) == SET
2273 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2275 switch (dep_insn_type)
2279 /* No savings here. */
2283 /* In these cases, we save one cycle. */
2287 /* In all other cases, we save two cycles. */
2288 return MAX (0, cost - 2);
2292 /* Another case that needs adjustment is an arithmetic or logical
2293 operation. It's cost is usually one cycle, but we default it to
2294 two in the MD file. The only case that it is actually two is
2295 for the address in loads, stores, and jumps. */
2297 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2312 /* The final case is when a compare feeds into an integer branch;
2313 the cost is only one cycle in that case. */
2315 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2320 /* And the lord DEC saith: "A special bypass provides an effective
2321 latency of 0 cycles for an ICMP or ILOG insn producing the test
2322 operand of an IBR or ICMOV insn." */
2324 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2325 && (set = single_set (dep_insn)) != 0)
2327 /* A branch only has one input. This must be it. */
2328 if (insn_type == TYPE_IBR)
2330 /* A conditional move has three, make sure it is the test. */
2331 if (insn_type == TYPE_ICMOV
2332 && GET_CODE (set_src = PATTERN (insn)) == SET
2333 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2334 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2338 /* "The multiplier is unable to receive data from IEU bypass paths.
2339 The instruction issues at the expected time, but its latency is
2340 increased by the time it takes for the input data to become
2341 available to the multiplier" -- which happens in pipeline stage
2342 six, when results are comitted to the register file. */
2344 if (insn_type == TYPE_IMUL)
2346 switch (dep_insn_type)
2348 /* These insns produce their results in pipeline stage five. */
2355 /* Other integer insns produce results in pipeline stage four. */
2363 /* There is additional latency to move the result of (most) FP
2364 operations anywhere but the FP register file. */
2366 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2367 && (dep_insn_type == TYPE_FADD ||
2368 dep_insn_type == TYPE_FMUL ||
2369 dep_insn_type == TYPE_FCMOV))
2375 /* Otherwise, return the default cost. */
2379 /* Functions to save and restore alpha_return_addr_rtx. */
2381 struct machine_function
2387 alpha_save_machine_status (p)
2390 struct machine_function *machine =
2391 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2393 p->machine = machine;
2394 machine->ra_rtx = alpha_return_addr_rtx;
2398 alpha_restore_machine_status (p)
2401 struct machine_function *machine = p->machine;
2403 alpha_return_addr_rtx = machine->ra_rtx;
2406 p->machine = (struct machine_function *)0;
2409 /* Do anything needed before RTL is emitted for each function. */
2412 alpha_init_expanders ()
2414 alpha_return_addr_rtx = NULL_RTX;
2416 /* Arrange to save and restore machine status around nested functions. */
2417 save_machine_status = alpha_save_machine_status;
2418 restore_machine_status = alpha_restore_machine_status;
2421 /* Start the ball rolling with RETURN_ADDR_RTX. */
2424 alpha_return_addr (count, frame)
2433 if (alpha_return_addr_rtx)
2434 return alpha_return_addr_rtx;
2436 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2437 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2438 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2439 gen_rtx_REG (Pmode, REG_RA));
2441 /* Emit the insn to the prologue with the other argument copies. */
2442 push_topmost_sequence ();
2443 emit_insn_after (init, get_insns ());
2444 pop_topmost_sequence ();
2446 return alpha_return_addr_rtx;
2450 alpha_ra_ever_killed ()
2452 if (!alpha_return_addr_rtx)
2453 return regs_ever_live[REG_RA];
2455 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2456 get_insns(), NULL_RTX);
2460 /* Print an operand. Recognize special options, documented below. */
2463 print_operand (file, x, code)
2473 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2474 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2475 mode. alpha_fprm controls which suffix is generated. */
2478 case ALPHA_FPRM_NORM:
2480 case ALPHA_FPRM_MINF:
2483 case ALPHA_FPRM_CHOP:
2486 case ALPHA_FPRM_DYN:
2493 /* Generates trap-mode suffix for instructions that accept the su
2494 suffix only (cmpt et al). */
2495 if (alpha_tp == ALPHA_TP_INSN)
2500 /* Generates trap-mode suffix for instructions that accept the
2501 v, sv, and svi suffix. The only instruction that needs this
2513 case ALPHA_FPTM_SUI:
2514 fputs ("svi", file);
2520 /* Generates trap-mode suffix for instructions that accept the u, su,
2521 and sui suffix. This is the bulk of the IEEE floating point
2522 instructions (addt et al). */
2533 case ALPHA_FPTM_SUI:
2534 fputs ("sui", file);
2540 /* Generates trap-mode suffix for instructions that accept the sui
2541 suffix (cvtqt and cvtqs). */
2544 case ALPHA_FPTM_N: case ALPHA_FPTM_U:
2545 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2547 case ALPHA_FPTM_SUI:
2548 fputs ("sui", file);
2554 /* Generates single precision instruction suffix. */
2555 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2559 /* Generates double precision instruction suffix. */
2560 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2564 /* If this operand is the constant zero, write it as "$31". */
2565 if (GET_CODE (x) == REG)
2566 fprintf (file, "%s", reg_names[REGNO (x)]);
2567 else if (x == CONST0_RTX (GET_MODE (x)))
2568 fprintf (file, "$31");
2570 output_operand_lossage ("invalid %%r value");
2575 /* Similar, but for floating-point. */
2576 if (GET_CODE (x) == REG)
2577 fprintf (file, "%s", reg_names[REGNO (x)]);
2578 else if (x == CONST0_RTX (GET_MODE (x)))
2579 fprintf (file, "$f31");
2581 output_operand_lossage ("invalid %%R value");
2586 /* Write the 1's complement of a constant. */
2587 if (GET_CODE (x) != CONST_INT)
2588 output_operand_lossage ("invalid %%N value");
2590 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2594 /* Write 1 << C, for a constant C. */
2595 if (GET_CODE (x) != CONST_INT)
2596 output_operand_lossage ("invalid %%P value");
2598 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2602 /* Write the high-order 16 bits of a constant, sign-extended. */
2603 if (GET_CODE (x) != CONST_INT)
2604 output_operand_lossage ("invalid %%h value");
2606 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2610 /* Write the low-order 16 bits of a constant, sign-extended. */
2611 if (GET_CODE (x) != CONST_INT)
2612 output_operand_lossage ("invalid %%L value");
2614 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2615 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2619 /* Write mask for ZAP insn. */
2620 if (GET_CODE (x) == CONST_DOUBLE)
2622 HOST_WIDE_INT mask = 0;
2623 HOST_WIDE_INT value;
2625 value = CONST_DOUBLE_LOW (x);
2626 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2631 value = CONST_DOUBLE_HIGH (x);
2632 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2635 mask |= (1 << (i + sizeof (int)));
2637 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2640 else if (GET_CODE (x) == CONST_INT)
2642 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2644 for (i = 0; i < 8; i++, value >>= 8)
2648 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2651 output_operand_lossage ("invalid %%m value");
2655 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2656 if (GET_CODE (x) != CONST_INT
2657 || (INTVAL (x) != 8 && INTVAL (x) != 16
2658 && INTVAL (x) != 32 && INTVAL (x) != 64))
2659 output_operand_lossage ("invalid %%M value");
2661 fprintf (file, "%s",
2662 (INTVAL (x) == 8 ? "b"
2663 : INTVAL (x) == 16 ? "w"
2664 : INTVAL (x) == 32 ? "l"
2669 /* Similar, except do it from the mask. */
2670 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2671 fprintf (file, "b");
2672 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2673 fprintf (file, "w");
2674 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2675 fprintf (file, "l");
2676 #if HOST_BITS_PER_WIDE_INT == 32
2677 else if (GET_CODE (x) == CONST_DOUBLE
2678 && CONST_DOUBLE_HIGH (x) == 0
2679 && CONST_DOUBLE_LOW (x) == -1)
2680 fprintf (file, "l");
2681 else if (GET_CODE (x) == CONST_DOUBLE
2682 && CONST_DOUBLE_HIGH (x) == -1
2683 && CONST_DOUBLE_LOW (x) == -1)
2684 fprintf (file, "q");
2686 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2687 fprintf (file, "q");
2688 else if (GET_CODE (x) == CONST_DOUBLE
2689 && CONST_DOUBLE_HIGH (x) == 0
2690 && CONST_DOUBLE_LOW (x) == -1)
2691 fprintf (file, "q");
2694 output_operand_lossage ("invalid %%U value");
2698 /* Write the constant value divided by 8. */
2699 if (GET_CODE (x) != CONST_INT
2700 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2701 && (INTVAL (x) & 7) != 8)
2702 output_operand_lossage ("invalid %%s value");
2704 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2708 /* Same, except compute (64 - c) / 8 */
2710 if (GET_CODE (x) != CONST_INT
2711 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2712 && (INTVAL (x) & 7) != 8)
2713 output_operand_lossage ("invalid %%s value");
2715 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2718 case 'C': case 'D': case 'c': case 'd':
2719 /* Write out comparison name. */
2721 enum rtx_code c = GET_CODE (x);
2723 if (GET_RTX_CLASS (c) != '<')
2724 output_operand_lossage ("invalid %%C value");
2727 c = reverse_condition (c);
2728 else if (code == 'c')
2729 c = swap_condition (c);
2730 else if (code == 'd')
2731 c = swap_condition (reverse_condition (c));
2734 fprintf (file, "ule");
2736 fprintf (file, "ult");
2738 fprintf (file, "%s", GET_RTX_NAME (c));
2743 /* Write the divide or modulus operator. */
2744 switch (GET_CODE (x))
2747 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2750 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2753 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2756 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2759 output_operand_lossage ("invalid %%E value");
2765 /* Write "_u" for unaligned access. */
2766 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2767 fprintf (file, "_u");
2771 if (GET_CODE (x) == REG)
2772 fprintf (file, "%s", reg_names[REGNO (x)]);
2773 else if (GET_CODE (x) == MEM)
2774 output_address (XEXP (x, 0));
2776 output_addr_const (file, x);
2780 output_operand_lossage ("invalid %%xn code");
2784 /* Do what is necessary for `va_start'. The argument is ignored;
2785 We look at the current function to determine if stdarg or varargs
2786 is used and fill in an initial va_list. A pointer to this constructor
2790 alpha_builtin_saveregs (arglist)
2793 rtx block, addr, dest, argsize;
2794 tree fntype = TREE_TYPE (current_function_decl);
2795 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2796 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2797 != void_type_node));
2799 /* Compute the current position into the args, taking into account
2800 both registers and memory. Both of these are already included in
2803 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2805 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2806 storing fp arg registers in the first 48 bytes, and the integer arg
2807 registers in the next 48 bytes. This is only done, however, if any
2808 integer registers need to be stored.
2810 If no integer registers need be stored, then we must subtract 48 in
2811 order to account for the integer arg registers which are counted in
2812 argsize above, but which are not actually stored on the stack. */
2814 if (TARGET_OPEN_VMS)
2815 addr = plus_constant (virtual_incoming_args_rtx,
2816 NUM_ARGS <= 5 + stdarg
2817 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2819 addr = (NUM_ARGS <= 5 + stdarg
2820 ? plus_constant (virtual_incoming_args_rtx,
2822 : plus_constant (virtual_incoming_args_rtx,
2823 - (6 * UNITS_PER_WORD)));
2825 /* For VMS, we include the argsize, while on Unix, it's handled as
2826 a separate field. */
2827 if (TARGET_OPEN_VMS)
2828 addr = plus_constant (addr, INTVAL (argsize));
2830 addr = force_operand (addr, NULL_RTX);
2832 #ifdef POINTERS_EXTEND_UNSIGNED
2833 addr = convert_memory_address (ptr_mode, addr);
2836 if (TARGET_OPEN_VMS)
2840 /* Allocate the va_list constructor */
2841 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2842 RTX_UNCHANGING_P (block) = 1;
2843 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2845 /* Store the address of the first integer register in the __base
2848 dest = change_address (block, ptr_mode, XEXP (block, 0));
2849 emit_move_insn (dest, addr);
2851 if (flag_check_memory_usage)
2852 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2854 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2855 TYPE_MODE (sizetype),
2856 GEN_INT (MEMORY_USE_RW),
2857 TYPE_MODE (integer_type_node));
2859 /* Store the argsize as the __va_offset member. */
2860 dest = change_address (block, TYPE_MODE (integer_type_node),
2861 plus_constant (XEXP (block, 0),
2862 POINTER_SIZE/BITS_PER_UNIT));
2863 emit_move_insn (dest, argsize);
2865 if (flag_check_memory_usage)
2866 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2868 GEN_INT (GET_MODE_SIZE
2869 (TYPE_MODE (integer_type_node))),
2870 TYPE_MODE (sizetype),
2871 GEN_INT (MEMORY_USE_RW),
2872 TYPE_MODE (integer_type_node));
2874 /* Return the address of the va_list constructor, but don't put it in a
2875 register. Doing so would fail when not optimizing and produce worse
2876 code when optimizing. */
2877 return XEXP (block, 0);
2881 /* This page contains routines that are used to determine what the function
2882 prologue and epilogue code will do and write them out. */
2884 /* Compute the size of the save area in the stack. */
2888 /* These variables are used for communication between the following functions.
2889 They indicate various things about the current function being compiled
2890 that are used to tell what kind of prologue, epilogue and procedure
2891 descriptior to generate. */
2893 /* Nonzero if we need a stack procedure. */
2894 static int is_stack_procedure;
2896 /* Register number (either FP or SP) that is used to unwind the frame. */
2897 static int unwind_regno;
2899 /* Register number used to save FP. We need not have one for RA since
2900 we don't modify it for register procedures. This is only defined
2901 for register frame procedures. */
2902 static int save_fp_regno;
2904 /* Register number used to reference objects off our PV. */
2905 static int base_regno;
2907 /* Compute register masks for saved registers. */
2910 alpha_sa_mask (imaskP, fmaskP)
2911 unsigned long *imaskP;
2912 unsigned long *fmaskP;
2914 unsigned long imask = 0;
2915 unsigned long fmask = 0;
2918 if (is_stack_procedure)
2919 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2921 /* One for every register we have to save. */
2923 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2924 if (! fixed_regs[i] && ! call_used_regs[i]
2925 && regs_ever_live[i] && i != REG_RA)
2930 fmask |= (1L << (i - 32));
2943 HOST_WIDE_INT stack_needed;
2946 /* One for every register we have to save. */
2948 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2949 if (! fixed_regs[i] && ! call_used_regs[i]
2950 && regs_ever_live[i] && i != REG_RA)
2953 /* Start by assuming we can use a register procedure if we don't make any
2954 calls (REG_RA not used) or need to save any registers and a stack
2955 procedure if we do. */
2956 is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2958 /* Decide whether to refer to objects off our PV via FP or PV.
2959 If we need FP for something else or if we receive a nonlocal
2960 goto (which expects PV to contain the value), we must use PV.
2961 Otherwise, start by assuming we can use FP. */
2962 base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
2963 || is_stack_procedure
2964 || current_function_outgoing_args_size
2965 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
2967 /* If we want to copy PV into FP, we need to find some register in which to
2972 if (base_regno == HARD_FRAME_POINTER_REGNUM)
2973 for (i = 0; i < 32; i++)
2974 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
2977 if (save_fp_regno == -1)
2978 base_regno = REG_PV, is_stack_procedure = 1;
2980 /* Stack unwinding should be done via FP unless we use it for PV. */
2982 = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
2984 /* If this is a stack procedure, allow space for saving FP and RA. */
2985 if (is_stack_procedure)
2992 alpha_pv_save_size ()
2995 return is_stack_procedure ? 8 : 0;
3002 return unwind_regno == HARD_FRAME_POINTER_REGNUM;
3005 #else /* ! OPEN_VMS */
3013 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3014 if (! fixed_regs[i] && ! call_used_regs[i]
3015 && regs_ever_live[i] && i != REG_RA)
3018 /* If some registers were saved but not reg 26, reg 26 must also
3019 be saved, so leave space for it. */
3020 if (size != 0 || alpha_ra_ever_killed ())
3023 /* Our size must be even (multiple of 16 bytes). */
3030 #endif /* ! OPEN_VMS */
3032 /* Return 1 if this function can directly return via $26. */
3037 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
3038 && get_frame_size () == 0
3039 && current_function_outgoing_args_size == 0
3040 && current_function_pretend_args_size == 0);
3043 /* Write a version stamp. Don't write anything if we are running as a
3044 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3046 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__) && !defined(VMS)
3051 alpha_write_verstamp (file)
3055 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3059 /* Write code to add constant C to register number IN_REG (possibly 31)
3060 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
3061 usually this will be OUT_REG, but should not be if OUT_REG is
3062 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
3063 Write the code to FILE. */
3066 add_long_const (file, c, in_reg, out_reg, temp_reg)
3069 int in_reg, out_reg, temp_reg;
3071 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
3072 HOST_WIDE_INT tmp1 = c - low;
3073 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3074 HOST_WIDE_INT extra = 0;
3076 /* We don't have code to write out constants larger than 32 bits. */
3077 #if HOST_BITS_PER_LONG_INT == 64
3078 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
3082 /* If HIGH will be interpreted as negative, we must adjust it to do two
3083 ldha insns. Note that we will never be building a negative constant
3090 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3095 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
3097 if (low >= 0 && low < 255)
3098 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
3100 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
3102 in_reg = result_reg;
3107 int result_reg = (high == 0) ? out_reg : temp_reg;
3109 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
3110 in_reg = result_reg;
3114 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
3117 /* Write function prologue. */
3121 /* On vms we have two kinds of functions:
3123 - stack frame (PROC_STACK)
3124 these are 'normal' functions with local vars and which are
3125 calling other functions
3126 - register frame (PROC_REGISTER)
3127 keeps all data in registers, needs no stack
3129 We must pass this to the assembler so it can generate the
3130 proper pdsc (procedure descriptor)
3131 This is done with the '.pdesc' command.
3133 size is the stack size needed for local variables. */
3136 output_prolog (file, size)
3140 unsigned long imask = 0;
3141 unsigned long fmask = 0;
3142 /* Stack space needed for pushing registers clobbered by us. */
3143 HOST_WIDE_INT sa_size;
3144 /* Complete stack size needed. */
3145 HOST_WIDE_INT frame_size;
3146 /* Offset from base reg to register save area. */
3148 /* Offset during register save. */
3150 /* Label for the procedure entry. */
3151 char *entry_label = (char *) alloca (strlen (alpha_function_name) + 6);
3154 sa_size = alpha_sa_size ();
3156 = ALPHA_ROUND (sa_size
3157 + (is_stack_procedure ? 8 : 0)
3158 + size + current_function_pretend_args_size);
3160 /* Issue function start and label. */
3161 fprintf (file, "\t.ent ");
3162 assemble_name (file, alpha_function_name);
3163 fprintf (file, "\n");
3164 sprintf (entry_label, "%s..en", alpha_function_name);
3165 ASM_OUTPUT_LABEL (file, entry_label);
3166 inside_function = TRUE;
3168 fprintf (file, "\t.base $%d\n", base_regno);
3170 /* Calculate register masks for clobbered registers. */
3172 if (is_stack_procedure)
3173 alpha_sa_mask (&imask, &fmask);
3175 /* Adjust the stack by the frame size. If the frame size is > 4096
3176 bytes, we need to be sure we probe somewhere in the first and last
3177 4096 bytes (we can probably get away without the latter test) and
3178 every 8192 bytes in between. If the frame size is > 32768, we
3179 do this in a loop. Otherwise, we generate the explicit probe
3182 Note that we are only allowed to adjust sp once in the prologue. */
3184 if (frame_size < 32768)
3186 if (frame_size > 4096)
3190 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3192 while (probed + 8192 < frame_size)
3193 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3195 /* We only have to do this probe if we aren't saving registers. */
3196 if (sa_size == 0 && probed + 4096 < frame_size)
3197 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3200 if (frame_size != 0)
3201 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3205 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
3206 number of 8192 byte blocks to probe. We then probe each block
3207 in the loop and then set SP to the proper location. If the
3208 amount remaining is > 4096, we have to do one more probe if we
3209 are not saving any registers. */
3211 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3212 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3214 add_long_const (file, blocks, 31, 23, 23);
3216 fprintf (file, "\tlda $22,4096($30)\n");
3219 assemble_name (file, alpha_function_name);
3220 fprintf (file, "..sc:\n");
3222 fprintf (file, "\tstq $31,-8192($22)\n");
3223 fprintf (file, "\tsubq $23,1,$23\n");
3224 fprintf (file, "\tlda $22,-8192($22)\n");
3226 fprintf (file, "\tbne $23,$");
3227 assemble_name (file, alpha_function_name);
3228 fprintf (file, "..sc\n");
3230 if (leftover > 4096 && sa_size == 0)
3231 fprintf (file, "\tstq $31,-%d($22)\n", leftover);
3233 fprintf (file, "\tlda $30,-%d($22)\n", leftover);
3236 if (is_stack_procedure)
3238 int reg_offset = rsa_offset;
3240 /* Store R26 (RA) first. */
3241 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
3244 /* Store integer regs. according to mask. */
3245 for (i = 0; i < 32; i++)
3246 if (imask & (1L<<i))
3248 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
3252 /* Print the register mask and do floating-point saves. */
3255 fprintf (file, "\t.mask 0x%x,0\n", imask);
3257 for (i = 0; i < 32; i++)
3259 if (fmask & (1L << i))
3261 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
3266 /* Print the floating-point mask, if we've saved any fp register. */
3268 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
3270 fprintf (file, "\tstq $27,0($30)\n");
3274 fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
3275 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3276 HARD_FRAME_POINTER_REGNUM, save_fp_regno);
3279 if (base_regno != REG_PV)
3280 fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
3282 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3283 fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
3284 STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
3286 /* Describe our frame. */
3287 fprintf (file, "\t.frame $%d,", unwind_regno);
3289 /* If the frame size is larger than an integer, print it as zero to
3290 avoid an assembler error. We won't be properly describing such a
3291 frame, but that's the best we can do. */
3292 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3293 #if HOST_BITS_PER_WIDE_INT == 64
3294 frame_size >= (1l << 31) ? 0:
3298 fprintf (file, ",$26,%d\n", rsa_offset);
3300 /* If we have to allocate space for outgoing args, do it now. */
3301 if (current_function_outgoing_args_size != 0)
3302 fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
3303 - ALPHA_ROUND (current_function_outgoing_args_size),
3304 HARD_FRAME_POINTER_REGNUM);
3306 fprintf (file, "\t.prologue\n");
3308 readonly_section ();
3309 fprintf (file, "\t.align 3\n");
3310 assemble_name (file, alpha_function_name); fputs ("..na:\n", file);
3311 fputs ("\t.ascii \"", file);
3312 assemble_name (file, alpha_function_name);
3313 fputs ("\\0\"\n", file);
3316 fprintf (file, "\t.align 3\n");
3317 fputs ("\t.name ", file);
3318 assemble_name (file, alpha_function_name);
3319 fputs ("..na\n", file);
3320 ASM_OUTPUT_LABEL (file, alpha_function_name);
3321 fprintf (file, "\t.pdesc ");
3322 assemble_name (file, alpha_function_name);
3323 fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
3324 alpha_need_linkage (alpha_function_name, 1);
3330 /* Write function epilogue. */
3333 output_epilog (file, size)
3337 unsigned long imask = 0;
3338 unsigned long fmask = 0;
3339 /* Stack space needed for pushing registers clobbered by us. */
3340 HOST_WIDE_INT sa_size = alpha_sa_size ();
3341 /* Complete stack size needed. */
3342 HOST_WIDE_INT frame_size
3343 = ALPHA_ROUND (sa_size
3344 + (is_stack_procedure ? 8 : 0)
3345 + size + current_function_pretend_args_size);
3347 rtx insn = get_last_insn ();
3349 /* If the last insn was a BARRIER, we don't have to write anything except
3350 the .end pseudo-op. */
3352 if (GET_CODE (insn) == NOTE)
3353 insn = prev_nonnote_insn (insn);
3355 if (insn == 0 || GET_CODE (insn) != BARRIER)
3357 /* Restore clobbered registers, load FP last. */
3359 if (is_stack_procedure)
3365 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3366 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3367 HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
3369 alpha_sa_mask (&imask, &fmask);
3371 /* Start reloading registers after RA. */
3372 reg_offset = rsa_offset + 8;
3374 for (i = 0; i < 32; i++)
3375 if (imask & (1L<<i))
3377 if (i == HARD_FRAME_POINTER_REGNUM)
3378 fp_offset = reg_offset;
3380 fprintf (file, "\tldq $%d,%d($30)\n",
3385 for (i = 0; i < 32; i++)
3386 if (fmask & (1L << i))
3388 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
3392 /* Restore R26 (RA). */
3393 fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
3395 /* Restore R29 (FP). */
3396 fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
3399 fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
3400 HARD_FRAME_POINTER_REGNUM);
3402 if (frame_size != 0)
3404 if (frame_size < 32768)
3405 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
3408 long high = frame_size >> 16;
3409 long low = frame_size & 0xffff;
3413 low = -32768 + (low & 0x7fff);
3415 fprintf (file, "\tldah $2,%ld($31)\n", high);
3416 fprintf (file, "\tlda $2,%ld($2)\n", low);
3417 fprintf (file, "\taddq $30,$2,$30\n");
3421 /* Finally return to the caller. */
3422 fprintf (file, "\tret $31,($26),1\n");
3425 /* End the function. */
3426 fprintf (file, "\t.end ");
3427 assemble_name (file, alpha_function_name);
3428 fprintf (file, "\n");
3429 inside_function = FALSE;
3431 /* Show that we know this function if it is called again. */
3432 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3436 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3442 if (is_attribute_p ("overlaid", identifier))
3443 return (args == NULL_TREE);
3447 #else /* !OPEN_VMS */
3450 alpha_does_function_need_gp ()
3454 /* We never need a GP for Windows/NT. */
3455 if (TARGET_WINDOWS_NT)
3458 #ifdef TARGET_PROFILING_NEEDS_GP
3463 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3464 Even if we are a static function, we still need to do this in case
3465 our address is taken and passed to something like qsort. */
3467 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3468 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3469 && GET_CODE (PATTERN (insn)) != USE
3470 && GET_CODE (PATTERN (insn)) != CLOBBER)
3472 enum attr_type type = get_attr_type (insn);
3473 if (type == TYPE_LDSYM || type == TYPE_JSR)
3481 output_prolog (file, size)
3485 HOST_WIDE_INT out_args_size
3486 = ALPHA_ROUND (current_function_outgoing_args_size);
3487 HOST_WIDE_INT sa_size = alpha_sa_size ();
3488 HOST_WIDE_INT frame_size
3489 = (out_args_size + sa_size
3490 + ALPHA_ROUND (size + current_function_pretend_args_size));
3491 HOST_WIDE_INT reg_offset = out_args_size;
3492 HOST_WIDE_INT start_reg_offset = reg_offset;
3493 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
3494 int int_reg_save_area_size = 0;
3495 unsigned reg_mask = 0;
3498 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3499 We have to do that before the .ent directive as we cannot switch
3500 files within procedures with native ecoff because line numbers are
3501 linked to procedure descriptors.
3502 Outputting the lineno helps debugging of one line functions as they
3503 would otherwise get no line number at all. Please note that we would
3504 like to put out last_linenum from final.c, but it is not accessible. */
3506 if (write_symbols == SDB_DEBUG)
3508 ASM_OUTPUT_SOURCE_FILENAME (file,
3509 DECL_SOURCE_FILE (current_function_decl));
3510 if (debug_info_level != DINFO_LEVEL_TERSE)
3511 ASM_OUTPUT_SOURCE_LINE (file,
3512 DECL_SOURCE_LINE (current_function_decl));
3515 /* The assembly language programmer's guide states that the second argument
3516 to the .ent directive, the lex_level, is ignored by the assembler,
3517 so we might as well omit it. */
3519 if (!flag_inhibit_size_directive)
3521 fprintf (file, "\t.ent ");
3522 assemble_name (file, alpha_function_name);
3523 fprintf (file, "\n");
3525 ASM_OUTPUT_LABEL (file, alpha_function_name);
3526 inside_function = TRUE;
3528 if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
3529 /* Set flags in procedure descriptor to request IEEE-conformant
3530 math-library routines. The value we set it to is PDSC_EXC_IEEE
3531 (/usr/include/pdsc.h). */
3532 fprintf (file, "\t.eflag 48\n");
3534 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3536 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3537 alpha_arg_offset = -frame_size + 48;
3539 alpha_function_needs_gp = alpha_does_function_need_gp ();
3541 if (TARGET_WINDOWS_NT == 0)
3543 if (alpha_function_needs_gp)
3544 fprintf (file, "\tldgp $29,0($27)\n");
3546 /* Put a label after the GP load so we can enter the function at it. */
3548 assemble_name (file, alpha_function_name);
3549 fprintf (file, "..ng:\n");
3552 /* Adjust the stack by the frame size. If the frame size is > 4096
3553 bytes, we need to be sure we probe somewhere in the first and last
3554 4096 bytes (we can probably get away without the latter test) and
3555 every 8192 bytes in between. If the frame size is > 32768, we
3556 do this in a loop. Otherwise, we generate the explicit probe
3559 Note that we are only allowed to adjust sp once in the prologue. */
3561 if (frame_size < 32768)
3563 if (frame_size > 4096)
3567 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3569 while (probed + 8192 < frame_size)
3570 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3572 /* We only have to do this probe if we aren't saving registers. */
3573 if (sa_size == 0 && probed + 4096 < frame_size)
3574 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3577 if (frame_size != 0)
3578 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3582 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
3583 number of 8192 byte blocks to probe. We then probe each block
3584 in the loop and then set SP to the proper location. If the
3585 amount remaining is > 4096, we have to do one more probe if we
3586 are not saving any registers. */
3588 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3589 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3591 add_long_const (file, blocks, 31, 5, 5);
3593 fprintf (file, "\tlda $4,4096($30)\n");
3596 assemble_name (file, alpha_function_name);
3597 fprintf (file, "..sc:\n");
3599 fprintf (file, "\tstq $31,-8192($4)\n");
3600 fprintf (file, "\tsubq $5,1,$5\n");
3601 fprintf (file, "\tlda $4,-8192($4)\n");
3603 fprintf (file, "\tbne $5,$");
3604 assemble_name (file, alpha_function_name);
3605 fprintf (file, "..sc\n");
3607 if (leftover > 4096 && sa_size == 0)
3608 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
3610 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
3613 /* Describe our frame. */
3614 if (!flag_inhibit_size_directive)
3616 fprintf (file, "\t.frame $%d,",
3617 (frame_pointer_needed
3618 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3620 /* If the frame size is larger than an integer, print it as zero to
3621 avoid an assembler error. We won't be properly describing such a
3622 frame, but that's the best we can do. */
3623 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3624 #if HOST_BITS_PER_WIDE_INT == 64
3625 frame_size >= (1l << 31) ? 0 :
3629 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3632 /* Cope with very large offsets to the register save area. */
3634 if (reg_offset + sa_size > 0x8000)
3636 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3637 if (low + sa_size <= 0x8000)
3639 add_long_const (file, reg_offset - low, 30, 24, 24);
3644 add_long_const (file, reg_offset, 30, 24, 24);
3650 /* Save register RA if any other register needs to be saved. */
3653 reg_mask |= 1 << REG_RA;
3654 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
3656 int_reg_save_area_size += 8;
3659 /* Now save any other used integer registers required to be saved. */
3660 for (i = 0; i < 32; i++)
3661 if (! fixed_regs[i] && ! call_used_regs[i]
3662 && regs_ever_live[i] && i != REG_RA)
3665 fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3667 int_reg_save_area_size += 8;
3670 /* Print the register mask and do floating-point saves. */
3671 if (reg_mask && !flag_inhibit_size_directive)
3673 fprintf (file, "\t.mask 0x%x,", reg_mask);
3674 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3675 #if HOST_BITS_PER_WIDE_INT == 64
3676 frame_size >= (1l << 31) ? 0 :
3678 actual_start_reg_offset - frame_size);
3679 fprintf (file, "\n");
3682 start_reg_offset = reg_offset;
3685 for (i = 0; i < 32; i++)
3686 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3687 && regs_ever_live[i + 32])
3690 fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3694 /* Print the floating-point mask, if we've saved any fp register. */
3695 if (reg_mask && !flag_inhibit_size_directive)
3696 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
3697 actual_start_reg_offset - frame_size + int_reg_save_area_size);
3699 /* If we need a frame pointer, set it from the stack pointer. Note that
3700 this must always be the last instruction in the prologue. */
3701 if (frame_pointer_needed)
3702 fprintf (file, "\tbis $30,$30,$15\n");
3704 /* End the prologue and say if we used gp. */
3705 if (!flag_inhibit_size_directive)
3706 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3709 /* Write function epilogue. */
3712 output_epilog (file, size)
3716 rtx insn = get_last_insn ();
3717 HOST_WIDE_INT out_args_size
3718 = ALPHA_ROUND (current_function_outgoing_args_size);
3719 HOST_WIDE_INT sa_size = alpha_sa_size ();
3720 HOST_WIDE_INT frame_size
3721 = (out_args_size + sa_size
3722 + ALPHA_ROUND (size + current_function_pretend_args_size));
3723 HOST_WIDE_INT reg_offset = out_args_size;
3725 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
3728 /* If the last insn was a BARRIER, we don't have to write anything except
3729 the .end pseudo-op. */
3730 if (GET_CODE (insn) == NOTE)
3731 insn = prev_nonnote_insn (insn);
3732 if (insn == 0 || GET_CODE (insn) != BARRIER)
3737 /* If we have a frame pointer, restore SP from it. */
3738 if (frame_pointer_needed)
3739 fprintf (file, "\tbis $15,$15,$30\n");
3741 /* Cope with large offsets to the register save area. */
3743 if (reg_offset + sa_size > 0x8000)
3745 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3746 if (low + sa_size <= 0x8000)
3748 add_long_const (file, reg_offset - low, 30, 24, 24);
3753 add_long_const (file, reg_offset, 30, 24, 24);
3759 /* Restore all the registers, starting with the return address
3763 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
3767 /* Now restore any other used integer registers that we saved,
3768 except for FP if it is being used as FP, since it must be
3771 for (i = 0; i < 32; i++)
3772 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
3775 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3776 fp_offset = reg_offset;
3778 fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3782 for (i = 0; i < 32; i++)
3783 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3784 && regs_ever_live[i + 32])
3786 fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3790 /* If the stack size is large and we have a frame pointer, compute the
3791 size of the stack into a register because the old FP restore, stack
3792 pointer adjust, and return are required to be consecutive
3794 if (frame_size > 32767 && restore_fp)
3795 add_long_const (file, frame_size, 31, 1, 1);
3797 /* If we needed a frame pointer and we have to restore it, do it
3798 now. This must be done in one instruction immediately
3799 before the SP update. */
3800 if (restore_fp && fp_offset)
3801 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
3803 /* Now update the stack pointer, if needed. Only one instruction must
3804 modify the stack pointer. It must be the last instruction in the
3805 sequence and must be an ADDQ or LDA instruction. If the frame
3806 pointer was loaded above, we may only put one instruction here. */
3808 if (frame_size > 32768 && restore_fp)
3809 fprintf (file, "\taddq $1,$30,$30\n");
3811 add_long_const (file, frame_size, 30, 30, 1);
3813 /* Finally return to the caller. */
3814 fprintf (file, "\tret $31,($26),1\n");
3817 /* End the function. */
3818 if (!flag_inhibit_size_directive)
3820 fprintf (file, "\t.end ");
3821 assemble_name (file, alpha_function_name);
3822 fprintf (file, "\n");
3824 inside_function = FALSE;
3826 /* Show that we know this function if it is called again.
3828 Don't do this for global functions in object files destined for a
3829 shared library because the function may be overridden by the application
3831 ??? Is this just ELF? */
3833 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3834 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3836 #endif /* !OPEN_VMS */
3838 /* Debugging support. */
3842 /* Count the number of sdb related labels are generated (to find block
3843 start and end boundaries). */
3845 int sdb_label_count = 0;
3847 /* Next label # for each statement. */
3849 static int sym_lineno = 0;
3851 /* Count the number of .file directives, so that .loc is up to date. */
3853 static int num_source_filenames = 0;
3855 /* Name of the file containing the current function. */
3857 static char *current_function_file = "";
3859 /* Offsets to alpha virtual arg/local debugging pointers. */
3861 long alpha_arg_offset;
3862 long alpha_auto_offset;
3864 /* Emit a new filename to a stream. */
3867 alpha_output_filename (stream, name)
3871 static int first_time = TRUE;
3872 char ltext_label_name[100];
3877 ++num_source_filenames;
3878 current_function_file = name;
3879 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3880 output_quoted_string (stream, name);
3881 fprintf (stream, "\n");
3882 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3883 fprintf (stream, "\t#@stabs\n");
3886 else if (write_symbols == DBX_DEBUG)
3888 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3889 fprintf (stream, "%s ", ASM_STABS_OP);
3890 output_quoted_string (stream, name);
3891 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3894 else if (name != current_function_file
3895 && strcmp (name, current_function_file) != 0)
3897 if (inside_function && ! TARGET_GAS)
3898 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3901 ++num_source_filenames;
3902 current_function_file = name;
3903 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3906 output_quoted_string (stream, name);
3907 fprintf (stream, "\n");
3911 /* Emit a linenumber to a stream. */
3914 alpha_output_lineno (stream, line)
3918 if (write_symbols == DBX_DEBUG)
3920 /* mips-tfile doesn't understand .stabd directives. */
3922 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3923 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3926 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3929 /* Structure to show the current status of registers and memory. */
3931 struct shadow_summary
3934 unsigned long i : 31; /* Mask of int regs */
3935 unsigned long fp : 31; /* Mask of fp regs */
3936 unsigned long mem : 1; /* mem == imem | fpmem */
3940 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3941 to the summary structure. SET is nonzero if the insn is setting the
3942 object, otherwise zero. */
3945 summarize_insn (x, sum, set)
3947 struct shadow_summary *sum;
3956 switch (GET_CODE (x))
3958 /* ??? Note that this case would be incorrect if the Alpha had a
3959 ZERO_EXTRACT in SET_DEST. */
3961 summarize_insn (SET_SRC (x), sum, 0);
3962 summarize_insn (SET_DEST (x), sum, 1);
3966 summarize_insn (XEXP (x, 0), sum, 1);
3970 summarize_insn (XEXP (x, 0), sum, 0);
3974 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3975 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3979 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3980 summarize_insn (XVECEXP (x, 0, i), sum, 0);
3989 int regno = REGNO (x);
3990 unsigned long mask = 1UL << (regno % 32);
3992 if (regno == 31 || regno == 63)
3998 sum->defd.i |= mask;
4000 sum->defd.fp |= mask;
4005 sum->used.i |= mask;
4007 sum->used.fp |= mask;
4018 /* Find the regs used in memory address computation: */
4019 summarize_insn (XEXP (x, 0), sum, 0);
4022 case CONST_INT: case CONST_DOUBLE:
4023 case SYMBOL_REF: case LABEL_REF: case CONST:
4026 /* Handle common unary and binary ops for efficiency. */
4027 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4028 case MOD: case UDIV: case UMOD: case AND: case IOR:
4029 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4030 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4031 case NE: case EQ: case GE: case GT: case LE:
4032 case LT: case GEU: case GTU: case LEU: case LTU:
4033 summarize_insn (XEXP (x, 0), sum, 0);
4034 summarize_insn (XEXP (x, 1), sum, 0);
4037 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4038 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4039 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4040 case SQRT: case FFS:
4041 summarize_insn (XEXP (x, 0), sum, 0);
4045 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4046 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4047 switch (format_ptr[i])
4050 summarize_insn (XEXP (x, i), sum, 0);
4054 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4055 summarize_insn (XVECEXP (x, i, j), sum, 0);
4064 /* Ensure a sufficient number of `trapb' insns are in the code when the user
4065 requests code with a trap precision of functions or instructions.
4067 In naive mode, when the user requests a trap-precision of "instruction", a
4068 trapb is needed after every instruction that may generate a trap (and after
4069 jsr/bsr instructions, because called functions may import a trap from the
4070 caller). This ensures that the code is resumption safe but it is also slow.
4072 When optimizations are turned on, we delay issuing a trapb as long as
4073 possible. In this context, a trap shadow is the sequence of instructions
4074 that starts with a (potentially) trap generating instruction and extends to
4075 the next trapb or call_pal instruction (but GCC never generates call_pal by
4076 itself). We can delay (and therefore sometimes omit) a trapb subject to the
4077 following conditions:
4079 (a) On entry to the trap shadow, if any Alpha register or memory location
4080 contains a value that is used as an operand value by some instruction in
4081 the trap shadow (live on entry), then no instruction in the trap shadow
4082 may modify the register or memory location.
4084 (b) Within the trap shadow, the computation of the base register for a
4085 memory load or store instruction may not involve using the result
4086 of an instruction that might generate an UNPREDICTABLE result.
4088 (c) Within the trap shadow, no register may be used more than once as a
4089 destination register. (This is to make life easier for the trap-handler.)
4091 (d) The trap shadow may not include any branch instructions. */
4094 alpha_handle_trap_shadows (insns)
4097 struct shadow_summary shadow;
4098 int trap_pending, exception_nesting;
4101 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
4105 exception_nesting = 0;
4108 shadow.used.mem = 0;
4109 shadow.defd = shadow.used;
4111 for (i = insns; i ; i = NEXT_INSN (i))
4113 if (GET_CODE (i) == NOTE)
4115 switch (NOTE_LINE_NUMBER (i))
4117 case NOTE_INSN_EH_REGION_BEG:
4118 exception_nesting++;
4123 case NOTE_INSN_EH_REGION_END:
4124 exception_nesting--;
4129 case NOTE_INSN_EPILOGUE_BEG:
4130 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4135 else if (trap_pending)
4137 if (alpha_tp == ALPHA_TP_FUNC)
4139 if (GET_CODE (i) == JUMP_INSN
4140 && GET_CODE (PATTERN (i)) == RETURN)
4143 else if (alpha_tp == ALPHA_TP_INSN)
4147 struct shadow_summary sum;
4152 sum.defd = sum.used;
4154 switch (GET_CODE (i))
4157 /* Annoyingly, get_attr_trap will abort on these. */
4158 if (GET_CODE (PATTERN (i)) == USE
4159 || GET_CODE (PATTERN (i)) == CLOBBER)
4162 summarize_insn (PATTERN (i), &sum, 0);
4164 if ((sum.defd.i & shadow.defd.i)
4165 || (sum.defd.fp & shadow.defd.fp))
4167 /* (c) would be violated */
4171 /* Combine shadow with summary of current insn: */
4172 shadow.used.i |= sum.used.i;
4173 shadow.used.fp |= sum.used.fp;
4174 shadow.used.mem |= sum.used.mem;
4175 shadow.defd.i |= sum.defd.i;
4176 shadow.defd.fp |= sum.defd.fp;
4177 shadow.defd.mem |= sum.defd.mem;
4179 if ((sum.defd.i & shadow.used.i)
4180 || (sum.defd.fp & shadow.used.fp)
4181 || (sum.defd.mem & shadow.used.mem))
4183 /* (a) would be violated (also takes care of (b)) */
4184 if (get_attr_trap (i) == TRAP_YES
4185 && ((sum.defd.i & sum.used.i)
4186 || (sum.defd.fp & sum.used.fp)))
4205 emit_insn_before (gen_trapb (), i);
4209 shadow.used.mem = 0;
4210 shadow.defd = shadow.used;
4215 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4216 && GET_CODE (i) == INSN
4217 && GET_CODE (PATTERN (i)) != USE
4218 && GET_CODE (PATTERN (i)) != CLOBBER
4219 && get_attr_trap (i) == TRAP_YES)
4221 if (optimize && !trap_pending)
4222 summarize_insn (PATTERN (i), &shadow, 0);
4228 /* Machine dependant reorg pass. */
4234 alpha_handle_trap_shadows (insns);
4238 /* Check a floating-point value for validity for a particular machine mode. */
4240 static char *float_strings[] =
4242 /* These are for FLOAT_VAX. */
4243 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4244 "-1.70141173319264430e+38",
4245 "2.93873587705571877e-39", /* 2^-128 */
4246 "-2.93873587705571877e-39",
4247 /* These are for the default broken IEEE mode, which traps
4248 on infinity or denormal numbers. */
4249 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4250 "-3.402823466385288598117e+38",
4251 "1.1754943508222875079687e-38", /* 2^-126 */
4252 "-1.1754943508222875079687e-38",
4255 static REAL_VALUE_TYPE float_values[8];
4256 static int inited_float_values = 0;
4259 check_float_value (mode, d, overflow)
4260 enum machine_mode mode;
4265 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4268 if (inited_float_values == 0)
4271 for (i = 0; i < 8; i++)
4272 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4274 inited_float_values = 1;
4280 REAL_VALUE_TYPE *fvptr;
4282 if (TARGET_FLOAT_VAX)
4283 fvptr = &float_values[0];
4285 fvptr = &float_values[4];
4287 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4288 if (REAL_VALUES_LESS (fvptr[0], r))
4290 bcopy ((char *) &fvptr[0], (char *) d,
4291 sizeof (REAL_VALUE_TYPE));
4294 else if (REAL_VALUES_LESS (r, fvptr[1]))
4296 bcopy ((char *) &fvptr[1], (char *) d,
4297 sizeof (REAL_VALUE_TYPE));
4300 else if (REAL_VALUES_LESS (dconst0, r)
4301 && REAL_VALUES_LESS (r, fvptr[2]))
4303 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4306 else if (REAL_VALUES_LESS (r, dconst0)
4307 && REAL_VALUES_LESS (fvptr[3], r))
4309 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4319 /* Return the VMS argument type corresponding to MODE. */
4322 alpha_arg_type (mode)
4323 enum machine_mode mode;
4328 return TARGET_FLOAT_VAX ? FF : FS;
4330 return TARGET_FLOAT_VAX ? FD : FT;
4336 /* Return an rtx for an integer representing the VMS Argument Information
4340 alpha_arg_info_reg_val (cum)
4341 CUMULATIVE_ARGS cum;
4343 unsigned HOST_WIDE_INT regval = cum.num_args;
4346 for (i = 0; i < 6; i++)
4347 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4349 return GEN_INT (regval);
4352 /* Structure to collect function names for final output
4355 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4358 struct alpha_links {
4359 struct alpha_links *next;
4361 enum links_kind kind;
4364 static struct alpha_links *alpha_links_base = 0;
4366 /* Make (or fake) .linkage entry for function call.
4368 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
4371 alpha_need_linkage (name, is_local)
4376 struct alpha_links *lptr, *nptr;
4381 /* Is this name already defined ? */
4383 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4384 if (strcmp (lptr->name, name) == 0)
4388 /* Defined here but external assumed. */
4389 if (lptr->kind == KIND_EXTERN)
4390 lptr->kind = KIND_LOCAL;
4394 /* Used here but unused assumed. */
4395 if (lptr->kind == KIND_UNUSED)
4396 lptr->kind = KIND_LOCAL;
4401 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4402 nptr->next = alpha_links_base;
4403 nptr->name = xstrdup (name);
4405 /* Assume external if no definition. */
4406 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4408 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
4409 get_identifier (name);
4411 alpha_links_base = nptr;
4418 alpha_write_linkage (stream)
4421 struct alpha_links *lptr, *nptr;
4423 readonly_section ();
4425 fprintf (stream, "\t.align 3\n");
4427 for (lptr = alpha_links_base; lptr; lptr = nptr)
4431 if (lptr->kind == KIND_UNUSED
4432 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4435 fprintf (stream, "$%s..lk:\n", lptr->name);
4436 if (lptr->kind == KIND_LOCAL)
4438 /* Local and used, build linkage pair. */
4439 fprintf (stream, "\t.quad %s..en\n", lptr->name);
4440 fprintf (stream, "\t.quad %s\n", lptr->name);
4443 /* External and used, request linkage pair. */
4444 fprintf (stream, "\t.linkage %s\n", lptr->name);
4451 alpha_need_linkage (name, is_local)
4457 #endif /* OPEN_VMS */