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. */
135 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
136 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
138 if (alpha_cpu_string)
140 if (! strcmp (alpha_cpu_string, "ev4")
141 || ! strcmp (alpha_cpu_string, "21064"))
143 alpha_cpu = PROCESSOR_EV4;
144 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
146 else if (! strcmp (alpha_cpu_string, "ev5")
147 || ! strcmp (alpha_cpu_string, "21164"))
149 alpha_cpu = PROCESSOR_EV5;
150 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
152 else if (! strcmp (alpha_cpu_string, "ev56")
153 || ! strcmp (alpha_cpu_string, "21164a"))
155 alpha_cpu = PROCESSOR_EV5;
156 target_flags |= MASK_BWX;
157 target_flags &= ~ (MASK_CIX | MASK_MAX);
159 else if (! strcmp (alpha_cpu_string, "pca56")
160 || ! strcmp (alpha_cpu_string, "21164PC")
161 || ! strcmp (alpha_cpu_string, "21164pc"))
163 alpha_cpu = PROCESSOR_EV5;
164 target_flags |= MASK_BWX | MASK_MAX;
165 target_flags &= ~ MASK_CIX;
167 else if (! strcmp (alpha_cpu_string, "ev6")
168 || ! strcmp (alpha_cpu_string, "21264"))
170 alpha_cpu = PROCESSOR_EV6;
171 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
174 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
177 alpha_tp = ALPHA_TP_PROG;
178 alpha_fprm = ALPHA_FPRM_NORM;
179 alpha_fptm = ALPHA_FPTM_N;
183 alpha_tp = ALPHA_TP_INSN;
184 alpha_fptm = ALPHA_FPTM_SU;
187 if (TARGET_IEEE_WITH_INEXACT)
189 alpha_tp = ALPHA_TP_INSN;
190 alpha_fptm = ALPHA_FPTM_SUI;
195 if (! strcmp (alpha_tp_string, "p"))
196 alpha_tp = ALPHA_TP_PROG;
197 else if (! strcmp (alpha_tp_string, "f"))
198 alpha_tp = ALPHA_TP_FUNC;
199 else if (! strcmp (alpha_tp_string, "i"))
200 alpha_tp = ALPHA_TP_INSN;
202 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
205 if (alpha_fprm_string)
207 if (! strcmp (alpha_fprm_string, "n"))
208 alpha_fprm = ALPHA_FPRM_NORM;
209 else if (! strcmp (alpha_fprm_string, "m"))
210 alpha_fprm = ALPHA_FPRM_MINF;
211 else if (! strcmp (alpha_fprm_string, "c"))
212 alpha_fprm = ALPHA_FPRM_CHOP;
213 else if (! strcmp (alpha_fprm_string,"d"))
214 alpha_fprm = ALPHA_FPRM_DYN;
216 error ("bad value `%s' for -mfp-rounding-mode switch",
220 if (alpha_fptm_string)
222 if (strcmp (alpha_fptm_string, "n") == 0)
223 alpha_fptm = ALPHA_FPTM_N;
224 else if (strcmp (alpha_fptm_string, "u") == 0)
225 alpha_fptm = ALPHA_FPTM_U;
226 else if (strcmp (alpha_fptm_string, "su") == 0)
227 alpha_fptm = ALPHA_FPTM_SU;
228 else if (strcmp (alpha_fptm_string, "sui") == 0)
229 alpha_fptm = ALPHA_FPTM_SUI;
231 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
234 /* Do some sanity checks on the above option. */
236 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
237 && alpha_tp != ALPHA_TP_INSN)
239 warning ("fp software completion requires -mtrap-precision=i");
240 alpha_tp = ALPHA_TP_INSN;
243 if (TARGET_FLOAT_VAX)
245 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
247 warning ("rounding mode not supported for VAX floats");
248 alpha_fprm = ALPHA_FPRM_NORM;
250 if (alpha_fptm == ALPHA_FPTM_SUI)
252 warning ("trap mode not supported for VAX floats");
253 alpha_fptm = ALPHA_FPTM_SU;
261 if (!alpha_mlat_string)
262 alpha_mlat_string = "L1";
264 if (isdigit (alpha_mlat_string[0])
265 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
267 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
268 && isdigit (alpha_mlat_string[1])
269 && alpha_mlat_string[2] == '\0')
271 static int const cache_latency[][4] =
273 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
274 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
275 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
278 lat = alpha_mlat_string[1] - '0';
279 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
281 warning ("L%d cache latency unknown for %s",
282 lat, alpha_cpu_name[alpha_cpu]);
286 lat = cache_latency[alpha_cpu][lat-1];
288 else if (! strcmp (alpha_mlat_string, "main"))
290 /* Most current memories have about 370ns latency. This is
291 a reasonable guess for a fast cpu. */
296 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
300 alpha_memory_latency = lat;
303 /* Default the definition of "small data" to 8 bytes. */
308 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
316 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
318 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
324 /* Returns 1 if OP is either the constant zero or a register. If a
325 register, it must be in the proper mode unless MODE is VOIDmode. */
328 reg_or_0_operand (op, mode)
330 enum machine_mode mode;
332 return op == const0_rtx || register_operand (op, mode);
335 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
339 reg_or_6bit_operand (op, mode)
341 enum machine_mode mode;
343 return ((GET_CODE (op) == CONST_INT
344 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
345 || register_operand (op, mode));
349 /* Return 1 if OP is an 8-bit constant or any register. */
352 reg_or_8bit_operand (op, mode)
354 enum machine_mode mode;
356 return ((GET_CODE (op) == CONST_INT
357 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
358 || register_operand (op, mode));
361 /* Return 1 if OP is an 8-bit constant. */
364 cint8_operand (op, mode)
366 enum machine_mode mode;
368 return (GET_CODE (op) == CONST_INT
369 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
372 /* Return 1 if the operand is a valid second operand to an add insn. */
375 add_operand (op, mode)
377 enum machine_mode mode;
379 if (GET_CODE (op) == CONST_INT)
380 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
381 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
382 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
384 return register_operand (op, mode);
387 /* Return 1 if the operand is a valid second operand to a sign-extending
391 sext_add_operand (op, mode)
393 enum machine_mode mode;
395 if (GET_CODE (op) == CONST_INT)
396 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
397 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
399 return register_operand (op, mode);
402 /* Return 1 if OP is the constant 4 or 8. */
405 const48_operand (op, mode)
407 enum machine_mode mode;
409 return (GET_CODE (op) == CONST_INT
410 && (INTVAL (op) == 4 || INTVAL (op) == 8));
413 /* Return 1 if OP is a valid first operand to an AND insn. */
416 and_operand (op, mode)
418 enum machine_mode mode;
420 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
421 return (zap_mask (CONST_DOUBLE_LOW (op))
422 && zap_mask (CONST_DOUBLE_HIGH (op)));
424 if (GET_CODE (op) == CONST_INT)
425 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
426 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
427 || zap_mask (INTVAL (op)));
429 return register_operand (op, mode);
432 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
435 or_operand (op, mode)
437 enum machine_mode mode;
439 if (GET_CODE (op) == CONST_INT)
440 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
441 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
443 return register_operand (op, mode);
446 /* Return 1 if OP is a constant that is the width, in bits, of an integral
447 mode smaller than DImode. */
450 mode_width_operand (op, mode)
452 enum machine_mode mode;
454 return (GET_CODE (op) == CONST_INT
455 && (INTVAL (op) == 8 || INTVAL (op) == 16
456 || INTVAL (op) == 32 || INTVAL (op) == 64));
459 /* Return 1 if OP is a constant that is the width of an integral machine mode
460 smaller than an integer. */
463 mode_mask_operand (op, mode)
465 enum machine_mode mode;
467 #if HOST_BITS_PER_WIDE_INT == 32
468 if (GET_CODE (op) == CONST_DOUBLE)
469 return (CONST_DOUBLE_LOW (op) == -1
470 && (CONST_DOUBLE_HIGH (op) == -1
471 || CONST_DOUBLE_HIGH (op) == 0));
473 if (GET_CODE (op) == CONST_DOUBLE)
474 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
477 return (GET_CODE (op) == CONST_INT
478 && (INTVAL (op) == 0xff
479 || INTVAL (op) == 0xffff
480 || INTVAL (op) == 0xffffffff
481 #if HOST_BITS_PER_WIDE_INT == 64
482 || INTVAL (op) == 0xffffffffffffffff
487 /* Return 1 if OP is a multiple of 8 less than 64. */
490 mul8_operand (op, mode)
492 enum machine_mode mode;
494 return (GET_CODE (op) == CONST_INT
495 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
496 && (INTVAL (op) & 7) == 0);
499 /* Return 1 if OP is the constant zero in floating-point. */
502 fp0_operand (op, mode)
504 enum machine_mode mode;
506 return (GET_MODE (op) == mode
507 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
510 /* Return 1 if OP is the floating-point constant zero or a register. */
513 reg_or_fp0_operand (op, mode)
515 enum machine_mode mode;
517 return fp0_operand (op, mode) || register_operand (op, mode);
520 /* Return 1 if OP is a hard floating-point register. */
523 hard_fp_register_operand (op, mode)
525 enum machine_mode mode;
527 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
528 || (GET_CODE (op) == SUBREG
529 && hard_fp_register_operand (SUBREG_REG (op), mode)));
532 /* Return 1 if OP is a register or a constant integer. */
536 reg_or_cint_operand (op, mode)
538 enum machine_mode mode;
540 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
543 /* Return 1 if OP is something that can be reloaded into a register;
544 if it is a MEM, it need not be valid. */
547 some_operand (op, mode)
549 enum machine_mode mode;
551 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
554 switch (GET_CODE (op))
556 case REG: case MEM: case CONST_DOUBLE:
557 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
561 return some_operand (SUBREG_REG (op), VOIDmode);
570 /* Return 1 if OP is a valid operand for the source of a move insn. */
573 input_operand (op, mode)
575 enum machine_mode mode;
577 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
580 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
583 switch (GET_CODE (op))
588 /* This handles both the Windows/NT and OSF cases. */
589 return mode == ptr_mode || mode == DImode;
595 if (register_operand (op, mode))
597 /* ... fall through ... */
599 return ((TARGET_BWX || (mode != HImode && mode != QImode))
600 && general_operand (op, mode));
603 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
606 return mode == QImode || mode == HImode || add_operand (op, mode);
615 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
619 current_file_function_operand (op, mode)
621 enum machine_mode mode;
623 return (GET_CODE (op) == SYMBOL_REF
624 && ! profile_flag && ! profile_block_flag
625 && (SYMBOL_REF_FLAG (op)
626 || op == XEXP (DECL_RTL (current_function_decl), 0)));
629 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
632 call_operand (op, mode)
634 enum machine_mode mode;
639 return (GET_CODE (op) == SYMBOL_REF
640 || (GET_CODE (op) == REG
641 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
644 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
645 comparisons are valid in which insn. */
648 alpha_comparison_operator (op, mode)
650 enum machine_mode mode;
652 enum rtx_code code = GET_CODE (op);
654 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
657 return (code == EQ || code == LE || code == LT
658 || (mode == DImode && (code == LEU || code == LTU)));
661 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
664 alpha_swapped_comparison_operator (op, mode)
666 enum machine_mode mode;
668 enum rtx_code code = GET_CODE (op);
670 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
673 code = swap_condition (code);
674 return (code == EQ || code == LE || code == LT
675 || (mode == DImode && (code == LEU || code == LTU)));
678 /* Return 1 if OP is a signed comparison operation. */
681 signed_comparison_operator (op, mode)
683 enum machine_mode mode;
685 switch (GET_CODE (op))
687 case EQ: case NE: case LE: case LT: case GE: case GT:
697 /* Return 1 if this is a divide or modulus operator. */
700 divmod_operator (op, mode)
702 enum machine_mode mode;
704 switch (GET_CODE (op))
706 case DIV: case MOD: case UDIV: case UMOD:
716 /* Return 1 if this memory address is a known aligned register plus
717 a constant. It must be a valid address. This means that we can do
718 this as an aligned reference plus some offset.
720 Take into account what reload will do.
722 We could say that out-of-range stack slots are alignable, but that would
723 complicate get_aligned_mem and it isn't worth the trouble since few
724 functions have large stack space. */
727 aligned_memory_operand (op, mode)
729 enum machine_mode mode;
731 if (GET_CODE (op) == SUBREG)
733 if (GET_MODE (op) != mode)
735 op = SUBREG_REG (op);
736 mode = GET_MODE (op);
739 if (reload_in_progress && GET_CODE (op) == REG
740 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
741 op = reg_equiv_mem[REGNO (op)];
743 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
744 || ! memory_address_p (mode, XEXP (op, 0)))
749 if (GET_CODE (op) == PLUS)
752 return (GET_CODE (op) == REG
753 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
756 /* Similar, but return 1 if OP is a MEM which is not alignable. */
759 unaligned_memory_operand (op, mode)
761 enum machine_mode mode;
763 if (GET_CODE (op) == SUBREG)
765 if (GET_MODE (op) != mode)
767 op = SUBREG_REG (op);
768 mode = GET_MODE (op);
771 if (reload_in_progress && GET_CODE (op) == REG
772 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
773 op = reg_equiv_mem[REGNO (op)];
775 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
780 if (! memory_address_p (mode, op))
783 if (GET_CODE (op) == PLUS)
786 return (GET_CODE (op) != REG
787 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
790 /* Return 1 if OP is either a register or an unaligned memory location. */
793 reg_or_unaligned_mem_operand (op, mode)
795 enum machine_mode mode;
797 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
800 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
803 any_memory_operand (op, mode)
805 enum machine_mode mode;
807 return (GET_CODE (op) == MEM
808 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
809 || (reload_in_progress && GET_CODE (op) == REG
810 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
811 || (reload_in_progress && GET_CODE (op) == SUBREG
812 && GET_CODE (SUBREG_REG (op)) == REG
813 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
816 /* REF is an alignable memory location. Place an aligned SImode
817 reference into *PALIGNED_MEM and the number of bits to shift into
821 get_aligned_mem (ref, paligned_mem, pbitnum)
823 rtx *paligned_mem, *pbitnum;
826 HOST_WIDE_INT offset = 0;
828 if (GET_CODE (ref) == SUBREG)
830 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
831 if (BYTES_BIG_ENDIAN)
832 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
833 - MIN (UNITS_PER_WORD,
834 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
835 ref = SUBREG_REG (ref);
838 if (GET_CODE (ref) == REG)
839 ref = reg_equiv_mem[REGNO (ref)];
841 if (reload_in_progress)
842 base = find_replacement (&XEXP (ref, 0));
844 base = XEXP (ref, 0);
846 if (GET_CODE (base) == PLUS)
847 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
849 *paligned_mem = gen_rtx_MEM (SImode,
850 plus_constant (base, offset & ~3));
851 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
852 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
853 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
855 *pbitnum = GEN_INT ((offset & 3) * 8);
858 /* Similar, but just get the address. Handle the two reload cases.
859 Add EXTRA_OFFSET to the address we return. */
862 get_unaligned_address (ref, extra_offset)
867 HOST_WIDE_INT offset = 0;
869 if (GET_CODE (ref) == SUBREG)
871 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
872 if (BYTES_BIG_ENDIAN)
873 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
874 - MIN (UNITS_PER_WORD,
875 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
876 ref = SUBREG_REG (ref);
879 if (GET_CODE (ref) == REG)
880 ref = reg_equiv_mem[REGNO (ref)];
882 if (reload_in_progress)
883 base = find_replacement (&XEXP (ref, 0));
885 base = XEXP (ref, 0);
887 if (GET_CODE (base) == PLUS)
888 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
890 return plus_constant (base, offset + extra_offset);
893 /* Subfunction of the following function. Update the flags of any MEM
894 found in part of X. */
897 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
899 int in_struct_p, volatile_p, unchanging_p;
903 switch (GET_CODE (x))
907 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
908 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
913 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
918 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
920 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
925 MEM_IN_STRUCT_P (x) = in_struct_p;
926 MEM_VOLATILE_P (x) = volatile_p;
927 RTX_UNCHANGING_P (x) = unchanging_p;
935 /* Given INSN, which is either an INSN or a SEQUENCE generated to
936 perform a memory operation, look for any MEMs in either a SET_DEST or
937 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
938 REF into each of the MEMs found. If REF is not a MEM, don't do
942 alpha_set_memflags (insn, ref)
946 /* Note that it is always safe to get these flags, though they won't
947 be what we think if REF is not a MEM. */
948 int in_struct_p = MEM_IN_STRUCT_P (ref);
949 int volatile_p = MEM_VOLATILE_P (ref);
950 int unchanging_p = RTX_UNCHANGING_P (ref);
952 if (GET_CODE (ref) != MEM
953 || (! in_struct_p && ! volatile_p && ! unchanging_p))
956 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
959 /* Try to output insns to set TARGET equal to the constant C if it can be
960 done in less than N insns. Do all computations in MODE. Returns the place
961 where the output has been placed if it can be done and the insns have been
962 emitted. If it would take more than N insns, zero is returned and no
963 insns and emitted. */
966 alpha_emit_set_const (target, mode, c, n)
968 enum machine_mode mode;
975 /* Try 1 insn, then 2, then up to N. */
976 for (i = 1; i <= n; i++)
977 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
983 /* Internal routine for the above to check for N or below insns. */
986 alpha_emit_set_const_1 (target, mode, c, n)
988 enum machine_mode mode;
992 HOST_WIDE_INT new = c;
994 /* Use a pseudo if highly optimizing and still generating RTL. */
996 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1000 #if HOST_BITS_PER_WIDE_INT == 64
1001 /* We are only called for SImode and DImode. If this is SImode, ensure that
1002 we are sign extended to a full word. This does not make any sense when
1003 cross-compiling on a narrow machine. */
1006 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1009 /* If this is a sign-extended 32-bit constant, we can do this in at most
1010 three insns, so do it if we have enough insns left. We always have
1011 a sign-extended 32-bit constant when compiling on a narrow machine. */
1013 if (HOST_BITS_PER_WIDE_INT != 64
1014 || c >> 31 == -1 || c >> 31 == 0)
1016 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1017 HOST_WIDE_INT tmp1 = c - low;
1019 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1020 HOST_WIDE_INT extra = 0;
1022 /* If HIGH will be interpreted as negative but the constant is
1023 positive, we must adjust it to do two ldha insns. */
1025 if ((high & 0x8000) != 0 && c >= 0)
1029 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1032 if (c == low || (low == 0 && extra == 0))
1034 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1035 but that meant that we can't handle INT_MIN on 32-bit machines
1036 (like NT/Alpha), because we recurse indefinitely through
1037 emit_move_insn to gen_movdi. So instead, since we know exactly
1038 what we want, create it explicitly. */
1041 target = gen_reg_rtx (mode);
1042 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1045 else if (n >= 2 + (extra != 0))
1047 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1050 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1051 subtarget, 0, OPTAB_WIDEN);
1053 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1054 target, 0, OPTAB_WIDEN);
1058 /* If we couldn't do it that way, try some other methods. But if we have
1059 no instructions left, don't bother. Likewise, if this is SImode and
1060 we can't make pseudos, we can't do anything since the expand_binop
1061 and expand_unop calls will widen and try to make pseudos. */
1064 || (mode == SImode && ! rtx_equal_function_value_matters))
1067 #if HOST_BITS_PER_WIDE_INT == 64
1068 /* First, see if can load a value into the target that is the same as the
1069 constant except that all bytes that are 0 are changed to be 0xff. If we
1070 can, then we can do a ZAPNOT to obtain the desired constant. */
1072 for (i = 0; i < 64; i += 8)
1073 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1074 new |= (HOST_WIDE_INT) 0xff << i;
1076 /* We are only called for SImode and DImode. If this is SImode, ensure that
1077 we are sign extended to a full word. */
1080 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1083 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1084 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1085 target, 0, OPTAB_WIDEN);
1088 /* Next, see if we can load a related constant and then shift and possibly
1089 negate it to get the constant we want. Try this once each increasing
1090 numbers of insns. */
1092 for (i = 1; i < n; i++)
1094 /* First try complementing. */
1095 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1096 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1098 /* Next try to form a constant and do a left shift. We can do this
1099 if some low-order bits are zero; the exact_log2 call below tells
1100 us that information. The bits we are shifting out could be any
1101 value, but here we'll just try the 0- and sign-extended forms of
1102 the constant. To try to increase the chance of having the same
1103 constant in more than one insn, start at the highest number of
1104 bits to shift, but try all possibilities in case a ZAPNOT will
1107 if ((bits = exact_log2 (c & - c)) > 0)
1108 for (; bits > 0; bits--)
1109 if ((temp = (alpha_emit_set_const
1111 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
1112 || ((temp = (alpha_emit_set_const
1114 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1116 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1117 target, 0, OPTAB_WIDEN);
1119 /* Now try high-order zero bits. Here we try the shifted-in bits as
1120 all zero and all ones. Be careful to avoid shifting outside the
1121 mode and to avoid shifting outside the host wide int size. */
1122 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1123 confuse the recursive call and set all of the high 32 bits. */
1125 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1126 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1127 for (; bits > 0; bits--)
1128 if ((temp = alpha_emit_set_const (subtarget, mode,
1130 || ((temp = (alpha_emit_set_const
1132 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1135 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1136 target, 1, OPTAB_WIDEN);
1138 /* Now try high-order 1 bits. We get that with a sign-extension.
1139 But one bit isn't enough here. Be careful to avoid shifting outside
1140 the mode and to avoid shifting outside the host wide int size. */
1142 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1143 - floor_log2 (~ c) - 2)) > 0)
1144 for (; bits > 0; bits--)
1145 if ((temp = alpha_emit_set_const (subtarget, mode,
1147 || ((temp = (alpha_emit_set_const
1149 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1152 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1153 target, 0, OPTAB_WIDEN);
1159 #if HOST_BITS_PER_WIDE_INT == 64
1160 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1161 fall back to a straight forward decomposition. We do this to avoid
1162 exponential run times encountered when looking for longer sequences
1163 with alpha_emit_set_const. */
1166 alpha_emit_set_long_const (target, c)
1170 /* Use a pseudo if highly optimizing and still generating RTL. */
1172 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1174 HOST_WIDE_INT d1, d2, d3, d4;
1177 /* Decompose the entire word */
1178 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1180 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1182 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1184 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1189 /* Construct the high word */
1191 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
1193 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
1195 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1196 subtarget, 0, OPTAB_WIDEN);
1198 /* Shift it into place */
1199 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1200 subtarget, 0, OPTAB_WIDEN);
1202 if (subtarget == 0 && d1 == d3 && d2 == d4)
1203 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1208 /* Add in the low word */
1210 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1211 subtarget, 0, OPTAB_WIDEN);
1213 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1214 subtarget, 0, OPTAB_WIDEN);
1218 r1 = copy_to_suggested_reg(r1, target, DImode);
1222 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1224 /* Generate the comparison for a conditional branch. */
1227 alpha_emit_conditional_branch (code)
1230 enum rtx_code cmp_code, branch_code;
1231 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1232 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1235 /* The general case: fold the comparison code to the types of compares
1236 that we have, choosing the branch as necessary. */
1239 case EQ: case LE: case LT: case LEU: case LTU:
1240 /* We have these compares: */
1241 cmp_code = code, branch_code = NE;
1245 /* This must be reversed. */
1246 cmp_code = EQ, branch_code = EQ;
1249 case GE: case GT: case GEU: case GTU:
1250 /* For FP, we swap them, for INT, we reverse them. */
1251 if (alpha_compare_fp_p)
1253 cmp_code = swap_condition (code);
1255 tem = op0, op0 = op1, op1 = tem;
1259 cmp_code = reverse_condition (code);
1268 if (alpha_compare_fp_p)
1273 /* When we are not as concerned about non-finite values, and we
1274 are comparing against zero, we can branch directly. */
1275 if (op1 == CONST0_RTX (DFmode))
1276 cmp_code = NIL, branch_code = code;
1277 else if (op0 == CONST0_RTX (DFmode))
1279 /* Undo the swap we probably did just above. */
1280 tem = op0, op0 = op1, op1 = tem;
1281 branch_code = swap_condition (cmp_code);
1287 /* ??? We mark the the branch mode to be CCmode to prevent the
1288 compare and branch from being combined, since the compare
1289 insn follows IEEE rules that the branch does not. */
1290 branch_mode = CCmode;
1297 /* The following optimizations are only for signed compares. */
1298 if (code != LEU && code != LTU && code != GEU && code != GTU)
1300 /* Whee. Compare and branch against 0 directly. */
1301 if (op1 == const0_rtx)
1302 cmp_code = NIL, branch_code = code;
1304 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1305 bypass between logicals and br/cmov on EV5. But we don't want to
1306 force valid immediate constants into registers needlessly. */
1307 else if (GET_CODE (op1) == CONST_INT)
1309 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1311 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1312 && (CONST_OK_FOR_LETTER_P (n, 'K')
1313 || CONST_OK_FOR_LETTER_P (n, 'L')))
1315 cmp_code = PLUS, branch_code = code;
1322 /* Force op0 into a register. */
1323 if (GET_CODE (op0) != REG)
1324 op0 = force_reg (cmp_mode, op0);
1326 /* Emit an initial compare instruction, if necessary. */
1328 if (cmp_code != NIL)
1330 tem = gen_reg_rtx (cmp_mode);
1331 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1334 /* Return the branch comparison. */
1335 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1339 /* Rewrite a comparison against zero CMP of the form
1340 (CODE (cc0) (const_int 0)) so it can be written validly in
1341 a conditional move (if_then_else CMP ...).
1342 If both of the operands that set cc0 are non-zero we must emit
1343 an insn to perform the compare (it can't be done within
1344 the conditional move). */
1346 alpha_emit_conditional_move (cmp, mode)
1348 enum machine_mode mode;
1350 enum rtx_code code = GET_CODE (cmp);
1351 enum rtx_code cmov_code = NE;
1352 rtx op0 = alpha_compare_op0;
1353 rtx op1 = alpha_compare_op1;
1354 enum machine_mode cmp_mode
1355 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1356 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1357 enum machine_mode cmov_mode = VOIDmode;
1360 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1363 /* We may be able to use a conditional move directly.
1364 This avoids emitting spurious compares. */
1365 if (signed_comparison_operator (cmp, cmp_op_mode)
1366 && (!alpha_compare_fp_p || flag_fast_math)
1367 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1368 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1370 /* We can't put the comparison insides a conditional move;
1371 emit a compare instruction and put that inside the
1372 conditional move. Make sure we emit only comparisons we have;
1373 swap or reverse as necessary. */
1377 case EQ: case LE: case LT: case LEU: case LTU:
1378 /* We have these compares: */
1382 /* This must be reversed. */
1383 code = reverse_condition (code);
1387 case GE: case GT: case GEU: case GTU:
1388 /* These must be swapped. Make sure the new first operand is in
1390 code = swap_condition (code);
1391 tem = op0, op0 = op1, op1 = tem;
1392 op0 = force_reg (cmp_mode, op0);
1399 /* ??? We mark the the branch mode to be CCmode to prevent the compare
1400 and cmov from being combined, since the compare insn follows IEEE
1401 rules that the cmov does not. */
1402 if (alpha_compare_fp_p && !flag_fast_math)
1405 tem = gen_reg_rtx (cmp_op_mode);
1406 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1407 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1410 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1414 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1415 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1416 lda r3,X(r11) lda r3,X+2(r11)
1417 extwl r1,r3,r1 extql r1,r3,r1
1418 extwh r2,r3,r2 extqh r2,r3,r2
1419 or r1.r2.r1 or r1,r2,r1
1422 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1423 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1424 lda r3,X(r11) lda r3,X(r11)
1425 extll r1,r3,r1 extll r1,r3,r1
1426 extlh r2,r3,r2 extlh r2,r3,r2
1427 or r1.r2.r1 addl r1,r2,r1
1429 quad: ldq_u r1,X(r11)
1438 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1440 HOST_WIDE_INT size, ofs;
1443 rtx meml, memh, addr, extl, exth;
1444 enum machine_mode mode;
1446 meml = gen_reg_rtx (DImode);
1447 memh = gen_reg_rtx (DImode);
1448 addr = gen_reg_rtx (DImode);
1449 extl = gen_reg_rtx (DImode);
1450 exth = gen_reg_rtx (DImode);
1452 emit_move_insn (meml,
1453 change_address (mem, DImode,
1454 gen_rtx_AND (DImode,
1455 plus_constant (XEXP (mem, 0),
1459 emit_move_insn (memh,
1460 change_address (mem, DImode,
1461 gen_rtx_AND (DImode,
1462 plus_constant (XEXP (mem, 0),
1466 if (sign && size == 2)
1468 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1470 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1471 emit_insn (gen_extqh (exth, memh, addr));
1473 /* We must use tgt here for the target. Alpha-vms port fails if we use
1474 addr for the target, because addr is marked as a pointer and combine
1475 knows that pointers are always sign-extended 32 bit values. */
1476 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1477 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1478 addr, 1, OPTAB_WIDEN);
1482 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1483 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1487 emit_insn (gen_extwh (exth, memh, addr));
1492 emit_insn (gen_extlh (exth, memh, addr));
1497 emit_insn (gen_extqh (exth, memh, addr));
1502 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1503 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1508 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1511 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1514 alpha_expand_unaligned_store (dst, src, size, ofs)
1516 HOST_WIDE_INT size, ofs;
1518 rtx dstl, dsth, addr, insl, insh, meml, memh;
1520 dstl = gen_reg_rtx (DImode);
1521 dsth = gen_reg_rtx (DImode);
1522 insl = gen_reg_rtx (DImode);
1523 insh = gen_reg_rtx (DImode);
1525 meml = change_address (dst, DImode,
1526 gen_rtx_AND (DImode,
1527 plus_constant (XEXP (dst, 0), ofs),
1529 memh = change_address (dst, DImode,
1530 gen_rtx_AND (DImode,
1531 plus_constant (XEXP (dst, 0),
1535 emit_move_insn (dsth, memh);
1536 emit_move_insn (dstl, meml);
1537 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1539 if (src != const0_rtx)
1541 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1542 GEN_INT (size*8), addr));
1547 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1550 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1553 emit_insn (gen_insql (insl, src, addr));
1558 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1563 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1566 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1570 #if HOST_BITS_PER_WIDE_INT == 32
1571 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1573 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1575 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1580 if (src != const0_rtx)
1582 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1583 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1586 /* Must store high before low for degenerate case of aligned. */
1587 emit_move_insn (memh, dsth);
1588 emit_move_insn (meml, dstl);
1591 /* The block move code tries to maximize speed by separating loads and
1592 stores at the expense of register pressure: we load all of the data
1593 before we store it back out. There are two secondary effects worth
1594 mentioning, that this speeds copying to/from aligned and unaligned
1595 buffers, and that it makes the code significantly easier to write. */
1597 #define MAX_MOVE_WORDS 8
1599 /* Load an integral number of consecutive unaligned quadwords. */
1602 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1605 HOST_WIDE_INT words, ofs;
1607 rtx const im8 = GEN_INT (-8);
1608 rtx const i64 = GEN_INT (64);
1609 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1613 /* Generate all the tmp registers we need. */
1614 for (i = 0; i < words; ++i)
1616 data_regs[i] = out_regs[i];
1617 ext_tmps[i] = gen_reg_rtx (DImode);
1619 data_regs[words] = gen_reg_rtx (DImode);
1622 smem = change_address (smem, GET_MODE (smem),
1623 plus_constant (XEXP (smem, 0), ofs));
1625 /* Load up all of the source data. */
1626 for (i = 0; i < words; ++i)
1628 emit_move_insn (data_regs[i],
1629 change_address (smem, DImode,
1630 gen_rtx_AND (DImode,
1631 plus_constant (XEXP(smem,0),
1635 emit_move_insn (data_regs[words],
1636 change_address (smem, DImode,
1637 gen_rtx_AND (DImode,
1638 plus_constant (XEXP(smem,0),
1642 /* Extract the half-word fragments. Unfortunately DEC decided to make
1643 extxh with offset zero a noop instead of zeroing the register, so
1644 we must take care of that edge condition ourselves with cmov. */
1646 sreg = copy_addr_to_reg (XEXP (smem, 0));
1647 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1649 for (i = 0; i < words; ++i)
1651 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1653 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1654 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1655 gen_rtx_IF_THEN_ELSE (DImode,
1656 gen_rtx_EQ (DImode, areg,
1658 const0_rtx, ext_tmps[i])));
1661 /* Merge the half-words into whole words. */
1662 for (i = 0; i < words; ++i)
1664 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1665 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1669 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1670 may be NULL to store zeros. */
1673 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1676 HOST_WIDE_INT words, ofs;
1678 rtx const im8 = GEN_INT (-8);
1679 rtx const i64 = GEN_INT (64);
1680 #if HOST_BITS_PER_WIDE_INT == 32
1681 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1683 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1685 rtx ins_tmps[MAX_MOVE_WORDS];
1686 rtx st_tmp_1, st_tmp_2, dreg;
1687 rtx st_addr_1, st_addr_2;
1690 /* Generate all the tmp registers we need. */
1691 if (data_regs != NULL)
1692 for (i = 0; i < words; ++i)
1693 ins_tmps[i] = gen_reg_rtx(DImode);
1694 st_tmp_1 = gen_reg_rtx(DImode);
1695 st_tmp_2 = gen_reg_rtx(DImode);
1698 dmem = change_address (dmem, GET_MODE (dmem),
1699 plus_constant (XEXP (dmem, 0), ofs));
1702 st_addr_2 = change_address (dmem, DImode,
1703 gen_rtx_AND (DImode,
1704 plus_constant (XEXP(dmem,0),
1707 st_addr_1 = change_address (dmem, DImode,
1708 gen_rtx_AND (DImode,
1712 /* Load up the destination end bits. */
1713 emit_move_insn (st_tmp_2, st_addr_2);
1714 emit_move_insn (st_tmp_1, st_addr_1);
1716 /* Shift the input data into place. */
1717 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1718 if (data_regs != NULL)
1720 for (i = words-1; i >= 0; --i)
1722 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1723 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1725 for (i = words-1; i > 0; --i)
1727 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1728 ins_tmps[i-1], ins_tmps[i-1], 1,
1733 /* Split and merge the ends with the destination data. */
1734 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1735 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1737 if (data_regs != NULL)
1739 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1740 st_tmp_2, 1, OPTAB_WIDEN);
1741 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1742 st_tmp_1, 1, OPTAB_WIDEN);
1746 emit_move_insn (st_addr_2, st_tmp_2);
1747 for (i = words-1; i > 0; --i)
1749 emit_move_insn (change_address (dmem, DImode,
1750 gen_rtx_AND (DImode,
1751 plus_constant(XEXP (dmem,0),
1754 data_regs ? ins_tmps[i-1] : const0_rtx);
1756 emit_move_insn (st_addr_1, st_tmp_1);
1760 /* Expand string/block move operations.
1762 operands[0] is the pointer to the destination.
1763 operands[1] is the pointer to the source.
1764 operands[2] is the number of bytes to move.
1765 operands[3] is the alignment. */
1768 alpha_expand_block_move (operands)
1771 rtx bytes_rtx = operands[2];
1772 rtx align_rtx = operands[3];
1773 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1774 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1775 HOST_WIDE_INT dst_align = src_align;
1776 rtx orig_src = operands[1];
1777 rtx orig_dst = operands[0];
1778 rtx data_regs[2*MAX_MOVE_WORDS+16];
1780 int i, words, ofs, nregs = 0;
1784 if (bytes > MAX_MOVE_WORDS*8)
1787 /* Look for additional alignment information from recorded register info. */
1789 tmp = XEXP (orig_src, 0);
1790 if (GET_CODE (tmp) == REG)
1792 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1793 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1795 else if (GET_CODE (tmp) == PLUS
1796 && GET_CODE (XEXP (tmp, 0)) == REG
1797 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1799 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1800 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1804 if (a >= 8 && c % 8 == 0)
1806 else if (a >= 4 && c % 4 == 0)
1808 else if (a >= 2 && c % 2 == 0)
1813 tmp = XEXP (orig_dst, 0);
1814 if (GET_CODE (tmp) == REG)
1816 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1817 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1819 else if (GET_CODE (tmp) == PLUS
1820 && GET_CODE (XEXP (tmp, 0)) == REG
1821 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1823 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1824 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1828 if (a >= 8 && c % 8 == 0)
1830 else if (a >= 4 && c % 4 == 0)
1832 else if (a >= 2 && c % 2 == 0)
1838 * Load the entire block into registers.
1841 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1843 enum machine_mode mode;
1844 tmp = XEXP (XEXP (orig_src, 0), 0);
1846 mode = mode_for_size (bytes, MODE_INT, 1);
1848 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1850 /* Whee! Optimize the load to use the existing register. */
1851 data_regs[nregs++] = gen_lowpart (mode, tmp);
1855 /* ??? We could potentially be copying 3 bytes or whatnot from
1856 a wider reg. Probably not worth worrying about. */
1857 /* No appropriate mode; fall back on memory. */
1858 orig_src = change_address (orig_src, GET_MODE (orig_src),
1859 copy_addr_to_reg (XEXP (orig_src, 0)));
1863 if (src_align >= 8 && bytes >= 8)
1867 for (i = 0; i < words; ++i)
1868 data_regs[nregs+i] = gen_reg_rtx(DImode);
1870 for (i = 0; i < words; ++i)
1872 emit_move_insn (data_regs[nregs+i],
1873 change_address(orig_src, DImode,
1874 plus_constant (XEXP (orig_src, 0),
1882 if (src_align >= 4 && bytes >= 4)
1886 for (i = 0; i < words; ++i)
1887 data_regs[nregs+i] = gen_reg_rtx(SImode);
1889 for (i = 0; i < words; ++i)
1891 emit_move_insn (data_regs[nregs+i],
1892 change_address(orig_src, SImode,
1893 plus_constant (XEXP (orig_src, 0),
1905 for (i = 0; i < words+1; ++i)
1906 data_regs[nregs+i] = gen_reg_rtx(DImode);
1908 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1914 if (!TARGET_BWX && bytes >= 8)
1916 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1917 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1921 if (!TARGET_BWX && bytes >= 4)
1923 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1924 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1933 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1934 emit_move_insn (tmp,
1935 change_address (orig_src, HImode,
1936 plus_constant (XEXP (orig_src, 0),
1940 } while (bytes >= 2);
1942 else if (!TARGET_BWX)
1944 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1945 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1952 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1953 emit_move_insn (tmp,
1954 change_address (orig_src, QImode,
1955 plus_constant (XEXP (orig_src, 0),
1962 if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1966 * Now save it back out again.
1971 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1973 enum machine_mode mode;
1974 tmp = XEXP (XEXP (orig_dst, 0), 0);
1976 mode = mode_for_size (bytes, MODE_INT, 1);
1977 if (GET_MODE (tmp) == mode && nregs == 1)
1979 emit_move_insn (tmp, data_regs[0]);
1984 /* ??? If nregs > 1, consider reconstructing the word in regs. */
1985 /* ??? Optimize mode < dst_mode with strict_low_part. */
1986 /* No appropriate mode; fall back on memory. */
1987 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
1988 copy_addr_to_reg (XEXP (orig_dst, 0)));
1991 /* Write out the data in whatever chunks reading the source allowed. */
1994 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
1996 emit_move_insn (change_address(orig_dst, DImode,
1997 plus_constant (XEXP (orig_dst, 0),
2006 /* If the source has remaining DImode regs, write them out in
2008 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2010 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2011 NULL_RTX, 1, OPTAB_WIDEN);
2013 emit_move_insn (change_address(orig_dst, SImode,
2014 plus_constant (XEXP (orig_dst, 0),
2016 gen_lowpart (SImode, data_regs[i]));
2017 emit_move_insn (change_address(orig_dst, SImode,
2018 plus_constant (XEXP (orig_dst, 0),
2020 gen_lowpart (SImode, tmp));
2025 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2027 emit_move_insn (change_address(orig_dst, SImode,
2028 plus_constant (XEXP (orig_dst, 0),
2035 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2037 /* Write out a remaining block of words using unaligned methods. */
2039 for (words = 1; i+words < nregs ; ++words)
2040 if (GET_MODE (data_regs[i+words]) != DImode)
2044 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2046 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2052 /* Due to the above, this won't be aligned. */
2053 /* ??? If we have more than one of these, consider constructing full
2054 words in registers and using alpha_expand_unaligned_store_words. */
2055 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2057 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2063 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2065 emit_move_insn (change_address (orig_dst, HImode,
2066 plus_constant (XEXP (orig_dst, 0),
2073 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2075 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2079 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2081 emit_move_insn (change_address (orig_dst, QImode,
2082 plus_constant (XEXP (orig_dst, 0),
2097 alpha_expand_block_clear (operands)
2100 rtx bytes_rtx = operands[1];
2101 rtx align_rtx = operands[2];
2102 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2103 HOST_WIDE_INT align = INTVAL (align_rtx);
2104 rtx orig_dst = operands[0];
2106 HOST_WIDE_INT i, words, ofs = 0;
2110 if (bytes > MAX_MOVE_WORDS*8)
2113 /* Look for stricter alignment. */
2115 tmp = XEXP (orig_dst, 0);
2116 if (GET_CODE (tmp) == REG)
2118 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2119 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2121 else if (GET_CODE (tmp) == PLUS
2122 && GET_CODE (XEXP (tmp, 0)) == REG
2123 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2125 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2126 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2130 if (a >= 8 && c % 8 == 0)
2132 else if (a >= 4 && c % 4 == 0)
2134 else if (a >= 2 && c % 2 == 0)
2139 /* Handle a block of contiguous words first. */
2141 if (align >= 8 && bytes >= 8)
2145 for (i = 0; i < words; ++i)
2147 emit_move_insn (change_address(orig_dst, DImode,
2148 plus_constant (XEXP (orig_dst, 0),
2156 if (align >= 4 && bytes >= 4)
2160 for (i = 0; i < words; ++i)
2162 emit_move_insn (change_address(orig_dst, SImode,
2163 plus_constant (XEXP (orig_dst, 0),
2175 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2181 /* Next clean up any trailing pieces. We know from the contiguous
2182 block move that there are no aligned SImode or DImode hunks left. */
2184 if (!TARGET_BWX && bytes >= 8)
2186 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2190 if (!TARGET_BWX && bytes >= 4)
2192 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2201 emit_move_insn (change_address (orig_dst, HImode,
2202 plus_constant (XEXP (orig_dst, 0),
2207 } while (bytes >= 2);
2209 else if (!TARGET_BWX)
2211 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2218 emit_move_insn (change_address (orig_dst, QImode,
2219 plus_constant (XEXP (orig_dst, 0),
2230 /* Adjust the cost of a scheduling dependency. Return the new cost of
2231 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2234 alpha_adjust_cost (insn, link, dep_insn, cost)
2241 enum attr_type insn_type, dep_insn_type;
2243 /* If the dependence is an anti-dependence, there is no cost. For an
2244 output dependence, there is sometimes a cost, but it doesn't seem
2245 worth handling those few cases. */
2247 if (REG_NOTE_KIND (link) != 0)
2250 /* If we can't recognize the insns, we can't really do anything. */
2251 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2254 insn_type = get_attr_type (insn);
2255 dep_insn_type = get_attr_type (dep_insn);
2257 /* Bring in the user-defined memory latency. */
2258 if (dep_insn_type == TYPE_ILD
2259 || dep_insn_type == TYPE_FLD
2260 || dep_insn_type == TYPE_LDSYM)
2261 cost += alpha_memory_latency-1;
2266 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2267 being stored, we can sometimes lower the cost. */
2269 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2270 && (set = single_set (dep_insn)) != 0
2271 && GET_CODE (PATTERN (insn)) == SET
2272 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2274 switch (dep_insn_type)
2278 /* No savings here. */
2282 /* In these cases, we save one cycle. */
2286 /* In all other cases, we save two cycles. */
2287 return MAX (0, cost - 2);
2291 /* Another case that needs adjustment is an arithmetic or logical
2292 operation. It's cost is usually one cycle, but we default it to
2293 two in the MD file. The only case that it is actually two is
2294 for the address in loads, stores, and jumps. */
2296 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2311 /* The final case is when a compare feeds into an integer branch;
2312 the cost is only one cycle in that case. */
2314 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2319 /* And the lord DEC saith: "A special bypass provides an effective
2320 latency of 0 cycles for an ICMP or ILOG insn producing the test
2321 operand of an IBR or ICMOV insn." */
2323 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2324 && (set = single_set (dep_insn)) != 0)
2326 /* A branch only has one input. This must be it. */
2327 if (insn_type == TYPE_IBR)
2329 /* A conditional move has three, make sure it is the test. */
2330 if (insn_type == TYPE_ICMOV
2331 && GET_CODE (set_src = PATTERN (insn)) == SET
2332 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2333 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2337 /* "The multiplier is unable to receive data from IEU bypass paths.
2338 The instruction issues at the expected time, but its latency is
2339 increased by the time it takes for the input data to become
2340 available to the multiplier" -- which happens in pipeline stage
2341 six, when results are comitted to the register file. */
2343 if (insn_type == TYPE_IMUL)
2345 switch (dep_insn_type)
2347 /* These insns produce their results in pipeline stage five. */
2354 /* Other integer insns produce results in pipeline stage four. */
2362 /* There is additional latency to move the result of (most) FP
2363 operations anywhere but the FP register file. */
2365 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2366 && (dep_insn_type == TYPE_FADD ||
2367 dep_insn_type == TYPE_FMUL ||
2368 dep_insn_type == TYPE_FCMOV))
2374 /* Otherwise, return the default cost. */
2378 /* Functions to save and restore alpha_return_addr_rtx. */
2380 struct machine_function
2386 alpha_save_machine_status (p)
2389 struct machine_function *machine =
2390 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2392 p->machine = machine;
2393 machine->ra_rtx = alpha_return_addr_rtx;
2397 alpha_restore_machine_status (p)
2400 struct machine_function *machine = p->machine;
2402 alpha_return_addr_rtx = machine->ra_rtx;
2405 p->machine = (struct machine_function *)0;
2408 /* Do anything needed before RTL is emitted for each function. */
2411 alpha_init_expanders ()
2413 alpha_return_addr_rtx = NULL_RTX;
2415 /* Arrange to save and restore machine status around nested functions. */
2416 save_machine_status = alpha_save_machine_status;
2417 restore_machine_status = alpha_restore_machine_status;
2420 /* Start the ball rolling with RETURN_ADDR_RTX. */
2423 alpha_return_addr (count, frame)
2432 if (alpha_return_addr_rtx)
2433 return alpha_return_addr_rtx;
2435 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2436 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2437 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2438 gen_rtx_REG (Pmode, REG_RA));
2440 /* Emit the insn to the prologue with the other argument copies. */
2441 push_topmost_sequence ();
2442 emit_insn_after (init, get_insns ());
2443 pop_topmost_sequence ();
2445 return alpha_return_addr_rtx;
2449 alpha_ra_ever_killed ()
2451 if (!alpha_return_addr_rtx)
2452 return regs_ever_live[REG_RA];
2454 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2455 get_insns(), NULL_RTX);
2459 /* Print an operand. Recognize special options, documented below. */
2462 print_operand (file, x, code)
2472 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2473 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2474 mode. alpha_fprm controls which suffix is generated. */
2477 case ALPHA_FPRM_NORM:
2479 case ALPHA_FPRM_MINF:
2482 case ALPHA_FPRM_CHOP:
2485 case ALPHA_FPRM_DYN:
2492 /* Generates trap-mode suffix for instructions that accept the su
2493 suffix only (cmpt et al). */
2494 if (alpha_tp == ALPHA_TP_INSN)
2499 /* Generates trap-mode suffix for instructions that accept the
2500 v and sv suffix. The only instruction that needs this is cvtql. */
2509 case ALPHA_FPTM_SUI:
2516 /* Generates trap-mode suffix for instructions that accept the
2517 v, sv, and svi suffix. The only instruction that needs this
2529 case ALPHA_FPTM_SUI:
2530 fputs ("svi", file);
2536 /* Generates trap-mode suffix for instructions that accept the u, su,
2537 and sui suffix. This is the bulk of the IEEE floating point
2538 instructions (addt et al). */
2549 case ALPHA_FPTM_SUI:
2550 fputs ("sui", file);
2556 /* Generates trap-mode suffix for instructions that accept the sui
2557 suffix (cvtqt and cvtqs). */
2562 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2564 case ALPHA_FPTM_SUI:
2565 fputs ("sui", file);
2571 /* Generates single precision instruction suffix. */
2572 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2576 /* Generates double precision instruction suffix. */
2577 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2581 /* If this operand is the constant zero, write it as "$31". */
2582 if (GET_CODE (x) == REG)
2583 fprintf (file, "%s", reg_names[REGNO (x)]);
2584 else if (x == CONST0_RTX (GET_MODE (x)))
2585 fprintf (file, "$31");
2587 output_operand_lossage ("invalid %%r value");
2592 /* Similar, but for floating-point. */
2593 if (GET_CODE (x) == REG)
2594 fprintf (file, "%s", reg_names[REGNO (x)]);
2595 else if (x == CONST0_RTX (GET_MODE (x)))
2596 fprintf (file, "$f31");
2598 output_operand_lossage ("invalid %%R value");
2603 /* Write the 1's complement of a constant. */
2604 if (GET_CODE (x) != CONST_INT)
2605 output_operand_lossage ("invalid %%N value");
2607 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2611 /* Write 1 << C, for a constant C. */
2612 if (GET_CODE (x) != CONST_INT)
2613 output_operand_lossage ("invalid %%P value");
2615 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2619 /* Write the high-order 16 bits of a constant, sign-extended. */
2620 if (GET_CODE (x) != CONST_INT)
2621 output_operand_lossage ("invalid %%h value");
2623 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2627 /* Write the low-order 16 bits of a constant, sign-extended. */
2628 if (GET_CODE (x) != CONST_INT)
2629 output_operand_lossage ("invalid %%L value");
2631 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2632 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2636 /* Write mask for ZAP insn. */
2637 if (GET_CODE (x) == CONST_DOUBLE)
2639 HOST_WIDE_INT mask = 0;
2640 HOST_WIDE_INT value;
2642 value = CONST_DOUBLE_LOW (x);
2643 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2648 value = CONST_DOUBLE_HIGH (x);
2649 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2652 mask |= (1 << (i + sizeof (int)));
2654 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2657 else if (GET_CODE (x) == CONST_INT)
2659 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2661 for (i = 0; i < 8; i++, value >>= 8)
2665 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2668 output_operand_lossage ("invalid %%m value");
2672 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2673 if (GET_CODE (x) != CONST_INT
2674 || (INTVAL (x) != 8 && INTVAL (x) != 16
2675 && INTVAL (x) != 32 && INTVAL (x) != 64))
2676 output_operand_lossage ("invalid %%M value");
2678 fprintf (file, "%s",
2679 (INTVAL (x) == 8 ? "b"
2680 : INTVAL (x) == 16 ? "w"
2681 : INTVAL (x) == 32 ? "l"
2686 /* Similar, except do it from the mask. */
2687 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2688 fprintf (file, "b");
2689 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2690 fprintf (file, "w");
2691 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2692 fprintf (file, "l");
2693 #if HOST_BITS_PER_WIDE_INT == 32
2694 else if (GET_CODE (x) == CONST_DOUBLE
2695 && CONST_DOUBLE_HIGH (x) == 0
2696 && CONST_DOUBLE_LOW (x) == -1)
2697 fprintf (file, "l");
2698 else if (GET_CODE (x) == CONST_DOUBLE
2699 && CONST_DOUBLE_HIGH (x) == -1
2700 && CONST_DOUBLE_LOW (x) == -1)
2701 fprintf (file, "q");
2703 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2704 fprintf (file, "q");
2705 else if (GET_CODE (x) == CONST_DOUBLE
2706 && CONST_DOUBLE_HIGH (x) == 0
2707 && CONST_DOUBLE_LOW (x) == -1)
2708 fprintf (file, "q");
2711 output_operand_lossage ("invalid %%U value");
2715 /* Write the constant value divided by 8. */
2716 if (GET_CODE (x) != CONST_INT
2717 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2718 && (INTVAL (x) & 7) != 8)
2719 output_operand_lossage ("invalid %%s value");
2721 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2725 /* Same, except compute (64 - c) / 8 */
2727 if (GET_CODE (x) != CONST_INT
2728 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2729 && (INTVAL (x) & 7) != 8)
2730 output_operand_lossage ("invalid %%s value");
2732 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2735 case 'C': case 'D': case 'c': case 'd':
2736 /* Write out comparison name. */
2738 enum rtx_code c = GET_CODE (x);
2740 if (GET_RTX_CLASS (c) != '<')
2741 output_operand_lossage ("invalid %%C value");
2744 c = reverse_condition (c);
2745 else if (code == 'c')
2746 c = swap_condition (c);
2747 else if (code == 'd')
2748 c = swap_condition (reverse_condition (c));
2751 fprintf (file, "ule");
2753 fprintf (file, "ult");
2755 fprintf (file, "%s", GET_RTX_NAME (c));
2760 /* Write the divide or modulus operator. */
2761 switch (GET_CODE (x))
2764 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2767 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2770 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2773 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2776 output_operand_lossage ("invalid %%E value");
2782 /* Write "_u" for unaligned access. */
2783 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2784 fprintf (file, "_u");
2788 if (GET_CODE (x) == REG)
2789 fprintf (file, "%s", reg_names[REGNO (x)]);
2790 else if (GET_CODE (x) == MEM)
2791 output_address (XEXP (x, 0));
2793 output_addr_const (file, x);
2797 output_operand_lossage ("invalid %%xn code");
2801 /* Do what is necessary for `va_start'. The argument is ignored;
2802 We look at the current function to determine if stdarg or varargs
2803 is used and fill in an initial va_list. A pointer to this constructor
2807 alpha_builtin_saveregs (arglist)
2810 rtx block, addr, dest, argsize;
2811 tree fntype = TREE_TYPE (current_function_decl);
2812 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2813 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2814 != void_type_node));
2816 /* Compute the current position into the args, taking into account
2817 both registers and memory. Both of these are already included in
2820 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2822 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2823 storing fp arg registers in the first 48 bytes, and the integer arg
2824 registers in the next 48 bytes. This is only done, however, if any
2825 integer registers need to be stored.
2827 If no integer registers need be stored, then we must subtract 48 in
2828 order to account for the integer arg registers which are counted in
2829 argsize above, but which are not actually stored on the stack. */
2831 if (TARGET_OPEN_VMS)
2832 addr = plus_constant (virtual_incoming_args_rtx,
2833 NUM_ARGS <= 5 + stdarg
2834 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2836 addr = (NUM_ARGS <= 5 + stdarg
2837 ? plus_constant (virtual_incoming_args_rtx,
2839 : plus_constant (virtual_incoming_args_rtx,
2840 - (6 * UNITS_PER_WORD)));
2842 /* For VMS, we include the argsize, while on Unix, it's handled as
2843 a separate field. */
2844 if (TARGET_OPEN_VMS)
2845 addr = plus_constant (addr, INTVAL (argsize));
2847 addr = force_operand (addr, NULL_RTX);
2849 #ifdef POINTERS_EXTEND_UNSIGNED
2850 addr = convert_memory_address (ptr_mode, addr);
2853 if (TARGET_OPEN_VMS)
2857 /* Allocate the va_list constructor */
2858 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2859 RTX_UNCHANGING_P (block) = 1;
2860 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2862 /* Store the address of the first integer register in the __base
2865 dest = change_address (block, ptr_mode, XEXP (block, 0));
2866 emit_move_insn (dest, addr);
2868 if (flag_check_memory_usage)
2869 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2871 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2872 TYPE_MODE (sizetype),
2873 GEN_INT (MEMORY_USE_RW),
2874 TYPE_MODE (integer_type_node));
2876 /* Store the argsize as the __va_offset member. */
2877 dest = change_address (block, TYPE_MODE (integer_type_node),
2878 plus_constant (XEXP (block, 0),
2879 POINTER_SIZE/BITS_PER_UNIT));
2880 emit_move_insn (dest, argsize);
2882 if (flag_check_memory_usage)
2883 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2885 GEN_INT (GET_MODE_SIZE
2886 (TYPE_MODE (integer_type_node))),
2887 TYPE_MODE (sizetype),
2888 GEN_INT (MEMORY_USE_RW),
2889 TYPE_MODE (integer_type_node));
2891 /* Return the address of the va_list constructor, but don't put it in a
2892 register. Doing so would fail when not optimizing and produce worse
2893 code when optimizing. */
2894 return XEXP (block, 0);
2898 /* This page contains routines that are used to determine what the function
2899 prologue and epilogue code will do and write them out. */
2901 /* Compute the size of the save area in the stack. */
2905 /* These variables are used for communication between the following functions.
2906 They indicate various things about the current function being compiled
2907 that are used to tell what kind of prologue, epilogue and procedure
2908 descriptior to generate. */
2910 /* Nonzero if we need a stack procedure. */
2911 static int is_stack_procedure;
2913 /* Register number (either FP or SP) that is used to unwind the frame. */
2914 static int unwind_regno;
2916 /* Register number used to save FP. We need not have one for RA since
2917 we don't modify it for register procedures. This is only defined
2918 for register frame procedures. */
2919 static int save_fp_regno;
2921 /* Register number used to reference objects off our PV. */
2922 static int base_regno;
2924 /* Compute register masks for saved registers. */
2927 alpha_sa_mask (imaskP, fmaskP)
2928 unsigned long *imaskP;
2929 unsigned long *fmaskP;
2931 unsigned long imask = 0;
2932 unsigned long fmask = 0;
2935 if (is_stack_procedure)
2936 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2938 /* One for every register we have to save. */
2940 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2941 if (! fixed_regs[i] && ! call_used_regs[i]
2942 && regs_ever_live[i] && i != REG_RA)
2947 fmask |= (1L << (i - 32));
2960 HOST_WIDE_INT stack_needed;
2963 /* One for every register we have to save. */
2965 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2966 if (! fixed_regs[i] && ! call_used_regs[i]
2967 && regs_ever_live[i] && i != REG_RA)
2970 /* Start by assuming we can use a register procedure if we don't make any
2971 calls (REG_RA not used) or need to save any registers and a stack
2972 procedure if we do. */
2973 is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2975 /* Decide whether to refer to objects off our PV via FP or PV.
2976 If we need FP for something else or if we receive a nonlocal
2977 goto (which expects PV to contain the value), we must use PV.
2978 Otherwise, start by assuming we can use FP. */
2979 base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
2980 || is_stack_procedure
2981 || current_function_outgoing_args_size
2982 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
2984 /* If we want to copy PV into FP, we need to find some register in which to
2989 if (base_regno == HARD_FRAME_POINTER_REGNUM)
2990 for (i = 0; i < 32; i++)
2991 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
2994 if (save_fp_regno == -1)
2995 base_regno = REG_PV, is_stack_procedure = 1;
2997 /* Stack unwinding should be done via FP unless we use it for PV. */
2999 = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
3001 /* If this is a stack procedure, allow space for saving FP and RA. */
3002 if (is_stack_procedure)
3009 alpha_pv_save_size ()
3012 return is_stack_procedure ? 8 : 0;
3019 return unwind_regno == HARD_FRAME_POINTER_REGNUM;
3022 #else /* ! OPEN_VMS */
3030 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3031 if (! fixed_regs[i] && ! call_used_regs[i]
3032 && regs_ever_live[i] && i != REG_RA)
3035 /* If some registers were saved but not reg 26, reg 26 must also
3036 be saved, so leave space for it. */
3037 if (size != 0 || alpha_ra_ever_killed ())
3040 /* Our size must be even (multiple of 16 bytes). */
3047 #endif /* ! OPEN_VMS */
3049 /* Return 1 if this function can directly return via $26. */
3054 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
3055 && get_frame_size () == 0
3056 && current_function_outgoing_args_size == 0
3057 && current_function_pretend_args_size == 0);
3060 /* Write a version stamp. Don't write anything if we are running as a
3061 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3068 alpha_write_verstamp (file)
3072 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3076 /* Write code to add constant C to register number IN_REG (possibly 31)
3077 and put the result into OUT_REG. Use TEMP_REG as a scratch register;
3078 usually this will be OUT_REG, but should not be if OUT_REG is
3079 STACK_POINTER_REGNUM, since it must be updated in a single instruction.
3080 Write the code to FILE. */
3083 add_long_const (file, c, in_reg, out_reg, temp_reg)
3086 int in_reg, out_reg, temp_reg;
3088 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
3089 HOST_WIDE_INT tmp1 = c - low;
3090 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3091 HOST_WIDE_INT extra = 0;
3093 /* We don't have code to write out constants larger than 32 bits. */
3094 #if HOST_BITS_PER_LONG_INT == 64
3095 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
3099 /* If HIGH will be interpreted as negative, we must adjust it to do two
3100 ldha insns. Note that we will never be building a negative constant
3107 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3112 int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
3114 if (low >= 0 && low < 255)
3115 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
3117 fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
3119 in_reg = result_reg;
3124 int result_reg = (high == 0) ? out_reg : temp_reg;
3126 fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
3127 in_reg = result_reg;
3131 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
3134 /* Write function prologue. */
3138 /* On vms we have two kinds of functions:
3140 - stack frame (PROC_STACK)
3141 these are 'normal' functions with local vars and which are
3142 calling other functions
3143 - register frame (PROC_REGISTER)
3144 keeps all data in registers, needs no stack
3146 We must pass this to the assembler so it can generate the
3147 proper pdsc (procedure descriptor)
3148 This is done with the '.pdesc' command.
3150 size is the stack size needed for local variables. */
3153 output_prolog (file, size)
3157 unsigned long imask = 0;
3158 unsigned long fmask = 0;
3159 /* Stack space needed for pushing registers clobbered by us. */
3160 HOST_WIDE_INT sa_size;
3161 /* Complete stack size needed. */
3162 HOST_WIDE_INT frame_size;
3163 /* Offset from base reg to register save area. */
3165 /* Offset during register save. */
3167 /* Label for the procedure entry. */
3168 char *entry_label = (char *) alloca (strlen (alpha_function_name) + 6);
3171 sa_size = alpha_sa_size ();
3173 = ALPHA_ROUND (sa_size
3174 + (is_stack_procedure ? 8 : 0)
3175 + size + current_function_pretend_args_size);
3177 /* Issue function start and label. */
3178 fprintf (file, "\t.ent ");
3179 assemble_name (file, alpha_function_name);
3180 fprintf (file, "\n");
3181 sprintf (entry_label, "%s..en", alpha_function_name);
3182 ASM_OUTPUT_LABEL (file, entry_label);
3183 inside_function = TRUE;
3185 fprintf (file, "\t.base $%d\n", base_regno);
3187 /* Calculate register masks for clobbered registers. */
3189 if (is_stack_procedure)
3190 alpha_sa_mask (&imask, &fmask);
3192 /* Adjust the stack by the frame size. If the frame size is > 4096
3193 bytes, we need to be sure we probe somewhere in the first and last
3194 4096 bytes (we can probably get away without the latter test) and
3195 every 8192 bytes in between. If the frame size is > 32768, we
3196 do this in a loop. Otherwise, we generate the explicit probe
3199 Note that we are only allowed to adjust sp once in the prologue. */
3201 if (frame_size < 32768)
3203 if (frame_size > 4096)
3207 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3209 while (probed + 8192 < frame_size)
3210 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3212 /* We only have to do this probe if we aren't saving registers. */
3213 if (sa_size == 0 && probed + 4096 < frame_size)
3214 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3217 if (frame_size != 0)
3218 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3222 /* Here we generate code to set R4 to SP + 4096 and set R23 to the
3223 number of 8192 byte blocks to probe. We then probe each block
3224 in the loop and then set SP to the proper location. If the
3225 amount remaining is > 4096, we have to do one more probe if we
3226 are not saving any registers. */
3228 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3229 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3231 add_long_const (file, blocks, 31, 23, 23);
3233 fprintf (file, "\tlda $22,4096($30)\n");
3236 assemble_name (file, alpha_function_name);
3237 fprintf (file, "..sc:\n");
3239 fprintf (file, "\tstq $31,-8192($22)\n");
3240 fprintf (file, "\tsubq $23,1,$23\n");
3241 fprintf (file, "\tlda $22,-8192($22)\n");
3243 fprintf (file, "\tbne $23,$");
3244 assemble_name (file, alpha_function_name);
3245 fprintf (file, "..sc\n");
3247 if (leftover > 4096 && sa_size == 0)
3248 fprintf (file, "\tstq $31,-%d($22)\n", leftover);
3250 fprintf (file, "\tlda $30,-%d($22)\n", leftover);
3253 if (is_stack_procedure)
3255 int reg_offset = rsa_offset;
3257 /* Store R26 (RA) first. */
3258 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
3261 /* Store integer regs. according to mask. */
3262 for (i = 0; i < 32; i++)
3263 if (imask & (1L<<i))
3265 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
3269 /* Print the register mask and do floating-point saves. */
3272 fprintf (file, "\t.mask 0x%x,0\n", imask);
3274 for (i = 0; i < 32; i++)
3276 if (fmask & (1L << i))
3278 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
3283 /* Print the floating-point mask, if we've saved any fp register. */
3285 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
3287 fprintf (file, "\tstq $27,0($30)\n");
3291 fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
3292 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3293 HARD_FRAME_POINTER_REGNUM, save_fp_regno);
3296 if (base_regno != REG_PV)
3297 fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
3299 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3300 fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
3301 STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
3303 /* Describe our frame. */
3304 fprintf (file, "\t.frame $%d,", unwind_regno);
3306 /* If the frame size is larger than an integer, print it as zero to
3307 avoid an assembler error. We won't be properly describing such a
3308 frame, but that's the best we can do. */
3309 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3310 #if HOST_BITS_PER_WIDE_INT == 64
3311 frame_size >= (1l << 31) ? 0:
3315 fprintf (file, ",$26,%d\n", rsa_offset);
3317 /* If we have to allocate space for outgoing args, do it now. */
3318 if (current_function_outgoing_args_size != 0)
3319 fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
3320 - ALPHA_ROUND (current_function_outgoing_args_size),
3321 HARD_FRAME_POINTER_REGNUM);
3323 fprintf (file, "\t.prologue\n");
3325 readonly_section ();
3326 fprintf (file, "\t.align 3\n");
3327 assemble_name (file, alpha_function_name); fputs ("..na:\n", file);
3328 fputs ("\t.ascii \"", file);
3329 assemble_name (file, alpha_function_name);
3330 fputs ("\\0\"\n", file);
3333 fprintf (file, "\t.align 3\n");
3334 fputs ("\t.name ", file);
3335 assemble_name (file, alpha_function_name);
3336 fputs ("..na\n", file);
3337 ASM_OUTPUT_LABEL (file, alpha_function_name);
3338 fprintf (file, "\t.pdesc ");
3339 assemble_name (file, alpha_function_name);
3340 fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
3341 alpha_need_linkage (alpha_function_name, 1);
3347 /* Write function epilogue. */
3350 output_epilog (file, size)
3354 unsigned long imask = 0;
3355 unsigned long fmask = 0;
3356 /* Stack space needed for pushing registers clobbered by us. */
3357 HOST_WIDE_INT sa_size = alpha_sa_size ();
3358 /* Complete stack size needed. */
3359 HOST_WIDE_INT frame_size
3360 = ALPHA_ROUND (sa_size
3361 + (is_stack_procedure ? 8 : 0)
3362 + size + current_function_pretend_args_size);
3364 rtx insn = get_last_insn ();
3366 /* If the last insn was a BARRIER, we don't have to write anything except
3367 the .end pseudo-op. */
3369 if (GET_CODE (insn) == NOTE)
3370 insn = prev_nonnote_insn (insn);
3372 if (insn == 0 || GET_CODE (insn) != BARRIER)
3374 /* Restore clobbered registers, load FP last. */
3376 if (is_stack_procedure)
3382 if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3383 fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3384 HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
3386 alpha_sa_mask (&imask, &fmask);
3388 /* Start reloading registers after RA. */
3389 reg_offset = rsa_offset + 8;
3391 for (i = 0; i < 32; i++)
3392 if (imask & (1L<<i))
3394 if (i == HARD_FRAME_POINTER_REGNUM)
3395 fp_offset = reg_offset;
3397 fprintf (file, "\tldq $%d,%d($30)\n",
3402 for (i = 0; i < 32; i++)
3403 if (fmask & (1L << i))
3405 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
3409 /* Restore R26 (RA). */
3410 fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
3412 /* Restore R29 (FP). */
3413 fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
3416 fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
3417 HARD_FRAME_POINTER_REGNUM);
3419 if (frame_size != 0)
3421 if (frame_size < 32768)
3422 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
3425 long high = frame_size >> 16;
3426 long low = frame_size & 0xffff;
3430 low = -32768 + (low & 0x7fff);
3432 fprintf (file, "\tldah $2,%ld($31)\n", high);
3433 fprintf (file, "\tlda $2,%ld($2)\n", low);
3434 fprintf (file, "\taddq $30,$2,$30\n");
3438 /* Finally return to the caller. */
3439 fprintf (file, "\tret $31,($26),1\n");
3442 /* End the function. */
3443 fprintf (file, "\t.end ");
3444 assemble_name (file, alpha_function_name);
3445 fprintf (file, "\n");
3446 inside_function = FALSE;
3448 /* Show that we know this function if it is called again. */
3449 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3453 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3459 if (is_attribute_p ("overlaid", identifier))
3460 return (args == NULL_TREE);
3464 #else /* !OPEN_VMS */
3467 alpha_does_function_need_gp ()
3471 /* We never need a GP for Windows/NT. */
3472 if (TARGET_WINDOWS_NT)
3475 #ifdef TARGET_PROFILING_NEEDS_GP
3480 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3481 Even if we are a static function, we still need to do this in case
3482 our address is taken and passed to something like qsort. */
3484 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3485 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3486 && GET_CODE (PATTERN (insn)) != USE
3487 && GET_CODE (PATTERN (insn)) != CLOBBER)
3489 enum attr_type type = get_attr_type (insn);
3490 if (type == TYPE_LDSYM || type == TYPE_JSR)
3498 output_prolog (file, size)
3502 HOST_WIDE_INT out_args_size
3503 = ALPHA_ROUND (current_function_outgoing_args_size);
3504 HOST_WIDE_INT sa_size = alpha_sa_size ();
3505 HOST_WIDE_INT frame_size
3506 = (out_args_size + sa_size
3507 + ALPHA_ROUND (size + current_function_pretend_args_size));
3508 HOST_WIDE_INT reg_offset = out_args_size;
3509 HOST_WIDE_INT start_reg_offset = reg_offset;
3510 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
3511 int int_reg_save_area_size = 0;
3512 unsigned reg_mask = 0;
3515 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3516 We have to do that before the .ent directive as we cannot switch
3517 files within procedures with native ecoff because line numbers are
3518 linked to procedure descriptors.
3519 Outputting the lineno helps debugging of one line functions as they
3520 would otherwise get no line number at all. Please note that we would
3521 like to put out last_linenum from final.c, but it is not accessible. */
3523 if (write_symbols == SDB_DEBUG)
3525 ASM_OUTPUT_SOURCE_FILENAME (file,
3526 DECL_SOURCE_FILE (current_function_decl));
3527 if (debug_info_level != DINFO_LEVEL_TERSE)
3528 ASM_OUTPUT_SOURCE_LINE (file,
3529 DECL_SOURCE_LINE (current_function_decl));
3532 /* The assembly language programmer's guide states that the second argument
3533 to the .ent directive, the lex_level, is ignored by the assembler,
3534 so we might as well omit it. */
3536 if (!flag_inhibit_size_directive)
3538 fprintf (file, "\t.ent ");
3539 assemble_name (file, alpha_function_name);
3540 fprintf (file, "\n");
3542 ASM_OUTPUT_LABEL (file, alpha_function_name);
3543 inside_function = TRUE;
3545 if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
3546 /* Set flags in procedure descriptor to request IEEE-conformant
3547 math-library routines. The value we set it to is PDSC_EXC_IEEE
3548 (/usr/include/pdsc.h). */
3549 fprintf (file, "\t.eflag 48\n");
3551 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3553 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3554 alpha_arg_offset = -frame_size + 48;
3556 alpha_function_needs_gp = alpha_does_function_need_gp ();
3558 if (TARGET_WINDOWS_NT == 0)
3560 if (alpha_function_needs_gp)
3561 fprintf (file, "\tldgp $29,0($27)\n");
3563 /* Put a label after the GP load so we can enter the function at it. */
3565 assemble_name (file, alpha_function_name);
3566 fprintf (file, "..ng:\n");
3569 /* Adjust the stack by the frame size. If the frame size is > 4096
3570 bytes, we need to be sure we probe somewhere in the first and last
3571 4096 bytes (we can probably get away without the latter test) and
3572 every 8192 bytes in between. If the frame size is > 32768, we
3573 do this in a loop. Otherwise, we generate the explicit probe
3576 Note that we are only allowed to adjust sp once in the prologue. */
3578 if (frame_size < 32768)
3580 if (frame_size > 4096)
3584 fprintf (file, "\tstq $31,-%d($30)\n", probed);
3586 while (probed + 8192 < frame_size)
3587 fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3589 /* We only have to do this probe if we aren't saving registers. */
3590 if (sa_size == 0 && probed + 4096 < frame_size)
3591 fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3594 if (frame_size != 0)
3595 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3599 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
3600 number of 8192 byte blocks to probe. We then probe each block
3601 in the loop and then set SP to the proper location. If the
3602 amount remaining is > 4096, we have to do one more probe if we
3603 are not saving any registers. */
3605 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3606 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3608 add_long_const (file, blocks, 31, 5, 5);
3610 fprintf (file, "\tlda $4,4096($30)\n");
3613 assemble_name (file, alpha_function_name);
3614 fprintf (file, "..sc:\n");
3616 fprintf (file, "\tstq $31,-8192($4)\n");
3617 fprintf (file, "\tsubq $5,1,$5\n");
3618 fprintf (file, "\tlda $4,-8192($4)\n");
3620 fprintf (file, "\tbne $5,$");
3621 assemble_name (file, alpha_function_name);
3622 fprintf (file, "..sc\n");
3624 if (leftover > 4096 && sa_size == 0)
3625 fprintf (file, "\tstq $31,-%d($4)\n", leftover);
3627 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
3630 /* Describe our frame. */
3631 if (!flag_inhibit_size_directive)
3633 fprintf (file, "\t.frame $%d,",
3634 (frame_pointer_needed
3635 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3637 /* If the frame size is larger than an integer, print it as zero to
3638 avoid an assembler error. We won't be properly describing such a
3639 frame, but that's the best we can do. */
3640 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3641 #if HOST_BITS_PER_WIDE_INT == 64
3642 frame_size >= (1l << 31) ? 0 :
3646 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3649 /* Cope with very large offsets to the register save area. */
3651 if (reg_offset + sa_size > 0x8000)
3653 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3654 if (low + sa_size <= 0x8000)
3656 add_long_const (file, reg_offset - low, 30, 24, 24);
3661 add_long_const (file, reg_offset, 30, 24, 24);
3667 /* Save register RA if any other register needs to be saved. */
3670 reg_mask |= 1 << REG_RA;
3671 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
3673 int_reg_save_area_size += 8;
3676 /* Now save any other used integer registers required to be saved. */
3677 for (i = 0; i < 32; i++)
3678 if (! fixed_regs[i] && ! call_used_regs[i]
3679 && regs_ever_live[i] && i != REG_RA)
3682 fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3684 int_reg_save_area_size += 8;
3687 /* Print the register mask and do floating-point saves. */
3688 if (reg_mask && !flag_inhibit_size_directive)
3690 fprintf (file, "\t.mask 0x%x,", reg_mask);
3691 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3692 #if HOST_BITS_PER_WIDE_INT == 64
3693 frame_size >= (1l << 31) ? 0 :
3695 actual_start_reg_offset - frame_size);
3696 fprintf (file, "\n");
3699 start_reg_offset = reg_offset;
3702 for (i = 0; i < 32; i++)
3703 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3704 && regs_ever_live[i + 32])
3707 fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3711 /* Print the floating-point mask, if we've saved any fp register. */
3712 if (reg_mask && !flag_inhibit_size_directive)
3713 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
3714 actual_start_reg_offset - frame_size + int_reg_save_area_size);
3716 /* If we need a frame pointer, set it from the stack pointer. Note that
3717 this must always be the last instruction in the prologue. */
3718 if (frame_pointer_needed)
3719 fprintf (file, "\tbis $30,$30,$15\n");
3721 /* End the prologue and say if we used gp. */
3722 if (!flag_inhibit_size_directive)
3723 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3726 /* Write function epilogue. */
3729 output_epilog (file, size)
3733 rtx insn = get_last_insn ();
3734 HOST_WIDE_INT out_args_size
3735 = ALPHA_ROUND (current_function_outgoing_args_size);
3736 HOST_WIDE_INT sa_size = alpha_sa_size ();
3737 HOST_WIDE_INT frame_size
3738 = (out_args_size + sa_size
3739 + ALPHA_ROUND (size + current_function_pretend_args_size));
3740 HOST_WIDE_INT reg_offset = out_args_size;
3742 = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
3745 /* If the last insn was a BARRIER, we don't have to write anything except
3746 the .end pseudo-op. */
3747 if (GET_CODE (insn) == NOTE)
3748 insn = prev_nonnote_insn (insn);
3749 if (insn == 0 || GET_CODE (insn) != BARRIER)
3754 /* If we have a frame pointer, restore SP from it. */
3755 if (frame_pointer_needed)
3756 fprintf (file, "\tbis $15,$15,$30\n");
3758 /* Cope with large offsets to the register save area. */
3760 if (reg_offset + sa_size > 0x8000)
3762 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3763 if (low + sa_size <= 0x8000)
3765 add_long_const (file, reg_offset - low, 30, 24, 24);
3770 add_long_const (file, reg_offset, 30, 24, 24);
3776 /* Restore all the registers, starting with the return address
3780 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
3784 /* Now restore any other used integer registers that we saved,
3785 except for FP if it is being used as FP, since it must be
3788 for (i = 0; i < 32; i++)
3789 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
3792 if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3793 fp_offset = reg_offset;
3795 fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3799 for (i = 0; i < 32; i++)
3800 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3801 && regs_ever_live[i + 32])
3803 fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3807 /* If the stack size is large and we have a frame pointer, compute the
3808 size of the stack into a register because the old FP restore, stack
3809 pointer adjust, and return are required to be consecutive
3811 if (frame_size > 32767 && restore_fp)
3812 add_long_const (file, frame_size, 31, 1, 1);
3814 /* If we needed a frame pointer and we have to restore it, do it
3815 now. This must be done in one instruction immediately
3816 before the SP update. */
3817 if (restore_fp && fp_offset)
3818 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
3820 /* Now update the stack pointer, if needed. Only one instruction must
3821 modify the stack pointer. It must be the last instruction in the
3822 sequence and must be an ADDQ or LDA instruction. If the frame
3823 pointer was loaded above, we may only put one instruction here. */
3825 if (frame_size > 32768 && restore_fp)
3826 fprintf (file, "\taddq $1,$30,$30\n");
3828 add_long_const (file, frame_size, 30, 30, 1);
3830 /* Finally return to the caller. */
3831 fprintf (file, "\tret $31,($26),1\n");
3834 /* End the function. */
3835 if (!flag_inhibit_size_directive)
3837 fprintf (file, "\t.end ");
3838 assemble_name (file, alpha_function_name);
3839 fprintf (file, "\n");
3841 inside_function = FALSE;
3843 /* Show that we know this function if it is called again.
3845 Don't do this for global functions in object files destined for a
3846 shared library because the function may be overridden by the application
3848 ??? Is this just ELF? */
3850 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3851 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3853 #endif /* !OPEN_VMS */
3855 /* Debugging support. */
3859 /* Count the number of sdb related labels are generated (to find block
3860 start and end boundaries). */
3862 int sdb_label_count = 0;
3864 /* Next label # for each statement. */
3866 static int sym_lineno = 0;
3868 /* Count the number of .file directives, so that .loc is up to date. */
3870 static int num_source_filenames = 0;
3872 /* Name of the file containing the current function. */
3874 static char *current_function_file = "";
3876 /* Offsets to alpha virtual arg/local debugging pointers. */
3878 long alpha_arg_offset;
3879 long alpha_auto_offset;
3881 /* Emit a new filename to a stream. */
3884 alpha_output_filename (stream, name)
3888 static int first_time = TRUE;
3889 char ltext_label_name[100];
3894 ++num_source_filenames;
3895 current_function_file = name;
3896 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3897 output_quoted_string (stream, name);
3898 fprintf (stream, "\n");
3899 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3900 fprintf (stream, "\t#@stabs\n");
3903 else if (write_symbols == DBX_DEBUG)
3905 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3906 fprintf (stream, "%s ", ASM_STABS_OP);
3907 output_quoted_string (stream, name);
3908 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3911 else if (name != current_function_file
3912 && strcmp (name, current_function_file) != 0)
3914 if (inside_function && ! TARGET_GAS)
3915 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3918 ++num_source_filenames;
3919 current_function_file = name;
3920 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3923 output_quoted_string (stream, name);
3924 fprintf (stream, "\n");
3928 /* Emit a linenumber to a stream. */
3931 alpha_output_lineno (stream, line)
3935 if (write_symbols == DBX_DEBUG)
3937 /* mips-tfile doesn't understand .stabd directives. */
3939 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3940 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3943 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3946 /* Structure to show the current status of registers and memory. */
3948 struct shadow_summary
3951 unsigned long i : 31; /* Mask of int regs */
3952 unsigned long fp : 31; /* Mask of fp regs */
3953 unsigned long mem : 1; /* mem == imem | fpmem */
3957 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3958 to the summary structure. SET is nonzero if the insn is setting the
3959 object, otherwise zero. */
3962 summarize_insn (x, sum, set)
3964 struct shadow_summary *sum;
3973 switch (GET_CODE (x))
3975 /* ??? Note that this case would be incorrect if the Alpha had a
3976 ZERO_EXTRACT in SET_DEST. */
3978 summarize_insn (SET_SRC (x), sum, 0);
3979 summarize_insn (SET_DEST (x), sum, 1);
3983 summarize_insn (XEXP (x, 0), sum, 1);
3987 summarize_insn (XEXP (x, 0), sum, 0);
3991 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3992 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3996 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3997 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4006 int regno = REGNO (x);
4007 unsigned long mask = 1UL << (regno % 32);
4009 if (regno == 31 || regno == 63)
4015 sum->defd.i |= mask;
4017 sum->defd.fp |= mask;
4022 sum->used.i |= mask;
4024 sum->used.fp |= mask;
4035 /* Find the regs used in memory address computation: */
4036 summarize_insn (XEXP (x, 0), sum, 0);
4039 case CONST_INT: case CONST_DOUBLE:
4040 case SYMBOL_REF: case LABEL_REF: case CONST:
4043 /* Handle common unary and binary ops for efficiency. */
4044 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4045 case MOD: case UDIV: case UMOD: case AND: case IOR:
4046 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4047 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4048 case NE: case EQ: case GE: case GT: case LE:
4049 case LT: case GEU: case GTU: case LEU: case LTU:
4050 summarize_insn (XEXP (x, 0), sum, 0);
4051 summarize_insn (XEXP (x, 1), sum, 0);
4054 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4055 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4056 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4057 case SQRT: case FFS:
4058 summarize_insn (XEXP (x, 0), sum, 0);
4062 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4063 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4064 switch (format_ptr[i])
4067 summarize_insn (XEXP (x, i), sum, 0);
4071 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4072 summarize_insn (XVECEXP (x, i, j), sum, 0);
4084 /* Ensure a sufficient number of `trapb' insns are in the code when the user
4085 requests code with a trap precision of functions or instructions.
4087 In naive mode, when the user requests a trap-precision of "instruction", a
4088 trapb is needed after every instruction that may generate a trap (and after
4089 jsr/bsr instructions, because called functions may import a trap from the
4090 caller). This ensures that the code is resumption safe but it is also slow.
4092 When optimizations are turned on, we delay issuing a trapb as long as
4093 possible. In this context, a trap shadow is the sequence of instructions
4094 that starts with a (potentially) trap generating instruction and extends to
4095 the next trapb or call_pal instruction (but GCC never generates call_pal by
4096 itself). We can delay (and therefore sometimes omit) a trapb subject to the
4097 following conditions:
4099 (a) On entry to the trap shadow, if any Alpha register or memory location
4100 contains a value that is used as an operand value by some instruction in
4101 the trap shadow (live on entry), then no instruction in the trap shadow
4102 may modify the register or memory location.
4104 (b) Within the trap shadow, the computation of the base register for a
4105 memory load or store instruction may not involve using the result
4106 of an instruction that might generate an UNPREDICTABLE result.
4108 (c) Within the trap shadow, no register may be used more than once as a
4109 destination register. (This is to make life easier for the trap-handler.)
4111 (d) The trap shadow may not include any branch instructions. */
4114 alpha_handle_trap_shadows (insns)
4117 struct shadow_summary shadow;
4118 int trap_pending, exception_nesting;
4121 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
4125 exception_nesting = 0;
4128 shadow.used.mem = 0;
4129 shadow.defd = shadow.used;
4131 for (i = insns; i ; i = NEXT_INSN (i))
4133 if (GET_CODE (i) == NOTE)
4135 switch (NOTE_LINE_NUMBER (i))
4137 case NOTE_INSN_EH_REGION_BEG:
4138 exception_nesting++;
4143 case NOTE_INSN_EH_REGION_END:
4144 exception_nesting--;
4149 case NOTE_INSN_EPILOGUE_BEG:
4150 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4155 else if (trap_pending)
4157 if (alpha_tp == ALPHA_TP_FUNC)
4159 if (GET_CODE (i) == JUMP_INSN
4160 && GET_CODE (PATTERN (i)) == RETURN)
4163 else if (alpha_tp == ALPHA_TP_INSN)
4167 struct shadow_summary sum;
4172 sum.defd = sum.used;
4174 switch (GET_CODE (i))
4177 /* Annoyingly, get_attr_trap will abort on these. */
4178 if (GET_CODE (PATTERN (i)) == USE
4179 || GET_CODE (PATTERN (i)) == CLOBBER)
4182 summarize_insn (PATTERN (i), &sum, 0);
4184 if ((sum.defd.i & shadow.defd.i)
4185 || (sum.defd.fp & shadow.defd.fp))
4187 /* (c) would be violated */
4191 /* Combine shadow with summary of current insn: */
4192 shadow.used.i |= sum.used.i;
4193 shadow.used.fp |= sum.used.fp;
4194 shadow.used.mem |= sum.used.mem;
4195 shadow.defd.i |= sum.defd.i;
4196 shadow.defd.fp |= sum.defd.fp;
4197 shadow.defd.mem |= sum.defd.mem;
4199 if ((sum.defd.i & shadow.used.i)
4200 || (sum.defd.fp & shadow.used.fp)
4201 || (sum.defd.mem & shadow.used.mem))
4203 /* (a) would be violated (also takes care of (b)) */
4204 if (get_attr_trap (i) == TRAP_YES
4205 && ((sum.defd.i & sum.used.i)
4206 || (sum.defd.fp & sum.used.fp)))
4225 emit_insn_before (gen_trapb (), i);
4229 shadow.used.mem = 0;
4230 shadow.defd = shadow.used;
4235 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4236 && GET_CODE (i) == INSN
4237 && GET_CODE (PATTERN (i)) != USE
4238 && GET_CODE (PATTERN (i)) != CLOBBER
4239 && get_attr_trap (i) == TRAP_YES)
4241 if (optimize && !trap_pending)
4242 summarize_insn (PATTERN (i), &shadow, 0);
4248 /* Machine dependant reorg pass. */
4254 alpha_handle_trap_shadows (insns);
4258 /* Check a floating-point value for validity for a particular machine mode. */
4260 static char *float_strings[] =
4262 /* These are for FLOAT_VAX. */
4263 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4264 "-1.70141173319264430e+38",
4265 "2.93873587705571877e-39", /* 2^-128 */
4266 "-2.93873587705571877e-39",
4267 /* These are for the default broken IEEE mode, which traps
4268 on infinity or denormal numbers. */
4269 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4270 "-3.402823466385288598117e+38",
4271 "1.1754943508222875079687e-38", /* 2^-126 */
4272 "-1.1754943508222875079687e-38",
4275 static REAL_VALUE_TYPE float_values[8];
4276 static int inited_float_values = 0;
4279 check_float_value (mode, d, overflow)
4280 enum machine_mode mode;
4285 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4288 if (inited_float_values == 0)
4291 for (i = 0; i < 8; i++)
4292 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4294 inited_float_values = 1;
4300 REAL_VALUE_TYPE *fvptr;
4302 if (TARGET_FLOAT_VAX)
4303 fvptr = &float_values[0];
4305 fvptr = &float_values[4];
4307 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4308 if (REAL_VALUES_LESS (fvptr[0], r))
4310 bcopy ((char *) &fvptr[0], (char *) d,
4311 sizeof (REAL_VALUE_TYPE));
4314 else if (REAL_VALUES_LESS (r, fvptr[1]))
4316 bcopy ((char *) &fvptr[1], (char *) d,
4317 sizeof (REAL_VALUE_TYPE));
4320 else if (REAL_VALUES_LESS (dconst0, r)
4321 && REAL_VALUES_LESS (r, fvptr[2]))
4323 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4326 else if (REAL_VALUES_LESS (r, dconst0)
4327 && REAL_VALUES_LESS (fvptr[3], r))
4329 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4339 /* Return the VMS argument type corresponding to MODE. */
4342 alpha_arg_type (mode)
4343 enum machine_mode mode;
4348 return TARGET_FLOAT_VAX ? FF : FS;
4350 return TARGET_FLOAT_VAX ? FD : FT;
4356 /* Return an rtx for an integer representing the VMS Argument Information
4360 alpha_arg_info_reg_val (cum)
4361 CUMULATIVE_ARGS cum;
4363 unsigned HOST_WIDE_INT regval = cum.num_args;
4366 for (i = 0; i < 6; i++)
4367 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4369 return GEN_INT (regval);
4372 /* Structure to collect function names for final output
4375 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4378 struct alpha_links {
4379 struct alpha_links *next;
4381 enum links_kind kind;
4384 static struct alpha_links *alpha_links_base = 0;
4386 /* Make (or fake) .linkage entry for function call.
4388 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
4391 alpha_need_linkage (name, is_local)
4396 struct alpha_links *lptr, *nptr;
4401 /* Is this name already defined ? */
4403 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4404 if (strcmp (lptr->name, name) == 0)
4408 /* Defined here but external assumed. */
4409 if (lptr->kind == KIND_EXTERN)
4410 lptr->kind = KIND_LOCAL;
4414 /* Used here but unused assumed. */
4415 if (lptr->kind == KIND_UNUSED)
4416 lptr->kind = KIND_LOCAL;
4421 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4422 nptr->next = alpha_links_base;
4423 nptr->name = xstrdup (name);
4425 /* Assume external if no definition. */
4426 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4428 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
4429 get_identifier (name);
4431 alpha_links_base = nptr;
4438 alpha_write_linkage (stream)
4441 struct alpha_links *lptr, *nptr;
4443 readonly_section ();
4445 fprintf (stream, "\t.align 3\n");
4447 for (lptr = alpha_links_base; lptr; lptr = nptr)
4451 if (lptr->kind == KIND_UNUSED
4452 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4455 fprintf (stream, "$%s..lk:\n", lptr->name);
4456 if (lptr->kind == KIND_LOCAL)
4458 /* Local and used, build linkage pair. */
4459 fprintf (stream, "\t.quad %s..en\n", lptr->name);
4460 fprintf (stream, "\t.quad %s\n", lptr->name);
4463 /* External and used, request linkage pair. */
4464 fprintf (stream, "\t.linkage %s\n", lptr->name);
4471 alpha_need_linkage (name, is_local)
4477 #endif /* OPEN_VMS */