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 branch_code = swap_condition (cmp_code);
1289 /* ??? We mark the the branch mode to be CCmode to prevent the
1290 compare and branch from being combined, since the compare
1291 insn follows IEEE rules that the branch does not. */
1292 branch_mode = CCmode;
1299 /* The following optimizations are only for signed compares. */
1300 if (code != LEU && code != LTU && code != GEU && code != GTU)
1302 /* Whee. Compare and branch against 0 directly. */
1303 if (op1 == const0_rtx)
1304 cmp_code = NIL, branch_code = code;
1306 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1307 bypass between logicals and br/cmov on EV5. But we don't want to
1308 force valid immediate constants into registers needlessly. */
1309 else if (GET_CODE (op1) == CONST_INT)
1311 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1313 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1314 && (CONST_OK_FOR_LETTER_P (n, 'K')
1315 || CONST_OK_FOR_LETTER_P (n, 'L')))
1317 cmp_code = PLUS, branch_code = code;
1324 /* Force op0 into a register. */
1325 if (GET_CODE (op0) != REG)
1326 op0 = force_reg (cmp_mode, op0);
1328 /* Emit an initial compare instruction, if necessary. */
1330 if (cmp_code != NIL)
1332 tem = gen_reg_rtx (cmp_mode);
1333 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1336 /* Return the branch comparison. */
1337 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1341 /* Rewrite a comparison against zero CMP of the form
1342 (CODE (cc0) (const_int 0)) so it can be written validly in
1343 a conditional move (if_then_else CMP ...).
1344 If both of the operands that set cc0 are non-zero we must emit
1345 an insn to perform the compare (it can't be done within
1346 the conditional move). */
1348 alpha_emit_conditional_move (cmp, mode)
1350 enum machine_mode mode;
1352 enum rtx_code code = GET_CODE (cmp);
1353 enum rtx_code cmov_code = NE;
1354 rtx op0 = alpha_compare_op0;
1355 rtx op1 = alpha_compare_op1;
1356 enum machine_mode cmp_mode
1357 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1358 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1359 enum machine_mode cmov_mode = VOIDmode;
1362 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1365 /* We may be able to use a conditional move directly.
1366 This avoids emitting spurious compares. */
1367 if (signed_comparison_operator (cmp, cmp_op_mode)
1368 && (!alpha_compare_fp_p || flag_fast_math)
1369 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1370 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1372 /* We can't put the comparison insides a conditional move;
1373 emit a compare instruction and put that inside the
1374 conditional move. Make sure we emit only comparisons we have;
1375 swap or reverse as necessary. */
1379 case EQ: case LE: case LT: case LEU: case LTU:
1380 /* We have these compares: */
1384 /* This must be reversed. */
1385 code = reverse_condition (code);
1389 case GE: case GT: case GEU: case GTU:
1390 /* These must be swapped. Make sure the new first operand is in
1392 code = swap_condition (code);
1393 tem = op0, op0 = op1, op1 = tem;
1394 op0 = force_reg (cmp_mode, op0);
1401 /* ??? We mark the the branch mode to be CCmode to prevent the compare
1402 and cmov from being combined, since the compare insn follows IEEE
1403 rules that the cmov does not. */
1404 if (alpha_compare_fp_p && !flag_fast_math)
1407 tem = gen_reg_rtx (cmp_op_mode);
1408 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1409 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1412 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1416 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1417 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1418 lda r3,X(r11) lda r3,X+2(r11)
1419 extwl r1,r3,r1 extql r1,r3,r1
1420 extwh r2,r3,r2 extqh r2,r3,r2
1421 or r1.r2.r1 or r1,r2,r1
1424 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1425 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1426 lda r3,X(r11) lda r3,X(r11)
1427 extll r1,r3,r1 extll r1,r3,r1
1428 extlh r2,r3,r2 extlh r2,r3,r2
1429 or r1.r2.r1 addl r1,r2,r1
1431 quad: ldq_u r1,X(r11)
1440 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1442 HOST_WIDE_INT size, ofs;
1445 rtx meml, memh, addr, extl, exth;
1446 enum machine_mode mode;
1448 meml = gen_reg_rtx (DImode);
1449 memh = gen_reg_rtx (DImode);
1450 addr = gen_reg_rtx (DImode);
1451 extl = gen_reg_rtx (DImode);
1452 exth = gen_reg_rtx (DImode);
1454 emit_move_insn (meml,
1455 change_address (mem, DImode,
1456 gen_rtx_AND (DImode,
1457 plus_constant (XEXP (mem, 0),
1461 emit_move_insn (memh,
1462 change_address (mem, DImode,
1463 gen_rtx_AND (DImode,
1464 plus_constant (XEXP (mem, 0),
1468 if (sign && size == 2)
1470 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1472 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1473 emit_insn (gen_extqh (exth, memh, addr));
1475 /* We must use tgt here for the target. Alpha-vms port fails if we use
1476 addr for the target, because addr is marked as a pointer and combine
1477 knows that pointers are always sign-extended 32 bit values. */
1478 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1479 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1480 addr, 1, OPTAB_WIDEN);
1484 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1485 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1489 emit_insn (gen_extwh (exth, memh, addr));
1494 emit_insn (gen_extlh (exth, memh, addr));
1499 emit_insn (gen_extqh (exth, memh, addr));
1504 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1505 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1510 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1513 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1516 alpha_expand_unaligned_store (dst, src, size, ofs)
1518 HOST_WIDE_INT size, ofs;
1520 rtx dstl, dsth, addr, insl, insh, meml, memh;
1522 dstl = gen_reg_rtx (DImode);
1523 dsth = gen_reg_rtx (DImode);
1524 insl = gen_reg_rtx (DImode);
1525 insh = gen_reg_rtx (DImode);
1527 meml = change_address (dst, DImode,
1528 gen_rtx_AND (DImode,
1529 plus_constant (XEXP (dst, 0), ofs),
1531 memh = change_address (dst, DImode,
1532 gen_rtx_AND (DImode,
1533 plus_constant (XEXP (dst, 0),
1537 emit_move_insn (dsth, memh);
1538 emit_move_insn (dstl, meml);
1539 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1541 if (src != const0_rtx)
1543 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1544 GEN_INT (size*8), addr));
1549 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1552 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1555 emit_insn (gen_insql (insl, src, addr));
1560 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1565 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1568 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1572 #if HOST_BITS_PER_WIDE_INT == 32
1573 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1575 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1577 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1582 if (src != const0_rtx)
1584 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1585 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1588 /* Must store high before low for degenerate case of aligned. */
1589 emit_move_insn (memh, dsth);
1590 emit_move_insn (meml, dstl);
1593 /* The block move code tries to maximize speed by separating loads and
1594 stores at the expense of register pressure: we load all of the data
1595 before we store it back out. There are two secondary effects worth
1596 mentioning, that this speeds copying to/from aligned and unaligned
1597 buffers, and that it makes the code significantly easier to write. */
1599 #define MAX_MOVE_WORDS 8
1601 /* Load an integral number of consecutive unaligned quadwords. */
1604 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1607 HOST_WIDE_INT words, ofs;
1609 rtx const im8 = GEN_INT (-8);
1610 rtx const i64 = GEN_INT (64);
1611 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1615 /* Generate all the tmp registers we need. */
1616 for (i = 0; i < words; ++i)
1618 data_regs[i] = out_regs[i];
1619 ext_tmps[i] = gen_reg_rtx (DImode);
1621 data_regs[words] = gen_reg_rtx (DImode);
1624 smem = change_address (smem, GET_MODE (smem),
1625 plus_constant (XEXP (smem, 0), ofs));
1627 /* Load up all of the source data. */
1628 for (i = 0; i < words; ++i)
1630 emit_move_insn (data_regs[i],
1631 change_address (smem, DImode,
1632 gen_rtx_AND (DImode,
1633 plus_constant (XEXP(smem,0),
1637 emit_move_insn (data_regs[words],
1638 change_address (smem, DImode,
1639 gen_rtx_AND (DImode,
1640 plus_constant (XEXP(smem,0),
1644 /* Extract the half-word fragments. Unfortunately DEC decided to make
1645 extxh with offset zero a noop instead of zeroing the register, so
1646 we must take care of that edge condition ourselves with cmov. */
1648 sreg = copy_addr_to_reg (XEXP (smem, 0));
1649 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1651 for (i = 0; i < words; ++i)
1653 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1655 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1656 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1657 gen_rtx_IF_THEN_ELSE (DImode,
1658 gen_rtx_EQ (DImode, areg,
1660 const0_rtx, ext_tmps[i])));
1663 /* Merge the half-words into whole words. */
1664 for (i = 0; i < words; ++i)
1666 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1667 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1671 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1672 may be NULL to store zeros. */
1675 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1678 HOST_WIDE_INT words, ofs;
1680 rtx const im8 = GEN_INT (-8);
1681 rtx const i64 = GEN_INT (64);
1682 #if HOST_BITS_PER_WIDE_INT == 32
1683 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1685 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1687 rtx ins_tmps[MAX_MOVE_WORDS];
1688 rtx st_tmp_1, st_tmp_2, dreg;
1689 rtx st_addr_1, st_addr_2;
1692 /* Generate all the tmp registers we need. */
1693 if (data_regs != NULL)
1694 for (i = 0; i < words; ++i)
1695 ins_tmps[i] = gen_reg_rtx(DImode);
1696 st_tmp_1 = gen_reg_rtx(DImode);
1697 st_tmp_2 = gen_reg_rtx(DImode);
1700 dmem = change_address (dmem, GET_MODE (dmem),
1701 plus_constant (XEXP (dmem, 0), ofs));
1704 st_addr_2 = change_address (dmem, DImode,
1705 gen_rtx_AND (DImode,
1706 plus_constant (XEXP(dmem,0),
1709 st_addr_1 = change_address (dmem, DImode,
1710 gen_rtx_AND (DImode,
1714 /* Load up the destination end bits. */
1715 emit_move_insn (st_tmp_2, st_addr_2);
1716 emit_move_insn (st_tmp_1, st_addr_1);
1718 /* Shift the input data into place. */
1719 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1720 if (data_regs != NULL)
1722 for (i = words-1; i >= 0; --i)
1724 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1725 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1727 for (i = words-1; i > 0; --i)
1729 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1730 ins_tmps[i-1], ins_tmps[i-1], 1,
1735 /* Split and merge the ends with the destination data. */
1736 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1737 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1739 if (data_regs != NULL)
1741 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1742 st_tmp_2, 1, OPTAB_WIDEN);
1743 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1744 st_tmp_1, 1, OPTAB_WIDEN);
1748 emit_move_insn (st_addr_2, st_tmp_2);
1749 for (i = words-1; i > 0; --i)
1751 emit_move_insn (change_address (dmem, DImode,
1752 gen_rtx_AND (DImode,
1753 plus_constant(XEXP (dmem,0),
1756 data_regs ? ins_tmps[i-1] : const0_rtx);
1758 emit_move_insn (st_addr_1, st_tmp_1);
1762 /* Expand string/block move operations.
1764 operands[0] is the pointer to the destination.
1765 operands[1] is the pointer to the source.
1766 operands[2] is the number of bytes to move.
1767 operands[3] is the alignment. */
1770 alpha_expand_block_move (operands)
1773 rtx bytes_rtx = operands[2];
1774 rtx align_rtx = operands[3];
1775 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1776 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1777 HOST_WIDE_INT dst_align = src_align;
1778 rtx orig_src = operands[1];
1779 rtx orig_dst = operands[0];
1780 rtx data_regs[2*MAX_MOVE_WORDS+16];
1782 int i, words, ofs, nregs = 0;
1786 if (bytes > MAX_MOVE_WORDS*8)
1789 /* Look for additional alignment information from recorded register info. */
1791 tmp = XEXP (orig_src, 0);
1792 if (GET_CODE (tmp) == REG)
1794 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1795 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1797 else if (GET_CODE (tmp) == PLUS
1798 && GET_CODE (XEXP (tmp, 0)) == REG
1799 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1801 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1802 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1806 if (a >= 8 && c % 8 == 0)
1808 else if (a >= 4 && c % 4 == 0)
1810 else if (a >= 2 && c % 2 == 0)
1815 tmp = XEXP (orig_dst, 0);
1816 if (GET_CODE (tmp) == REG)
1818 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1819 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1821 else if (GET_CODE (tmp) == PLUS
1822 && GET_CODE (XEXP (tmp, 0)) == REG
1823 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1825 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1826 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1830 if (a >= 8 && c % 8 == 0)
1832 else if (a >= 4 && c % 4 == 0)
1834 else if (a >= 2 && c % 2 == 0)
1840 * Load the entire block into registers.
1843 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1845 enum machine_mode mode;
1846 tmp = XEXP (XEXP (orig_src, 0), 0);
1848 mode = mode_for_size (bytes, MODE_INT, 1);
1850 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1852 /* Whee! Optimize the load to use the existing register. */
1853 data_regs[nregs++] = gen_lowpart (mode, tmp);
1857 /* ??? We could potentially be copying 3 bytes or whatnot from
1858 a wider reg. Probably not worth worrying about. */
1859 /* No appropriate mode; fall back on memory. */
1860 orig_src = change_address (orig_src, GET_MODE (orig_src),
1861 copy_addr_to_reg (XEXP (orig_src, 0)));
1865 if (src_align >= 8 && bytes >= 8)
1869 for (i = 0; i < words; ++i)
1870 data_regs[nregs+i] = gen_reg_rtx(DImode);
1872 for (i = 0; i < words; ++i)
1874 emit_move_insn (data_regs[nregs+i],
1875 change_address(orig_src, DImode,
1876 plus_constant (XEXP (orig_src, 0),
1884 if (src_align >= 4 && bytes >= 4)
1888 for (i = 0; i < words; ++i)
1889 data_regs[nregs+i] = gen_reg_rtx(SImode);
1891 for (i = 0; i < words; ++i)
1893 emit_move_insn (data_regs[nregs+i],
1894 change_address(orig_src, SImode,
1895 plus_constant (XEXP (orig_src, 0),
1907 for (i = 0; i < words+1; ++i)
1908 data_regs[nregs+i] = gen_reg_rtx(DImode);
1910 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1916 if (!TARGET_BWX && bytes >= 8)
1918 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1919 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1923 if (!TARGET_BWX && bytes >= 4)
1925 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1926 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1935 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1936 emit_move_insn (tmp,
1937 change_address (orig_src, HImode,
1938 plus_constant (XEXP (orig_src, 0),
1942 } while (bytes >= 2);
1944 else if (!TARGET_BWX)
1946 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1947 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1954 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1955 emit_move_insn (tmp,
1956 change_address (orig_src, QImode,
1957 plus_constant (XEXP (orig_src, 0),
1964 if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1968 * Now save it back out again.
1973 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1975 enum machine_mode mode;
1976 tmp = XEXP (XEXP (orig_dst, 0), 0);
1978 mode = mode_for_size (bytes, MODE_INT, 1);
1979 if (GET_MODE (tmp) == mode && nregs == 1)
1981 emit_move_insn (tmp, data_regs[0]);
1986 /* ??? If nregs > 1, consider reconstructing the word in regs. */
1987 /* ??? Optimize mode < dst_mode with strict_low_part. */
1988 /* No appropriate mode; fall back on memory. */
1989 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
1990 copy_addr_to_reg (XEXP (orig_dst, 0)));
1993 /* Write out the data in whatever chunks reading the source allowed. */
1996 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
1998 emit_move_insn (change_address(orig_dst, DImode,
1999 plus_constant (XEXP (orig_dst, 0),
2008 /* If the source has remaining DImode regs, write them out in
2010 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2012 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2013 NULL_RTX, 1, OPTAB_WIDEN);
2015 emit_move_insn (change_address(orig_dst, SImode,
2016 plus_constant (XEXP (orig_dst, 0),
2018 gen_lowpart (SImode, data_regs[i]));
2019 emit_move_insn (change_address(orig_dst, SImode,
2020 plus_constant (XEXP (orig_dst, 0),
2022 gen_lowpart (SImode, tmp));
2027 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2029 emit_move_insn (change_address(orig_dst, SImode,
2030 plus_constant (XEXP (orig_dst, 0),
2037 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2039 /* Write out a remaining block of words using unaligned methods. */
2041 for (words = 1; i+words < nregs ; ++words)
2042 if (GET_MODE (data_regs[i+words]) != DImode)
2046 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2048 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2054 /* Due to the above, this won't be aligned. */
2055 /* ??? If we have more than one of these, consider constructing full
2056 words in registers and using alpha_expand_unaligned_store_words. */
2057 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2059 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2065 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2067 emit_move_insn (change_address (orig_dst, HImode,
2068 plus_constant (XEXP (orig_dst, 0),
2075 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2077 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2081 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2083 emit_move_insn (change_address (orig_dst, QImode,
2084 plus_constant (XEXP (orig_dst, 0),
2099 alpha_expand_block_clear (operands)
2102 rtx bytes_rtx = operands[1];
2103 rtx align_rtx = operands[2];
2104 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2105 HOST_WIDE_INT align = INTVAL (align_rtx);
2106 rtx orig_dst = operands[0];
2108 HOST_WIDE_INT i, words, ofs = 0;
2112 if (bytes > MAX_MOVE_WORDS*8)
2115 /* Look for stricter alignment. */
2117 tmp = XEXP (orig_dst, 0);
2118 if (GET_CODE (tmp) == REG)
2120 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2121 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2123 else if (GET_CODE (tmp) == PLUS
2124 && GET_CODE (XEXP (tmp, 0)) == REG
2125 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2127 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2128 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2132 if (a >= 8 && c % 8 == 0)
2134 else if (a >= 4 && c % 4 == 0)
2136 else if (a >= 2 && c % 2 == 0)
2141 /* Handle a block of contiguous words first. */
2143 if (align >= 8 && bytes >= 8)
2147 for (i = 0; i < words; ++i)
2149 emit_move_insn (change_address(orig_dst, DImode,
2150 plus_constant (XEXP (orig_dst, 0),
2158 if (align >= 4 && bytes >= 4)
2162 for (i = 0; i < words; ++i)
2164 emit_move_insn (change_address(orig_dst, SImode,
2165 plus_constant (XEXP (orig_dst, 0),
2177 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2183 /* Next clean up any trailing pieces. We know from the contiguous
2184 block move that there are no aligned SImode or DImode hunks left. */
2186 if (!TARGET_BWX && bytes >= 8)
2188 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2192 if (!TARGET_BWX && bytes >= 4)
2194 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2203 emit_move_insn (change_address (orig_dst, HImode,
2204 plus_constant (XEXP (orig_dst, 0),
2209 } while (bytes >= 2);
2211 else if (!TARGET_BWX)
2213 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2220 emit_move_insn (change_address (orig_dst, QImode,
2221 plus_constant (XEXP (orig_dst, 0),
2232 /* Adjust the cost of a scheduling dependency. Return the new cost of
2233 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2236 alpha_adjust_cost (insn, link, dep_insn, cost)
2243 enum attr_type insn_type, dep_insn_type;
2245 /* If the dependence is an anti-dependence, there is no cost. For an
2246 output dependence, there is sometimes a cost, but it doesn't seem
2247 worth handling those few cases. */
2249 if (REG_NOTE_KIND (link) != 0)
2252 /* If we can't recognize the insns, we can't really do anything. */
2253 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2256 insn_type = get_attr_type (insn);
2257 dep_insn_type = get_attr_type (dep_insn);
2259 /* Bring in the user-defined memory latency. */
2260 if (dep_insn_type == TYPE_ILD
2261 || dep_insn_type == TYPE_FLD
2262 || dep_insn_type == TYPE_LDSYM)
2263 cost += alpha_memory_latency-1;
2268 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2269 being stored, we can sometimes lower the cost. */
2271 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2272 && (set = single_set (dep_insn)) != 0
2273 && GET_CODE (PATTERN (insn)) == SET
2274 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2276 switch (dep_insn_type)
2280 /* No savings here. */
2284 /* In these cases, we save one cycle. */
2288 /* In all other cases, we save two cycles. */
2289 return MAX (0, cost - 2);
2293 /* Another case that needs adjustment is an arithmetic or logical
2294 operation. It's cost is usually one cycle, but we default it to
2295 two in the MD file. The only case that it is actually two is
2296 for the address in loads, stores, and jumps. */
2298 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2313 /* The final case is when a compare feeds into an integer branch;
2314 the cost is only one cycle in that case. */
2316 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2321 /* And the lord DEC saith: "A special bypass provides an effective
2322 latency of 0 cycles for an ICMP or ILOG insn producing the test
2323 operand of an IBR or ICMOV insn." */
2325 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2326 && (set = single_set (dep_insn)) != 0)
2328 /* A branch only has one input. This must be it. */
2329 if (insn_type == TYPE_IBR)
2331 /* A conditional move has three, make sure it is the test. */
2332 if (insn_type == TYPE_ICMOV
2333 && GET_CODE (set_src = PATTERN (insn)) == SET
2334 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2335 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2339 /* "The multiplier is unable to receive data from IEU bypass paths.
2340 The instruction issues at the expected time, but its latency is
2341 increased by the time it takes for the input data to become
2342 available to the multiplier" -- which happens in pipeline stage
2343 six, when results are comitted to the register file. */
2345 if (insn_type == TYPE_IMUL)
2347 switch (dep_insn_type)
2349 /* These insns produce their results in pipeline stage five. */
2356 /* Other integer insns produce results in pipeline stage four. */
2364 /* There is additional latency to move the result of (most) FP
2365 operations anywhere but the FP register file. */
2367 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2368 && (dep_insn_type == TYPE_FADD ||
2369 dep_insn_type == TYPE_FMUL ||
2370 dep_insn_type == TYPE_FCMOV))
2376 /* Otherwise, return the default cost. */
2380 /* Functions to save and restore alpha_return_addr_rtx. */
2382 struct machine_function
2388 alpha_save_machine_status (p)
2391 struct machine_function *machine =
2392 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2394 p->machine = machine;
2395 machine->ra_rtx = alpha_return_addr_rtx;
2399 alpha_restore_machine_status (p)
2402 struct machine_function *machine = p->machine;
2404 alpha_return_addr_rtx = machine->ra_rtx;
2407 p->machine = (struct machine_function *)0;
2410 /* Do anything needed before RTL is emitted for each function. */
2413 alpha_init_expanders ()
2415 alpha_return_addr_rtx = NULL_RTX;
2417 /* Arrange to save and restore machine status around nested functions. */
2418 save_machine_status = alpha_save_machine_status;
2419 restore_machine_status = alpha_restore_machine_status;
2422 /* Start the ball rolling with RETURN_ADDR_RTX. */
2425 alpha_return_addr (count, frame)
2434 if (alpha_return_addr_rtx)
2435 return alpha_return_addr_rtx;
2437 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2438 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2439 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2440 gen_rtx_REG (Pmode, REG_RA));
2442 /* Emit the insn to the prologue with the other argument copies. */
2443 push_topmost_sequence ();
2444 emit_insn_after (init, get_insns ());
2445 pop_topmost_sequence ();
2447 return alpha_return_addr_rtx;
2451 alpha_ra_ever_killed ()
2453 if (!alpha_return_addr_rtx)
2454 return regs_ever_live[REG_RA];
2456 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2457 get_insns(), NULL_RTX);
2461 /* Print an operand. Recognize special options, documented below. */
2464 print_operand (file, x, code)
2474 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2475 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2476 mode. alpha_fprm controls which suffix is generated. */
2479 case ALPHA_FPRM_NORM:
2481 case ALPHA_FPRM_MINF:
2484 case ALPHA_FPRM_CHOP:
2487 case ALPHA_FPRM_DYN:
2494 /* Generates trap-mode suffix for instructions that accept the su
2495 suffix only (cmpt et al). */
2496 if (alpha_tp == ALPHA_TP_INSN)
2501 /* Generates trap-mode suffix for instructions that accept the
2502 v and sv suffix. The only instruction that needs this is cvtql. */
2511 case ALPHA_FPTM_SUI:
2518 /* Generates trap-mode suffix for instructions that accept the
2519 v, sv, and svi suffix. The only instruction that needs this
2531 case ALPHA_FPTM_SUI:
2532 fputs ("svi", file);
2538 /* Generates trap-mode suffix for instructions that accept the u, su,
2539 and sui suffix. This is the bulk of the IEEE floating point
2540 instructions (addt et al). */
2551 case ALPHA_FPTM_SUI:
2552 fputs ("sui", file);
2558 /* Generates trap-mode suffix for instructions that accept the sui
2559 suffix (cvtqt and cvtqs). */
2564 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2566 case ALPHA_FPTM_SUI:
2567 fputs ("sui", file);
2573 /* Generates single precision instruction suffix. */
2574 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2578 /* Generates double precision instruction suffix. */
2579 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2583 /* If this operand is the constant zero, write it as "$31". */
2584 if (GET_CODE (x) == REG)
2585 fprintf (file, "%s", reg_names[REGNO (x)]);
2586 else if (x == CONST0_RTX (GET_MODE (x)))
2587 fprintf (file, "$31");
2589 output_operand_lossage ("invalid %%r value");
2594 /* Similar, but for floating-point. */
2595 if (GET_CODE (x) == REG)
2596 fprintf (file, "%s", reg_names[REGNO (x)]);
2597 else if (x == CONST0_RTX (GET_MODE (x)))
2598 fprintf (file, "$f31");
2600 output_operand_lossage ("invalid %%R value");
2605 /* Write the 1's complement of a constant. */
2606 if (GET_CODE (x) != CONST_INT)
2607 output_operand_lossage ("invalid %%N value");
2609 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2613 /* Write 1 << C, for a constant C. */
2614 if (GET_CODE (x) != CONST_INT)
2615 output_operand_lossage ("invalid %%P value");
2617 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2621 /* Write the high-order 16 bits of a constant, sign-extended. */
2622 if (GET_CODE (x) != CONST_INT)
2623 output_operand_lossage ("invalid %%h value");
2625 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2629 /* Write the low-order 16 bits of a constant, sign-extended. */
2630 if (GET_CODE (x) != CONST_INT)
2631 output_operand_lossage ("invalid %%L value");
2633 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2634 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2638 /* Write mask for ZAP insn. */
2639 if (GET_CODE (x) == CONST_DOUBLE)
2641 HOST_WIDE_INT mask = 0;
2642 HOST_WIDE_INT value;
2644 value = CONST_DOUBLE_LOW (x);
2645 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2650 value = CONST_DOUBLE_HIGH (x);
2651 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2654 mask |= (1 << (i + sizeof (int)));
2656 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2659 else if (GET_CODE (x) == CONST_INT)
2661 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2663 for (i = 0; i < 8; i++, value >>= 8)
2667 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2670 output_operand_lossage ("invalid %%m value");
2674 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2675 if (GET_CODE (x) != CONST_INT
2676 || (INTVAL (x) != 8 && INTVAL (x) != 16
2677 && INTVAL (x) != 32 && INTVAL (x) != 64))
2678 output_operand_lossage ("invalid %%M value");
2680 fprintf (file, "%s",
2681 (INTVAL (x) == 8 ? "b"
2682 : INTVAL (x) == 16 ? "w"
2683 : INTVAL (x) == 32 ? "l"
2688 /* Similar, except do it from the mask. */
2689 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2690 fprintf (file, "b");
2691 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2692 fprintf (file, "w");
2693 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2694 fprintf (file, "l");
2695 #if HOST_BITS_PER_WIDE_INT == 32
2696 else if (GET_CODE (x) == CONST_DOUBLE
2697 && CONST_DOUBLE_HIGH (x) == 0
2698 && CONST_DOUBLE_LOW (x) == -1)
2699 fprintf (file, "l");
2700 else if (GET_CODE (x) == CONST_DOUBLE
2701 && CONST_DOUBLE_HIGH (x) == -1
2702 && CONST_DOUBLE_LOW (x) == -1)
2703 fprintf (file, "q");
2705 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2706 fprintf (file, "q");
2707 else if (GET_CODE (x) == CONST_DOUBLE
2708 && CONST_DOUBLE_HIGH (x) == 0
2709 && CONST_DOUBLE_LOW (x) == -1)
2710 fprintf (file, "q");
2713 output_operand_lossage ("invalid %%U value");
2717 /* Write the constant value divided by 8. */
2718 if (GET_CODE (x) != CONST_INT
2719 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2720 && (INTVAL (x) & 7) != 8)
2721 output_operand_lossage ("invalid %%s value");
2723 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2727 /* Same, except compute (64 - c) / 8 */
2729 if (GET_CODE (x) != CONST_INT
2730 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2731 && (INTVAL (x) & 7) != 8)
2732 output_operand_lossage ("invalid %%s value");
2734 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2737 case 'C': case 'D': case 'c': case 'd':
2738 /* Write out comparison name. */
2740 enum rtx_code c = GET_CODE (x);
2742 if (GET_RTX_CLASS (c) != '<')
2743 output_operand_lossage ("invalid %%C value");
2746 c = reverse_condition (c);
2747 else if (code == 'c')
2748 c = swap_condition (c);
2749 else if (code == 'd')
2750 c = swap_condition (reverse_condition (c));
2753 fprintf (file, "ule");
2755 fprintf (file, "ult");
2757 fprintf (file, "%s", GET_RTX_NAME (c));
2762 /* Write the divide or modulus operator. */
2763 switch (GET_CODE (x))
2766 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2769 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2772 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2775 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2778 output_operand_lossage ("invalid %%E value");
2784 /* Write "_u" for unaligned access. */
2785 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2786 fprintf (file, "_u");
2790 if (GET_CODE (x) == REG)
2791 fprintf (file, "%s", reg_names[REGNO (x)]);
2792 else if (GET_CODE (x) == MEM)
2793 output_address (XEXP (x, 0));
2795 output_addr_const (file, x);
2799 output_operand_lossage ("invalid %%xn code");
2803 /* Do what is necessary for `va_start'. The argument is ignored;
2804 We look at the current function to determine if stdarg or varargs
2805 is used and fill in an initial va_list. A pointer to this constructor
2809 alpha_builtin_saveregs (arglist)
2812 rtx block, addr, dest, argsize;
2813 tree fntype = TREE_TYPE (current_function_decl);
2814 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2815 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2816 != void_type_node));
2818 /* Compute the current position into the args, taking into account
2819 both registers and memory. Both of these are already included in
2822 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2824 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2825 storing fp arg registers in the first 48 bytes, and the integer arg
2826 registers in the next 48 bytes. This is only done, however, if any
2827 integer registers need to be stored.
2829 If no integer registers need be stored, then we must subtract 48 in
2830 order to account for the integer arg registers which are counted in
2831 argsize above, but which are not actually stored on the stack. */
2833 if (TARGET_OPEN_VMS)
2834 addr = plus_constant (virtual_incoming_args_rtx,
2835 NUM_ARGS <= 5 + stdarg
2836 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2838 addr = (NUM_ARGS <= 5 + stdarg
2839 ? plus_constant (virtual_incoming_args_rtx,
2841 : plus_constant (virtual_incoming_args_rtx,
2842 - (6 * UNITS_PER_WORD)));
2844 /* For VMS, we include the argsize, while on Unix, it's handled as
2845 a separate field. */
2846 if (TARGET_OPEN_VMS)
2847 addr = plus_constant (addr, INTVAL (argsize));
2849 addr = force_operand (addr, NULL_RTX);
2851 #ifdef POINTERS_EXTEND_UNSIGNED
2852 addr = convert_memory_address (ptr_mode, addr);
2855 if (TARGET_OPEN_VMS)
2859 /* Allocate the va_list constructor */
2860 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2861 RTX_UNCHANGING_P (block) = 1;
2862 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2864 /* Store the address of the first integer register in the __base
2867 dest = change_address (block, ptr_mode, XEXP (block, 0));
2868 emit_move_insn (dest, addr);
2870 if (flag_check_memory_usage)
2871 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2873 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2874 TYPE_MODE (sizetype),
2875 GEN_INT (MEMORY_USE_RW),
2876 TYPE_MODE (integer_type_node));
2878 /* Store the argsize as the __va_offset member. */
2879 dest = change_address (block, TYPE_MODE (integer_type_node),
2880 plus_constant (XEXP (block, 0),
2881 POINTER_SIZE/BITS_PER_UNIT));
2882 emit_move_insn (dest, argsize);
2884 if (flag_check_memory_usage)
2885 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2887 GEN_INT (GET_MODE_SIZE
2888 (TYPE_MODE (integer_type_node))),
2889 TYPE_MODE (sizetype),
2890 GEN_INT (MEMORY_USE_RW),
2891 TYPE_MODE (integer_type_node));
2893 /* Return the address of the va_list constructor, but don't put it in a
2894 register. Doing so would fail when not optimizing and produce worse
2895 code when optimizing. */
2896 return XEXP (block, 0);
2900 /* This page contains routines that are used to determine what the function
2901 prologue and epilogue code will do and write them out. */
2903 /* Compute the size of the save area in the stack. */
2907 /* These variables are used for communication between the following functions.
2908 They indicate various things about the current function being compiled
2909 that are used to tell what kind of prologue, epilogue and procedure
2910 descriptior to generate. */
2912 /* Nonzero if we need a stack procedure. */
2913 static int is_stack_procedure;
2915 /* Register number (either FP or SP) that is used to unwind the frame. */
2916 static int unwind_regno;
2918 /* Register number used to save FP. We need not have one for RA since
2919 we don't modify it for register procedures. This is only defined
2920 for register frame procedures. */
2921 static int save_fp_regno;
2923 /* Register number used to reference objects off our PV. */
2924 static int base_regno;
2926 /* Compute register masks for saved registers. */
2929 alpha_sa_mask (imaskP, fmaskP)
2930 unsigned long *imaskP;
2931 unsigned long *fmaskP;
2933 unsigned long imask = 0;
2934 unsigned long fmask = 0;
2937 if (is_stack_procedure)
2938 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2940 /* One for every register we have to save. */
2942 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2943 if (! fixed_regs[i] && ! call_used_regs[i]
2944 && regs_ever_live[i] && i != REG_RA)
2949 fmask |= (1L << (i - 32));
2962 HOST_WIDE_INT stack_needed;
2965 /* One for every register we have to save. */
2967 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2968 if (! fixed_regs[i] && ! call_used_regs[i]
2969 && regs_ever_live[i] && i != REG_RA)
2972 /* Start by assuming we can use a register procedure if we don't make any
2973 calls (REG_RA not used) or need to save any registers and a stack
2974 procedure if we do. */
2975 is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2977 /* Decide whether to refer to objects off our PV via FP or PV.
2978 If we need FP for something else or if we receive a nonlocal
2979 goto (which expects PV to contain the value), we must use PV.
2980 Otherwise, start by assuming we can use FP. */
2981 base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
2982 || is_stack_procedure
2983 || current_function_outgoing_args_size
2984 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
2986 /* If we want to copy PV into FP, we need to find some register in which to
2991 if (base_regno == HARD_FRAME_POINTER_REGNUM)
2992 for (i = 0; i < 32; i++)
2993 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
2996 if (save_fp_regno == -1)
2997 base_regno = REG_PV, is_stack_procedure = 1;
2999 /* Stack unwinding should be done via FP unless we use it for PV. */
3001 = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
3003 /* If this is a stack procedure, allow space for saving FP and RA. */
3004 if (is_stack_procedure)
3011 alpha_pv_save_size ()
3014 return is_stack_procedure ? 8 : 0;
3021 return unwind_regno == HARD_FRAME_POINTER_REGNUM;
3024 #else /* ! OPEN_VMS */
3032 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3033 if (! fixed_regs[i] && ! call_used_regs[i]
3034 && regs_ever_live[i] && i != REG_RA)
3037 /* If some registers were saved but not reg 26, reg 26 must also
3038 be saved, so leave space for it. */
3039 if (size != 0 || alpha_ra_ever_killed ())
3042 /* Our size must be even (multiple of 16 bytes). */
3049 #endif /* ! OPEN_VMS */
3051 /* Return 1 if this function can directly return via $26. */
3056 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
3057 && get_frame_size () == 0
3058 && current_function_outgoing_args_size == 0
3059 && current_function_pretend_args_size == 0);
3062 /* Write a version stamp. Don't write anything if we are running as a
3063 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3070 alpha_write_verstamp (file)
3074 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3078 /* Write code to add constant C to register number IN_REG (possibly 31)
3079 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
3080 usually this will be OUT_REG, but should not be if OUT_REG is
3081 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
3082 Write the code to FILE. */
3085 add_long_const (file, c, in_reg, out_reg, temp_reg)
3088 int in_reg, out_reg, temp_reg;
3090 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
3091 HOST_WIDE_INT tmp1 = c - low;
3092 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3093 HOST_WIDE_INT extra = 0;
3095 /* We don't have code to write out constants larger than 32 bits. */
3096 #if HOST_BITS_PER_LONG_INT == 64
3097 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
3101 /* If HIGH will be interpreted as negative, we must adjust it to do two
3102 ldha insns. Note that we will never be building a negative constant
3109 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3114 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
3116 if (low >= 0 && low < 255)
3117 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
3119 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
3121 in_reg = result_reg;
3126 int result_reg = (high == 0) ? out_reg : temp_reg;
3128 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
3129 in_reg = result_reg;
3133 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
3136 /* Write function prologue. */
3140 /* On vms we have two kinds of functions:
3142 - stack frame (PROC_STACK)
3143 these are 'normal' functions with local vars and which are
3144 calling other functions
3145 - register frame (PROC_REGISTER)
3146 keeps all data in registers, needs no stack
3148 We must pass this to the assembler so it can generate the
3149 proper pdsc (procedure descriptor)
3150 This is done with the '.pdesc' command.
3152 size is the stack size needed for local variables. */
3155 output_prolog (file, size)
3159 unsigned long imask = 0;
3160 unsigned long fmask = 0;
3161 /* Stack space needed for pushing registers clobbered by us. */
3162 HOST_WIDE_INT sa_size;
3163 /* Complete stack size needed. */
3164 HOST_WIDE_INT frame_size;
3165 /* Offset from base reg to register save area. */
3167 /* Offset during register save. */
3169 /* Label for the procedure entry. */
3170 char *entry_label = (char *) alloca (strlen (alpha_function_name) + 6);
3173 sa_size = alpha_sa_size ();
3175 = ALPHA_ROUND (sa_size
3176 + (is_stack_procedure ? 8 : 0)
3177 + size + current_function_pretend_args_size);
3179 /* Issue function start and label. */
3180 fprintf (file, "\t.ent ");
3181 assemble_name (file, alpha_function_name);
3182 fprintf (file, "\n");
3183 sprintf (entry_label, "%s..en", alpha_function_name);
3184 ASM_OUTPUT_LABEL (file, entry_label);
3185 inside_function = TRUE;
3187 fprintf (file, "\t.base $%d\n", base_regno);
3189 /* Calculate register masks for clobbered registers. */
3191 if (is_stack_procedure)
3192 alpha_sa_mask (&imask, &fmask);
3194 /* Adjust the stack by the frame size. If the frame size is > 4096
3195 bytes, we need to be sure we probe somewhere in the first and last
3196 4096 bytes (we can probably get away without the latter test) and
3197 every 8192 bytes in between. If the frame size is > 32768, we
3198 do this in a loop. Otherwise, we generate the explicit probe
3201 Note that we are only allowed to adjust sp once in the prologue. */
3203 if (frame_size < 32768)
3205 if (frame_size > 4096)
3209 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3211 while (probed + 8192 < frame_size)
3212 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3214 /* We only have to do this probe if we aren't saving registers. */
3215 if (sa_size == 0 && probed + 4096 < frame_size)
3216 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3219 if (frame_size != 0)
3220 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3224 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
3225 number of 8192 byte blocks to probe. We then probe each block
3226 in the loop and then set SP to the proper location. If the
3227 amount remaining is > 4096, we have to do one more probe if we
3228 are not saving any registers. */
3230 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3231 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3233 add_long_const (file, blocks, 31, 23, 23);
3235 fprintf (file, "\tlda $22,4096($30)\n");
3238 assemble_name (file, alpha_function_name);
3239 fprintf (file, "..sc:\n");
3241 fprintf (file, "\tstq $31,-8192($22)\n");
3242 fprintf (file, "\tsubq $23,1,$23\n");
3243 fprintf (file, "\tlda $22,-8192($22)\n");
3245 fprintf (file, "\tbne $23,$");
3246 assemble_name (file, alpha_function_name);
3247 fprintf (file, "..sc\n");
3249 if (leftover > 4096 && sa_size == 0)
3250 fprintf (file, "\tstq $31,-%d($22)\n", leftover);
3252 fprintf (file, "\tlda $30,-%d($22)\n", leftover);
3255 if (is_stack_procedure)
3257 int reg_offset = rsa_offset;
3259 /* Store R26 (RA) first. */
3260 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
3263 /* Store integer regs. according to mask. */
3264 for (i = 0; i < 32; i++)
3265 if (imask & (1L<<i))
3267 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
3271 /* Print the register mask and do floating-point saves. */
3274 fprintf (file, "\t.mask 0x%x,0\n", imask);
3276 for (i = 0; i < 32; i++)
3278 if (fmask & (1L << i))
3280 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
3285 /* Print the floating-point mask, if we've saved any fp register. */
3287 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
3289 fprintf (file, "\tstq $27,0($30)\n");
3293 fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
3294 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3295 HARD_FRAME_POINTER_REGNUM, save_fp_regno);
3298 if (base_regno != REG_PV)
3299 fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
3301 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3302 fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
3303 STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
3305 /* Describe our frame. */
3306 fprintf (file, "\t.frame $%d,", unwind_regno);
3308 /* If the frame size is larger than an integer, print it as zero to
3309 avoid an assembler error. We won't be properly describing such a
3310 frame, but that's the best we can do. */
3311 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3312 #if HOST_BITS_PER_WIDE_INT == 64
3313 frame_size >= (1l << 31) ? 0:
3317 fprintf (file, ",$26,%d\n", rsa_offset);
3319 /* If we have to allocate space for outgoing args, do it now. */
3320 if (current_function_outgoing_args_size != 0)
3321 fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
3322 - ALPHA_ROUND (current_function_outgoing_args_size),
3323 HARD_FRAME_POINTER_REGNUM);
3325 fprintf (file, "\t.prologue\n");
3327 readonly_section ();
3328 fprintf (file, "\t.align 3\n");
3329 assemble_name (file, alpha_function_name); fputs ("..na:\n", file);
3330 fputs ("\t.ascii \"", file);
3331 assemble_name (file, alpha_function_name);
3332 fputs ("\\0\"\n", file);
3335 fprintf (file, "\t.align 3\n");
3336 fputs ("\t.name ", file);
3337 assemble_name (file, alpha_function_name);
3338 fputs ("..na\n", file);
3339 ASM_OUTPUT_LABEL (file, alpha_function_name);
3340 fprintf (file, "\t.pdesc ");
3341 assemble_name (file, alpha_function_name);
3342 fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
3343 alpha_need_linkage (alpha_function_name, 1);
3349 /* Write function epilogue. */
3352 output_epilog (file, size)
3356 unsigned long imask = 0;
3357 unsigned long fmask = 0;
3358 /* Stack space needed for pushing registers clobbered by us. */
3359 HOST_WIDE_INT sa_size = alpha_sa_size ();
3360 /* Complete stack size needed. */
3361 HOST_WIDE_INT frame_size
3362 = ALPHA_ROUND (sa_size
3363 + (is_stack_procedure ? 8 : 0)
3364 + size + current_function_pretend_args_size);
3366 rtx insn = get_last_insn ();
3368 /* If the last insn was a BARRIER, we don't have to write anything except
3369 the .end pseudo-op. */
3371 if (GET_CODE (insn) == NOTE)
3372 insn = prev_nonnote_insn (insn);
3374 if (insn == 0 || GET_CODE (insn) != BARRIER)
3376 /* Restore clobbered registers, load FP last. */
3378 if (is_stack_procedure)
3384 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3385 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3386 HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
3388 alpha_sa_mask (&imask, &fmask);
3390 /* Start reloading registers after RA. */
3391 reg_offset = rsa_offset + 8;
3393 for (i = 0; i < 32; i++)
3394 if (imask & (1L<<i))
3396 if (i == HARD_FRAME_POINTER_REGNUM)
3397 fp_offset = reg_offset;
3399 fprintf (file, "\tldq $%d,%d($30)\n",
3404 for (i = 0; i < 32; i++)
3405 if (fmask & (1L << i))
3407 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
3411 /* Restore R26 (RA). */
3412 fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
3414 /* Restore R29 (FP). */
3415 fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
3418 fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
3419 HARD_FRAME_POINTER_REGNUM);
3421 if (frame_size != 0)
3423 if (frame_size < 32768)
3424 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
3427 long high = frame_size >> 16;
3428 long low = frame_size & 0xffff;
3432 low = -32768 + (low & 0x7fff);
3434 fprintf (file, "\tldah $2,%ld($31)\n", high);
3435 fprintf (file, "\tlda $2,%ld($2)\n", low);
3436 fprintf (file, "\taddq $30,$2,$30\n");
3440 /* Finally return to the caller. */
3441 fprintf (file, "\tret $31,($26),1\n");
3444 /* End the function. */
3445 fprintf (file, "\t.end ");
3446 assemble_name (file, alpha_function_name);
3447 fprintf (file, "\n");
3448 inside_function = FALSE;
3450 /* Show that we know this function if it is called again. */
3451 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3455 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3461 if (is_attribute_p ("overlaid", identifier))
3462 return (args == NULL_TREE);
3466 #else /* !OPEN_VMS */
3469 alpha_does_function_need_gp ()
3473 /* We never need a GP for Windows/NT. */
3474 if (TARGET_WINDOWS_NT)
3477 #ifdef TARGET_PROFILING_NEEDS_GP
3482 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3483 Even if we are a static function, we still need to do this in case
3484 our address is taken and passed to something like qsort. */
3486 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3487 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3488 && GET_CODE (PATTERN (insn)) != USE
3489 && GET_CODE (PATTERN (insn)) != CLOBBER)
3491 enum attr_type type = get_attr_type (insn);
3492 if (type == TYPE_LDSYM || type == TYPE_JSR)
3500 output_prolog (file, size)
3504 HOST_WIDE_INT out_args_size
3505 = ALPHA_ROUND (current_function_outgoing_args_size);
3506 HOST_WIDE_INT sa_size = alpha_sa_size ();
3507 HOST_WIDE_INT frame_size
3508 = (out_args_size + sa_size
3509 + ALPHA_ROUND (size + current_function_pretend_args_size));
3510 HOST_WIDE_INT reg_offset = out_args_size;
3511 HOST_WIDE_INT start_reg_offset = reg_offset;
3512 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
3513 int int_reg_save_area_size = 0;
3514 unsigned reg_mask = 0;
3517 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3518 We have to do that before the .ent directive as we cannot switch
3519 files within procedures with native ecoff because line numbers are
3520 linked to procedure descriptors.
3521 Outputting the lineno helps debugging of one line functions as they
3522 would otherwise get no line number at all. Please note that we would
3523 like to put out last_linenum from final.c, but it is not accessible. */
3525 if (write_symbols == SDB_DEBUG)
3527 ASM_OUTPUT_SOURCE_FILENAME (file,
3528 DECL_SOURCE_FILE (current_function_decl));
3529 if (debug_info_level != DINFO_LEVEL_TERSE)
3530 ASM_OUTPUT_SOURCE_LINE (file,
3531 DECL_SOURCE_LINE (current_function_decl));
3534 /* The assembly language programmer's guide states that the second argument
3535 to the .ent directive, the lex_level, is ignored by the assembler,
3536 so we might as well omit it. */
3538 if (!flag_inhibit_size_directive)
3540 fprintf (file, "\t.ent ");
3541 assemble_name (file, alpha_function_name);
3542 fprintf (file, "\n");
3544 ASM_OUTPUT_LABEL (file, alpha_function_name);
3545 inside_function = TRUE;
3547 if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
3548 /* Set flags in procedure descriptor to request IEEE-conformant
3549 math-library routines. The value we set it to is PDSC_EXC_IEEE
3550 (/usr/include/pdsc.h). */
3551 fprintf (file, "\t.eflag 48\n");
3553 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3555 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3556 alpha_arg_offset = -frame_size + 48;
3558 alpha_function_needs_gp = alpha_does_function_need_gp ();
3560 if (TARGET_WINDOWS_NT == 0)
3562 if (alpha_function_needs_gp)
3563 fprintf (file, "\tldgp $29,0($27)\n");
3565 /* Put a label after the GP load so we can enter the function at it. */
3567 assemble_name (file, alpha_function_name);
3568 fprintf (file, "..ng:\n");
3571 /* Adjust the stack by the frame size. If the frame size is > 4096
3572 bytes, we need to be sure we probe somewhere in the first and last
3573 4096 bytes (we can probably get away without the latter test) and
3574 every 8192 bytes in between. If the frame size is > 32768, we
3575 do this in a loop. Otherwise, we generate the explicit probe
3578 Note that we are only allowed to adjust sp once in the prologue. */
3580 if (frame_size < 32768)
3582 if (frame_size > 4096)
3586 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3588 while (probed + 8192 < frame_size)
3589 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3591 /* We only have to do this probe if we aren't saving registers. */
3592 if (sa_size == 0 && probed + 4096 < frame_size)
3593 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3596 if (frame_size != 0)
3597 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3601 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
3602 number of 8192 byte blocks to probe. We then probe each block
3603 in the loop and then set SP to the proper location. If the
3604 amount remaining is > 4096, we have to do one more probe if we
3605 are not saving any registers. */
3607 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3608 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3610 add_long_const (file, blocks, 31, 5, 5);
3612 fprintf (file, "\tlda $4,4096($30)\n");
3615 assemble_name (file, alpha_function_name);
3616 fprintf (file, "..sc:\n");
3618 fprintf (file, "\tstq $31,-8192($4)\n");
3619 fprintf (file, "\tsubq $5,1,$5\n");
3620 fprintf (file, "\tlda $4,-8192($4)\n");
3622 fprintf (file, "\tbne $5,$");
3623 assemble_name (file, alpha_function_name);
3624 fprintf (file, "..sc\n");
3626 if (leftover > 4096 && sa_size == 0)
3627 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
3629 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
3632 /* Describe our frame. */
3633 if (!flag_inhibit_size_directive)
3635 fprintf (file, "\t.frame $%d,",
3636 (frame_pointer_needed
3637 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3639 /* If the frame size is larger than an integer, print it as zero to
3640 avoid an assembler error. We won't be properly describing such a
3641 frame, but that's the best we can do. */
3642 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3643 #if HOST_BITS_PER_WIDE_INT == 64
3644 frame_size >= (1l << 31) ? 0 :
3648 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3651 /* Cope with very large offsets to the register save area. */
3653 if (reg_offset + sa_size > 0x8000)
3655 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3656 if (low + sa_size <= 0x8000)
3658 add_long_const (file, reg_offset - low, 30, 24, 24);
3663 add_long_const (file, reg_offset, 30, 24, 24);
3669 /* Save register RA if any other register needs to be saved. */
3672 reg_mask |= 1 << REG_RA;
3673 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
3675 int_reg_save_area_size += 8;
3678 /* Now save any other used integer registers required to be saved. */
3679 for (i = 0; i < 32; i++)
3680 if (! fixed_regs[i] && ! call_used_regs[i]
3681 && regs_ever_live[i] && i != REG_RA)
3684 fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3686 int_reg_save_area_size += 8;
3689 /* Print the register mask and do floating-point saves. */
3690 if (reg_mask && !flag_inhibit_size_directive)
3692 fprintf (file, "\t.mask 0x%x,", reg_mask);
3693 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3694 #if HOST_BITS_PER_WIDE_INT == 64
3695 frame_size >= (1l << 31) ? 0 :
3697 actual_start_reg_offset - frame_size);
3698 fprintf (file, "\n");
3701 start_reg_offset = reg_offset;
3704 for (i = 0; i < 32; i++)
3705 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3706 && regs_ever_live[i + 32])
3709 fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3713 /* Print the floating-point mask, if we've saved any fp register. */
3714 if (reg_mask && !flag_inhibit_size_directive)
3715 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
3716 actual_start_reg_offset - frame_size + int_reg_save_area_size);
3718 /* If we need a frame pointer, set it from the stack pointer. Note that
3719 this must always be the last instruction in the prologue. */
3720 if (frame_pointer_needed)
3721 fprintf (file, "\tbis $30,$30,$15\n");
3723 /* End the prologue and say if we used gp. */
3724 if (!flag_inhibit_size_directive)
3725 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3728 /* Write function epilogue. */
3731 output_epilog (file, size)
3735 rtx insn = get_last_insn ();
3736 HOST_WIDE_INT out_args_size
3737 = ALPHA_ROUND (current_function_outgoing_args_size);
3738 HOST_WIDE_INT sa_size = alpha_sa_size ();
3739 HOST_WIDE_INT frame_size
3740 = (out_args_size + sa_size
3741 + ALPHA_ROUND (size + current_function_pretend_args_size));
3742 HOST_WIDE_INT reg_offset = out_args_size;
3744 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
3747 /* If the last insn was a BARRIER, we don't have to write anything except
3748 the .end pseudo-op. */
3749 if (GET_CODE (insn) == NOTE)
3750 insn = prev_nonnote_insn (insn);
3751 if (insn == 0 || GET_CODE (insn) != BARRIER)
3756 /* If we have a frame pointer, restore SP from it. */
3757 if (frame_pointer_needed)
3758 fprintf (file, "\tbis $15,$15,$30\n");
3760 /* Cope with large offsets to the register save area. */
3762 if (reg_offset + sa_size > 0x8000)
3764 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3765 if (low + sa_size <= 0x8000)
3767 add_long_const (file, reg_offset - low, 30, 24, 24);
3772 add_long_const (file, reg_offset, 30, 24, 24);
3778 /* Restore all the registers, starting with the return address
3782 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
3786 /* Now restore any other used integer registers that we saved,
3787 except for FP if it is being used as FP, since it must be
3790 for (i = 0; i < 32; i++)
3791 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
3794 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3795 fp_offset = reg_offset;
3797 fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3801 for (i = 0; i < 32; i++)
3802 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3803 && regs_ever_live[i + 32])
3805 fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3809 /* If the stack size is large and we have a frame pointer, compute the
3810 size of the stack into a register because the old FP restore, stack
3811 pointer adjust, and return are required to be consecutive
3813 if (frame_size > 32767 && restore_fp)
3814 add_long_const (file, frame_size, 31, 1, 1);
3816 /* If we needed a frame pointer and we have to restore it, do it
3817 now. This must be done in one instruction immediately
3818 before the SP update. */
3819 if (restore_fp && fp_offset)
3820 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
3822 /* Now update the stack pointer, if needed. Only one instruction must
3823 modify the stack pointer. It must be the last instruction in the
3824 sequence and must be an ADDQ or LDA instruction. If the frame
3825 pointer was loaded above, we may only put one instruction here. */
3827 if (frame_size > 32768 && restore_fp)
3828 fprintf (file, "\taddq $1,$30,$30\n");
3830 add_long_const (file, frame_size, 30, 30, 1);
3832 /* Finally return to the caller. */
3833 fprintf (file, "\tret $31,($26),1\n");
3836 /* End the function. */
3837 if (!flag_inhibit_size_directive)
3839 fprintf (file, "\t.end ");
3840 assemble_name (file, alpha_function_name);
3841 fprintf (file, "\n");
3843 inside_function = FALSE;
3845 /* Show that we know this function if it is called again.
3847 Don't do this for global functions in object files destined for a
3848 shared library because the function may be overridden by the application
3850 ??? Is this just ELF? */
3852 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3853 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3855 #endif /* !OPEN_VMS */
3857 /* Debugging support. */
3861 /* Count the number of sdb related labels are generated (to find block
3862 start and end boundaries). */
3864 int sdb_label_count = 0;
3866 /* Next label # for each statement. */
3868 static int sym_lineno = 0;
3870 /* Count the number of .file directives, so that .loc is up to date. */
3872 static int num_source_filenames = 0;
3874 /* Name of the file containing the current function. */
3876 static char *current_function_file = "";
3878 /* Offsets to alpha virtual arg/local debugging pointers. */
3880 long alpha_arg_offset;
3881 long alpha_auto_offset;
3883 /* Emit a new filename to a stream. */
3886 alpha_output_filename (stream, name)
3890 static int first_time = TRUE;
3891 char ltext_label_name[100];
3896 ++num_source_filenames;
3897 current_function_file = name;
3898 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3899 output_quoted_string (stream, name);
3900 fprintf (stream, "\n");
3901 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3902 fprintf (stream, "\t#@stabs\n");
3905 else if (write_symbols == DBX_DEBUG)
3907 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3908 fprintf (stream, "%s ", ASM_STABS_OP);
3909 output_quoted_string (stream, name);
3910 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3913 else if (name != current_function_file
3914 && strcmp (name, current_function_file) != 0)
3916 if (inside_function && ! TARGET_GAS)
3917 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3920 ++num_source_filenames;
3921 current_function_file = name;
3922 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3925 output_quoted_string (stream, name);
3926 fprintf (stream, "\n");
3930 /* Emit a linenumber to a stream. */
3933 alpha_output_lineno (stream, line)
3937 if (write_symbols == DBX_DEBUG)
3939 /* mips-tfile doesn't understand .stabd directives. */
3941 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3942 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3945 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3948 /* Structure to show the current status of registers and memory. */
3950 struct shadow_summary
3953 unsigned long i : 31; /* Mask of int regs */
3954 unsigned long fp : 31; /* Mask of fp regs */
3955 unsigned long mem : 1; /* mem == imem | fpmem */
3959 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3960 to the summary structure. SET is nonzero if the insn is setting the
3961 object, otherwise zero. */
3964 summarize_insn (x, sum, set)
3966 struct shadow_summary *sum;
3975 switch (GET_CODE (x))
3977 /* ??? Note that this case would be incorrect if the Alpha had a
3978 ZERO_EXTRACT in SET_DEST. */
3980 summarize_insn (SET_SRC (x), sum, 0);
3981 summarize_insn (SET_DEST (x), sum, 1);
3985 summarize_insn (XEXP (x, 0), sum, 1);
3989 summarize_insn (XEXP (x, 0), sum, 0);
3993 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3994 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3998 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3999 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4008 int regno = REGNO (x);
4009 unsigned long mask = 1UL << (regno % 32);
4011 if (regno == 31 || regno == 63)
4017 sum->defd.i |= mask;
4019 sum->defd.fp |= mask;
4024 sum->used.i |= mask;
4026 sum->used.fp |= mask;
4037 /* Find the regs used in memory address computation: */
4038 summarize_insn (XEXP (x, 0), sum, 0);
4041 case CONST_INT: case CONST_DOUBLE:
4042 case SYMBOL_REF: case LABEL_REF: case CONST:
4045 /* Handle common unary and binary ops for efficiency. */
4046 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4047 case MOD: case UDIV: case UMOD: case AND: case IOR:
4048 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4049 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4050 case NE: case EQ: case GE: case GT: case LE:
4051 case LT: case GEU: case GTU: case LEU: case LTU:
4052 summarize_insn (XEXP (x, 0), sum, 0);
4053 summarize_insn (XEXP (x, 1), sum, 0);
4056 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4057 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4058 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4059 case SQRT: case FFS:
4060 summarize_insn (XEXP (x, 0), sum, 0);
4064 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4065 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4066 switch (format_ptr[i])
4069 summarize_insn (XEXP (x, i), sum, 0);
4073 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4074 summarize_insn (XVECEXP (x, i, j), sum, 0);
4086 /* Ensure a sufficient number of `trapb' insns are in the code when the user
4087 requests code with a trap precision of functions or instructions.
4089 In naive mode, when the user requests a trap-precision of "instruction", a
4090 trapb is needed after every instruction that may generate a trap (and after
4091 jsr/bsr instructions, because called functions may import a trap from the
4092 caller). This ensures that the code is resumption safe but it is also slow.
4094 When optimizations are turned on, we delay issuing a trapb as long as
4095 possible. In this context, a trap shadow is the sequence of instructions
4096 that starts with a (potentially) trap generating instruction and extends to
4097 the next trapb or call_pal instruction (but GCC never generates call_pal by
4098 itself). We can delay (and therefore sometimes omit) a trapb subject to the
4099 following conditions:
4101 (a) On entry to the trap shadow, if any Alpha register or memory location
4102 contains a value that is used as an operand value by some instruction in
4103 the trap shadow (live on entry), then no instruction in the trap shadow
4104 may modify the register or memory location.
4106 (b) Within the trap shadow, the computation of the base register for a
4107 memory load or store instruction may not involve using the result
4108 of an instruction that might generate an UNPREDICTABLE result.
4110 (c) Within the trap shadow, no register may be used more than once as a
4111 destination register. (This is to make life easier for the trap-handler.)
4113 (d) The trap shadow may not include any branch instructions. */
4116 alpha_handle_trap_shadows (insns)
4119 struct shadow_summary shadow;
4120 int trap_pending, exception_nesting;
4123 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
4127 exception_nesting = 0;
4130 shadow.used.mem = 0;
4131 shadow.defd = shadow.used;
4133 for (i = insns; i ; i = NEXT_INSN (i))
4135 if (GET_CODE (i) == NOTE)
4137 switch (NOTE_LINE_NUMBER (i))
4139 case NOTE_INSN_EH_REGION_BEG:
4140 exception_nesting++;
4145 case NOTE_INSN_EH_REGION_END:
4146 exception_nesting--;
4151 case NOTE_INSN_EPILOGUE_BEG:
4152 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4157 else if (trap_pending)
4159 if (alpha_tp == ALPHA_TP_FUNC)
4161 if (GET_CODE (i) == JUMP_INSN
4162 && GET_CODE (PATTERN (i)) == RETURN)
4165 else if (alpha_tp == ALPHA_TP_INSN)
4169 struct shadow_summary sum;
4174 sum.defd = sum.used;
4176 switch (GET_CODE (i))
4179 /* Annoyingly, get_attr_trap will abort on these. */
4180 if (GET_CODE (PATTERN (i)) == USE
4181 || GET_CODE (PATTERN (i)) == CLOBBER)
4184 summarize_insn (PATTERN (i), &sum, 0);
4186 if ((sum.defd.i & shadow.defd.i)
4187 || (sum.defd.fp & shadow.defd.fp))
4189 /* (c) would be violated */
4193 /* Combine shadow with summary of current insn: */
4194 shadow.used.i |= sum.used.i;
4195 shadow.used.fp |= sum.used.fp;
4196 shadow.used.mem |= sum.used.mem;
4197 shadow.defd.i |= sum.defd.i;
4198 shadow.defd.fp |= sum.defd.fp;
4199 shadow.defd.mem |= sum.defd.mem;
4201 if ((sum.defd.i & shadow.used.i)
4202 || (sum.defd.fp & shadow.used.fp)
4203 || (sum.defd.mem & shadow.used.mem))
4205 /* (a) would be violated (also takes care of (b)) */
4206 if (get_attr_trap (i) == TRAP_YES
4207 && ((sum.defd.i & sum.used.i)
4208 || (sum.defd.fp & sum.used.fp)))
4227 emit_insn_before (gen_trapb (), i);
4231 shadow.used.mem = 0;
4232 shadow.defd = shadow.used;
4237 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4238 && GET_CODE (i) == INSN
4239 && GET_CODE (PATTERN (i)) != USE
4240 && GET_CODE (PATTERN (i)) != CLOBBER
4241 && get_attr_trap (i) == TRAP_YES)
4243 if (optimize && !trap_pending)
4244 summarize_insn (PATTERN (i), &shadow, 0);
4250 /* Machine dependant reorg pass. */
4256 alpha_handle_trap_shadows (insns);
4260 /* Check a floating-point value for validity for a particular machine mode. */
4262 static char *float_strings[] =
4264 /* These are for FLOAT_VAX. */
4265 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4266 "-1.70141173319264430e+38",
4267 "2.93873587705571877e-39", /* 2^-128 */
4268 "-2.93873587705571877e-39",
4269 /* These are for the default broken IEEE mode, which traps
4270 on infinity or denormal numbers. */
4271 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4272 "-3.402823466385288598117e+38",
4273 "1.1754943508222875079687e-38", /* 2^-126 */
4274 "-1.1754943508222875079687e-38",
4277 static REAL_VALUE_TYPE float_values[8];
4278 static int inited_float_values = 0;
4281 check_float_value (mode, d, overflow)
4282 enum machine_mode mode;
4287 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4290 if (inited_float_values == 0)
4293 for (i = 0; i < 8; i++)
4294 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4296 inited_float_values = 1;
4302 REAL_VALUE_TYPE *fvptr;
4304 if (TARGET_FLOAT_VAX)
4305 fvptr = &float_values[0];
4307 fvptr = &float_values[4];
4309 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4310 if (REAL_VALUES_LESS (fvptr[0], r))
4312 bcopy ((char *) &fvptr[0], (char *) d,
4313 sizeof (REAL_VALUE_TYPE));
4316 else if (REAL_VALUES_LESS (r, fvptr[1]))
4318 bcopy ((char *) &fvptr[1], (char *) d,
4319 sizeof (REAL_VALUE_TYPE));
4322 else if (REAL_VALUES_LESS (dconst0, r)
4323 && REAL_VALUES_LESS (r, fvptr[2]))
4325 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4328 else if (REAL_VALUES_LESS (r, dconst0)
4329 && REAL_VALUES_LESS (fvptr[3], r))
4331 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4341 /* Return the VMS argument type corresponding to MODE. */
4344 alpha_arg_type (mode)
4345 enum machine_mode mode;
4350 return TARGET_FLOAT_VAX ? FF : FS;
4352 return TARGET_FLOAT_VAX ? FD : FT;
4358 /* Return an rtx for an integer representing the VMS Argument Information
4362 alpha_arg_info_reg_val (cum)
4363 CUMULATIVE_ARGS cum;
4365 unsigned HOST_WIDE_INT regval = cum.num_args;
4368 for (i = 0; i < 6; i++)
4369 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4371 return GEN_INT (regval);
4374 /* Structure to collect function names for final output
4377 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4380 struct alpha_links {
4381 struct alpha_links *next;
4383 enum links_kind kind;
4386 static struct alpha_links *alpha_links_base = 0;
4388 /* Make (or fake) .linkage entry for function call.
4390 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
4393 alpha_need_linkage (name, is_local)
4398 struct alpha_links *lptr, *nptr;
4403 /* Is this name already defined ? */
4405 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4406 if (strcmp (lptr->name, name) == 0)
4410 /* Defined here but external assumed. */
4411 if (lptr->kind == KIND_EXTERN)
4412 lptr->kind = KIND_LOCAL;
4416 /* Used here but unused assumed. */
4417 if (lptr->kind == KIND_UNUSED)
4418 lptr->kind = KIND_LOCAL;
4423 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4424 nptr->next = alpha_links_base;
4425 nptr->name = xstrdup (name);
4427 /* Assume external if no definition. */
4428 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4430 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
4431 get_identifier (name);
4433 alpha_links_base = nptr;
4440 alpha_write_linkage (stream)
4443 struct alpha_links *lptr, *nptr;
4445 readonly_section ();
4447 fprintf (stream, "\t.align 3\n");
4449 for (lptr = alpha_links_base; lptr; lptr = nptr)
4453 if (lptr->kind == KIND_UNUSED
4454 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4457 fprintf (stream, "$%s..lk:\n", lptr->name);
4458 if (lptr->kind == KIND_LOCAL)
4460 /* Local and used, build linkage pair. */
4461 fprintf (stream, "\t.quad %s..en\n", lptr->name);
4462 fprintf (stream, "\t.quad %s\n", lptr->name);
4465 /* External and used, request linkage pair. */
4466 fprintf (stream, "\t.linkage %s\n", lptr->name);
4473 alpha_need_linkage (name, is_local)
4479 #endif /* OPEN_VMS */