1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 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"
48 extern int rtx_equal_function_value_matters;
50 /* Specify which cpu to schedule for. */
52 enum processor_type alpha_cpu;
53 static const char * const alpha_cpu_name[] =
58 /* Specify how accurate floating-point traps need to be. */
60 enum alpha_trap_precision alpha_tp;
62 /* Specify the floating-point rounding mode. */
64 enum alpha_fp_rounding_mode alpha_fprm;
66 /* Specify which things cause traps. */
68 enum alpha_fp_trap_mode alpha_fptm;
70 /* Strings decoded into the above options. */
72 const char *alpha_cpu_string; /* -mcpu= */
73 const char *alpha_tune_string; /* -mtune= */
74 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
75 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
76 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
77 const char *alpha_mlat_string; /* -mmemory-latency= */
79 /* Save information from a "cmpxx" operation until the branch or scc is
82 struct alpha_compare alpha_compare;
84 /* Non-zero if inside of a function, because the Alpha asm can't
85 handle .files inside of functions. */
87 static int inside_function = FALSE;
89 /* The number of cycles of latency we should assume on memory reads. */
91 int alpha_memory_latency = 3;
93 /* Whether the function needs the GP. */
95 static int alpha_function_needs_gp;
97 /* The alias set for prologue/epilogue register save/restore. */
99 static int alpha_sr_alias_set;
101 /* The assembler name of the current function. */
103 static const char *alpha_fnname;
105 /* Declarations of static functions. */
106 static void alpha_set_memflags_1
107 PARAMS ((rtx, int, int, int));
108 static rtx alpha_emit_set_const_1
109 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
110 static void alpha_expand_unaligned_load_words
111 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
112 static void alpha_expand_unaligned_store_words
113 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
114 static void alpha_sa_mask
115 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
116 static int alpha_does_function_need_gp
118 static void alpha_init_machine_status
119 PARAMS ((struct function *p));
120 static void alpha_mark_machine_status
121 PARAMS ((struct function *p));
122 static int alpha_ra_ever_killed
124 static rtx set_frame_related_p
126 static const char *alpha_lookup_xfloating_lib_func
127 PARAMS ((enum rtx_code));
128 static int alpha_compute_xfloating_mode_arg
129 PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
130 static void alpha_emit_xfloating_libcall
131 PARAMS ((const char *, rtx, rtx[], int, rtx));
132 static rtx alpha_emit_xfloating_compare
133 PARAMS ((enum rtx_code, rtx, rtx));
135 /* Get the number of args of a function in one of two ways. */
137 #define NUM_ARGS current_function_args_info.num_args
139 #define NUM_ARGS current_function_args_info
145 /* Parse target option strings. */
151 static struct cpu_table {
153 enum processor_type processor;
156 #define EV5_MASK (MASK_CPU_EV5)
157 #define EV6_MASK (MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX)
158 { "ev4", PROCESSOR_EV4, 0 },
159 { "ev45", PROCESSOR_EV4, 0 },
160 { "21064", PROCESSOR_EV4, 0 },
161 { "ev5", PROCESSOR_EV5, EV5_MASK },
162 { "21164", PROCESSOR_EV5, EV5_MASK },
163 { "ev56", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
164 { "21164a", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
165 { "pca56", PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
166 { "21164PC",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
167 { "21164pc",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
168 { "ev6", PROCESSOR_EV6, EV6_MASK },
169 { "21264", PROCESSOR_EV6, EV6_MASK },
170 { "ev67", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
171 { "21264a", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
175 alpha_tp = ALPHA_TP_PROG;
176 alpha_fprm = ALPHA_FPRM_NORM;
177 alpha_fptm = ALPHA_FPTM_N;
181 alpha_tp = ALPHA_TP_INSN;
182 alpha_fptm = ALPHA_FPTM_SU;
185 if (TARGET_IEEE_WITH_INEXACT)
187 alpha_tp = ALPHA_TP_INSN;
188 alpha_fptm = ALPHA_FPTM_SUI;
193 if (! strcmp (alpha_tp_string, "p"))
194 alpha_tp = ALPHA_TP_PROG;
195 else if (! strcmp (alpha_tp_string, "f"))
196 alpha_tp = ALPHA_TP_FUNC;
197 else if (! strcmp (alpha_tp_string, "i"))
198 alpha_tp = ALPHA_TP_INSN;
200 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
203 if (alpha_fprm_string)
205 if (! strcmp (alpha_fprm_string, "n"))
206 alpha_fprm = ALPHA_FPRM_NORM;
207 else if (! strcmp (alpha_fprm_string, "m"))
208 alpha_fprm = ALPHA_FPRM_MINF;
209 else if (! strcmp (alpha_fprm_string, "c"))
210 alpha_fprm = ALPHA_FPRM_CHOP;
211 else if (! strcmp (alpha_fprm_string,"d"))
212 alpha_fprm = ALPHA_FPRM_DYN;
214 error ("bad value `%s' for -mfp-rounding-mode switch",
218 if (alpha_fptm_string)
220 if (strcmp (alpha_fptm_string, "n") == 0)
221 alpha_fptm = ALPHA_FPTM_N;
222 else if (strcmp (alpha_fptm_string, "u") == 0)
223 alpha_fptm = ALPHA_FPTM_U;
224 else if (strcmp (alpha_fptm_string, "su") == 0)
225 alpha_fptm = ALPHA_FPTM_SU;
226 else if (strcmp (alpha_fptm_string, "sui") == 0)
227 alpha_fptm = ALPHA_FPTM_SUI;
229 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
233 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
234 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
236 if (alpha_cpu_string)
238 for (i = 0; cpu_table [i].name; i++)
239 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
241 alpha_cpu = cpu_table [i].processor;
242 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX
243 | MASK_CPU_EV5 | MASK_CPU_EV6);
244 target_flags |= cpu_table [i].flags;
247 if (! cpu_table [i].name)
248 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
251 if (alpha_tune_string)
253 for (i = 0; cpu_table [i].name; i++)
254 if (! strcmp (alpha_tune_string, cpu_table [i].name))
256 alpha_cpu = cpu_table [i].processor;
259 if (! cpu_table [i].name)
260 error ("bad value `%s' for -mcpu switch", alpha_tune_string);
263 /* Do some sanity checks on the above options. */
265 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
266 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
268 warning ("fp software completion requires -mtrap-precision=i");
269 alpha_tp = ALPHA_TP_INSN;
274 /* Except for EV6 pass 1 (not released), we always have precise
275 arithmetic traps. Which means we can do software completion
276 without minding trap shadows. */
277 alpha_tp = ALPHA_TP_PROG;
280 if (TARGET_FLOAT_VAX)
282 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
284 warning ("rounding mode not supported for VAX floats");
285 alpha_fprm = ALPHA_FPRM_NORM;
287 if (alpha_fptm == ALPHA_FPTM_SUI)
289 warning ("trap mode not supported for VAX floats");
290 alpha_fptm = ALPHA_FPTM_SU;
298 if (!alpha_mlat_string)
299 alpha_mlat_string = "L1";
301 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
302 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
304 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
305 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
306 && alpha_mlat_string[2] == '\0')
308 static int const cache_latency[][4] =
310 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
311 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
312 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
315 lat = alpha_mlat_string[1] - '0';
316 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
318 warning ("L%d cache latency unknown for %s",
319 lat, alpha_cpu_name[alpha_cpu]);
323 lat = cache_latency[alpha_cpu][lat-1];
325 else if (! strcmp (alpha_mlat_string, "main"))
327 /* Most current memories have about 370ns latency. This is
328 a reasonable guess for a fast cpu. */
333 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
337 alpha_memory_latency = lat;
340 /* Default the definition of "small data" to 8 bytes. */
344 /* Acquire a unique set number for our register saves and restores. */
345 alpha_sr_alias_set = new_alias_set ();
347 /* Set up function hooks. */
348 init_machine_status = alpha_init_machine_status;
349 mark_machine_status = alpha_mark_machine_status;
352 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
360 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
362 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
368 /* Returns 1 if OP is either the constant zero or a register. If a
369 register, it must be in the proper mode unless MODE is VOIDmode. */
372 reg_or_0_operand (op, mode)
374 enum machine_mode mode;
376 return op == const0_rtx || register_operand (op, mode);
379 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
383 reg_or_6bit_operand (op, mode)
385 enum machine_mode mode;
387 return ((GET_CODE (op) == CONST_INT
388 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
389 || register_operand (op, mode));
393 /* Return 1 if OP is an 8-bit constant or any register. */
396 reg_or_8bit_operand (op, mode)
398 enum machine_mode mode;
400 return ((GET_CODE (op) == CONST_INT
401 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
402 || register_operand (op, mode));
405 /* Return 1 if OP is an 8-bit constant. */
408 cint8_operand (op, mode)
410 enum machine_mode mode ATTRIBUTE_UNUSED;
412 return ((GET_CODE (op) == CONST_INT
413 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
416 /* Return 1 if the operand is a valid second operand to an add insn. */
419 add_operand (op, mode)
421 enum machine_mode mode;
423 if (GET_CODE (op) == CONST_INT)
424 /* Constraints I, J, O and P are covered by K. */
425 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
426 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
428 return register_operand (op, mode);
431 /* Return 1 if the operand is a valid second operand to a sign-extending
435 sext_add_operand (op, mode)
437 enum machine_mode mode;
439 if (GET_CODE (op) == CONST_INT)
440 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
441 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
443 return reg_not_elim_operand (op, mode);
446 /* Return 1 if OP is the constant 4 or 8. */
449 const48_operand (op, mode)
451 enum machine_mode mode ATTRIBUTE_UNUSED;
453 return (GET_CODE (op) == CONST_INT
454 && (INTVAL (op) == 4 || INTVAL (op) == 8));
457 /* Return 1 if OP is a valid first operand to an AND insn. */
460 and_operand (op, mode)
462 enum machine_mode mode;
464 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
465 return (zap_mask (CONST_DOUBLE_LOW (op))
466 && zap_mask (CONST_DOUBLE_HIGH (op)));
468 if (GET_CODE (op) == CONST_INT)
469 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
470 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
471 || zap_mask (INTVAL (op)));
473 return register_operand (op, mode);
476 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
479 or_operand (op, mode)
481 enum machine_mode mode;
483 if (GET_CODE (op) == CONST_INT)
484 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
485 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
487 return register_operand (op, mode);
490 /* Return 1 if OP is a constant that is the width, in bits, of an integral
491 mode smaller than DImode. */
494 mode_width_operand (op, mode)
496 enum machine_mode mode ATTRIBUTE_UNUSED;
498 return (GET_CODE (op) == CONST_INT
499 && (INTVAL (op) == 8 || INTVAL (op) == 16
500 || INTVAL (op) == 32 || INTVAL (op) == 64));
503 /* Return 1 if OP is a constant that is the width of an integral machine mode
504 smaller than an integer. */
507 mode_mask_operand (op, mode)
509 enum machine_mode mode ATTRIBUTE_UNUSED;
511 #if HOST_BITS_PER_WIDE_INT == 32
512 if (GET_CODE (op) == CONST_DOUBLE)
513 return (CONST_DOUBLE_LOW (op) == -1
514 && (CONST_DOUBLE_HIGH (op) == -1
515 || CONST_DOUBLE_HIGH (op) == 0));
517 if (GET_CODE (op) == CONST_DOUBLE)
518 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
521 return (GET_CODE (op) == CONST_INT
522 && (INTVAL (op) == 0xff
523 || INTVAL (op) == 0xffff
524 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
525 #if HOST_BITS_PER_WIDE_INT == 64
531 /* Return 1 if OP is a multiple of 8 less than 64. */
534 mul8_operand (op, mode)
536 enum machine_mode mode ATTRIBUTE_UNUSED;
538 return (GET_CODE (op) == CONST_INT
539 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
540 && (INTVAL (op) & 7) == 0);
543 /* Return 1 if OP is the constant zero in floating-point. */
546 fp0_operand (op, mode)
548 enum machine_mode mode;
550 return (GET_MODE (op) == mode
551 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
554 /* Return 1 if OP is the floating-point constant zero or a register. */
557 reg_or_fp0_operand (op, mode)
559 enum machine_mode mode;
561 return fp0_operand (op, mode) || register_operand (op, mode);
564 /* Return 1 if OP is a hard floating-point register. */
567 hard_fp_register_operand (op, mode)
569 enum machine_mode mode;
571 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
574 if (GET_CODE (op) == SUBREG)
575 op = SUBREG_REG (op);
576 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;
579 /* Return 1 if OP is a hard general register. */
582 hard_int_register_operand (op, mode)
584 enum machine_mode mode;
586 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
589 if (GET_CODE (op) == SUBREG)
590 op = SUBREG_REG (op);
591 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;
594 /* Return 1 if OP is a register or a constant integer. */
598 reg_or_cint_operand (op, mode)
600 enum machine_mode mode;
602 return (GET_CODE (op) == CONST_INT
603 || register_operand (op, mode));
606 /* Return 1 if OP is something that can be reloaded into a register;
607 if it is a MEM, it need not be valid. */
610 some_operand (op, mode)
612 enum machine_mode mode;
614 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
617 switch (GET_CODE (op))
619 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
620 case SYMBOL_REF: case CONST:
624 return some_operand (SUBREG_REG (op), VOIDmode);
633 /* Likewise, but don't accept constants. */
636 some_ni_operand (op, mode)
638 enum machine_mode mode;
640 if (GET_MODE (op) != mode && mode != VOIDmode)
643 if (GET_CODE (op) == SUBREG)
644 op = SUBREG_REG (op);
646 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
649 /* Return 1 if OP is a valid operand for the source of a move insn. */
652 input_operand (op, mode)
654 enum machine_mode mode;
656 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
659 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
662 switch (GET_CODE (op))
667 /* This handles both the Windows/NT and OSF cases. */
668 return mode == ptr_mode || mode == DImode;
675 if (register_operand (op, mode))
677 /* ... fall through ... */
679 return ((TARGET_BWX || (mode != HImode && mode != QImode))
680 && general_operand (op, mode));
683 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
686 return mode == QImode || mode == HImode || add_operand (op, mode);
698 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
702 current_file_function_operand (op, mode)
704 enum machine_mode mode ATTRIBUTE_UNUSED;
706 return (GET_CODE (op) == SYMBOL_REF
707 && ! profile_flag && ! profile_block_flag
708 && (SYMBOL_REF_FLAG (op)
709 || op == XEXP (DECL_RTL (current_function_decl), 0)));
712 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
715 call_operand (op, mode)
717 enum machine_mode mode;
722 return (GET_CODE (op) == SYMBOL_REF
723 || (GET_CODE (op) == REG
724 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
727 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
728 comparisons are valid in which insn. */
731 alpha_comparison_operator (op, mode)
733 enum machine_mode mode;
735 enum rtx_code code = GET_CODE (op);
737 if (mode != GET_MODE (op) && mode != VOIDmode)
740 return (code == EQ || code == LE || code == LT
741 || code == LEU || code == LTU);
744 /* Return 1 if OP is a valid Alpha comparison operator against zero.
745 Here we know which comparisons are valid in which insn. */
748 alpha_zero_comparison_operator (op, mode)
750 enum machine_mode mode;
752 enum rtx_code code = GET_CODE (op);
754 if (mode != GET_MODE (op) && mode != VOIDmode)
757 return (code == EQ || code == NE || code == LE || code == LT
758 || code == LEU || code == LTU);
761 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
764 alpha_swapped_comparison_operator (op, mode)
766 enum machine_mode mode;
768 enum rtx_code code = GET_CODE (op);
770 if ((mode != GET_MODE (op) && mode != VOIDmode)
771 || GET_RTX_CLASS (code) != '<')
774 code = swap_condition (code);
775 return (code == EQ || code == LE || code == LT
776 || code == LEU || code == LTU);
779 /* Return 1 if OP is a signed comparison operation. */
782 signed_comparison_operator (op, mode)
784 enum machine_mode mode ATTRIBUTE_UNUSED;
786 enum rtx_code code = GET_CODE (op);
788 if (mode != GET_MODE (op) && mode != VOIDmode)
791 return (code == EQ || code == NE
792 || code == LE || code == LT
793 || code == GE || code == GT);
796 /* Return 1 if OP is a valid Alpha floating point comparison operator.
797 Here we know which comparisons are valid in which insn. */
800 alpha_fp_comparison_operator (op, mode)
802 enum machine_mode mode;
804 enum rtx_code code = GET_CODE (op);
806 if (mode != GET_MODE (op) && mode != VOIDmode)
809 return (code == EQ || code == LE || code == LT || code == UNORDERED);
812 /* Return 1 if this is a divide or modulus operator. */
815 divmod_operator (op, mode)
817 enum machine_mode mode ATTRIBUTE_UNUSED;
819 switch (GET_CODE (op))
821 case DIV: case MOD: case UDIV: case UMOD:
831 /* Return 1 if this memory address is a known aligned register plus
832 a constant. It must be a valid address. This means that we can do
833 this as an aligned reference plus some offset.
835 Take into account what reload will do. */
838 aligned_memory_operand (op, mode)
840 enum machine_mode mode;
844 if (reload_in_progress)
847 if (GET_CODE (tmp) == SUBREG)
848 tmp = SUBREG_REG (tmp);
849 if (GET_CODE (tmp) == REG
850 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
852 op = reg_equiv_memory_loc[REGNO (tmp)];
858 if (GET_CODE (op) != MEM
859 || GET_MODE (op) != mode)
863 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
864 sorts of constructs. Dig for the real base register. */
865 if (reload_in_progress
866 && GET_CODE (op) == PLUS
867 && GET_CODE (XEXP (op, 0)) == PLUS)
868 base = XEXP (XEXP (op, 0), 0);
871 if (! memory_address_p (mode, op))
873 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
876 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
879 /* Similar, but return 1 if OP is a MEM which is not alignable. */
882 unaligned_memory_operand (op, mode)
884 enum machine_mode mode;
888 if (reload_in_progress)
891 if (GET_CODE (tmp) == SUBREG)
892 tmp = SUBREG_REG (tmp);
893 if (GET_CODE (tmp) == REG
894 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
896 op = reg_equiv_memory_loc[REGNO (tmp)];
902 if (GET_CODE (op) != MEM
903 || GET_MODE (op) != mode)
907 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
908 sorts of constructs. Dig for the real base register. */
909 if (reload_in_progress
910 && GET_CODE (op) == PLUS
911 && GET_CODE (XEXP (op, 0)) == PLUS)
912 base = XEXP (XEXP (op, 0), 0);
915 if (! memory_address_p (mode, op))
917 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
920 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
923 /* Return 1 if OP is either a register or an unaligned memory location. */
926 reg_or_unaligned_mem_operand (op, mode)
928 enum machine_mode mode;
930 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
933 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
936 any_memory_operand (op, mode)
938 enum machine_mode mode ATTRIBUTE_UNUSED;
940 return (GET_CODE (op) == MEM
941 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
942 || (reload_in_progress && GET_CODE (op) == REG
943 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
944 || (reload_in_progress && GET_CODE (op) == SUBREG
945 && GET_CODE (SUBREG_REG (op)) == REG
946 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
949 /* Returns 1 if OP is not an eliminable register.
951 This exists to cure a pathological abort in the s8addq (et al) patterns,
953 long foo () { long t; bar(); return (long) &t * 26107; }
955 which run afoul of a hack in reload to cure a (presumably) similar
956 problem with lea-type instructions on other targets. But there is
957 one of us and many of them, so work around the problem by selectively
958 preventing combine from making the optimization. */
961 reg_not_elim_operand (op, mode)
963 enum machine_mode mode;
966 if (GET_CODE (op) == SUBREG)
967 inner = SUBREG_REG (op);
968 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
971 return register_operand (op, mode);
974 /* Return 1 is OP is a memory location that is not a reference (using
975 an AND) to an unaligned location. Take into account what reload
979 normal_memory_operand (op, mode)
981 enum machine_mode mode ATTRIBUTE_UNUSED;
983 if (reload_in_progress)
986 if (GET_CODE (tmp) == SUBREG)
987 tmp = SUBREG_REG (tmp);
988 if (GET_CODE (tmp) == REG
989 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
991 op = reg_equiv_memory_loc[REGNO (tmp)];
993 /* This may not have been assigned an equivalent address if it will
994 be eliminated. In that case, it doesn't matter what we do. */
1000 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
1003 /* Accept a register, but not a subreg of any kind. This allows us to
1004 avoid pathological cases in reload wrt data movement common in
1005 int->fp conversion. */
1008 reg_no_subreg_operand (op, mode)
1010 enum machine_mode mode;
1012 if (GET_CODE (op) == SUBREG)
1014 return register_operand (op, mode);
1017 /* Recognize a addition operation that includes a constant. Used to
1018 convince reload to canonize (plus (plus reg c1) c2) during register
1022 addition_operation (op, mode)
1024 enum machine_mode mode;
1026 if (GET_MODE (op) != mode && mode != VOIDmode)
1028 if (GET_CODE (op) == PLUS
1029 && register_operand (XEXP (op, 0), mode)
1030 && GET_CODE (XEXP (op, 1)) == CONST_INT
1031 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
1036 /* Return 1 if this function can directly return via $26. */
1041 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
1042 && get_frame_size () == 0
1043 && current_function_outgoing_args_size == 0
1044 && current_function_pretend_args_size == 0);
1047 /* REF is an alignable memory location. Place an aligned SImode
1048 reference into *PALIGNED_MEM and the number of bits to shift into
1049 *PBITNUM. SCRATCH is a free register for use in reloading out
1050 of range stack slots. */
1053 get_aligned_mem (ref, paligned_mem, pbitnum)
1055 rtx *paligned_mem, *pbitnum;
1058 HOST_WIDE_INT offset = 0;
1060 if (GET_CODE (ref) != MEM)
1063 if (reload_in_progress
1064 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1066 base = find_replacement (&XEXP (ref, 0));
1068 if (! memory_address_p (GET_MODE (ref), base))
1073 base = XEXP (ref, 0);
1076 if (GET_CODE (base) == PLUS)
1077 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1079 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1080 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1082 /* Sadly, we cannot use alias sets here because we may overlap other
1083 data in a different alias set. */
1084 MEM_ALIAS_SET (*paligned_mem) = 0;
1086 *pbitnum = GEN_INT ((offset & 3) * 8);
1089 /* Similar, but just get the address. Handle the two reload cases.
1090 Add EXTRA_OFFSET to the address we return. */
1093 get_unaligned_address (ref, extra_offset)
1098 HOST_WIDE_INT offset = 0;
1100 if (GET_CODE (ref) != MEM)
1103 if (reload_in_progress
1104 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1106 base = find_replacement (&XEXP (ref, 0));
1108 if (! memory_address_p (GET_MODE (ref), base))
1113 base = XEXP (ref, 0);
1116 if (GET_CODE (base) == PLUS)
1117 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1119 return plus_constant (base, offset + extra_offset);
1122 /* Loading and storing HImode or QImode values to and from memory
1123 usually requires a scratch register. The exceptions are loading
1124 QImode and HImode from an aligned address to a general register
1125 unless byte instructions are permitted.
1127 We also cannot load an unaligned address or a paradoxical SUBREG
1128 into an FP register.
1130 We also cannot do integral arithmetic into FP regs, as might result
1131 from register elimination into a DImode fp register. */
1134 secondary_reload_class (class, mode, x, in)
1135 enum reg_class class;
1136 enum machine_mode mode;
1140 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1142 if (GET_CODE (x) == MEM
1143 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1144 || (GET_CODE (x) == SUBREG
1145 && (GET_CODE (SUBREG_REG (x)) == MEM
1146 || (GET_CODE (SUBREG_REG (x)) == REG
1147 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1149 if (!in || !aligned_memory_operand(x, mode))
1150 return GENERAL_REGS;
1154 if (class == FLOAT_REGS)
1156 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1157 return GENERAL_REGS;
1159 if (GET_CODE (x) == SUBREG
1160 && (GET_MODE_SIZE (GET_MODE (x))
1161 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1162 return GENERAL_REGS;
1164 if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
1165 return GENERAL_REGS;
1171 /* Subfunction of the following function. Update the flags of any MEM
1172 found in part of X. */
1175 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1177 int in_struct_p, volatile_p, unchanging_p;
1181 switch (GET_CODE (x))
1185 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1186 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1191 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1196 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1198 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1203 MEM_IN_STRUCT_P (x) = in_struct_p;
1204 MEM_VOLATILE_P (x) = volatile_p;
1205 RTX_UNCHANGING_P (x) = unchanging_p;
1206 /* Sadly, we cannot use alias sets because the extra aliasing
1207 produced by the AND interferes. Given that two-byte quantities
1208 are the only thing we would be able to differentiate anyway,
1209 there does not seem to be any point in convoluting the early
1210 out of the alias check. */
1211 /* MEM_ALIAS_SET (x) = alias_set; */
1219 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1220 perform a memory operation, look for any MEMs in either a SET_DEST or
1221 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1222 REF into each of the MEMs found. If REF is not a MEM, don't do
1226 alpha_set_memflags (insn, ref)
1230 int in_struct_p, volatile_p, unchanging_p;
1232 if (GET_CODE (ref) != MEM)
1235 in_struct_p = MEM_IN_STRUCT_P (ref);
1236 volatile_p = MEM_VOLATILE_P (ref);
1237 unchanging_p = RTX_UNCHANGING_P (ref);
1239 /* This is only called from alpha.md, after having had something
1240 generated from one of the insn patterns. So if everything is
1241 zero, the pattern is already up-to-date. */
1242 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1245 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1248 /* Try to output insns to set TARGET equal to the constant C if it can be
1249 done in less than N insns. Do all computations in MODE. Returns the place
1250 where the output has been placed if it can be done and the insns have been
1251 emitted. If it would take more than N insns, zero is returned and no
1252 insns and emitted. */
1255 alpha_emit_set_const (target, mode, c, n)
1257 enum machine_mode mode;
1264 /* Try 1 insn, then 2, then up to N. */
1265 for (i = 1; i <= n; i++)
1266 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1272 /* Internal routine for the above to check for N or below insns. */
1275 alpha_emit_set_const_1 (target, mode, c, n)
1277 enum machine_mode mode;
1283 /* Use a pseudo if highly optimizing and still generating RTL. */
1285 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1289 #if HOST_BITS_PER_WIDE_INT == 64
1290 /* We are only called for SImode and DImode. If this is SImode, ensure that
1291 we are sign extended to a full word. This does not make any sense when
1292 cross-compiling on a narrow machine. */
1295 c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1298 /* If this is a sign-extended 32-bit constant, we can do this in at most
1299 three insns, so do it if we have enough insns left. We always have
1300 a sign-extended 32-bit constant when compiling on a narrow machine. */
1302 if (HOST_BITS_PER_WIDE_INT != 64
1303 || c >> 31 == -1 || c >> 31 == 0)
1305 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1306 HOST_WIDE_INT tmp1 = c - low;
1307 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1308 HOST_WIDE_INT extra = 0;
1310 /* If HIGH will be interpreted as negative but the constant is
1311 positive, we must adjust it to do two ldha insns. */
1313 if ((high & 0x8000) != 0 && c >= 0)
1317 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1320 if (c == low || (low == 0 && extra == 0))
1322 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1323 but that meant that we can't handle INT_MIN on 32-bit machines
1324 (like NT/Alpha), because we recurse indefinitely through
1325 emit_move_insn to gen_movdi. So instead, since we know exactly
1326 what we want, create it explicitly. */
1329 target = gen_reg_rtx (mode);
1330 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1333 else if (n >= 2 + (extra != 0))
1335 temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
1338 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1339 subtarget, 0, OPTAB_WIDEN);
1341 return expand_binop (mode, add_optab, temp, GEN_INT (low),
1342 target, 0, OPTAB_WIDEN);
1346 /* If we couldn't do it that way, try some other methods. But if we have
1347 no instructions left, don't bother. Likewise, if this is SImode and
1348 we can't make pseudos, we can't do anything since the expand_binop
1349 and expand_unop calls will widen and try to make pseudos. */
1352 || (mode == SImode && ! rtx_equal_function_value_matters))
1355 /* Next, see if we can load a related constant and then shift and possibly
1356 negate it to get the constant we want. Try this once each increasing
1357 numbers of insns. */
1359 for (i = 1; i < n; i++)
1361 /* First, see if minus some low bits, we've an easy load of
1364 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1366 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
1367 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1368 target, 0, OPTAB_WIDEN);
1370 /* Next try complementing. */
1371 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1372 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1374 /* Next try to form a constant and do a left shift. We can do this
1375 if some low-order bits are zero; the exact_log2 call below tells
1376 us that information. The bits we are shifting out could be any
1377 value, but here we'll just try the 0- and sign-extended forms of
1378 the constant. To try to increase the chance of having the same
1379 constant in more than one insn, start at the highest number of
1380 bits to shift, but try all possibilities in case a ZAPNOT will
1383 if ((bits = exact_log2 (c & - c)) > 0)
1384 for (; bits > 0; bits--)
1385 if ((temp = (alpha_emit_set_const
1386 (subtarget, mode, c >> bits, i))) != 0
1387 || ((temp = (alpha_emit_set_const
1389 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1391 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1392 target, 0, OPTAB_WIDEN);
1394 /* Now try high-order zero bits. Here we try the shifted-in bits as
1395 all zero and all ones. Be careful to avoid shifting outside the
1396 mode and to avoid shifting outside the host wide int size. */
1397 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1398 confuse the recursive call and set all of the high 32 bits. */
1400 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1401 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1402 for (; bits > 0; bits--)
1403 if ((temp = alpha_emit_set_const (subtarget, mode,
1405 || ((temp = (alpha_emit_set_const
1407 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1410 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1411 target, 1, OPTAB_WIDEN);
1413 /* Now try high-order 1 bits. We get that with a sign-extension.
1414 But one bit isn't enough here. Be careful to avoid shifting outside
1415 the mode and to avoid shifting outside the host wide int size. */
1417 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1418 - floor_log2 (~ c) - 2)) > 0)
1419 for (; bits > 0; bits--)
1420 if ((temp = alpha_emit_set_const (subtarget, mode,
1422 || ((temp = (alpha_emit_set_const
1424 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1427 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1428 target, 0, OPTAB_WIDEN);
1431 #if HOST_BITS_PER_WIDE_INT == 64
1432 /* Finally, see if can load a value into the target that is the same as the
1433 constant except that all bytes that are 0 are changed to be 0xff. If we
1434 can, then we can do a ZAPNOT to obtain the desired constant. */
1437 for (i = 0; i < 64; i += 8)
1438 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1439 new |= (HOST_WIDE_INT) 0xff << i;
1441 /* We are only called for SImode and DImode. If this is SImode, ensure that
1442 we are sign extended to a full word. */
1445 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1447 if (new != c && new != -1
1448 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1449 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1450 target, 0, OPTAB_WIDEN);
1456 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1457 fall back to a straight forward decomposition. We do this to avoid
1458 exponential run times encountered when looking for longer sequences
1459 with alpha_emit_set_const. */
1462 alpha_emit_set_long_const (target, c1, c2)
1464 HOST_WIDE_INT c1, c2;
1466 HOST_WIDE_INT d1, d2, d3, d4;
1468 /* Decompose the entire word */
1469 #if HOST_BITS_PER_WIDE_INT >= 64
1470 if (c2 != -(c1 < 0))
1472 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1474 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1475 c1 = (c1 - d2) >> 32;
1476 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1478 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1482 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1484 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1488 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1490 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1495 /* Construct the high word */
1498 emit_move_insn (target, GEN_INT (d4));
1500 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1503 emit_move_insn (target, GEN_INT (d3));
1505 /* Shift it into place */
1506 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1508 /* Add in the low bits. */
1510 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1512 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1517 /* Generate an unsigned DImode to FP conversion. This is the same code
1518 optabs would emit if we didn't have TFmode patterns.
1520 For SFmode, this is the only construction I've found that can pass
1521 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
1522 intermediates will work, because you'll get intermediate rounding
1523 that ruins the end result. Some of this could be fixed by turning
1524 on round-to-positive-infinity, but that requires diddling the fpsr,
1525 which kills performance. I tried turning this around and converting
1526 to a negative number, so that I could turn on /m, but either I did
1527 it wrong or there's something else cause I wound up with the exact
1528 same single-bit error. There is a branch-less form of this same code:
1539 fcmoveq $f10,$f11,$f0
1541 I'm not using it because it's the same number of instructions as
1542 this branch-full form, and it has more serialized long latency
1543 instructions on the critical path.
1545 For DFmode, we can avoid rounding errors by breaking up the word
1546 into two pieces, converting them separately, and adding them back:
1548 LC0: .long 0,0x5f800000
1553 cpyse $f11,$f31,$f10
1554 cpyse $f31,$f11,$f11
1562 This doesn't seem to be a clear-cut win over the optabs form.
1563 It probably all depends on the distribution of numbers being
1564 converted -- in the optabs form, all but high-bit-set has a
1565 much lower minimum execution time. */
1568 alpha_emit_floatuns (operands)
1571 rtx neglab, donelab, i0, i1, f0, in, out;
1572 enum machine_mode mode;
1575 in = force_reg (DImode, operands[1]);
1576 mode = GET_MODE (out);
1577 neglab = gen_label_rtx ();
1578 donelab = gen_label_rtx ();
1579 i0 = gen_reg_rtx (DImode);
1580 i1 = gen_reg_rtx (DImode);
1581 f0 = gen_reg_rtx (mode);
1583 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0,
1586 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
1587 emit_jump_insn (gen_jump (donelab));
1590 emit_label (neglab);
1592 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
1593 emit_insn (gen_anddi3 (i1, in, const1_rtx));
1594 emit_insn (gen_iordi3 (i0, i0, i1));
1595 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
1596 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
1598 emit_label (donelab);
1601 /* Generate the comparison for a conditional branch. */
1604 alpha_emit_conditional_branch (code)
1607 enum rtx_code cmp_code, branch_code;
1608 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1609 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1612 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
1614 if (! TARGET_HAS_XFLOATING_LIBS)
1617 /* X_floating library comparison functions return
1621 Convert the compare against the raw return value. */
1623 if (code == UNORDERED || code == ORDERED)
1628 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
1630 alpha_compare.fp_p = 0;
1632 if (code == UNORDERED)
1634 else if (code == ORDERED)
1640 /* The general case: fold the comparison code to the types of compares
1641 that we have, choosing the branch as necessary. */
1644 case EQ: case LE: case LT: case LEU: case LTU:
1646 /* We have these compares: */
1647 cmp_code = code, branch_code = NE;
1652 /* These must be reversed. */
1653 cmp_code = reverse_condition (code), branch_code = EQ;
1656 case GE: case GT: case GEU: case GTU:
1657 /* For FP, we swap them, for INT, we reverse them. */
1658 if (alpha_compare.fp_p)
1660 cmp_code = swap_condition (code);
1662 tem = op0, op0 = op1, op1 = tem;
1666 cmp_code = reverse_condition (code);
1675 if (alpha_compare.fp_p)
1680 /* When we are not as concerned about non-finite values, and we
1681 are comparing against zero, we can branch directly. */
1682 if (op1 == CONST0_RTX (DFmode))
1683 cmp_code = NIL, branch_code = code;
1684 else if (op0 == CONST0_RTX (DFmode))
1686 /* Undo the swap we probably did just above. */
1687 tem = op0, op0 = op1, op1 = tem;
1688 branch_code = swap_condition (cmp_code);
1694 /* ??? We mark the the branch mode to be CCmode to prevent the
1695 compare and branch from being combined, since the compare
1696 insn follows IEEE rules that the branch does not. */
1697 branch_mode = CCmode;
1704 /* The following optimizations are only for signed compares. */
1705 if (code != LEU && code != LTU && code != GEU && code != GTU)
1707 /* Whee. Compare and branch against 0 directly. */
1708 if (op1 == const0_rtx)
1709 cmp_code = NIL, branch_code = code;
1711 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1712 bypass between logicals and br/cmov on EV5. But we don't want to
1713 force valid immediate constants into registers needlessly. */
1714 else if (GET_CODE (op1) == CONST_INT)
1716 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1718 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1719 && (CONST_OK_FOR_LETTER_P (n, 'K')
1720 || CONST_OK_FOR_LETTER_P (n, 'L')))
1722 cmp_code = PLUS, branch_code = code;
1728 if (!reg_or_0_operand (op0, DImode))
1729 op0 = force_reg (DImode, op0);
1730 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
1731 op1 = force_reg (DImode, op1);
1734 /* Emit an initial compare instruction, if necessary. */
1736 if (cmp_code != NIL)
1738 tem = gen_reg_rtx (cmp_mode);
1739 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1742 /* Zero the operands. */
1743 memset (&alpha_compare, 0, sizeof (alpha_compare));
1745 /* Return the branch comparison. */
1746 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1749 /* Certain simplifications can be done to make invalid setcc operations
1750 valid. Return the final comparison, or NULL if we can't work. */
1753 alpha_emit_setcc (code)
1756 enum rtx_code cmp_code;
1757 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1758 int fp_p = alpha_compare.fp_p;
1761 /* Zero the operands. */
1762 memset (&alpha_compare, 0, sizeof (alpha_compare));
1764 if (fp_p && GET_MODE (op0) == TFmode)
1766 if (! TARGET_HAS_XFLOATING_LIBS)
1769 /* X_floating library comparison functions return
1773 Convert the compare against the raw return value. */
1775 if (code == UNORDERED || code == ORDERED)
1780 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
1784 if (code == UNORDERED)
1786 else if (code == ORDERED)
1792 if (fp_p && !TARGET_FIX)
1795 /* The general case: fold the comparison code to the types of compares
1796 that we have, choosing the branch as necessary. */
1801 case EQ: case LE: case LT: case LEU: case LTU:
1803 /* We have these compares. */
1805 cmp_code = code, code = NE;
1809 if (!fp_p && op1 == const0_rtx)
1814 cmp_code = reverse_condition (code);
1818 case GE: case GT: case GEU: case GTU:
1819 /* These are normally need swapping, but for integer zero we have
1820 special patterns that recognize swapped operands. */
1821 if (!fp_p && op1 == const0_rtx)
1823 code = swap_condition (code);
1825 cmp_code = code, code = NE;
1826 tmp = op0, op0 = op1, op1 = tmp;
1835 if (!register_operand (op0, DImode))
1836 op0 = force_reg (DImode, op0);
1837 if (!reg_or_8bit_operand (op1, DImode))
1838 op1 = force_reg (DImode, op1);
1841 /* Emit an initial compare instruction, if necessary. */
1842 if (cmp_code != NIL)
1844 enum machine_mode mode = fp_p ? DFmode : DImode;
1846 tmp = gen_reg_rtx (mode);
1847 emit_insn (gen_rtx_SET (VOIDmode, tmp,
1848 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
1850 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
1854 /* Return the setcc comparison. */
1855 return gen_rtx_fmt_ee (code, DImode, op0, op1);
1859 /* Rewrite a comparison against zero CMP of the form
1860 (CODE (cc0) (const_int 0)) so it can be written validly in
1861 a conditional move (if_then_else CMP ...).
1862 If both of the operands that set cc0 are non-zero we must emit
1863 an insn to perform the compare (it can't be done within
1864 the conditional move). */
1866 alpha_emit_conditional_move (cmp, mode)
1868 enum machine_mode mode;
1870 enum rtx_code code = GET_CODE (cmp);
1871 enum rtx_code cmov_code = NE;
1872 rtx op0 = alpha_compare.op0;
1873 rtx op1 = alpha_compare.op1;
1874 int fp_p = alpha_compare.fp_p;
1875 enum machine_mode cmp_mode
1876 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1877 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1878 enum machine_mode cmov_mode = VOIDmode;
1879 int local_fast_math = flag_fast_math;
1882 /* Zero the operands. */
1883 memset (&alpha_compare, 0, sizeof (alpha_compare));
1885 if (fp_p != FLOAT_MODE_P (mode))
1887 enum rtx_code cmp_code;
1892 /* If we have fp<->int register move instructions, do a cmov by
1893 performing the comparison in fp registers, and move the
1894 zero/non-zero value to integer registers, where we can then
1895 use a normal cmov, or vice-versa. */
1899 case EQ: case LE: case LT: case LEU: case LTU:
1900 /* We have these compares. */
1901 cmp_code = code, code = NE;
1905 /* This must be reversed. */
1906 cmp_code = EQ, code = EQ;
1909 case GE: case GT: case GEU: case GTU:
1910 /* These must be swapped. */
1911 cmp_code = swap_condition (code);
1913 tem = op0, op0 = op1, op1 = tem;
1920 tem = gen_reg_rtx (cmp_op_mode);
1921 emit_insn (gen_rtx_SET (VOIDmode, tem,
1922 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1925 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1926 op0 = gen_lowpart (cmp_op_mode, tem);
1927 op1 = CONST0_RTX (cmp_op_mode);
1929 local_fast_math = 1;
1932 /* We may be able to use a conditional move directly.
1933 This avoids emitting spurious compares. */
1934 if (signed_comparison_operator (cmp, VOIDmode)
1935 && (!fp_p || local_fast_math)
1936 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1937 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1939 /* We can't put the comparison inside the conditional move;
1940 emit a compare instruction and put that inside the
1941 conditional move. Make sure we emit only comparisons we have;
1942 swap or reverse as necessary. */
1949 case EQ: case LE: case LT: case LEU: case LTU:
1950 /* We have these compares: */
1954 /* This must be reversed. */
1955 code = reverse_condition (code);
1959 case GE: case GT: case GEU: case GTU:
1960 /* These must be swapped. */
1961 code = swap_condition (code);
1962 tem = op0, op0 = op1, op1 = tem;
1971 if (!reg_or_0_operand (op0, DImode))
1972 op0 = force_reg (DImode, op0);
1973 if (!reg_or_8bit_operand (op1, DImode))
1974 op1 = force_reg (DImode, op1);
1977 /* ??? We mark the branch mode to be CCmode to prevent the compare
1978 and cmov from being combined, since the compare insn follows IEEE
1979 rules that the cmov does not. */
1980 if (fp_p && !local_fast_math)
1983 tem = gen_reg_rtx (cmp_op_mode);
1984 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1985 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1988 /* Simplify a conditional move of two constants into a setcc with
1989 arithmetic. This is done with a splitter since combine would
1990 just undo the work if done during code generation. It also catches
1991 cases we wouldn't have before cse. */
1994 alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
1996 rtx dest, cond, t_rtx, f_rtx;
1998 HOST_WIDE_INT t, f, diff;
1999 enum machine_mode mode;
2000 rtx target, subtarget, tmp;
2002 mode = GET_MODE (dest);
2007 if (((code == NE || code == EQ) && diff < 0)
2008 || (code == GE || code == GT))
2010 code = reverse_condition (code);
2011 diff = t, t = f, f = diff;
2015 subtarget = target = dest;
2018 target = gen_lowpart (DImode, dest);
2019 if (! no_new_pseudos)
2020 subtarget = gen_reg_rtx (DImode);
2025 if (f == 0 && exact_log2 (diff) > 0
2026 /* On EV6, we've got enough shifters to make non-arithmatic shifts
2027 viable over a longer latency cmove. On EV5, the E0 slot is a
2028 scarce resource, and on EV4 shift has the same latency as a cmove. */
2029 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2031 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2032 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2034 tmp = gen_rtx_ASHIFT (DImode, subtarget, GEN_INT (exact_log2 (t)));
2035 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2037 else if (f == 0 && t == -1)
2039 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2040 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2042 emit_insn (gen_negdi2 (target, subtarget));
2044 else if (diff == 1 || diff == 4 || diff == 8)
2048 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2049 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2052 emit_insn (gen_adddi3 (target, subtarget, GEN_INT (f)));
2055 add_op = GEN_INT (f);
2056 if (sext_add_operand (add_op, mode))
2058 tmp = gen_rtx_MULT (DImode, subtarget, GEN_INT (diff));
2059 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2060 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2072 /* Look up the function X_floating library function name for the
2076 alpha_lookup_xfloating_lib_func (code)
2085 static const struct xfloating_op vms_xfloating_ops[] =
2087 { PLUS, "OTS$ADD_X" },
2088 { MINUS, "OTS$SUB_X" },
2089 { MULT, "OTS$MUL_X" },
2090 { DIV, "OTS$DIV_X" },
2091 { EQ, "OTS$EQL_X" },
2092 { NE, "OTS$NEQ_X" },
2093 { LT, "OTS$LSS_X" },
2094 { LE, "OTS$LEQ_X" },
2095 { GT, "OTS$GTR_X" },
2096 { GE, "OTS$GEQ_X" },
2097 { FIX, "OTS$CVTXQ" },
2098 { FLOAT, "OTS$CVTQX" },
2099 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
2100 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
2101 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
2104 static const struct xfloating_op osf_xfloating_ops[] =
2106 { PLUS, "_OtsAddX" },
2107 { MINUS, "_OtsSubX" },
2108 { MULT, "_OtsMulX" },
2109 { DIV, "_OtsDivX" },
2116 { FIX, "_OtsCvtXQ" },
2117 { FLOAT, "_OtsCvtQX" },
2118 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
2119 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
2120 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
2123 const struct xfloating_op *ops;
2124 const long n = ARRAY_SIZE (osf_xfloating_ops);
2127 /* How irritating. Nothing to key off for the table. Hardcode
2128 knowledge of the G_floating routines. */
2129 if (TARGET_FLOAT_VAX)
2131 if (TARGET_OPEN_VMS)
2133 if (code == FLOAT_EXTEND)
2134 return "OTS$CVT_FLOAT_G_X";
2135 if (code == FLOAT_TRUNCATE)
2136 return "OTS$CVT_FLOAT_X_G";
2140 if (code == FLOAT_EXTEND)
2141 return "_OtsConvertFloatGX";
2142 if (code == FLOAT_TRUNCATE)
2143 return "_OtsConvertFloatXG";
2147 if (TARGET_OPEN_VMS)
2148 ops = vms_xfloating_ops;
2150 ops = osf_xfloating_ops;
2152 for (i = 0; i < n; ++i)
2153 if (ops[i].code == code)
2159 /* Most X_floating operations take the rounding mode as an argument.
2160 Compute that here. */
2163 alpha_compute_xfloating_mode_arg (code, round)
2165 enum alpha_fp_rounding_mode round;
2171 case ALPHA_FPRM_NORM:
2174 case ALPHA_FPRM_MINF:
2177 case ALPHA_FPRM_CHOP:
2180 case ALPHA_FPRM_DYN:
2186 /* XXX For reference, round to +inf is mode = 3. */
2189 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2195 /* Emit an X_floating library function call.
2197 Note that these functions do not follow normal calling conventions:
2198 TFmode arguments are passed in two integer registers (as opposed to
2199 indirect); TFmode return values appear in R16+R17.
2201 FUNC is the function name to call.
2202 TARGET is where the output belongs.
2203 OPERANDS are the inputs.
2204 NOPERANDS is the count of inputs.
2205 EQUIV is the expression equivalent for the function.
2209 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
2216 rtx usage = NULL_RTX, tmp, reg;
2221 for (i = 0; i < noperands; ++i)
2223 switch (GET_MODE (operands[i]))
2226 reg = gen_rtx_REG (TFmode, regno);
2231 reg = gen_rtx_REG (DFmode, regno + 32);
2236 if (GET_CODE (operands[i]) != CONST_INT)
2240 reg = gen_rtx_REG (DImode, regno);
2248 emit_move_insn (reg, operands[i]);
2249 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2252 switch (GET_MODE (target))
2255 reg = gen_rtx_REG (TFmode, 16);
2258 reg = gen_rtx_REG (DFmode, 32);
2261 reg = gen_rtx_REG (DImode, 0);
2267 tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
2268 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2269 const0_rtx, const0_rtx));
2270 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2275 emit_libcall_block (tmp, target, reg, equiv);
2278 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2281 alpha_emit_xfloating_arith (code, operands)
2287 rtx out_operands[3];
2289 func = alpha_lookup_xfloating_lib_func (code);
2290 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2292 out_operands[0] = operands[1];
2293 out_operands[1] = operands[2];
2294 out_operands[2] = GEN_INT (mode);
2295 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2296 gen_rtx_fmt_ee (code, TFmode, operands[1],
2300 /* Emit an X_floating library function call for a comparison. */
2303 alpha_emit_xfloating_compare (code, op0, op1)
2308 rtx out, operands[2];
2310 func = alpha_lookup_xfloating_lib_func (code);
2314 out = gen_reg_rtx (DImode);
2316 /* ??? Strange equiv cause what's actually returned is -1,0,1, not a
2317 proper boolean value. */
2318 alpha_emit_xfloating_libcall (func, out, operands, 2,
2319 gen_rtx_COMPARE (TFmode, op0, op1));
2324 /* Emit an X_floating library function call for a conversion. */
2327 alpha_emit_xfloating_cvt (code, operands)
2331 int noperands = 1, mode;
2332 rtx out_operands[2];
2335 func = alpha_lookup_xfloating_lib_func (code);
2337 out_operands[0] = operands[1];
2342 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2343 out_operands[1] = GEN_INT (mode);
2346 case FLOAT_TRUNCATE:
2347 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2348 out_operands[1] = GEN_INT (mode);
2355 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
2356 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
2361 alpha_split_tfmode_pair (operands)
2364 if (GET_CODE (operands[1]) == REG)
2366 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
2367 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
2369 else if (GET_CODE (operands[1]) == MEM)
2371 operands[3] = change_address (operands[1], DImode,
2372 plus_constant (XEXP (operands[1], 0), 8));
2373 operands[2] = change_address (operands[1], DImode, NULL_RTX);
2375 else if (operands[1] == CONST0_RTX (TFmode))
2376 operands[2] = operands[3] = const0_rtx;
2380 if (GET_CODE (operands[0]) == REG)
2382 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
2383 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
2385 else if (GET_CODE (operands[0]) == MEM)
2387 operands[1] = change_address (operands[0], DImode,
2388 plus_constant (XEXP (operands[0], 0), 8));
2389 operands[0] = change_address (operands[0], DImode, NULL_RTX);
2395 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
2399 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
2400 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
2401 lda r3,X(r11) lda r3,X+2(r11)
2402 extwl r1,r3,r1 extql r1,r3,r1
2403 extwh r2,r3,r2 extqh r2,r3,r2
2404 or r1.r2.r1 or r1,r2,r1
2407 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
2408 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
2409 lda r3,X(r11) lda r3,X(r11)
2410 extll r1,r3,r1 extll r1,r3,r1
2411 extlh r2,r3,r2 extlh r2,r3,r2
2412 or r1.r2.r1 addl r1,r2,r1
2414 quad: ldq_u r1,X(r11)
2423 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
2425 HOST_WIDE_INT size, ofs;
2428 rtx meml, memh, addr, extl, exth, tmp;
2429 enum machine_mode mode;
2431 meml = gen_reg_rtx (DImode);
2432 memh = gen_reg_rtx (DImode);
2433 addr = gen_reg_rtx (DImode);
2434 extl = gen_reg_rtx (DImode);
2435 exth = gen_reg_rtx (DImode);
2437 /* AND addresses cannot be in any alias set, since they may implicitly
2438 alias surrounding code. Ideally we'd have some alias set that
2439 covered all types except those with alignment 8 or higher. */
2441 tmp = change_address (mem, DImode,
2442 gen_rtx_AND (DImode,
2443 plus_constant (XEXP (mem, 0), ofs),
2445 MEM_ALIAS_SET (tmp) = 0;
2446 emit_move_insn (meml, tmp);
2448 tmp = change_address (mem, DImode,
2449 gen_rtx_AND (DImode,
2450 plus_constant (XEXP (mem, 0),
2453 MEM_ALIAS_SET (tmp) = 0;
2454 emit_move_insn (memh, tmp);
2456 if (sign && size == 2)
2458 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
2460 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
2461 emit_insn (gen_extqh (exth, memh, addr));
2463 /* We must use tgt here for the target. Alpha-vms port fails if we use
2464 addr for the target, because addr is marked as a pointer and combine
2465 knows that pointers are always sign-extended 32 bit values. */
2466 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
2467 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
2468 addr, 1, OPTAB_WIDEN);
2472 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
2473 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
2477 emit_insn (gen_extwh (exth, memh, addr));
2482 emit_insn (gen_extlh (exth, memh, addr));
2487 emit_insn (gen_extqh (exth, memh, addr));
2495 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
2496 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
2501 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
2504 /* Similarly, use ins and msk instructions to perform unaligned stores. */
2507 alpha_expand_unaligned_store (dst, src, size, ofs)
2509 HOST_WIDE_INT size, ofs;
2511 rtx dstl, dsth, addr, insl, insh, meml, memh;
2513 dstl = gen_reg_rtx (DImode);
2514 dsth = gen_reg_rtx (DImode);
2515 insl = gen_reg_rtx (DImode);
2516 insh = gen_reg_rtx (DImode);
2518 /* AND addresses cannot be in any alias set, since they may implicitly
2519 alias surrounding code. Ideally we'd have some alias set that
2520 covered all types except those with alignment 8 or higher. */
2522 meml = change_address (dst, DImode,
2523 gen_rtx_AND (DImode,
2524 plus_constant (XEXP (dst, 0), ofs),
2526 MEM_ALIAS_SET (meml) = 0;
2528 memh = change_address (dst, DImode,
2529 gen_rtx_AND (DImode,
2530 plus_constant (XEXP (dst, 0),
2533 MEM_ALIAS_SET (memh) = 0;
2535 emit_move_insn (dsth, memh);
2536 emit_move_insn (dstl, meml);
2537 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
2539 if (src != const0_rtx)
2541 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
2542 GEN_INT (size*8), addr));
2547 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
2550 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
2553 emit_insn (gen_insql (insl, src, addr));
2558 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
2563 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
2566 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
2570 #if HOST_BITS_PER_WIDE_INT == 32
2571 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
2573 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
2575 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
2580 if (src != const0_rtx)
2582 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
2583 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
2586 /* Must store high before low for degenerate case of aligned. */
2587 emit_move_insn (memh, dsth);
2588 emit_move_insn (meml, dstl);
2591 /* The block move code tries to maximize speed by separating loads and
2592 stores at the expense of register pressure: we load all of the data
2593 before we store it back out. There are two secondary effects worth
2594 mentioning, that this speeds copying to/from aligned and unaligned
2595 buffers, and that it makes the code significantly easier to write. */
2597 #define MAX_MOVE_WORDS 8
2599 /* Load an integral number of consecutive unaligned quadwords. */
2602 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
2605 HOST_WIDE_INT words, ofs;
2607 rtx const im8 = GEN_INT (-8);
2608 rtx const i64 = GEN_INT (64);
2609 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
2610 rtx sreg, areg, tmp;
2613 /* Generate all the tmp registers we need. */
2614 for (i = 0; i < words; ++i)
2616 data_regs[i] = out_regs[i];
2617 ext_tmps[i] = gen_reg_rtx (DImode);
2619 data_regs[words] = gen_reg_rtx (DImode);
2622 smem = change_address (smem, GET_MODE (smem),
2623 plus_constant (XEXP (smem, 0), ofs));
2625 /* Load up all of the source data. */
2626 for (i = 0; i < words; ++i)
2628 tmp = change_address (smem, DImode,
2629 gen_rtx_AND (DImode,
2630 plus_constant (XEXP(smem,0), 8*i),
2632 MEM_ALIAS_SET (tmp) = 0;
2633 emit_move_insn (data_regs[i], tmp);
2636 tmp = change_address (smem, DImode,
2637 gen_rtx_AND (DImode,
2638 plus_constant (XEXP(smem,0), 8*words - 1),
2640 MEM_ALIAS_SET (tmp) = 0;
2641 emit_move_insn (data_regs[words], tmp);
2643 /* Extract the half-word fragments. Unfortunately DEC decided to make
2644 extxh with offset zero a noop instead of zeroing the register, so
2645 we must take care of that edge condition ourselves with cmov. */
2647 sreg = copy_addr_to_reg (XEXP (smem, 0));
2648 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
2650 for (i = 0; i < words; ++i)
2652 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
2654 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
2655 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
2656 gen_rtx_IF_THEN_ELSE (DImode,
2657 gen_rtx_EQ (DImode, areg,
2659 const0_rtx, ext_tmps[i])));
2662 /* Merge the half-words into whole words. */
2663 for (i = 0; i < words; ++i)
2665 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
2666 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
2670 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
2671 may be NULL to store zeros. */
2674 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
2677 HOST_WIDE_INT words, ofs;
2679 rtx const im8 = GEN_INT (-8);
2680 rtx const i64 = GEN_INT (64);
2681 #if HOST_BITS_PER_WIDE_INT == 32
2682 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
2684 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
2686 rtx ins_tmps[MAX_MOVE_WORDS];
2687 rtx st_tmp_1, st_tmp_2, dreg;
2688 rtx st_addr_1, st_addr_2;
2691 /* Generate all the tmp registers we need. */
2692 if (data_regs != NULL)
2693 for (i = 0; i < words; ++i)
2694 ins_tmps[i] = gen_reg_rtx(DImode);
2695 st_tmp_1 = gen_reg_rtx(DImode);
2696 st_tmp_2 = gen_reg_rtx(DImode);
2699 dmem = change_address (dmem, GET_MODE (dmem),
2700 plus_constant (XEXP (dmem, 0), ofs));
2703 st_addr_2 = change_address (dmem, DImode,
2704 gen_rtx_AND (DImode,
2705 plus_constant (XEXP(dmem,0),
2708 MEM_ALIAS_SET (st_addr_2) = 0;
2710 st_addr_1 = change_address (dmem, DImode,
2711 gen_rtx_AND (DImode,
2714 MEM_ALIAS_SET (st_addr_1) = 0;
2716 /* Load up the destination end bits. */
2717 emit_move_insn (st_tmp_2, st_addr_2);
2718 emit_move_insn (st_tmp_1, st_addr_1);
2720 /* Shift the input data into place. */
2721 dreg = copy_addr_to_reg (XEXP (dmem, 0));
2722 if (data_regs != NULL)
2724 for (i = words-1; i >= 0; --i)
2726 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
2727 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2729 for (i = words-1; i > 0; --i)
2731 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2732 ins_tmps[i-1], ins_tmps[i-1], 1,
2737 /* Split and merge the ends with the destination data. */
2738 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2739 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2741 if (data_regs != NULL)
2743 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2744 st_tmp_2, 1, OPTAB_WIDEN);
2745 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2746 st_tmp_1, 1, OPTAB_WIDEN);
2750 emit_move_insn (st_addr_2, st_tmp_2);
2751 for (i = words-1; i > 0; --i)
2753 rtx tmp = change_address (dmem, DImode,
2754 gen_rtx_AND (DImode,
2755 plus_constant(XEXP (dmem,0), i*8),
2757 MEM_ALIAS_SET (tmp) = 0;
2758 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
2760 emit_move_insn (st_addr_1, st_tmp_1);
2764 /* Expand string/block move operations.
2766 operands[0] is the pointer to the destination.
2767 operands[1] is the pointer to the source.
2768 operands[2] is the number of bytes to move.
2769 operands[3] is the alignment. */
2772 alpha_expand_block_move (operands)
2775 rtx bytes_rtx = operands[2];
2776 rtx align_rtx = operands[3];
2777 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2778 unsigned HOST_WIDE_INT bytes = orig_bytes;
2779 unsigned HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
2780 unsigned HOST_WIDE_INT dst_align = src_align;
2781 rtx orig_src = operands[1];
2782 rtx orig_dst = operands[0];
2783 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
2785 unsigned int i, words, ofs, nregs = 0;
2787 if (orig_bytes <= 0)
2789 else if (bytes > MAX_MOVE_WORDS * BITS_PER_UNIT)
2792 /* Look for additional alignment information from recorded register info. */
2794 tmp = XEXP (orig_src, 0);
2795 if (GET_CODE (tmp) == REG)
2796 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2797 else if (GET_CODE (tmp) == PLUS
2798 && GET_CODE (XEXP (tmp, 0)) == REG
2799 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2801 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2802 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2806 if (a >= 64 && c % 8 == 0)
2808 else if (a >= 32 && c % 4 == 0)
2810 else if (a >= 16 && c % 2 == 0)
2815 tmp = XEXP (orig_dst, 0);
2816 if (GET_CODE (tmp) == REG)
2817 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2818 else if (GET_CODE (tmp) == PLUS
2819 && GET_CODE (XEXP (tmp, 0)) == REG
2820 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2822 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2823 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2827 if (a >= 64 && c % 8 == 0)
2829 else if (a >= 32 && c % 4 == 0)
2831 else if (a >= 16 && c % 2 == 0)
2836 /* Load the entire block into registers. */
2837 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2839 enum machine_mode mode;
2841 tmp = XEXP (XEXP (orig_src, 0), 0);
2843 /* Don't use the existing register if we're reading more than
2844 is held in the register. Nor if there is not a mode that
2845 handles the exact size. */
2846 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2848 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2852 data_regs[nregs] = gen_lowpart (DImode, tmp);
2853 data_regs[nregs+1] = gen_highpart (DImode, tmp);
2857 data_regs[nregs++] = gen_lowpart (mode, tmp);
2862 /* No appropriate mode; fall back on memory. */
2863 orig_src = change_address (orig_src, GET_MODE (orig_src),
2864 copy_addr_to_reg (XEXP (orig_src, 0)));
2868 if (src_align >= 64 && bytes >= 8)
2872 for (i = 0; i < words; ++i)
2873 data_regs[nregs + i] = gen_reg_rtx(DImode);
2875 for (i = 0; i < words; ++i)
2876 emit_move_insn (data_regs[nregs + i],
2877 change_address (orig_src, DImode,
2878 plus_constant (XEXP (orig_src, 0),
2886 if (src_align >= 32 && bytes >= 4)
2890 for (i = 0; i < words; ++i)
2891 data_regs[nregs + i] = gen_reg_rtx(SImode);
2893 for (i = 0; i < words; ++i)
2894 emit_move_insn (data_regs[nregs + i],
2895 change_address (orig_src, SImode,
2896 plus_constant (XEXP (orig_src, 0),
2908 for (i = 0; i < words+1; ++i)
2909 data_regs[nregs + i] = gen_reg_rtx(DImode);
2911 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2919 if (! TARGET_BWX && bytes >= 8)
2921 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2922 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2927 if (! TARGET_BWX && bytes >= 4)
2929 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2930 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2937 if (src_align >= 16)
2940 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2941 emit_move_insn (tmp,
2942 change_address (orig_src, HImode,
2943 plus_constant (XEXP (orig_src, 0),
2947 } while (bytes >= 2);
2950 else if (! TARGET_BWX)
2952 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2953 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2961 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2962 emit_move_insn (tmp,
2963 change_address (orig_src, QImode,
2964 plus_constant (XEXP (orig_src, 0),
2972 if (nregs > ARRAY_SIZE (data_regs))
2975 /* Now save it back out again. */
2979 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2981 enum machine_mode mode;
2982 tmp = XEXP (XEXP (orig_dst, 0), 0);
2984 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2985 if (GET_MODE (tmp) == mode)
2989 emit_move_insn (tmp, data_regs[0]);
2994 else if (nregs == 2 && mode == TImode)
2996 /* Undo the subregging done above when copying between
2997 two TImode registers. */
2998 if (GET_CODE (data_regs[0]) == SUBREG
2999 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
3000 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
3006 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
3007 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
3011 emit_no_conflict_block (seq, tmp, data_regs[0],
3012 data_regs[1], NULL_RTX);
3020 /* ??? If nregs > 1, consider reconstructing the word in regs. */
3021 /* ??? Optimize mode < dst_mode with strict_low_part. */
3023 /* No appropriate mode; fall back on memory. We can speed things
3024 up by recognizing extra alignment information. */
3025 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
3026 copy_addr_to_reg (XEXP (orig_dst, 0)));
3027 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
3030 /* Write out the data in whatever chunks reading the source allowed. */
3031 if (dst_align >= 64)
3033 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3035 emit_move_insn (change_address (orig_dst, DImode,
3036 plus_constant (XEXP (orig_dst, 0),
3044 if (dst_align >= 32)
3046 /* If the source has remaining DImode regs, write them out in
3048 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3050 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3051 NULL_RTX, 1, OPTAB_WIDEN);
3053 emit_move_insn (change_address (orig_dst, SImode,
3054 plus_constant (XEXP (orig_dst, 0),
3056 gen_lowpart (SImode, data_regs[i]));
3057 emit_move_insn (change_address (orig_dst, SImode,
3058 plus_constant (XEXP (orig_dst, 0),
3060 gen_lowpart (SImode, tmp));
3065 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3067 emit_move_insn (change_address(orig_dst, SImode,
3068 plus_constant (XEXP (orig_dst, 0),
3076 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3078 /* Write out a remaining block of words using unaligned methods. */
3080 for (words = 1; i + words < nregs; words++)
3081 if (GET_MODE (data_regs[i + words]) != DImode)
3085 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3087 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3094 /* Due to the above, this won't be aligned. */
3095 /* ??? If we have more than one of these, consider constructing full
3096 words in registers and using alpha_expand_unaligned_store_words. */
3097 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3099 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3104 if (dst_align >= 16)
3105 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3107 emit_move_insn (change_address (orig_dst, HImode,
3108 plus_constant (XEXP (orig_dst, 0),
3115 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3117 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3122 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
3124 emit_move_insn (change_address (orig_dst, QImode,
3125 plus_constant (XEXP (orig_dst, 0),
3141 alpha_expand_block_clear (operands)
3144 rtx bytes_rtx = operands[1];
3145 rtx align_rtx = operands[2];
3146 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3147 unsigned HOST_WIDE_INT bytes = orig_bytes;
3148 unsigned HOST_WIDE_INT align = INTVAL (align_rtx);
3149 rtx orig_dst = operands[0];
3151 unsigned HOST_WIDE_INT i, words, ofs = 0;
3153 if (orig_bytes <= 0)
3155 if (bytes > MAX_MOVE_WORDS*8)
3158 /* Look for stricter alignment. */
3159 tmp = XEXP (orig_dst, 0);
3160 if (GET_CODE (tmp) == REG)
3161 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3162 else if (GET_CODE (tmp) == PLUS
3163 && GET_CODE (XEXP (tmp, 0)) == REG
3164 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3166 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3167 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3171 if (a >= 64 && c % 8 == 0)
3173 else if (a >= 32 && c % 4 == 0)
3175 else if (a >= 16 && c % 2 == 0)
3180 else if (GET_CODE (tmp) == ADDRESSOF)
3182 enum machine_mode mode;
3184 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
3185 if (GET_MODE (XEXP (tmp, 0)) == mode)
3187 emit_move_insn (XEXP (tmp, 0), const0_rtx);
3191 /* No appropriate mode; fall back on memory. */
3192 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
3193 copy_addr_to_reg (tmp));
3194 align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));
3197 /* Handle a block of contiguous words first. */
3199 if (align >= 64 && bytes >= 8)
3203 for (i = 0; i < words; ++i)
3204 emit_move_insn (change_address(orig_dst, DImode,
3205 plus_constant (XEXP (orig_dst, 0),
3213 if (align >= 16 && bytes >= 4)
3217 for (i = 0; i < words; ++i)
3218 emit_move_insn (change_address (orig_dst, SImode,
3219 plus_constant (XEXP (orig_dst, 0),
3231 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
3237 /* Next clean up any trailing pieces. We know from the contiguous
3238 block move that there are no aligned SImode or DImode hunks left. */
3240 if (! TARGET_BWX && bytes >= 8)
3242 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
3247 if (!TARGET_BWX && bytes >= 4)
3249 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
3259 emit_move_insn (change_address (orig_dst, HImode,
3260 plus_constant (XEXP (orig_dst, 0),
3265 } while (bytes >= 2);
3267 else if (! TARGET_BWX)
3269 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
3277 emit_move_insn (change_address (orig_dst, QImode,
3278 plus_constant (XEXP (orig_dst, 0),
3288 /* Adjust the cost of a scheduling dependency. Return the new cost of
3289 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
3292 alpha_adjust_cost (insn, link, dep_insn, cost)
3299 enum attr_type insn_type, dep_insn_type;
3301 /* If the dependence is an anti-dependence, there is no cost. For an
3302 output dependence, there is sometimes a cost, but it doesn't seem
3303 worth handling those few cases. */
3305 if (REG_NOTE_KIND (link) != 0)
3308 /* If we can't recognize the insns, we can't really do anything. */
3309 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3312 insn_type = get_attr_type (insn);
3313 dep_insn_type = get_attr_type (dep_insn);
3315 /* Bring in the user-defined memory latency. */
3316 if (dep_insn_type == TYPE_ILD
3317 || dep_insn_type == TYPE_FLD
3318 || dep_insn_type == TYPE_LDSYM)
3319 cost += alpha_memory_latency-1;
3324 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
3325 being stored, we can sometimes lower the cost. */
3327 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
3328 && (set = single_set (dep_insn)) != 0
3329 && GET_CODE (PATTERN (insn)) == SET
3330 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
3332 switch (dep_insn_type)
3336 /* No savings here. */
3340 /* In these cases, we save one cycle. */
3344 /* In all other cases, we save two cycles. */
3345 return MAX (0, cost - 2);
3349 /* Another case that needs adjustment is an arithmetic or logical
3350 operation. It's cost is usually one cycle, but we default it to
3351 two in the MD file. The only case that it is actually two is
3352 for the address in loads, stores, and jumps. */
3354 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
3369 /* The final case is when a compare feeds into an integer branch;
3370 the cost is only one cycle in that case. */
3372 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
3377 /* And the lord DEC saith: "A special bypass provides an effective
3378 latency of 0 cycles for an ICMP or ILOG insn producing the test
3379 operand of an IBR or ICMOV insn." */
3381 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
3382 && (set = single_set (dep_insn)) != 0)
3384 /* A branch only has one input. This must be it. */
3385 if (insn_type == TYPE_IBR)
3387 /* A conditional move has three, make sure it is the test. */
3388 if (insn_type == TYPE_ICMOV
3389 && GET_CODE (set_src = PATTERN (insn)) == SET
3390 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
3391 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
3395 /* "The multiplier is unable to receive data from IEU bypass paths.
3396 The instruction issues at the expected time, but its latency is
3397 increased by the time it takes for the input data to become
3398 available to the multiplier" -- which happens in pipeline stage
3399 six, when results are comitted to the register file. */
3401 if (insn_type == TYPE_IMUL)
3403 switch (dep_insn_type)
3405 /* These insns produce their results in pipeline stage five. */
3412 /* Other integer insns produce results in pipeline stage four. */
3420 /* There is additional latency to move the result of (most) FP
3421 operations anywhere but the FP register file. */
3423 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
3424 && (dep_insn_type == TYPE_FADD ||
3425 dep_insn_type == TYPE_FMUL ||
3426 dep_insn_type == TYPE_FCMOV))
3432 /* Otherwise, return the default cost. */
3436 /* Functions to save and restore alpha_return_addr_rtx. */
3439 alpha_init_machine_status (p)
3443 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
3447 alpha_mark_machine_status (p)
3450 struct machine_function *machine = p->machine;
3452 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
3453 ggc_mark_rtx (machine->ra_rtx);
3456 /* Start the ball rolling with RETURN_ADDR_RTX. */
3459 alpha_return_addr (count, frame)
3461 rtx frame ATTRIBUTE_UNUSED;
3468 reg = cfun->machine->ra_rtx;
3471 /* No rtx yet. Invent one, and initialize it from $26 in
3473 reg = gen_reg_rtx (Pmode);
3474 cfun->machine->ra_rtx = reg;
3475 init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
3477 /* Emit the insn to the prologue with the other argument copies. */
3478 push_topmost_sequence ();
3479 emit_insn_after (init, get_insns ());
3480 pop_topmost_sequence ();
3487 alpha_ra_ever_killed ()
3491 #ifdef ASM_OUTPUT_MI_THUNK
3492 if (current_function_is_thunk)
3495 if (!cfun->machine->ra_rtx)
3496 return regs_ever_live[REG_RA];
3498 push_topmost_sequence ();
3500 pop_topmost_sequence ();
3502 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
3506 /* Print an operand. Recognize special options, documented below. */
3509 print_operand (file, x, code)
3519 /* Print the assembler name of the current function. */
3520 assemble_name (file, alpha_fnname);
3524 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
3525 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
3526 mode. alpha_fprm controls which suffix is generated. */
3529 case ALPHA_FPRM_NORM:
3531 case ALPHA_FPRM_MINF:
3534 case ALPHA_FPRM_CHOP:
3537 case ALPHA_FPRM_DYN:
3546 /* Generates trap-mode suffix for instructions that accept the su
3547 suffix only (cmpt et al). */
3548 if (alpha_fptm >= ALPHA_FPTM_SU)
3553 /* Generates trap-mode suffix for instructions that accept the
3554 v and sv suffix. The only instruction that needs this is cvtql. */
3563 case ALPHA_FPTM_SUI:
3570 /* Generates trap-mode suffix for instructions that accept the
3571 v, sv, and svi suffix. The only instruction that needs this
3583 case ALPHA_FPTM_SUI:
3584 fputs ("svi", file);
3590 /* Generates trap-mode suffix for instructions that accept the u, su,
3591 and sui suffix. This is the bulk of the IEEE floating point
3592 instructions (addt et al). */
3603 case ALPHA_FPTM_SUI:
3604 fputs ("sui", file);
3610 /* Generates trap-mode suffix for instructions that accept the sui
3611 suffix (cvtqt and cvtqs). */
3616 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
3618 case ALPHA_FPTM_SUI:
3619 fputs ("sui", file);
3625 /* Generates single precision instruction suffix. */
3626 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
3630 /* Generates double precision instruction suffix. */
3631 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
3635 /* If this operand is the constant zero, write it as "$31". */
3636 if (GET_CODE (x) == REG)
3637 fprintf (file, "%s", reg_names[REGNO (x)]);
3638 else if (x == CONST0_RTX (GET_MODE (x)))
3639 fprintf (file, "$31");
3641 output_operand_lossage ("invalid %%r value");
3646 /* Similar, but for floating-point. */
3647 if (GET_CODE (x) == REG)
3648 fprintf (file, "%s", reg_names[REGNO (x)]);
3649 else if (x == CONST0_RTX (GET_MODE (x)))
3650 fprintf (file, "$f31");
3652 output_operand_lossage ("invalid %%R value");
3657 /* Write the 1's complement of a constant. */
3658 if (GET_CODE (x) != CONST_INT)
3659 output_operand_lossage ("invalid %%N value");
3661 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
3665 /* Write 1 << C, for a constant C. */
3666 if (GET_CODE (x) != CONST_INT)
3667 output_operand_lossage ("invalid %%P value");
3669 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
3673 /* Write the high-order 16 bits of a constant, sign-extended. */
3674 if (GET_CODE (x) != CONST_INT)
3675 output_operand_lossage ("invalid %%h value");
3677 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
3681 /* Write the low-order 16 bits of a constant, sign-extended. */
3682 if (GET_CODE (x) != CONST_INT)
3683 output_operand_lossage ("invalid %%L value");
3685 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3686 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
3690 /* Write mask for ZAP insn. */
3691 if (GET_CODE (x) == CONST_DOUBLE)
3693 HOST_WIDE_INT mask = 0;
3694 HOST_WIDE_INT value;
3696 value = CONST_DOUBLE_LOW (x);
3697 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3702 value = CONST_DOUBLE_HIGH (x);
3703 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3706 mask |= (1 << (i + sizeof (int)));
3708 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
3711 else if (GET_CODE (x) == CONST_INT)
3713 HOST_WIDE_INT mask = 0, value = INTVAL (x);
3715 for (i = 0; i < 8; i++, value >>= 8)
3719 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
3722 output_operand_lossage ("invalid %%m value");
3726 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
3727 if (GET_CODE (x) != CONST_INT
3728 || (INTVAL (x) != 8 && INTVAL (x) != 16
3729 && INTVAL (x) != 32 && INTVAL (x) != 64))
3730 output_operand_lossage ("invalid %%M value");
3732 fprintf (file, "%s",
3733 (INTVAL (x) == 8 ? "b"
3734 : INTVAL (x) == 16 ? "w"
3735 : INTVAL (x) == 32 ? "l"
3740 /* Similar, except do it from the mask. */
3741 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3742 fprintf (file, "b");
3743 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3744 fprintf (file, "w");
3745 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3746 fprintf (file, "l");
3747 #if HOST_BITS_PER_WIDE_INT == 32
3748 else if (GET_CODE (x) == CONST_DOUBLE
3749 && CONST_DOUBLE_HIGH (x) == 0
3750 && CONST_DOUBLE_LOW (x) == -1)
3751 fprintf (file, "l");
3752 else if (GET_CODE (x) == CONST_DOUBLE
3753 && CONST_DOUBLE_HIGH (x) == -1
3754 && CONST_DOUBLE_LOW (x) == -1)
3755 fprintf (file, "q");
3757 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3758 fprintf (file, "q");
3759 else if (GET_CODE (x) == CONST_DOUBLE
3760 && CONST_DOUBLE_HIGH (x) == 0
3761 && CONST_DOUBLE_LOW (x) == -1)
3762 fprintf (file, "q");
3765 output_operand_lossage ("invalid %%U value");
3769 /* Write the constant value divided by 8. */
3770 if (GET_CODE (x) != CONST_INT
3771 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3772 && (INTVAL (x) & 7) != 8)
3773 output_operand_lossage ("invalid %%s value");
3775 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3779 /* Same, except compute (64 - c) / 8 */
3781 if (GET_CODE (x) != CONST_INT
3782 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3783 && (INTVAL (x) & 7) != 8)
3784 output_operand_lossage ("invalid %%s value");
3786 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
3789 case 'C': case 'D': case 'c': case 'd':
3790 /* Write out comparison name. */
3792 enum rtx_code c = GET_CODE (x);
3794 if (GET_RTX_CLASS (c) != '<')
3795 output_operand_lossage ("invalid %%C value");
3797 else if (code == 'D')
3798 c = reverse_condition (c);
3799 else if (code == 'c')
3800 c = swap_condition (c);
3801 else if (code == 'd')
3802 c = swap_condition (reverse_condition (c));
3805 fprintf (file, "ule");
3807 fprintf (file, "ult");
3808 else if (c == UNORDERED)
3809 fprintf (file, "un");
3811 fprintf (file, "%s", GET_RTX_NAME (c));
3816 /* Write the divide or modulus operator. */
3817 switch (GET_CODE (x))
3820 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
3823 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
3826 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
3829 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
3832 output_operand_lossage ("invalid %%E value");
3838 /* Write "_u" for unaligned access. */
3839 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
3840 fprintf (file, "_u");
3844 if (GET_CODE (x) == REG)
3845 fprintf (file, "%s", reg_names[REGNO (x)]);
3846 else if (GET_CODE (x) == MEM)
3847 output_address (XEXP (x, 0));
3849 output_addr_const (file, x);
3853 output_operand_lossage ("invalid %%xn code");
3858 print_operand_address (file, addr)
3863 HOST_WIDE_INT offset = 0;
3865 if (GET_CODE (addr) == AND)
3866 addr = XEXP (addr, 0);
3868 if (GET_CODE (addr) == PLUS
3869 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3871 offset = INTVAL (XEXP (addr, 1));
3872 addr = XEXP (addr, 0);
3874 if (GET_CODE (addr) == REG)
3875 basereg = REGNO (addr);
3876 else if (GET_CODE (addr) == SUBREG
3877 && GET_CODE (SUBREG_REG (addr)) == REG)
3878 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
3879 else if (GET_CODE (addr) == CONST_INT)
3880 offset = INTVAL (addr);
3884 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
3885 fprintf (file, "($%d)", basereg);
3888 /* Emit RTL insns to initialize the variable parts of a trampoline at
3889 TRAMP. FNADDR is an RTX for the address of the function's pure
3890 code. CXT is an RTX for the static chain value for the function.
3892 The three offset parameters are for the individual template's
3893 layout. A JMPOFS < 0 indicates that the trampoline does not
3894 contain instructions at all.
3896 We assume here that a function will be called many more times than
3897 its address is taken (e.g., it might be passed to qsort), so we
3898 take the trouble to initialize the "hint" field in the JMP insn.
3899 Note that the hint field is PC (new) + 4 * bits 13:0. */
3902 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
3903 rtx tramp, fnaddr, cxt;
3904 int fnofs, cxtofs, jmpofs;
3906 rtx temp, temp1, addr;
3907 /* VMS really uses DImode pointers in memory at this point. */
3908 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
3910 #ifdef POINTERS_EXTEND_UNSIGNED
3911 fnaddr = convert_memory_address (mode, fnaddr);
3912 cxt = convert_memory_address (mode, cxt);
3915 /* Store function address and CXT. */
3916 addr = memory_address (mode, plus_constant (tramp, fnofs));
3917 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
3918 addr = memory_address (mode, plus_constant (tramp, cxtofs));
3919 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
3921 /* This has been disabled since the hint only has a 32k range, and in
3922 no existing OS is the stack within 32k of the text segment. */
3923 if (0 && jmpofs >= 0)
3925 /* Compute hint value. */
3926 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3927 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3929 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3930 build_int_2 (2, 0), NULL_RTX, 1);
3931 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3933 /* Merge in the hint. */
3934 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3935 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
3936 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3937 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3939 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
3942 #ifdef TRANSFER_FROM_TRAMPOLINE
3943 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
3944 0, VOIDmode, 1, addr, Pmode);
3948 emit_insn (gen_imb ());
3951 /* Determine where to put an argument to a function.
3952 Value is zero to push the argument on the stack,
3953 or a hard register in which to store the argument.
3955 MODE is the argument's machine mode.
3956 TYPE is the data type of the argument (as a tree).
3957 This is null for libcalls where that information may
3959 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3960 the preceding args and about the function being called.
3961 NAMED is nonzero if this argument is a named parameter
3962 (otherwise it is an extra parameter matching an ellipsis).
3964 On Alpha the first 6 words of args are normally in registers
3965 and the rest are pushed. */
3968 function_arg (cum, mode, type, named)
3969 CUMULATIVE_ARGS cum;
3970 enum machine_mode mode;
3972 int named ATTRIBUTE_UNUSED;
3982 /* VOID is passed as a special flag for "last argument". */
3983 if (type == void_type_node)
3985 else if (MUST_PASS_IN_STACK (mode, type))
3987 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
3990 if (mode == VOIDmode)
3991 return alpha_arg_info_reg_val (cum);
3993 num_args = cum.num_args;
3994 if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
3996 #endif /* OPEN_VMS */
3997 else if (TARGET_FPREGS
3998 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3999 || GET_MODE_CLASS (mode) == MODE_FLOAT))
4004 return gen_rtx_REG (mode, num_args + basereg);
4008 alpha_build_va_list ()
4010 tree base, ofs, record, type_decl;
4012 if (TARGET_OPEN_VMS)
4013 return ptr_type_node;
4015 record = make_lang_type (RECORD_TYPE);
4016 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
4017 TREE_CHAIN (record) = type_decl;
4018 TYPE_NAME (record) = type_decl;
4020 /* C++? SET_IS_AGGR_TYPE (record, 1); */
4022 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
4024 DECL_FIELD_CONTEXT (ofs) = record;
4026 base = build_decl (FIELD_DECL, get_identifier ("__base"),
4028 DECL_FIELD_CONTEXT (base) = record;
4029 TREE_CHAIN (base) = ofs;
4031 TYPE_FIELDS (record) = base;
4032 layout_type (record);
4038 alpha_va_start (stdarg_p, valist, nextarg)
4041 rtx nextarg ATTRIBUTE_UNUSED;
4043 HOST_WIDE_INT offset;
4044 tree t, offset_field, base_field;
4046 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
4049 if (TARGET_OPEN_VMS)
4050 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
4052 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
4053 up by 48, storing fp arg registers in the first 48 bytes, and the
4054 integer arg registers in the next 48 bytes. This is only done,
4055 however, if any integer registers need to be stored.
4057 If no integer registers need be stored, then we must subtract 48
4058 in order to account for the integer arg registers which are counted
4059 in argsize above, but which are not actually stored on the stack. */
4061 if (NUM_ARGS <= 5 + stdarg_p)
4062 offset = 6 * UNITS_PER_WORD;
4064 offset = -6 * UNITS_PER_WORD;
4066 base_field = TYPE_FIELDS (TREE_TYPE (valist));
4067 offset_field = TREE_CHAIN (base_field);
4069 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
4070 valist, base_field);
4071 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
4072 valist, offset_field);
4074 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
4075 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
4076 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
4077 TREE_SIDE_EFFECTS (t) = 1;
4078 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4080 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
4081 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
4082 TREE_SIDE_EFFECTS (t) = 1;
4083 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4087 alpha_va_arg (valist, type)
4090 HOST_WIDE_INT tsize;
4093 tree offset_field, base_field, addr_tree, addend;
4094 tree wide_type, wide_ofs;
4096 if (TARGET_OPEN_VMS)
4097 return std_expand_builtin_va_arg (valist, type);
4099 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
4101 base_field = TYPE_FIELDS (TREE_TYPE (valist));
4102 offset_field = TREE_CHAIN (base_field);
4104 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
4105 valist, base_field);
4106 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
4107 valist, offset_field);
4109 wide_type = make_signed_type (64);
4110 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
4113 if (FLOAT_TYPE_P (type))
4115 tree fpaddend, cond;
4117 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
4118 addend, build_int_2 (-6*8, 0)));
4120 cond = fold (build (LT_EXPR, integer_type_node,
4121 wide_ofs, build_int_2 (6*8, 0)));
4123 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
4127 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
4128 base_field, addend);
4130 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4131 addr = copy_to_reg (addr);
4133 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
4134 build (PLUS_EXPR, TREE_TYPE (offset_field),
4135 offset_field, build_int_2 (tsize, 0)));
4136 TREE_SIDE_EFFECTS (t) = 1;
4137 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4142 /* This page contains routines that are used to determine what the function
4143 prologue and epilogue code will do and write them out. */
4145 /* Compute the size of the save area in the stack. */
4147 /* These variables are used for communication between the following functions.
4148 They indicate various things about the current function being compiled
4149 that are used to tell what kind of prologue, epilogue and procedure
4150 descriptior to generate. */
4152 /* Nonzero if we need a stack procedure. */
4153 static int vms_is_stack_procedure;
4155 /* Register number (either FP or SP) that is used to unwind the frame. */
4156 static int vms_unwind_regno;
4158 /* Register number used to save FP. We need not have one for RA since
4159 we don't modify it for register procedures. This is only defined
4160 for register frame procedures. */
4161 static int vms_save_fp_regno;
4163 /* Register number used to reference objects off our PV. */
4164 static int vms_base_regno;
4166 /* Compute register masks for saved registers. */
4169 alpha_sa_mask (imaskP, fmaskP)
4170 unsigned long *imaskP;
4171 unsigned long *fmaskP;
4173 unsigned long imask = 0;
4174 unsigned long fmask = 0;
4177 #ifdef ASM_OUTPUT_MI_THUNK
4178 if (!current_function_is_thunk)
4181 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4182 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
4184 /* One for every register we have to save. */
4185 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4186 if (! fixed_regs[i] && ! call_used_regs[i]
4187 && regs_ever_live[i] && i != REG_RA)
4192 fmask |= (1L << (i - 32));
4195 if (imask || fmask || alpha_ra_ever_killed ())
4196 imask |= (1L << REG_RA);
4209 #ifdef ASM_OUTPUT_MI_THUNK
4210 if (current_function_is_thunk)
4215 /* One for every register we have to save. */
4216 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4217 if (! fixed_regs[i] && ! call_used_regs[i]
4218 && regs_ever_live[i] && i != REG_RA)
4222 if (TARGET_OPEN_VMS)
4224 /* Start by assuming we can use a register procedure if we don't
4225 make any calls (REG_RA not used) or need to save any
4226 registers and a stack procedure if we do. */
4227 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
4229 /* Decide whether to refer to objects off our PV via FP or PV.
4230 If we need FP for something else or if we receive a nonlocal
4231 goto (which expects PV to contain the value), we must use PV.
4232 Otherwise, start by assuming we can use FP. */
4233 vms_base_regno = (frame_pointer_needed
4234 || current_function_has_nonlocal_label
4235 || vms_is_stack_procedure
4236 || current_function_outgoing_args_size
4237 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
4239 /* If we want to copy PV into FP, we need to find some register
4240 in which to save FP. */
4242 vms_save_fp_regno = -1;
4243 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
4244 for (i = 0; i < 32; i++)
4245 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
4246 vms_save_fp_regno = i;
4248 if (vms_save_fp_regno == -1)
4249 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
4251 /* Stack unwinding should be done via FP unless we use it for PV. */
4252 vms_unwind_regno = (vms_base_regno == REG_PV
4253 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
4255 /* If this is a stack procedure, allow space for saving FP and RA. */
4256 if (vms_is_stack_procedure)
4261 /* If some registers were saved but not RA, RA must also be saved,
4262 so leave space for it. */
4263 if (sa_size != 0 || alpha_ra_ever_killed ())
4266 /* Our size must be even (multiple of 16 bytes). */
4275 alpha_pv_save_size ()
4278 return vms_is_stack_procedure ? 8 : 0;
4285 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
4289 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
4290 tree decl ATTRIBUTE_UNUSED;
4291 tree attributes ATTRIBUTE_UNUSED;
4295 if (is_attribute_p ("overlaid", identifier))
4296 return (args == NULL_TREE);
4301 alpha_does_function_need_gp ()
4305 /* We never need a GP for Windows/NT or VMS. */
4306 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4309 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4312 #ifdef ASM_OUTPUT_MI_THUNK
4313 if (current_function_is_thunk)
4317 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
4318 Even if we are a static function, we still need to do this in case
4319 our address is taken and passed to something like qsort. */
4321 push_topmost_sequence ();
4322 insn = get_insns ();
4323 pop_topmost_sequence ();
4325 for (; insn; insn = NEXT_INSN (insn))
4327 && GET_CODE (PATTERN (insn)) != USE
4328 && GET_CODE (PATTERN (insn)) != CLOBBER)
4330 enum attr_type type = get_attr_type (insn);
4331 if (type == TYPE_LDSYM || type == TYPE_JSR)
4338 /* Write a version stamp. Don't write anything if we are running as a
4339 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
4346 alpha_write_verstamp (file)
4347 FILE *file ATTRIBUTE_UNUSED;
4350 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
4354 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
4358 set_frame_related_p ()
4360 rtx seq = gen_sequence ();
4363 if (GET_CODE (seq) == SEQUENCE)
4365 int i = XVECLEN (seq, 0);
4367 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
4368 return emit_insn (seq);
4372 seq = emit_insn (seq);
4373 RTX_FRAME_RELATED_P (seq) = 1;
4378 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
4380 /* Write function prologue. */
4382 /* On vms we have two kinds of functions:
4384 - stack frame (PROC_STACK)
4385 these are 'normal' functions with local vars and which are
4386 calling other functions
4387 - register frame (PROC_REGISTER)
4388 keeps all data in registers, needs no stack
4390 We must pass this to the assembler so it can generate the
4391 proper pdsc (procedure descriptor)
4392 This is done with the '.pdesc' command.
4394 On not-vms, we don't really differentiate between the two, as we can
4395 simply allocate stack without saving registers. */
4398 alpha_expand_prologue ()
4400 /* Registers to save. */
4401 unsigned long imask = 0;
4402 unsigned long fmask = 0;
4403 /* Stack space needed for pushing registers clobbered by us. */
4404 HOST_WIDE_INT sa_size;
4405 /* Complete stack size needed. */
4406 HOST_WIDE_INT frame_size;
4407 /* Offset from base reg to register save area. */
4408 HOST_WIDE_INT reg_offset;
4412 sa_size = alpha_sa_size ();
4414 frame_size = get_frame_size ();
4415 if (TARGET_OPEN_VMS)
4416 frame_size = ALPHA_ROUND (sa_size
4417 + (vms_is_stack_procedure ? 8 : 0)
4419 + current_function_pretend_args_size);
4421 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4423 + ALPHA_ROUND (frame_size
4424 + current_function_pretend_args_size));
4426 if (TARGET_OPEN_VMS)
4429 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4431 alpha_sa_mask (&imask, &fmask);
4433 /* Emit an insn to reload GP, if needed. */
4434 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
4436 alpha_function_needs_gp = alpha_does_function_need_gp ();
4437 if (alpha_function_needs_gp)
4438 emit_insn (gen_prologue_ldgp ());
4441 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
4442 the call to mcount ourselves, rather than having the linker do it
4443 magically in response to -pg. Since _mcount has special linkage,
4444 don't represent the call as a call. */
4445 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4446 emit_insn (gen_prologue_mcount ());
4448 /* Adjust the stack by the frame size. If the frame size is > 4096
4449 bytes, we need to be sure we probe somewhere in the first and last
4450 4096 bytes (we can probably get away without the latter test) and
4451 every 8192 bytes in between. If the frame size is > 32768, we
4452 do this in a loop. Otherwise, we generate the explicit probe
4455 Note that we are only allowed to adjust sp once in the prologue. */
4457 if (frame_size <= 32768)
4459 if (frame_size > 4096)
4464 emit_insn (gen_probe_stack (GEN_INT (-probed)));
4465 while ((probed += 8192) < frame_size);
4467 /* We only have to do this probe if we aren't saving registers. */
4468 if (sa_size == 0 && probed + 4096 < frame_size)
4469 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
4472 if (frame_size != 0)
4474 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
4475 GEN_INT (-frame_size))));
4480 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
4481 number of 8192 byte blocks to probe. We then probe each block
4482 in the loop and then set SP to the proper location. If the
4483 amount remaining is > 4096, we have to do one more probe if we
4484 are not saving any registers. */
4486 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
4487 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
4488 rtx ptr = gen_rtx_REG (DImode, 22);
4489 rtx count = gen_rtx_REG (DImode, 23);
4492 emit_move_insn (count, GEN_INT (blocks));
4493 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
4495 /* Because of the difficulty in emitting a new basic block this
4496 late in the compilation, generate the loop as a single insn. */
4497 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
4499 if (leftover > 4096 && sa_size == 0)
4501 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
4502 MEM_VOLATILE_P (last) = 1;
4503 emit_move_insn (last, const0_rtx);
4506 if (TARGET_WINDOWS_NT)
4508 /* For NT stack unwind (done by 'reverse execution'), it's
4509 not OK to take the result of a loop, even though the value
4510 is already in ptr, so we reload it via a single operation
4511 and subtract it to sp.
4513 Yes, that's correct -- we have to reload the whole constant
4514 into a temporary via ldah+lda then subtract from sp. To
4515 ensure we get ldah+lda, we use a special pattern. */
4517 HOST_WIDE_INT lo, hi;
4518 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4519 hi = frame_size - lo;
4521 emit_move_insn (ptr, GEN_INT (hi));
4522 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
4523 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
4528 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
4529 GEN_INT (-leftover)));
4532 /* This alternative is special, because the DWARF code cannot
4533 possibly intuit through the loop above. So we invent this
4534 note it looks at instead. */
4535 RTX_FRAME_RELATED_P (seq) = 1;
4537 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4538 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4539 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4540 GEN_INT (-frame_size))),
4544 /* Cope with very large offsets to the register save area. */
4545 sa_reg = stack_pointer_rtx;
4546 if (reg_offset + sa_size > 0x8000)
4548 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4551 if (low + sa_size <= 0x8000)
4552 bias = reg_offset - low, reg_offset = low;
4554 bias = reg_offset, reg_offset = 0;
4556 sa_reg = gen_rtx_REG (DImode, 24);
4557 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
4560 /* Save regs in stack order. Beginning with VMS PV. */
4561 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4563 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
4564 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4565 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
4568 /* Save register RA next. */
4569 if (imask & (1L << REG_RA))
4571 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4572 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4573 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
4574 imask &= ~(1L << REG_RA);
4578 /* Now save any other registers required to be saved. */
4579 for (i = 0; i < 32; i++)
4580 if (imask & (1L << i))
4582 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4583 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4584 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
4588 for (i = 0; i < 32; i++)
4589 if (fmask & (1L << i))
4591 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
4592 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4593 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
4597 if (TARGET_OPEN_VMS)
4599 if (!vms_is_stack_procedure)
4601 /* Register frame procedures fave the fp. */
4602 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
4603 hard_frame_pointer_rtx));
4606 if (vms_base_regno != REG_PV)
4607 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
4608 gen_rtx_REG (DImode, REG_PV)));
4610 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4612 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4615 /* If we have to allocate space for outgoing args, do it now. */
4616 if (current_function_outgoing_args_size != 0)
4618 FRP (emit_move_insn (stack_pointer_rtx,
4619 plus_constant (hard_frame_pointer_rtx,
4620 - ALPHA_ROUND (current_function_outgoing_args_size))));
4625 /* If we need a frame pointer, set it from the stack pointer. */
4626 if (frame_pointer_needed)
4628 if (TARGET_CAN_FAULT_IN_PROLOGUE)
4629 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4632 /* This must always be the last instruction in the
4633 prologue, thus we emit a special move + clobber. */
4634 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
4635 stack_pointer_rtx, sa_reg)));
4640 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
4641 the prologue, for exception handling reasons, we cannot do this for
4642 any insn that might fault. We could prevent this for mems with a
4643 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
4644 have to prevent all such scheduling with a blockage.
4646 Linux, on the other hand, never bothered to implement OSF/1's
4647 exception handling, and so doesn't care about such things. Anyone
4648 planning to use dwarf2 frame-unwind info can also omit the blockage. */
4650 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
4651 emit_insn (gen_blockage ());
4654 /* Output the textual info surrounding the prologue. */
4657 alpha_start_function (file, fnname, decl)
4660 tree decl ATTRIBUTE_UNUSED;
4662 unsigned long imask = 0;
4663 unsigned long fmask = 0;
4664 /* Stack space needed for pushing registers clobbered by us. */
4665 HOST_WIDE_INT sa_size;
4666 /* Complete stack size needed. */
4667 HOST_WIDE_INT frame_size;
4668 /* Offset from base reg to register save area. */
4669 HOST_WIDE_INT reg_offset;
4670 char *entry_label = (char *) alloca (strlen (fnname) + 6);
4673 alpha_fnname = fnname;
4674 sa_size = alpha_sa_size ();
4676 frame_size = get_frame_size ();
4677 if (TARGET_OPEN_VMS)
4678 frame_size = ALPHA_ROUND (sa_size
4679 + (vms_is_stack_procedure ? 8 : 0)
4681 + current_function_pretend_args_size);
4683 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4685 + ALPHA_ROUND (frame_size
4686 + current_function_pretend_args_size));
4688 if (TARGET_OPEN_VMS)
4691 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4693 alpha_sa_mask (&imask, &fmask);
4695 /* Ecoff can handle multiple .file directives, so put out file and lineno.
4696 We have to do that before the .ent directive as we cannot switch
4697 files within procedures with native ecoff because line numbers are
4698 linked to procedure descriptors.
4699 Outputting the lineno helps debugging of one line functions as they
4700 would otherwise get no line number at all. Please note that we would
4701 like to put out last_linenum from final.c, but it is not accessible. */
4703 if (write_symbols == SDB_DEBUG)
4705 ASM_OUTPUT_SOURCE_FILENAME (file,
4706 DECL_SOURCE_FILE (current_function_decl));
4707 if (debug_info_level != DINFO_LEVEL_TERSE)
4708 ASM_OUTPUT_SOURCE_LINE (file,
4709 DECL_SOURCE_LINE (current_function_decl));
4712 /* Issue function start and label. */
4713 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
4715 fputs ("\t.ent ", file);
4716 assemble_name (file, fnname);
4719 /* If the function needs GP, we'll write the "..ng" label there.
4720 Otherwise, do it here. */
4721 if (! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT
4722 && ! alpha_function_needs_gp)
4725 assemble_name (file, fnname);
4726 fputs ("..ng:\n", file);
4730 strcpy (entry_label, fnname);
4731 if (TARGET_OPEN_VMS)
4732 strcat (entry_label, "..en");
4733 ASM_OUTPUT_LABEL (file, entry_label);
4734 inside_function = TRUE;
4736 if (TARGET_OPEN_VMS)
4737 fprintf (file, "\t.base $%d\n", vms_base_regno);
4739 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
4740 && !flag_inhibit_size_directive)
4742 /* Set flags in procedure descriptor to request IEEE-conformant
4743 math-library routines. The value we set it to is PDSC_EXC_IEEE
4744 (/usr/include/pdsc.h). */
4745 fputs ("\t.eflag 48\n", file);
4748 /* Set up offsets to alpha virtual arg/local debugging pointer. */
4749 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
4750 alpha_arg_offset = -frame_size + 48;
4752 /* Describe our frame. If the frame size is larger than an integer,
4753 print it as zero to avoid an assembler error. We won't be
4754 properly describing such a frame, but that's the best we can do. */
4755 if (TARGET_OPEN_VMS)
4757 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
4758 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4759 frame_size >= (1l << 31) ? 0 : frame_size);
4760 fputs (",$26,", file);
4761 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
4764 else if (!flag_inhibit_size_directive)
4766 fprintf (file, "\t.frame $%d,",
4767 (frame_pointer_needed
4768 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
4769 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4770 frame_size >= (1l << 31) ? 0 : frame_size);
4771 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
4774 /* Describe which registers were spilled. */
4775 if (TARGET_OPEN_VMS)
4778 /* ??? Does VMS care if mask contains ra? The old code did'nt
4779 set it, so I don't here. */
4780 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
4782 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
4783 if (!vms_is_stack_procedure)
4784 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
4786 else if (!flag_inhibit_size_directive)
4790 fprintf (file, "\t.mask 0x%lx,", imask);
4791 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4792 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4795 for (i = 0; i < 32; ++i)
4796 if (imask & (1L << i))
4802 fprintf (file, "\t.fmask 0x%lx,", fmask);
4803 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4804 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4810 /* Ifdef'ed cause readonly_section and link_section are only
4812 readonly_section ();
4813 fprintf (file, "\t.align 3\n");
4814 assemble_name (file, fnname); fputs ("..na:\n", file);
4815 fputs ("\t.ascii \"", file);
4816 assemble_name (file, fnname);
4817 fputs ("\\0\"\n", file);
4820 fprintf (file, "\t.align 3\n");
4821 fputs ("\t.name ", file);
4822 assemble_name (file, fnname);
4823 fputs ("..na\n", file);
4824 ASM_OUTPUT_LABEL (file, fnname);
4825 fprintf (file, "\t.pdesc ");
4826 assemble_name (file, fnname);
4827 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
4828 alpha_need_linkage (fnname, 1);
4833 /* Emit the .prologue note at the scheduled end of the prologue. */
4836 output_end_prologue (file)
4839 if (TARGET_OPEN_VMS)
4840 fputs ("\t.prologue\n", file);
4841 else if (TARGET_WINDOWS_NT)
4842 fputs ("\t.prologue 0\n", file);
4843 else if (!flag_inhibit_size_directive)
4844 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
4847 /* Write function epilogue. */
4849 /* ??? At some point we will want to support full unwind, and so will
4850 need to mark the epilogue as well. At the moment, we just confuse
4853 #define FRP(exp) exp
4856 alpha_expand_epilogue ()
4858 /* Registers to save. */
4859 unsigned long imask = 0;
4860 unsigned long fmask = 0;
4861 /* Stack space needed for pushing registers clobbered by us. */
4862 HOST_WIDE_INT sa_size;
4863 /* Complete stack size needed. */
4864 HOST_WIDE_INT frame_size;
4865 /* Offset from base reg to register save area. */
4866 HOST_WIDE_INT reg_offset;
4867 int fp_is_frame_pointer, fp_offset;
4868 rtx sa_reg, sa_reg_exp = NULL;
4869 rtx sp_adj1, sp_adj2, mem;
4873 sa_size = alpha_sa_size ();
4875 frame_size = get_frame_size ();
4876 if (TARGET_OPEN_VMS)
4877 frame_size = ALPHA_ROUND (sa_size
4878 + (vms_is_stack_procedure ? 8 : 0)
4880 + current_function_pretend_args_size);
4882 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4884 + ALPHA_ROUND (frame_size
4885 + current_function_pretend_args_size));
4887 if (TARGET_OPEN_VMS)
4890 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4892 alpha_sa_mask (&imask, &fmask);
4894 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
4895 || (!TARGET_OPEN_VMS && frame_pointer_needed));
4897 sa_reg = stack_pointer_rtx;
4899 eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
4902 /* If we have a frame pointer, restore SP from it. */
4903 if ((TARGET_OPEN_VMS
4904 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4905 || (!TARGET_OPEN_VMS && frame_pointer_needed))
4907 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
4910 /* Cope with very large offsets to the register save area. */
4911 if (reg_offset + sa_size > 0x8000)
4913 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4916 if (low + sa_size <= 0x8000)
4917 bias = reg_offset - low, reg_offset = low;
4919 bias = reg_offset, reg_offset = 0;
4921 sa_reg = gen_rtx_REG (DImode, 22);
4922 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
4924 FRP (emit_move_insn (sa_reg, sa_reg_exp));
4927 /* Restore registers in order, excepting a true frame pointer. */
4931 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4932 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4933 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
4936 imask &= ~(1L << REG_RA);
4938 for (i = 0; i < 32; ++i)
4939 if (imask & (1L << i))
4941 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
4942 fp_offset = reg_offset;
4945 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4946 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4947 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
4952 for (i = 0; i < 32; ++i)
4953 if (fmask & (1L << i))
4955 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
4956 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4957 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
4962 if (frame_size || eh_ofs)
4964 sp_adj1 = stack_pointer_rtx;
4968 sp_adj1 = gen_rtx_REG (DImode, 23);
4969 emit_move_insn (sp_adj1,
4970 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
4973 /* If the stack size is large, begin computation into a temporary
4974 register so as not to interfere with a potential fp restore,
4975 which must be consecutive with an SP restore. */
4976 if (frame_size < 32768)
4977 sp_adj2 = GEN_INT (frame_size);
4978 else if (frame_size < 0x40007fffL)
4980 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4982 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
4983 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
4987 sp_adj1 = gen_rtx_REG (DImode, 23);
4988 FRP (emit_move_insn (sp_adj1, sp_adj2));
4990 sp_adj2 = GEN_INT (low);
4994 rtx tmp = gen_rtx_REG (DImode, 23);
4995 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
4998 /* We can't drop new things to memory this late, afaik,
4999 so build it up by pieces. */
5000 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
5001 -(frame_size < 0)));
5007 /* From now on, things must be in order. So emit blockages. */
5009 /* Restore the frame pointer. */
5010 if (fp_is_frame_pointer)
5012 emit_insn (gen_blockage ());
5013 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
5014 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
5015 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
5017 else if (TARGET_OPEN_VMS)
5019 emit_insn (gen_blockage ());
5020 FRP (emit_move_insn (hard_frame_pointer_rtx,
5021 gen_rtx_REG (DImode, vms_save_fp_regno)));
5024 /* Restore the stack pointer. */
5025 emit_insn (gen_blockage ());
5026 FRP (emit_move_insn (stack_pointer_rtx,
5027 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
5031 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
5033 emit_insn (gen_blockage ());
5034 FRP (emit_move_insn (hard_frame_pointer_rtx,
5035 gen_rtx_REG (DImode, vms_save_fp_regno)));
5040 /* Output the rest of the textual info surrounding the epilogue. */
5043 alpha_end_function (file, fnname, decl)
5046 tree decl ATTRIBUTE_UNUSED;
5048 /* End the function. */
5049 if (!flag_inhibit_size_directive)
5051 fputs ("\t.end ", file);
5052 assemble_name (file, fnname);
5055 inside_function = FALSE;
5057 /* Show that we know this function if it is called again.
5059 Don't do this for global functions in object files destined for a
5060 shared library because the function may be overridden by the application
5061 or other libraries. Similarly, don't do this for weak functions. */
5063 if (!DECL_WEAK (current_function_decl)
5064 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
5065 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
5068 /* Debugging support. */
5072 /* Count the number of sdb related labels are generated (to find block
5073 start and end boundaries). */
5075 int sdb_label_count = 0;
5077 /* Next label # for each statement. */
5079 static int sym_lineno = 0;
5081 /* Count the number of .file directives, so that .loc is up to date. */
5083 static int num_source_filenames = 0;
5085 /* Name of the file containing the current function. */
5087 static const char *current_function_file = "";
5089 /* Offsets to alpha virtual arg/local debugging pointers. */
5091 long alpha_arg_offset;
5092 long alpha_auto_offset;
5094 /* Emit a new filename to a stream. */
5097 alpha_output_filename (stream, name)
5101 static int first_time = TRUE;
5102 char ltext_label_name[100];
5107 ++num_source_filenames;
5108 current_function_file = name;
5109 fprintf (stream, "\t.file\t%d ", num_source_filenames);
5110 output_quoted_string (stream, name);
5111 fprintf (stream, "\n");
5112 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
5113 fprintf (stream, "\t#@stabs\n");
5116 else if (write_symbols == DBX_DEBUG)
5118 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
5119 fprintf (stream, "%s", ASM_STABS_OP);
5120 output_quoted_string (stream, name);
5121 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
5124 else if (name != current_function_file
5125 && strcmp (name, current_function_file) != 0)
5127 if (inside_function && ! TARGET_GAS)
5128 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
5131 ++num_source_filenames;
5132 current_function_file = name;
5133 fprintf (stream, "\t.file\t%d ", num_source_filenames);
5136 output_quoted_string (stream, name);
5137 fprintf (stream, "\n");
5141 /* Emit a linenumber to a stream. */
5144 alpha_output_lineno (stream, line)
5148 if (write_symbols == DBX_DEBUG)
5150 /* mips-tfile doesn't understand .stabd directives. */
5152 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
5153 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
5156 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
5159 /* Structure to show the current status of registers and memory. */
5161 struct shadow_summary
5164 unsigned int i : 31; /* Mask of int regs */
5165 unsigned int fp : 31; /* Mask of fp regs */
5166 unsigned int mem : 1; /* mem == imem | fpmem */
5170 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
5171 static void alpha_handle_trap_shadows PARAMS ((rtx));
5173 /* Summary the effects of expression X on the machine. Update SUM, a pointer
5174 to the summary structure. SET is nonzero if the insn is setting the
5175 object, otherwise zero. */
5178 summarize_insn (x, sum, set)
5180 struct shadow_summary *sum;
5183 const char *format_ptr;
5189 switch (GET_CODE (x))
5191 /* ??? Note that this case would be incorrect if the Alpha had a
5192 ZERO_EXTRACT in SET_DEST. */
5194 summarize_insn (SET_SRC (x), sum, 0);
5195 summarize_insn (SET_DEST (x), sum, 1);
5199 summarize_insn (XEXP (x, 0), sum, 1);
5203 summarize_insn (XEXP (x, 0), sum, 0);
5207 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
5208 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
5212 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
5213 summarize_insn (XVECEXP (x, 0, i), sum, 0);
5217 summarize_insn (SUBREG_REG (x), sum, 0);
5222 int regno = REGNO (x);
5223 unsigned long mask = ((unsigned long) 1) << (regno % 32);
5225 if (regno == 31 || regno == 63)
5231 sum->defd.i |= mask;
5233 sum->defd.fp |= mask;
5238 sum->used.i |= mask;
5240 sum->used.fp |= mask;
5251 /* Find the regs used in memory address computation: */
5252 summarize_insn (XEXP (x, 0), sum, 0);
5255 case CONST_INT: case CONST_DOUBLE:
5256 case SYMBOL_REF: case LABEL_REF: case CONST:
5260 /* Handle common unary and binary ops for efficiency. */
5261 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
5262 case MOD: case UDIV: case UMOD: case AND: case IOR:
5263 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
5264 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
5265 case NE: case EQ: case GE: case GT: case LE:
5266 case LT: case GEU: case GTU: case LEU: case LTU:
5267 summarize_insn (XEXP (x, 0), sum, 0);
5268 summarize_insn (XEXP (x, 1), sum, 0);
5271 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
5272 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
5273 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
5274 case SQRT: case FFS:
5275 summarize_insn (XEXP (x, 0), sum, 0);
5279 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
5280 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5281 switch (format_ptr[i])
5284 summarize_insn (XEXP (x, i), sum, 0);
5288 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
5289 summarize_insn (XVECEXP (x, i, j), sum, 0);
5301 /* Ensure a sufficient number of `trapb' insns are in the code when
5302 the user requests code with a trap precision of functions or
5305 In naive mode, when the user requests a trap-precision of
5306 "instruction", a trapb is needed after every instruction that may
5307 generate a trap. This ensures that the code is resumption safe but
5310 When optimizations are turned on, we delay issuing a trapb as long
5311 as possible. In this context, a trap shadow is the sequence of
5312 instructions that starts with a (potentially) trap generating
5313 instruction and extends to the next trapb or call_pal instruction
5314 (but GCC never generates call_pal by itself). We can delay (and
5315 therefore sometimes omit) a trapb subject to the following
5318 (a) On entry to the trap shadow, if any Alpha register or memory
5319 location contains a value that is used as an operand value by some
5320 instruction in the trap shadow (live on entry), then no instruction
5321 in the trap shadow may modify the register or memory location.
5323 (b) Within the trap shadow, the computation of the base register
5324 for a memory load or store instruction may not involve using the
5325 result of an instruction that might generate an UNPREDICTABLE
5328 (c) Within the trap shadow, no register may be used more than once
5329 as a destination register. (This is to make life easier for the
5332 (d) The trap shadow may not include any branch instructions. */
5335 alpha_handle_trap_shadows (insns)
5338 struct shadow_summary shadow;
5339 int trap_pending, exception_nesting;
5343 exception_nesting = 0;
5346 shadow.used.mem = 0;
5347 shadow.defd = shadow.used;
5349 for (i = insns; i ; i = NEXT_INSN (i))
5351 if (GET_CODE (i) == NOTE)
5353 switch (NOTE_LINE_NUMBER (i))
5355 case NOTE_INSN_EH_REGION_BEG:
5356 exception_nesting++;
5361 case NOTE_INSN_EH_REGION_END:
5362 exception_nesting--;
5367 case NOTE_INSN_EPILOGUE_BEG:
5368 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
5373 else if (trap_pending)
5375 if (alpha_tp == ALPHA_TP_FUNC)
5377 if (GET_CODE (i) == JUMP_INSN
5378 && GET_CODE (PATTERN (i)) == RETURN)
5381 else if (alpha_tp == ALPHA_TP_INSN)
5385 struct shadow_summary sum;
5390 sum.defd = sum.used;
5392 switch (GET_CODE (i))
5395 /* Annoyingly, get_attr_trap will abort on these. */
5396 if (GET_CODE (PATTERN (i)) == USE
5397 || GET_CODE (PATTERN (i)) == CLOBBER)
5400 summarize_insn (PATTERN (i), &sum, 0);
5402 if ((sum.defd.i & shadow.defd.i)
5403 || (sum.defd.fp & shadow.defd.fp))
5405 /* (c) would be violated */
5409 /* Combine shadow with summary of current insn: */
5410 shadow.used.i |= sum.used.i;
5411 shadow.used.fp |= sum.used.fp;
5412 shadow.used.mem |= sum.used.mem;
5413 shadow.defd.i |= sum.defd.i;
5414 shadow.defd.fp |= sum.defd.fp;
5415 shadow.defd.mem |= sum.defd.mem;
5417 if ((sum.defd.i & shadow.used.i)
5418 || (sum.defd.fp & shadow.used.fp)
5419 || (sum.defd.mem & shadow.used.mem))
5421 /* (a) would be violated (also takes care of (b)) */
5422 if (get_attr_trap (i) == TRAP_YES
5423 && ((sum.defd.i & sum.used.i)
5424 || (sum.defd.fp & sum.used.fp)))
5443 n = emit_insn_before (gen_trapb (), i);
5444 PUT_MODE (n, TImode);
5445 PUT_MODE (i, TImode);
5449 shadow.used.mem = 0;
5450 shadow.defd = shadow.used;
5455 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
5456 && GET_CODE (i) == INSN
5457 && GET_CODE (PATTERN (i)) != USE
5458 && GET_CODE (PATTERN (i)) != CLOBBER
5459 && get_attr_trap (i) == TRAP_YES)
5461 if (optimize && !trap_pending)
5462 summarize_insn (PATTERN (i), &shadow, 0);
5468 /* Alpha can only issue instruction groups simultaneously if they are
5469 suitibly aligned. This is very processor-specific. */
5471 enum alphaev4_pipe {
5478 enum alphaev5_pipe {
5489 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
5490 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
5491 static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
5492 static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
5493 static rtx alphaev4_next_nop PARAMS ((int *));
5494 static rtx alphaev5_next_nop PARAMS ((int *));
5496 static void alpha_align_insns
5497 PARAMS ((rtx, unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
5499 static enum alphaev4_pipe
5500 alphaev4_insn_pipe (insn)
5503 if (recog_memoized (insn) < 0)
5505 if (get_attr_length (insn) != 4)
5508 switch (get_attr_type (insn))
5541 static enum alphaev5_pipe
5542 alphaev5_insn_pipe (insn)
5545 if (recog_memoized (insn) < 0)
5547 if (get_attr_length (insn) != 4)
5550 switch (get_attr_type (insn))
5590 /* IN_USE is a mask of the slots currently filled within the insn group.
5591 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
5592 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
5594 LEN is, of course, the length of the group in bytes. */
5597 alphaev4_next_group (insn, pin_use, plen)
5599 int *pin_use, *plen;
5606 || GET_CODE (PATTERN (insn)) == CLOBBER
5607 || GET_CODE (PATTERN (insn)) == USE)
5612 enum alphaev4_pipe pipe;
5614 pipe = alphaev4_insn_pipe (insn);
5618 /* Force complex instructions to start new groups. */
5622 /* If this is a completely unrecognized insn, its an asm.
5623 We don't know how long it is, so record length as -1 to
5624 signal a needed realignment. */
5625 if (recog_memoized (insn) < 0)
5628 len = get_attr_length (insn);
5632 if (in_use & EV4_IB0)
5634 if (in_use & EV4_IB1)
5639 in_use |= EV4_IB0 | EV4_IBX;
5643 if (in_use & EV4_IB0)
5645 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
5653 if (in_use & EV4_IB1)
5663 /* Haifa doesn't do well scheduling branches. */
5664 if (GET_CODE (insn) == JUMP_INSN)
5668 insn = next_nonnote_insn (insn);
5670 if (!insn || ! INSN_P (insn))
5673 /* Let Haifa tell us where it thinks insn group boundaries are. */
5674 if (GET_MODE (insn) == TImode)
5677 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5682 insn = next_nonnote_insn (insn);
5690 /* IN_USE is a mask of the slots currently filled within the insn group.
5691 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
5692 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
5694 LEN is, of course, the length of the group in bytes. */
5697 alphaev5_next_group (insn, pin_use, plen)
5699 int *pin_use, *plen;
5706 || GET_CODE (PATTERN (insn)) == CLOBBER
5707 || GET_CODE (PATTERN (insn)) == USE)
5712 enum alphaev5_pipe pipe;
5714 pipe = alphaev5_insn_pipe (insn);
5718 /* Force complex instructions to start new groups. */
5722 /* If this is a completely unrecognized insn, its an asm.
5723 We don't know how long it is, so record length as -1 to
5724 signal a needed realignment. */
5725 if (recog_memoized (insn) < 0)
5728 len = get_attr_length (insn);
5731 /* ??? Most of the places below, we would like to abort, as
5732 it would indicate an error either in Haifa, or in the
5733 scheduling description. Unfortunately, Haifa never
5734 schedules the last instruction of the BB, so we don't
5735 have an accurate TI bit to go off. */
5737 if (in_use & EV5_E0)
5739 if (in_use & EV5_E1)
5744 in_use |= EV5_E0 | EV5_E01;
5748 if (in_use & EV5_E0)
5750 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
5758 if (in_use & EV5_E1)
5764 if (in_use & EV5_FA)
5766 if (in_use & EV5_FM)
5771 in_use |= EV5_FA | EV5_FAM;
5775 if (in_use & EV5_FA)
5781 if (in_use & EV5_FM)
5794 /* Haifa doesn't do well scheduling branches. */
5795 /* ??? If this is predicted not-taken, slotting continues, except
5796 that no more IBR, FBR, or JSR insns may be slotted. */
5797 if (GET_CODE (insn) == JUMP_INSN)
5801 insn = next_nonnote_insn (insn);
5803 if (!insn || ! INSN_P (insn))
5806 /* Let Haifa tell us where it thinks insn group boundaries are. */
5807 if (GET_MODE (insn) == TImode)
5810 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5815 insn = next_nonnote_insn (insn);
5824 alphaev4_next_nop (pin_use)
5827 int in_use = *pin_use;
5830 if (!(in_use & EV4_IB0))
5835 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
5840 else if (TARGET_FP && !(in_use & EV4_IB1))
5853 alphaev5_next_nop (pin_use)
5856 int in_use = *pin_use;
5859 if (!(in_use & EV5_E1))
5864 else if (TARGET_FP && !(in_use & EV5_FA))
5869 else if (TARGET_FP && !(in_use & EV5_FM))
5881 /* The instruction group alignment main loop. */
5884 alpha_align_insns (insns, max_align, next_group, next_nop)
5886 unsigned int max_align;
5887 rtx (*next_group) PARAMS ((rtx, int *, int *));
5888 rtx (*next_nop) PARAMS ((int *));
5890 /* ALIGN is the known alignment for the insn group. */
5892 /* OFS is the offset of the current insn in the insn group. */
5894 int prev_in_use, in_use, len;
5897 /* Let shorten branches care for assigning alignments to code labels. */
5898 shorten_branches (insns);
5900 align = (FUNCTION_BOUNDARY / BITS_PER_UNIT < max_align
5901 ? FUNCTION_BOUNDARY / BITS_PER_UNIT : max_align);
5903 ofs = prev_in_use = 0;
5905 if (GET_CODE (i) == NOTE)
5906 i = next_nonnote_insn (i);
5910 next = (*next_group) (i, &in_use, &len);
5912 /* When we see a label, resync alignment etc. */
5913 if (GET_CODE (i) == CODE_LABEL)
5915 unsigned int new_align = 1 << label_to_alignment (i);
5917 if (new_align >= align)
5919 align = new_align < max_align ? new_align : max_align;
5923 else if (ofs & (new_align-1))
5924 ofs = (ofs | (new_align-1)) + 1;
5929 /* Handle complex instructions special. */
5930 else if (in_use == 0)
5932 /* Asms will have length < 0. This is a signal that we have
5933 lost alignment knowledge. Assume, however, that the asm
5934 will not mis-align instructions. */
5943 /* If the known alignment is smaller than the recognized insn group,
5944 realign the output. */
5945 else if (align < len)
5947 unsigned int new_log_align = len > 8 ? 4 : 3;
5950 where = prev_nonnote_insn (i);
5951 if (!where || GET_CODE (where) != CODE_LABEL)
5954 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
5955 align = 1 << new_log_align;
5959 /* If the group won't fit in the same INT16 as the previous,
5960 we need to add padding to keep the group together. Rather
5961 than simply leaving the insn filling to the assembler, we
5962 can make use of the knowledge of what sorts of instructions
5963 were issued in the previous group to make sure that all of
5964 the added nops are really free. */
5965 else if (ofs + len > align)
5967 int nop_count = (align - ofs) / 4;
5970 /* Insert nops before labels and branches to truely merge the
5971 execution of the nops with the previous instruction group. */
5972 where = prev_nonnote_insn (i);
5975 if (GET_CODE (where) == CODE_LABEL)
5977 rtx where2 = prev_nonnote_insn (where);
5978 if (where2 && GET_CODE (where2) == JUMP_INSN)
5981 else if (GET_CODE (where) != JUMP_INSN)
5988 emit_insn_before ((*next_nop)(&prev_in_use), where);
5989 while (--nop_count);
5993 ofs = (ofs + len) & (align - 1);
5994 prev_in_use = in_use;
5999 /* Machine dependant reorg pass. */
6005 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
6006 alpha_handle_trap_shadows (insns);
6008 /* Due to the number of extra trapb insns, don't bother fixing up
6009 alignment when trap precision is instruction. Moreover, we can
6010 only do our job when sched2 is run. */
6011 if (optimize && !optimize_size
6012 && alpha_tp != ALPHA_TP_INSN
6013 && flag_schedule_insns_after_reload)
6015 if (alpha_cpu == PROCESSOR_EV4)
6016 alpha_align_insns (insns, 8, alphaev4_next_group, alphaev4_next_nop);
6017 else if (alpha_cpu == PROCESSOR_EV5)
6018 alpha_align_insns (insns, 16, alphaev5_next_group, alphaev5_next_nop);
6022 /* Check a floating-point value for validity for a particular machine mode. */
6024 static const char * const float_strings[] =
6026 /* These are for FLOAT_VAX. */
6027 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
6028 "-1.70141173319264430e+38",
6029 "2.93873587705571877e-39", /* 2^-128 */
6030 "-2.93873587705571877e-39",
6031 /* These are for the default broken IEEE mode, which traps
6032 on infinity or denormal numbers. */
6033 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
6034 "-3.402823466385288598117e+38",
6035 "1.1754943508222875079687e-38", /* 2^-126 */
6036 "-1.1754943508222875079687e-38",
6039 static REAL_VALUE_TYPE float_values[8];
6040 static int inited_float_values = 0;
6043 check_float_value (mode, d, overflow)
6044 enum machine_mode mode;
6046 int overflow ATTRIBUTE_UNUSED;
6049 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
6052 if (inited_float_values == 0)
6055 for (i = 0; i < 8; i++)
6056 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
6058 inited_float_values = 1;
6064 REAL_VALUE_TYPE *fvptr;
6066 if (TARGET_FLOAT_VAX)
6067 fvptr = &float_values[0];
6069 fvptr = &float_values[4];
6071 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
6072 if (REAL_VALUES_LESS (fvptr[0], r))
6074 bcopy ((char *) &fvptr[0], (char *) d,
6075 sizeof (REAL_VALUE_TYPE));
6078 else if (REAL_VALUES_LESS (r, fvptr[1]))
6080 bcopy ((char *) &fvptr[1], (char *) d,
6081 sizeof (REAL_VALUE_TYPE));
6084 else if (REAL_VALUES_LESS (dconst0, r)
6085 && REAL_VALUES_LESS (r, fvptr[2]))
6087 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
6090 else if (REAL_VALUES_LESS (r, dconst0)
6091 && REAL_VALUES_LESS (fvptr[3], r))
6093 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
6103 /* Return the VMS argument type corresponding to MODE. */
6106 alpha_arg_type (mode)
6107 enum machine_mode mode;
6112 return TARGET_FLOAT_VAX ? FF : FS;
6114 return TARGET_FLOAT_VAX ? FD : FT;
6120 /* Return an rtx for an integer representing the VMS Argument Information
6124 alpha_arg_info_reg_val (cum)
6125 CUMULATIVE_ARGS cum;
6127 unsigned HOST_WIDE_INT regval = cum.num_args;
6130 for (i = 0; i < 6; i++)
6131 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
6133 return GEN_INT (regval);
6136 #include <splay-tree.h>
6138 /* Structure to collect function names for final output
6141 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
6146 enum links_kind kind;
6149 static splay_tree alpha_links;
6151 static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
6152 static void mark_alpha_links PARAMS ((void *));
6153 static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
6155 /* Protect alpha_links from garbage collection. */
6158 mark_alpha_links_node (node, data)
6159 splay_tree_node node;
6160 void *data ATTRIBUTE_UNUSED;
6162 struct alpha_links *links = (struct alpha_links *) node->value;
6163 ggc_mark_rtx (links->linkage);
6168 mark_alpha_links (ptr)
6171 splay_tree tree = *(splay_tree *) ptr;
6172 splay_tree_foreach (tree, mark_alpha_links_node, NULL);
6175 /* Make (or fake) .linkage entry for function call.
6177 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
6179 Return an SYMBOL_REF rtx for the linkage. */
6182 alpha_need_linkage (name, is_local)
6186 splay_tree_node node;
6187 struct alpha_links *al;
6194 /* Is this name already defined? */
6196 node = splay_tree_lookup (alpha_links, (splay_tree_key) name);
6199 al = (struct alpha_links *) node->value;
6202 /* Defined here but external assumed. */
6203 if (al->kind == KIND_EXTERN)
6204 al->kind = KIND_LOCAL;
6208 /* Used here but unused assumed. */
6209 if (al->kind == KIND_UNUSED)
6210 al->kind = KIND_LOCAL;
6217 alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
6218 (splay_tree_delete_key_fn) free,
6219 (splay_tree_delete_key_fn) free);
6220 ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
6223 al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
6224 name = xstrdup (name);
6226 /* Assume external if no definition. */
6227 al->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
6229 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
6230 get_identifier (name);
6232 /* Construct a SYMBOL_REF for us to call. */
6234 size_t name_len = strlen (name);
6235 char *linksym = ggc_alloc_string (NULL, name_len + 6);
6238 memcpy (linksym + 1, name, name_len);
6239 memcpy (linksym + 1 + name_len, "..lk", 5);
6240 al->linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
6243 splay_tree_insert (alpha_links, (splay_tree_key) name,
6244 (splay_tree_value) al);
6250 alpha_write_one_linkage (node, data)
6251 splay_tree_node node;
6254 const char *name = (const char *) node->key;
6255 struct alpha_links *links = (struct alpha_links *) node->value;
6256 FILE *stream = (FILE *) data;
6258 if (links->kind == KIND_UNUSED
6259 || ! TREE_SYMBOL_REFERENCED (get_identifier (name)))
6262 fprintf (stream, "$%s..lk:\n", name);
6263 if (links->kind == KIND_LOCAL)
6265 /* Local and used, build linkage pair. */
6266 fprintf (stream, "\t.quad %s..en\n", name);
6267 fprintf (stream, "\t.quad %s\n", name);
6271 /* External and used, request linkage pair. */
6272 fprintf (stream, "\t.linkage %s\n", name);
6279 alpha_write_linkage (stream)
6282 readonly_section ();
6283 fprintf (stream, "\t.align 3\n");
6284 splay_tree_foreach (alpha_links, alpha_write_one_linkage, stream);
6290 alpha_need_linkage (name, is_local)
6291 const char *name ATTRIBUTE_UNUSED;
6292 int is_local ATTRIBUTE_UNUSED;
6297 #endif /* OPEN_VMS */