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 op0 = alpha_emit_xfloating_compare (code, op0, op1);
1625 alpha_compare.fp_p = 0;
1629 /* The general case: fold the comparison code to the types of compares
1630 that we have, choosing the branch as necessary. */
1633 case EQ: case LE: case LT: case LEU: case LTU:
1635 /* We have these compares: */
1636 cmp_code = code, branch_code = NE;
1641 /* These must be reversed. */
1642 cmp_code = reverse_condition (code), branch_code = EQ;
1645 case GE: case GT: case GEU: case GTU:
1646 /* For FP, we swap them, for INT, we reverse them. */
1647 if (alpha_compare.fp_p)
1649 cmp_code = swap_condition (code);
1651 tem = op0, op0 = op1, op1 = tem;
1655 cmp_code = reverse_condition (code);
1664 if (alpha_compare.fp_p)
1669 /* When we are not as concerned about non-finite values, and we
1670 are comparing against zero, we can branch directly. */
1671 if (op1 == CONST0_RTX (DFmode))
1672 cmp_code = NIL, branch_code = code;
1673 else if (op0 == CONST0_RTX (DFmode))
1675 /* Undo the swap we probably did just above. */
1676 tem = op0, op0 = op1, op1 = tem;
1677 branch_code = swap_condition (cmp_code);
1683 /* ??? We mark the the branch mode to be CCmode to prevent the
1684 compare and branch from being combined, since the compare
1685 insn follows IEEE rules that the branch does not. */
1686 branch_mode = CCmode;
1693 /* The following optimizations are only for signed compares. */
1694 if (code != LEU && code != LTU && code != GEU && code != GTU)
1696 /* Whee. Compare and branch against 0 directly. */
1697 if (op1 == const0_rtx)
1698 cmp_code = NIL, branch_code = code;
1700 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1701 bypass between logicals and br/cmov on EV5. But we don't want to
1702 force valid immediate constants into registers needlessly. */
1703 else if (GET_CODE (op1) == CONST_INT)
1705 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1707 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1708 && (CONST_OK_FOR_LETTER_P (n, 'K')
1709 || CONST_OK_FOR_LETTER_P (n, 'L')))
1711 cmp_code = PLUS, branch_code = code;
1718 /* Force op0 into a register. */
1719 if (GET_CODE (op0) != REG)
1720 op0 = force_reg (cmp_mode, op0);
1722 /* Emit an initial compare instruction, if necessary. */
1724 if (cmp_code != NIL)
1726 tem = gen_reg_rtx (cmp_mode);
1727 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1730 /* Zero the operands. */
1731 memset (&alpha_compare, 0, sizeof (alpha_compare));
1733 /* Return the branch comparison. */
1734 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1738 /* Rewrite a comparison against zero CMP of the form
1739 (CODE (cc0) (const_int 0)) so it can be written validly in
1740 a conditional move (if_then_else CMP ...).
1741 If both of the operands that set cc0 are non-zero we must emit
1742 an insn to perform the compare (it can't be done within
1743 the conditional move). */
1745 alpha_emit_conditional_move (cmp, mode)
1747 enum machine_mode mode;
1749 enum rtx_code code = GET_CODE (cmp);
1750 enum rtx_code cmov_code = NE;
1751 rtx op0 = alpha_compare.op0;
1752 rtx op1 = alpha_compare.op1;
1753 int fp_p = alpha_compare.fp_p;
1754 enum machine_mode cmp_mode
1755 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1756 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1757 enum machine_mode cmov_mode = VOIDmode;
1758 int local_fast_math = flag_fast_math;
1761 /* Zero the operands. */
1762 memset (&alpha_compare, 0, sizeof (alpha_compare));
1764 if (fp_p != FLOAT_MODE_P (mode))
1766 enum rtx_code cmp_code;
1771 /* If we have fp<->int register move instructions, do a cmov by
1772 performing the comparison in fp registers, and move the
1773 zero/non-zero value to integer registers, where we can then
1774 use a normal cmov, or vice-versa. */
1778 case EQ: case LE: case LT: case LEU: case LTU:
1779 /* We have these compares. */
1780 cmp_code = code, code = NE;
1784 /* This must be reversed. */
1785 cmp_code = EQ, code = EQ;
1788 case GE: case GT: case GEU: case GTU:
1789 /* These must be swapped. */
1790 cmp_code = swap_condition (code);
1792 tem = op0, op0 = op1, op1 = tem;
1799 tem = gen_reg_rtx (cmp_op_mode);
1800 emit_insn (gen_rtx_SET (VOIDmode, tem,
1801 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1804 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1805 op0 = gen_lowpart (cmp_op_mode, tem);
1806 op1 = CONST0_RTX (cmp_op_mode);
1808 local_fast_math = 1;
1811 /* We may be able to use a conditional move directly.
1812 This avoids emitting spurious compares. */
1813 if (signed_comparison_operator (cmp, VOIDmode)
1814 && (!fp_p || local_fast_math)
1815 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1816 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1818 /* We can't put the comparison inside the conditional move;
1819 emit a compare instruction and put that inside the
1820 conditional move. Make sure we emit only comparisons we have;
1821 swap or reverse as necessary. */
1828 case EQ: case LE: case LT: case LEU: case LTU:
1829 /* We have these compares: */
1833 /* This must be reversed. */
1834 code = reverse_condition (code);
1838 case GE: case GT: case GEU: case GTU:
1839 /* These must be swapped. Make sure the new first operand is in
1841 code = swap_condition (code);
1842 tem = op0, op0 = op1, op1 = tem;
1843 op0 = force_reg (cmp_mode, op0);
1850 /* ??? We mark the branch mode to be CCmode to prevent the compare
1851 and cmov from being combined, since the compare insn follows IEEE
1852 rules that the cmov does not. */
1853 if (fp_p && !local_fast_math)
1856 tem = gen_reg_rtx (cmp_op_mode);
1857 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1858 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1861 /* Simplify a conditional move of two constants into a setcc with
1862 arithmetic. This is done with a splitter since combine would
1863 just undo the work if done during code generation. It also catches
1864 cases we wouldn't have before cse. */
1867 alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
1869 rtx dest, cond, t_rtx, f_rtx;
1871 HOST_WIDE_INT t, f, diff;
1872 enum machine_mode mode;
1873 rtx target, subtarget, tmp;
1875 mode = GET_MODE (dest);
1880 if (((code == NE || code == EQ) && diff < 0)
1881 || (code == GE || code == GT))
1883 code = reverse_condition (code);
1884 diff = t, t = f, f = diff;
1888 subtarget = target = dest;
1891 target = gen_lowpart (DImode, dest);
1892 if (! no_new_pseudos)
1893 subtarget = gen_reg_rtx (DImode);
1898 if (f == 0 && exact_log2 (diff) > 0
1899 /* On EV6, we've got enough shifters to make non-arithmatic shifts
1900 viable over a longer latency cmove. On EV5, the E0 slot is a
1901 scarce resource, and on EV4 shift has the same latency as a cmove. */
1902 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
1904 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
1905 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
1907 tmp = gen_rtx_ASHIFT (DImode, subtarget, GEN_INT (exact_log2 (t)));
1908 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
1910 else if (f == 0 && t == -1)
1912 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
1913 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
1915 emit_insn (gen_negdi2 (target, subtarget));
1917 else if (diff == 1 || diff == 4 || diff == 8)
1921 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
1922 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
1925 emit_insn (gen_adddi3 (target, subtarget, GEN_INT (f)));
1928 add_op = GEN_INT (f);
1929 if (sext_add_operand (add_op, mode))
1931 tmp = gen_rtx_MULT (DImode, subtarget, GEN_INT (diff));
1932 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
1933 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
1945 /* Look up the function X_floating library function name for the
1949 alpha_lookup_xfloating_lib_func (code)
1958 static const struct xfloating_op vms_xfloating_ops[] =
1960 { PLUS, "OTS$ADD_X" },
1961 { MINUS, "OTS$SUB_X" },
1962 { MULT, "OTS$MUL_X" },
1963 { DIV, "OTS$DIV_X" },
1964 { EQ, "OTS$EQL_X" },
1965 { NE, "OTS$NEQ_X" },
1966 { LT, "OTS$LSS_X" },
1967 { LE, "OTS$LEQ_X" },
1968 { GT, "OTS$GTR_X" },
1969 { GE, "OTS$GEQ_X" },
1970 { FIX, "OTS$CVTXQ" },
1971 { FLOAT, "OTS$CVTQX" },
1972 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
1973 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
1974 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
1977 static const struct xfloating_op osf_xfloating_ops[] =
1979 { PLUS, "_OtsAddX" },
1980 { MINUS, "_OtsSubX" },
1981 { MULT, "_OtsMulX" },
1982 { DIV, "_OtsDivX" },
1989 { FIX, "_OtsCvtXQ" },
1990 { FLOAT, "_OtsCvtQX" },
1991 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
1992 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
1993 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
1996 const struct xfloating_op *ops;
1997 const long n = ARRAY_SIZE (osf_xfloating_ops);
2000 /* How irritating. Nothing to key off for the table. Hardcode
2001 knowledge of the G_floating routines. */
2002 if (TARGET_FLOAT_VAX)
2004 if (TARGET_OPEN_VMS)
2006 if (code == FLOAT_EXTEND)
2007 return "OTS$CVT_FLOAT_G_X";
2008 if (code == FLOAT_TRUNCATE)
2009 return "OTS$CVT_FLOAT_X_G";
2013 if (code == FLOAT_EXTEND)
2014 return "_OtsConvertFloatGX";
2015 if (code == FLOAT_TRUNCATE)
2016 return "_OtsConvertFloatXG";
2020 if (TARGET_OPEN_VMS)
2021 ops = vms_xfloating_ops;
2023 ops = osf_xfloating_ops;
2025 for (i = 0; i < n; ++i)
2026 if (ops[i].code == code)
2032 /* Most X_floating operations take the rounding mode as an argument.
2033 Compute that here. */
2036 alpha_compute_xfloating_mode_arg (code, round)
2038 enum alpha_fp_rounding_mode round;
2044 case ALPHA_FPRM_NORM:
2047 case ALPHA_FPRM_MINF:
2050 case ALPHA_FPRM_CHOP:
2053 case ALPHA_FPRM_DYN:
2059 /* XXX For reference, round to +inf is mode = 3. */
2062 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2068 /* Emit an X_floating library function call.
2070 Note that these functions do not follow normal calling conventions:
2071 TFmode arguments are passed in two integer registers (as opposed to
2072 indirect); TFmode return values appear in R16+R17.
2074 FUNC is the function name to call.
2075 TARGET is where the output belongs.
2076 OPERANDS are the inputs.
2077 NOPERANDS is the count of inputs.
2078 EQUIV is the expression equivalent for the function.
2082 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
2089 rtx usage = NULL_RTX, tmp, reg;
2094 for (i = 0; i < noperands; ++i)
2096 switch (GET_MODE (operands[i]))
2099 reg = gen_rtx_REG (TFmode, regno);
2104 reg = gen_rtx_REG (DFmode, regno + 32);
2109 if (GET_CODE (operands[i]) != CONST_INT)
2113 reg = gen_rtx_REG (DImode, regno);
2121 emit_move_insn (reg, operands[i]);
2122 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2125 switch (GET_MODE (target))
2128 reg = gen_rtx_REG (TFmode, 16);
2131 reg = gen_rtx_REG (DFmode, 32);
2134 reg = gen_rtx_REG (DImode, 0);
2140 tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
2141 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2142 const0_rtx, const0_rtx));
2143 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2148 emit_libcall_block (tmp, target, reg, equiv);
2151 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2154 alpha_emit_xfloating_arith (code, operands)
2160 rtx out_operands[3];
2162 func = alpha_lookup_xfloating_lib_func (code);
2163 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2165 out_operands[0] = operands[1];
2166 out_operands[1] = operands[2];
2167 out_operands[2] = GEN_INT (mode);
2168 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2169 gen_rtx_fmt_ee (code, TFmode, operands[1],
2173 /* Emit an X_floating library function call for a comparison. */
2176 alpha_emit_xfloating_compare (code, op0, op1)
2181 rtx out, operands[2];
2183 func = alpha_lookup_xfloating_lib_func (code);
2187 out = gen_reg_rtx (DImode);
2189 /* ??? Strange equiv cause what's actually returned is -1,0,1, not a
2190 proper boolean value. */
2191 alpha_emit_xfloating_libcall (func, out, operands, 2,
2192 gen_rtx_COMPARE (TFmode, op0, op1));
2197 /* Emit an X_floating library function call for a conversion. */
2200 alpha_emit_xfloating_cvt (code, operands)
2204 int noperands = 1, mode;
2205 rtx out_operands[2];
2208 func = alpha_lookup_xfloating_lib_func (code);
2210 out_operands[0] = operands[1];
2215 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2216 out_operands[1] = GEN_INT (mode);
2219 case FLOAT_TRUNCATE:
2220 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2221 out_operands[1] = GEN_INT (mode);
2228 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
2229 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
2234 alpha_split_tfmode_pair (operands)
2237 if (GET_CODE (operands[1]) == REG)
2239 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
2240 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
2242 else if (GET_CODE (operands[1]) == MEM)
2244 operands[3] = change_address (operands[1], DImode,
2245 plus_constant (XEXP (operands[1], 0), 8));
2246 operands[2] = change_address (operands[1], DImode, NULL_RTX);
2248 else if (operands[1] == CONST0_RTX (TFmode))
2249 operands[2] = operands[3] = const0_rtx;
2253 if (GET_CODE (operands[0]) == REG)
2255 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
2256 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
2258 else if (GET_CODE (operands[0]) == MEM)
2260 operands[1] = change_address (operands[0], DImode,
2261 plus_constant (XEXP (operands[0], 0), 8));
2262 operands[0] = change_address (operands[0], DImode, NULL_RTX);
2268 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
2272 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
2273 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
2274 lda r3,X(r11) lda r3,X+2(r11)
2275 extwl r1,r3,r1 extql r1,r3,r1
2276 extwh r2,r3,r2 extqh r2,r3,r2
2277 or r1.r2.r1 or r1,r2,r1
2280 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
2281 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
2282 lda r3,X(r11) lda r3,X(r11)
2283 extll r1,r3,r1 extll r1,r3,r1
2284 extlh r2,r3,r2 extlh r2,r3,r2
2285 or r1.r2.r1 addl r1,r2,r1
2287 quad: ldq_u r1,X(r11)
2296 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
2298 HOST_WIDE_INT size, ofs;
2301 rtx meml, memh, addr, extl, exth, tmp;
2302 enum machine_mode mode;
2304 meml = gen_reg_rtx (DImode);
2305 memh = gen_reg_rtx (DImode);
2306 addr = gen_reg_rtx (DImode);
2307 extl = gen_reg_rtx (DImode);
2308 exth = gen_reg_rtx (DImode);
2310 /* AND addresses cannot be in any alias set, since they may implicitly
2311 alias surrounding code. Ideally we'd have some alias set that
2312 covered all types except those with alignment 8 or higher. */
2314 tmp = change_address (mem, DImode,
2315 gen_rtx_AND (DImode,
2316 plus_constant (XEXP (mem, 0), ofs),
2318 MEM_ALIAS_SET (tmp) = 0;
2319 emit_move_insn (meml, tmp);
2321 tmp = change_address (mem, DImode,
2322 gen_rtx_AND (DImode,
2323 plus_constant (XEXP (mem, 0),
2326 MEM_ALIAS_SET (tmp) = 0;
2327 emit_move_insn (memh, tmp);
2329 if (sign && size == 2)
2331 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
2333 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
2334 emit_insn (gen_extqh (exth, memh, addr));
2336 /* We must use tgt here for the target. Alpha-vms port fails if we use
2337 addr for the target, because addr is marked as a pointer and combine
2338 knows that pointers are always sign-extended 32 bit values. */
2339 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
2340 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
2341 addr, 1, OPTAB_WIDEN);
2345 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
2346 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
2350 emit_insn (gen_extwh (exth, memh, addr));
2355 emit_insn (gen_extlh (exth, memh, addr));
2360 emit_insn (gen_extqh (exth, memh, addr));
2368 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
2369 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
2374 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
2377 /* Similarly, use ins and msk instructions to perform unaligned stores. */
2380 alpha_expand_unaligned_store (dst, src, size, ofs)
2382 HOST_WIDE_INT size, ofs;
2384 rtx dstl, dsth, addr, insl, insh, meml, memh;
2386 dstl = gen_reg_rtx (DImode);
2387 dsth = gen_reg_rtx (DImode);
2388 insl = gen_reg_rtx (DImode);
2389 insh = gen_reg_rtx (DImode);
2391 /* AND addresses cannot be in any alias set, since they may implicitly
2392 alias surrounding code. Ideally we'd have some alias set that
2393 covered all types except those with alignment 8 or higher. */
2395 meml = change_address (dst, DImode,
2396 gen_rtx_AND (DImode,
2397 plus_constant (XEXP (dst, 0), ofs),
2399 MEM_ALIAS_SET (meml) = 0;
2401 memh = change_address (dst, DImode,
2402 gen_rtx_AND (DImode,
2403 plus_constant (XEXP (dst, 0),
2406 MEM_ALIAS_SET (memh) = 0;
2408 emit_move_insn (dsth, memh);
2409 emit_move_insn (dstl, meml);
2410 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
2412 if (src != const0_rtx)
2414 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
2415 GEN_INT (size*8), addr));
2420 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
2423 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
2426 emit_insn (gen_insql (insl, src, addr));
2431 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
2436 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
2439 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
2443 #if HOST_BITS_PER_WIDE_INT == 32
2444 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
2446 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
2448 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
2453 if (src != const0_rtx)
2455 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
2456 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
2459 /* Must store high before low for degenerate case of aligned. */
2460 emit_move_insn (memh, dsth);
2461 emit_move_insn (meml, dstl);
2464 /* The block move code tries to maximize speed by separating loads and
2465 stores at the expense of register pressure: we load all of the data
2466 before we store it back out. There are two secondary effects worth
2467 mentioning, that this speeds copying to/from aligned and unaligned
2468 buffers, and that it makes the code significantly easier to write. */
2470 #define MAX_MOVE_WORDS 8
2472 /* Load an integral number of consecutive unaligned quadwords. */
2475 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
2478 HOST_WIDE_INT words, ofs;
2480 rtx const im8 = GEN_INT (-8);
2481 rtx const i64 = GEN_INT (64);
2482 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
2483 rtx sreg, areg, tmp;
2486 /* Generate all the tmp registers we need. */
2487 for (i = 0; i < words; ++i)
2489 data_regs[i] = out_regs[i];
2490 ext_tmps[i] = gen_reg_rtx (DImode);
2492 data_regs[words] = gen_reg_rtx (DImode);
2495 smem = change_address (smem, GET_MODE (smem),
2496 plus_constant (XEXP (smem, 0), ofs));
2498 /* Load up all of the source data. */
2499 for (i = 0; i < words; ++i)
2501 tmp = change_address (smem, DImode,
2502 gen_rtx_AND (DImode,
2503 plus_constant (XEXP(smem,0), 8*i),
2505 MEM_ALIAS_SET (tmp) = 0;
2506 emit_move_insn (data_regs[i], tmp);
2509 tmp = change_address (smem, DImode,
2510 gen_rtx_AND (DImode,
2511 plus_constant (XEXP(smem,0), 8*words - 1),
2513 MEM_ALIAS_SET (tmp) = 0;
2514 emit_move_insn (data_regs[words], tmp);
2516 /* Extract the half-word fragments. Unfortunately DEC decided to make
2517 extxh with offset zero a noop instead of zeroing the register, so
2518 we must take care of that edge condition ourselves with cmov. */
2520 sreg = copy_addr_to_reg (XEXP (smem, 0));
2521 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
2523 for (i = 0; i < words; ++i)
2525 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
2527 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
2528 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
2529 gen_rtx_IF_THEN_ELSE (DImode,
2530 gen_rtx_EQ (DImode, areg,
2532 const0_rtx, ext_tmps[i])));
2535 /* Merge the half-words into whole words. */
2536 for (i = 0; i < words; ++i)
2538 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
2539 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
2543 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
2544 may be NULL to store zeros. */
2547 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
2550 HOST_WIDE_INT words, ofs;
2552 rtx const im8 = GEN_INT (-8);
2553 rtx const i64 = GEN_INT (64);
2554 #if HOST_BITS_PER_WIDE_INT == 32
2555 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
2557 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
2559 rtx ins_tmps[MAX_MOVE_WORDS];
2560 rtx st_tmp_1, st_tmp_2, dreg;
2561 rtx st_addr_1, st_addr_2;
2564 /* Generate all the tmp registers we need. */
2565 if (data_regs != NULL)
2566 for (i = 0; i < words; ++i)
2567 ins_tmps[i] = gen_reg_rtx(DImode);
2568 st_tmp_1 = gen_reg_rtx(DImode);
2569 st_tmp_2 = gen_reg_rtx(DImode);
2572 dmem = change_address (dmem, GET_MODE (dmem),
2573 plus_constant (XEXP (dmem, 0), ofs));
2576 st_addr_2 = change_address (dmem, DImode,
2577 gen_rtx_AND (DImode,
2578 plus_constant (XEXP(dmem,0),
2581 MEM_ALIAS_SET (st_addr_2) = 0;
2583 st_addr_1 = change_address (dmem, DImode,
2584 gen_rtx_AND (DImode,
2587 MEM_ALIAS_SET (st_addr_1) = 0;
2589 /* Load up the destination end bits. */
2590 emit_move_insn (st_tmp_2, st_addr_2);
2591 emit_move_insn (st_tmp_1, st_addr_1);
2593 /* Shift the input data into place. */
2594 dreg = copy_addr_to_reg (XEXP (dmem, 0));
2595 if (data_regs != NULL)
2597 for (i = words-1; i >= 0; --i)
2599 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
2600 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2602 for (i = words-1; i > 0; --i)
2604 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2605 ins_tmps[i-1], ins_tmps[i-1], 1,
2610 /* Split and merge the ends with the destination data. */
2611 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2612 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2614 if (data_regs != NULL)
2616 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2617 st_tmp_2, 1, OPTAB_WIDEN);
2618 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2619 st_tmp_1, 1, OPTAB_WIDEN);
2623 emit_move_insn (st_addr_2, st_tmp_2);
2624 for (i = words-1; i > 0; --i)
2626 rtx tmp = change_address (dmem, DImode,
2627 gen_rtx_AND (DImode,
2628 plus_constant(XEXP (dmem,0), i*8),
2630 MEM_ALIAS_SET (tmp) = 0;
2631 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
2633 emit_move_insn (st_addr_1, st_tmp_1);
2637 /* Expand string/block move operations.
2639 operands[0] is the pointer to the destination.
2640 operands[1] is the pointer to the source.
2641 operands[2] is the number of bytes to move.
2642 operands[3] is the alignment. */
2645 alpha_expand_block_move (operands)
2648 rtx bytes_rtx = operands[2];
2649 rtx align_rtx = operands[3];
2650 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2651 unsigned HOST_WIDE_INT bytes = orig_bytes;
2652 unsigned HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
2653 unsigned HOST_WIDE_INT dst_align = src_align;
2654 rtx orig_src = operands[1];
2655 rtx orig_dst = operands[0];
2656 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
2658 unsigned int i, words, ofs, nregs = 0;
2660 if (orig_bytes <= 0)
2662 else if (bytes > MAX_MOVE_WORDS * BITS_PER_UNIT)
2665 /* Look for additional alignment information from recorded register info. */
2667 tmp = XEXP (orig_src, 0);
2668 if (GET_CODE (tmp) == REG)
2669 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2670 else if (GET_CODE (tmp) == PLUS
2671 && GET_CODE (XEXP (tmp, 0)) == REG
2672 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2674 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2675 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2679 if (a >= 64 && c % 8 == 0)
2681 else if (a >= 32 && c % 4 == 0)
2683 else if (a >= 16 && c % 2 == 0)
2688 tmp = XEXP (orig_dst, 0);
2689 if (GET_CODE (tmp) == REG)
2690 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2691 else if (GET_CODE (tmp) == PLUS
2692 && GET_CODE (XEXP (tmp, 0)) == REG
2693 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2695 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2696 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2700 if (a >= 64 && c % 8 == 0)
2702 else if (a >= 32 && c % 4 == 0)
2704 else if (a >= 16 && c % 2 == 0)
2709 /* Load the entire block into registers. */
2710 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2712 enum machine_mode mode;
2714 tmp = XEXP (XEXP (orig_src, 0), 0);
2716 /* Don't use the existing register if we're reading more than
2717 is held in the register. Nor if there is not a mode that
2718 handles the exact size. */
2719 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2721 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2725 data_regs[nregs] = gen_lowpart (DImode, tmp);
2726 data_regs[nregs+1] = gen_highpart (DImode, tmp);
2730 data_regs[nregs++] = gen_lowpart (mode, tmp);
2735 /* No appropriate mode; fall back on memory. */
2736 orig_src = change_address (orig_src, GET_MODE (orig_src),
2737 copy_addr_to_reg (XEXP (orig_src, 0)));
2741 if (src_align >= 64 && bytes >= 8)
2745 for (i = 0; i < words; ++i)
2746 data_regs[nregs + i] = gen_reg_rtx(DImode);
2748 for (i = 0; i < words; ++i)
2749 emit_move_insn (data_regs[nregs + i],
2750 change_address (orig_src, DImode,
2751 plus_constant (XEXP (orig_src, 0),
2759 if (src_align >= 32 && bytes >= 4)
2763 for (i = 0; i < words; ++i)
2764 data_regs[nregs + i] = gen_reg_rtx(SImode);
2766 for (i = 0; i < words; ++i)
2767 emit_move_insn (data_regs[nregs + i],
2768 change_address (orig_src, SImode,
2769 plus_constant (XEXP (orig_src, 0),
2781 for (i = 0; i < words+1; ++i)
2782 data_regs[nregs + i] = gen_reg_rtx(DImode);
2784 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2792 if (! TARGET_BWX && bytes >= 8)
2794 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2795 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2800 if (! TARGET_BWX && bytes >= 4)
2802 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2803 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2810 if (src_align >= 16)
2813 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2814 emit_move_insn (tmp,
2815 change_address (orig_src, HImode,
2816 plus_constant (XEXP (orig_src, 0),
2820 } while (bytes >= 2);
2823 else if (! TARGET_BWX)
2825 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2826 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2834 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2835 emit_move_insn (tmp,
2836 change_address (orig_src, QImode,
2837 plus_constant (XEXP (orig_src, 0),
2845 if (nregs > ARRAY_SIZE (data_regs))
2848 /* Now save it back out again. */
2852 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2854 enum machine_mode mode;
2855 tmp = XEXP (XEXP (orig_dst, 0), 0);
2857 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2858 if (GET_MODE (tmp) == mode)
2862 emit_move_insn (tmp, data_regs[0]);
2867 else if (nregs == 2 && mode == TImode)
2869 /* Undo the subregging done above when copying between
2870 two TImode registers. */
2871 if (GET_CODE (data_regs[0]) == SUBREG
2872 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
2873 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
2879 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
2880 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
2884 emit_no_conflict_block (seq, tmp, data_regs[0],
2885 data_regs[1], NULL_RTX);
2893 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2894 /* ??? Optimize mode < dst_mode with strict_low_part. */
2896 /* No appropriate mode; fall back on memory. We can speed things
2897 up by recognizing extra alignment information. */
2898 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2899 copy_addr_to_reg (XEXP (orig_dst, 0)));
2900 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2903 /* Write out the data in whatever chunks reading the source allowed. */
2904 if (dst_align >= 64)
2906 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2908 emit_move_insn (change_address (orig_dst, DImode,
2909 plus_constant (XEXP (orig_dst, 0),
2917 if (dst_align >= 32)
2919 /* If the source has remaining DImode regs, write them out in
2921 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2923 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2924 NULL_RTX, 1, OPTAB_WIDEN);
2926 emit_move_insn (change_address (orig_dst, SImode,
2927 plus_constant (XEXP (orig_dst, 0),
2929 gen_lowpart (SImode, data_regs[i]));
2930 emit_move_insn (change_address (orig_dst, SImode,
2931 plus_constant (XEXP (orig_dst, 0),
2933 gen_lowpart (SImode, tmp));
2938 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2940 emit_move_insn (change_address(orig_dst, SImode,
2941 plus_constant (XEXP (orig_dst, 0),
2949 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2951 /* Write out a remaining block of words using unaligned methods. */
2953 for (words = 1; i + words < nregs; words++)
2954 if (GET_MODE (data_regs[i + words]) != DImode)
2958 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2960 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
2967 /* Due to the above, this won't be aligned. */
2968 /* ??? If we have more than one of these, consider constructing full
2969 words in registers and using alpha_expand_unaligned_store_words. */
2970 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2972 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2977 if (dst_align >= 16)
2978 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2980 emit_move_insn (change_address (orig_dst, HImode,
2981 plus_constant (XEXP (orig_dst, 0),
2988 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2990 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2995 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2997 emit_move_insn (change_address (orig_dst, QImode,
2998 plus_constant (XEXP (orig_dst, 0),
3014 alpha_expand_block_clear (operands)
3017 rtx bytes_rtx = operands[1];
3018 rtx align_rtx = operands[2];
3019 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3020 unsigned HOST_WIDE_INT bytes = orig_bytes;
3021 unsigned HOST_WIDE_INT align = INTVAL (align_rtx);
3022 rtx orig_dst = operands[0];
3024 unsigned HOST_WIDE_INT i, words, ofs = 0;
3026 if (orig_bytes <= 0)
3028 if (bytes > MAX_MOVE_WORDS*8)
3031 /* Look for stricter alignment. */
3032 tmp = XEXP (orig_dst, 0);
3033 if (GET_CODE (tmp) == REG)
3034 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3035 else if (GET_CODE (tmp) == PLUS
3036 && GET_CODE (XEXP (tmp, 0)) == REG
3037 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3039 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3040 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3044 if (a >= 64 && c % 8 == 0)
3046 else if (a >= 32 && c % 4 == 0)
3048 else if (a >= 16 && c % 2 == 0)
3053 else if (GET_CODE (tmp) == ADDRESSOF)
3055 enum machine_mode mode;
3057 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
3058 if (GET_MODE (XEXP (tmp, 0)) == mode)
3060 emit_move_insn (XEXP (tmp, 0), const0_rtx);
3064 /* No appropriate mode; fall back on memory. */
3065 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
3066 copy_addr_to_reg (tmp));
3067 align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));
3070 /* Handle a block of contiguous words first. */
3072 if (align >= 64 && bytes >= 8)
3076 for (i = 0; i < words; ++i)
3077 emit_move_insn (change_address(orig_dst, DImode,
3078 plus_constant (XEXP (orig_dst, 0),
3086 if (align >= 16 && bytes >= 4)
3090 for (i = 0; i < words; ++i)
3091 emit_move_insn (change_address (orig_dst, SImode,
3092 plus_constant (XEXP (orig_dst, 0),
3104 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
3110 /* Next clean up any trailing pieces. We know from the contiguous
3111 block move that there are no aligned SImode or DImode hunks left. */
3113 if (! TARGET_BWX && bytes >= 8)
3115 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
3120 if (!TARGET_BWX && bytes >= 4)
3122 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
3132 emit_move_insn (change_address (orig_dst, HImode,
3133 plus_constant (XEXP (orig_dst, 0),
3138 } while (bytes >= 2);
3140 else if (! TARGET_BWX)
3142 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
3150 emit_move_insn (change_address (orig_dst, QImode,
3151 plus_constant (XEXP (orig_dst, 0),
3161 /* Adjust the cost of a scheduling dependency. Return the new cost of
3162 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
3165 alpha_adjust_cost (insn, link, dep_insn, cost)
3172 enum attr_type insn_type, dep_insn_type;
3174 /* If the dependence is an anti-dependence, there is no cost. For an
3175 output dependence, there is sometimes a cost, but it doesn't seem
3176 worth handling those few cases. */
3178 if (REG_NOTE_KIND (link) != 0)
3181 /* If we can't recognize the insns, we can't really do anything. */
3182 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3185 insn_type = get_attr_type (insn);
3186 dep_insn_type = get_attr_type (dep_insn);
3188 /* Bring in the user-defined memory latency. */
3189 if (dep_insn_type == TYPE_ILD
3190 || dep_insn_type == TYPE_FLD
3191 || dep_insn_type == TYPE_LDSYM)
3192 cost += alpha_memory_latency-1;
3197 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
3198 being stored, we can sometimes lower the cost. */
3200 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
3201 && (set = single_set (dep_insn)) != 0
3202 && GET_CODE (PATTERN (insn)) == SET
3203 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
3205 switch (dep_insn_type)
3209 /* No savings here. */
3213 /* In these cases, we save one cycle. */
3217 /* In all other cases, we save two cycles. */
3218 return MAX (0, cost - 2);
3222 /* Another case that needs adjustment is an arithmetic or logical
3223 operation. It's cost is usually one cycle, but we default it to
3224 two in the MD file. The only case that it is actually two is
3225 for the address in loads, stores, and jumps. */
3227 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
3242 /* The final case is when a compare feeds into an integer branch;
3243 the cost is only one cycle in that case. */
3245 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
3250 /* And the lord DEC saith: "A special bypass provides an effective
3251 latency of 0 cycles for an ICMP or ILOG insn producing the test
3252 operand of an IBR or ICMOV insn." */
3254 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
3255 && (set = single_set (dep_insn)) != 0)
3257 /* A branch only has one input. This must be it. */
3258 if (insn_type == TYPE_IBR)
3260 /* A conditional move has three, make sure it is the test. */
3261 if (insn_type == TYPE_ICMOV
3262 && GET_CODE (set_src = PATTERN (insn)) == SET
3263 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
3264 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
3268 /* "The multiplier is unable to receive data from IEU bypass paths.
3269 The instruction issues at the expected time, but its latency is
3270 increased by the time it takes for the input data to become
3271 available to the multiplier" -- which happens in pipeline stage
3272 six, when results are comitted to the register file. */
3274 if (insn_type == TYPE_IMUL)
3276 switch (dep_insn_type)
3278 /* These insns produce their results in pipeline stage five. */
3285 /* Other integer insns produce results in pipeline stage four. */
3293 /* There is additional latency to move the result of (most) FP
3294 operations anywhere but the FP register file. */
3296 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
3297 && (dep_insn_type == TYPE_FADD ||
3298 dep_insn_type == TYPE_FMUL ||
3299 dep_insn_type == TYPE_FCMOV))
3305 /* Otherwise, return the default cost. */
3309 /* Functions to save and restore alpha_return_addr_rtx. */
3312 alpha_init_machine_status (p)
3316 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
3320 alpha_mark_machine_status (p)
3323 struct machine_function *machine = p->machine;
3325 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
3326 ggc_mark_rtx (machine->ra_rtx);
3329 /* Start the ball rolling with RETURN_ADDR_RTX. */
3332 alpha_return_addr (count, frame)
3334 rtx frame ATTRIBUTE_UNUSED;
3341 reg = cfun->machine->ra_rtx;
3344 /* No rtx yet. Invent one, and initialize it from $26 in
3346 reg = gen_reg_rtx (Pmode);
3347 cfun->machine->ra_rtx = reg;
3348 init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
3350 /* Emit the insn to the prologue with the other argument copies. */
3351 push_topmost_sequence ();
3352 emit_insn_after (init, get_insns ());
3353 pop_topmost_sequence ();
3360 alpha_ra_ever_killed ()
3364 #ifdef ASM_OUTPUT_MI_THUNK
3365 if (current_function_is_thunk)
3368 if (!cfun->machine->ra_rtx)
3369 return regs_ever_live[REG_RA];
3371 push_topmost_sequence ();
3373 pop_topmost_sequence ();
3375 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
3379 /* Print an operand. Recognize special options, documented below. */
3382 print_operand (file, x, code)
3392 /* Print the assembler name of the current function. */
3393 assemble_name (file, alpha_fnname);
3397 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
3398 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
3399 mode. alpha_fprm controls which suffix is generated. */
3402 case ALPHA_FPRM_NORM:
3404 case ALPHA_FPRM_MINF:
3407 case ALPHA_FPRM_CHOP:
3410 case ALPHA_FPRM_DYN:
3419 /* Generates trap-mode suffix for instructions that accept the su
3420 suffix only (cmpt et al). */
3421 if (alpha_fptm >= ALPHA_FPTM_SU)
3426 /* Generates trap-mode suffix for instructions that accept the
3427 v and sv suffix. The only instruction that needs this is cvtql. */
3436 case ALPHA_FPTM_SUI:
3443 /* Generates trap-mode suffix for instructions that accept the
3444 v, sv, and svi suffix. The only instruction that needs this
3456 case ALPHA_FPTM_SUI:
3457 fputs ("svi", file);
3463 /* Generates trap-mode suffix for instructions that accept the u, su,
3464 and sui suffix. This is the bulk of the IEEE floating point
3465 instructions (addt et al). */
3476 case ALPHA_FPTM_SUI:
3477 fputs ("sui", file);
3483 /* Generates trap-mode suffix for instructions that accept the sui
3484 suffix (cvtqt and cvtqs). */
3489 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
3491 case ALPHA_FPTM_SUI:
3492 fputs ("sui", file);
3498 /* Generates single precision instruction suffix. */
3499 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
3503 /* Generates double precision instruction suffix. */
3504 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
3508 /* If this operand is the constant zero, write it as "$31". */
3509 if (GET_CODE (x) == REG)
3510 fprintf (file, "%s", reg_names[REGNO (x)]);
3511 else if (x == CONST0_RTX (GET_MODE (x)))
3512 fprintf (file, "$31");
3514 output_operand_lossage ("invalid %%r value");
3519 /* Similar, but for floating-point. */
3520 if (GET_CODE (x) == REG)
3521 fprintf (file, "%s", reg_names[REGNO (x)]);
3522 else if (x == CONST0_RTX (GET_MODE (x)))
3523 fprintf (file, "$f31");
3525 output_operand_lossage ("invalid %%R value");
3530 /* Write the 1's complement of a constant. */
3531 if (GET_CODE (x) != CONST_INT)
3532 output_operand_lossage ("invalid %%N value");
3534 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
3538 /* Write 1 << C, for a constant C. */
3539 if (GET_CODE (x) != CONST_INT)
3540 output_operand_lossage ("invalid %%P value");
3542 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
3546 /* Write the high-order 16 bits of a constant, sign-extended. */
3547 if (GET_CODE (x) != CONST_INT)
3548 output_operand_lossage ("invalid %%h value");
3550 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
3554 /* Write the low-order 16 bits of a constant, sign-extended. */
3555 if (GET_CODE (x) != CONST_INT)
3556 output_operand_lossage ("invalid %%L value");
3558 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3559 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
3563 /* Write mask for ZAP insn. */
3564 if (GET_CODE (x) == CONST_DOUBLE)
3566 HOST_WIDE_INT mask = 0;
3567 HOST_WIDE_INT value;
3569 value = CONST_DOUBLE_LOW (x);
3570 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3575 value = CONST_DOUBLE_HIGH (x);
3576 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3579 mask |= (1 << (i + sizeof (int)));
3581 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
3584 else if (GET_CODE (x) == CONST_INT)
3586 HOST_WIDE_INT mask = 0, value = INTVAL (x);
3588 for (i = 0; i < 8; i++, value >>= 8)
3592 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
3595 output_operand_lossage ("invalid %%m value");
3599 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
3600 if (GET_CODE (x) != CONST_INT
3601 || (INTVAL (x) != 8 && INTVAL (x) != 16
3602 && INTVAL (x) != 32 && INTVAL (x) != 64))
3603 output_operand_lossage ("invalid %%M value");
3605 fprintf (file, "%s",
3606 (INTVAL (x) == 8 ? "b"
3607 : INTVAL (x) == 16 ? "w"
3608 : INTVAL (x) == 32 ? "l"
3613 /* Similar, except do it from the mask. */
3614 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3615 fprintf (file, "b");
3616 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3617 fprintf (file, "w");
3618 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3619 fprintf (file, "l");
3620 #if HOST_BITS_PER_WIDE_INT == 32
3621 else if (GET_CODE (x) == CONST_DOUBLE
3622 && CONST_DOUBLE_HIGH (x) == 0
3623 && CONST_DOUBLE_LOW (x) == -1)
3624 fprintf (file, "l");
3625 else if (GET_CODE (x) == CONST_DOUBLE
3626 && CONST_DOUBLE_HIGH (x) == -1
3627 && CONST_DOUBLE_LOW (x) == -1)
3628 fprintf (file, "q");
3630 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3631 fprintf (file, "q");
3632 else if (GET_CODE (x) == CONST_DOUBLE
3633 && CONST_DOUBLE_HIGH (x) == 0
3634 && CONST_DOUBLE_LOW (x) == -1)
3635 fprintf (file, "q");
3638 output_operand_lossage ("invalid %%U value");
3642 /* Write the constant value divided by 8. */
3643 if (GET_CODE (x) != CONST_INT
3644 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3645 && (INTVAL (x) & 7) != 8)
3646 output_operand_lossage ("invalid %%s value");
3648 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3652 /* Same, except compute (64 - c) / 8 */
3654 if (GET_CODE (x) != CONST_INT
3655 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3656 && (INTVAL (x) & 7) != 8)
3657 output_operand_lossage ("invalid %%s value");
3659 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
3662 case 'C': case 'D': case 'c': case 'd':
3663 /* Write out comparison name. */
3665 enum rtx_code c = GET_CODE (x);
3667 if (GET_RTX_CLASS (c) != '<')
3668 output_operand_lossage ("invalid %%C value");
3671 c = reverse_condition (c);
3672 else if (code == 'c')
3673 c = swap_condition (c);
3674 else if (code == 'd')
3675 c = swap_condition (reverse_condition (c));
3678 fprintf (file, "ule");
3680 fprintf (file, "ult");
3681 else if (c == UNORDERED)
3682 fprintf (file, "un");
3684 fprintf (file, "%s", GET_RTX_NAME (c));
3689 /* Write the divide or modulus operator. */
3690 switch (GET_CODE (x))
3693 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
3696 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
3699 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
3702 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
3705 output_operand_lossage ("invalid %%E value");
3711 /* Write "_u" for unaligned access. */
3712 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
3713 fprintf (file, "_u");
3717 if (GET_CODE (x) == REG)
3718 fprintf (file, "%s", reg_names[REGNO (x)]);
3719 else if (GET_CODE (x) == MEM)
3720 output_address (XEXP (x, 0));
3722 output_addr_const (file, x);
3726 output_operand_lossage ("invalid %%xn code");
3731 print_operand_address (file, addr)
3736 HOST_WIDE_INT offset = 0;
3738 if (GET_CODE (addr) == AND)
3739 addr = XEXP (addr, 0);
3741 if (GET_CODE (addr) == PLUS
3742 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3744 offset = INTVAL (XEXP (addr, 1));
3745 addr = XEXP (addr, 0);
3747 if (GET_CODE (addr) == REG)
3748 basereg = REGNO (addr);
3749 else if (GET_CODE (addr) == SUBREG
3750 && GET_CODE (SUBREG_REG (addr)) == REG)
3751 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
3752 else if (GET_CODE (addr) == CONST_INT)
3753 offset = INTVAL (addr);
3757 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
3758 fprintf (file, "($%d)", basereg);
3761 /* Emit RTL insns to initialize the variable parts of a trampoline at
3762 TRAMP. FNADDR is an RTX for the address of the function's pure
3763 code. CXT is an RTX for the static chain value for the function.
3765 The three offset parameters are for the individual template's
3766 layout. A JMPOFS < 0 indicates that the trampoline does not
3767 contain instructions at all.
3769 We assume here that a function will be called many more times than
3770 its address is taken (e.g., it might be passed to qsort), so we
3771 take the trouble to initialize the "hint" field in the JMP insn.
3772 Note that the hint field is PC (new) + 4 * bits 13:0. */
3775 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
3776 rtx tramp, fnaddr, cxt;
3777 int fnofs, cxtofs, jmpofs;
3779 rtx temp, temp1, addr;
3780 /* VMS really uses DImode pointers in memory at this point. */
3781 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
3783 #ifdef POINTERS_EXTEND_UNSIGNED
3784 fnaddr = convert_memory_address (mode, fnaddr);
3785 cxt = convert_memory_address (mode, cxt);
3788 /* Store function address and CXT. */
3789 addr = memory_address (mode, plus_constant (tramp, fnofs));
3790 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
3791 addr = memory_address (mode, plus_constant (tramp, cxtofs));
3792 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
3794 /* This has been disabled since the hint only has a 32k range, and in
3795 no existing OS is the stack within 32k of the text segment. */
3796 if (0 && jmpofs >= 0)
3798 /* Compute hint value. */
3799 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3800 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3802 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3803 build_int_2 (2, 0), NULL_RTX, 1);
3804 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3806 /* Merge in the hint. */
3807 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3808 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
3809 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3810 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3812 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
3815 #ifdef TRANSFER_FROM_TRAMPOLINE
3816 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
3817 0, VOIDmode, 1, addr, Pmode);
3821 emit_insn (gen_imb ());
3824 /* Determine where to put an argument to a function.
3825 Value is zero to push the argument on the stack,
3826 or a hard register in which to store the argument.
3828 MODE is the argument's machine mode.
3829 TYPE is the data type of the argument (as a tree).
3830 This is null for libcalls where that information may
3832 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3833 the preceding args and about the function being called.
3834 NAMED is nonzero if this argument is a named parameter
3835 (otherwise it is an extra parameter matching an ellipsis).
3837 On Alpha the first 6 words of args are normally in registers
3838 and the rest are pushed. */
3841 function_arg (cum, mode, type, named)
3842 CUMULATIVE_ARGS cum;
3843 enum machine_mode mode;
3845 int named ATTRIBUTE_UNUSED;
3855 /* VOID is passed as a special flag for "last argument". */
3856 if (type == void_type_node)
3858 else if (MUST_PASS_IN_STACK (mode, type))
3860 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
3863 if (mode == VOIDmode)
3864 return alpha_arg_info_reg_val (cum);
3866 num_args = cum.num_args;
3867 if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
3869 #endif /* OPEN_VMS */
3870 else if (TARGET_FPREGS
3871 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3872 || GET_MODE_CLASS (mode) == MODE_FLOAT))
3877 return gen_rtx_REG (mode, num_args + basereg);
3881 alpha_build_va_list ()
3883 tree base, ofs, record, type_decl;
3885 if (TARGET_OPEN_VMS)
3886 return ptr_type_node;
3888 record = make_lang_type (RECORD_TYPE);
3889 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
3890 TREE_CHAIN (record) = type_decl;
3891 TYPE_NAME (record) = type_decl;
3893 /* C++? SET_IS_AGGR_TYPE (record, 1); */
3895 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
3897 DECL_FIELD_CONTEXT (ofs) = record;
3899 base = build_decl (FIELD_DECL, get_identifier ("__base"),
3901 DECL_FIELD_CONTEXT (base) = record;
3902 TREE_CHAIN (base) = ofs;
3904 TYPE_FIELDS (record) = base;
3905 layout_type (record);
3911 alpha_va_start (stdarg_p, valist, nextarg)
3914 rtx nextarg ATTRIBUTE_UNUSED;
3916 HOST_WIDE_INT offset;
3917 tree t, offset_field, base_field;
3919 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
3922 if (TARGET_OPEN_VMS)
3923 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
3925 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
3926 up by 48, storing fp arg registers in the first 48 bytes, and the
3927 integer arg registers in the next 48 bytes. This is only done,
3928 however, if any integer registers need to be stored.
3930 If no integer registers need be stored, then we must subtract 48
3931 in order to account for the integer arg registers which are counted
3932 in argsize above, but which are not actually stored on the stack. */
3934 if (NUM_ARGS <= 5 + stdarg_p)
3935 offset = 6 * UNITS_PER_WORD;
3937 offset = -6 * UNITS_PER_WORD;
3939 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3940 offset_field = TREE_CHAIN (base_field);
3942 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3943 valist, base_field);
3944 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3945 valist, offset_field);
3947 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3948 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
3949 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
3950 TREE_SIDE_EFFECTS (t) = 1;
3951 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3953 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
3954 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
3955 TREE_SIDE_EFFECTS (t) = 1;
3956 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3960 alpha_va_arg (valist, type)
3963 HOST_WIDE_INT tsize;
3966 tree offset_field, base_field, addr_tree, addend;
3967 tree wide_type, wide_ofs;
3969 if (TARGET_OPEN_VMS)
3970 return std_expand_builtin_va_arg (valist, type);
3972 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
3974 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3975 offset_field = TREE_CHAIN (base_field);
3977 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3978 valist, base_field);
3979 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3980 valist, offset_field);
3982 wide_type = make_signed_type (64);
3983 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
3986 if (FLOAT_TYPE_P (type))
3988 tree fpaddend, cond;
3990 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
3991 addend, build_int_2 (-6*8, 0)));
3993 cond = fold (build (LT_EXPR, integer_type_node,
3994 wide_ofs, build_int_2 (6*8, 0)));
3996 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
4000 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
4001 base_field, addend);
4003 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4004 addr = copy_to_reg (addr);
4006 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
4007 build (PLUS_EXPR, TREE_TYPE (offset_field),
4008 offset_field, build_int_2 (tsize, 0)));
4009 TREE_SIDE_EFFECTS (t) = 1;
4010 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4015 /* This page contains routines that are used to determine what the function
4016 prologue and epilogue code will do and write them out. */
4018 /* Compute the size of the save area in the stack. */
4020 /* These variables are used for communication between the following functions.
4021 They indicate various things about the current function being compiled
4022 that are used to tell what kind of prologue, epilogue and procedure
4023 descriptior to generate. */
4025 /* Nonzero if we need a stack procedure. */
4026 static int vms_is_stack_procedure;
4028 /* Register number (either FP or SP) that is used to unwind the frame. */
4029 static int vms_unwind_regno;
4031 /* Register number used to save FP. We need not have one for RA since
4032 we don't modify it for register procedures. This is only defined
4033 for register frame procedures. */
4034 static int vms_save_fp_regno;
4036 /* Register number used to reference objects off our PV. */
4037 static int vms_base_regno;
4039 /* Compute register masks for saved registers. */
4042 alpha_sa_mask (imaskP, fmaskP)
4043 unsigned long *imaskP;
4044 unsigned long *fmaskP;
4046 unsigned long imask = 0;
4047 unsigned long fmask = 0;
4050 #ifdef ASM_OUTPUT_MI_THUNK
4051 if (!current_function_is_thunk)
4054 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4055 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
4057 /* One for every register we have to save. */
4058 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4059 if (! fixed_regs[i] && ! call_used_regs[i]
4060 && regs_ever_live[i] && i != REG_RA)
4065 fmask |= (1L << (i - 32));
4068 if (imask || fmask || alpha_ra_ever_killed ())
4069 imask |= (1L << REG_RA);
4082 #ifdef ASM_OUTPUT_MI_THUNK
4083 if (current_function_is_thunk)
4088 /* One for every register we have to save. */
4089 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4090 if (! fixed_regs[i] && ! call_used_regs[i]
4091 && regs_ever_live[i] && i != REG_RA)
4095 if (TARGET_OPEN_VMS)
4097 /* Start by assuming we can use a register procedure if we don't
4098 make any calls (REG_RA not used) or need to save any
4099 registers and a stack procedure if we do. */
4100 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
4102 /* Decide whether to refer to objects off our PV via FP or PV.
4103 If we need FP for something else or if we receive a nonlocal
4104 goto (which expects PV to contain the value), we must use PV.
4105 Otherwise, start by assuming we can use FP. */
4106 vms_base_regno = (frame_pointer_needed
4107 || current_function_has_nonlocal_label
4108 || vms_is_stack_procedure
4109 || current_function_outgoing_args_size
4110 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
4112 /* If we want to copy PV into FP, we need to find some register
4113 in which to save FP. */
4115 vms_save_fp_regno = -1;
4116 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
4117 for (i = 0; i < 32; i++)
4118 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
4119 vms_save_fp_regno = i;
4121 if (vms_save_fp_regno == -1)
4122 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
4124 /* Stack unwinding should be done via FP unless we use it for PV. */
4125 vms_unwind_regno = (vms_base_regno == REG_PV
4126 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
4128 /* If this is a stack procedure, allow space for saving FP and RA. */
4129 if (vms_is_stack_procedure)
4134 /* If some registers were saved but not RA, RA must also be saved,
4135 so leave space for it. */
4136 if (sa_size != 0 || alpha_ra_ever_killed ())
4139 /* Our size must be even (multiple of 16 bytes). */
4148 alpha_pv_save_size ()
4151 return vms_is_stack_procedure ? 8 : 0;
4158 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
4162 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
4163 tree decl ATTRIBUTE_UNUSED;
4164 tree attributes ATTRIBUTE_UNUSED;
4168 if (is_attribute_p ("overlaid", identifier))
4169 return (args == NULL_TREE);
4174 alpha_does_function_need_gp ()
4178 /* We never need a GP for Windows/NT or VMS. */
4179 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4182 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4185 #ifdef ASM_OUTPUT_MI_THUNK
4186 if (current_function_is_thunk)
4190 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
4191 Even if we are a static function, we still need to do this in case
4192 our address is taken and passed to something like qsort. */
4194 push_topmost_sequence ();
4195 insn = get_insns ();
4196 pop_topmost_sequence ();
4198 for (; insn; insn = NEXT_INSN (insn))
4200 && GET_CODE (PATTERN (insn)) != USE
4201 && GET_CODE (PATTERN (insn)) != CLOBBER)
4203 enum attr_type type = get_attr_type (insn);
4204 if (type == TYPE_LDSYM || type == TYPE_JSR)
4211 /* Write a version stamp. Don't write anything if we are running as a
4212 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
4219 alpha_write_verstamp (file)
4220 FILE *file ATTRIBUTE_UNUSED;
4223 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
4227 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
4231 set_frame_related_p ()
4233 rtx seq = gen_sequence ();
4236 if (GET_CODE (seq) == SEQUENCE)
4238 int i = XVECLEN (seq, 0);
4240 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
4241 return emit_insn (seq);
4245 seq = emit_insn (seq);
4246 RTX_FRAME_RELATED_P (seq) = 1;
4251 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
4253 /* Write function prologue. */
4255 /* On vms we have two kinds of functions:
4257 - stack frame (PROC_STACK)
4258 these are 'normal' functions with local vars and which are
4259 calling other functions
4260 - register frame (PROC_REGISTER)
4261 keeps all data in registers, needs no stack
4263 We must pass this to the assembler so it can generate the
4264 proper pdsc (procedure descriptor)
4265 This is done with the '.pdesc' command.
4267 On not-vms, we don't really differentiate between the two, as we can
4268 simply allocate stack without saving registers. */
4271 alpha_expand_prologue ()
4273 /* Registers to save. */
4274 unsigned long imask = 0;
4275 unsigned long fmask = 0;
4276 /* Stack space needed for pushing registers clobbered by us. */
4277 HOST_WIDE_INT sa_size;
4278 /* Complete stack size needed. */
4279 HOST_WIDE_INT frame_size;
4280 /* Offset from base reg to register save area. */
4281 HOST_WIDE_INT reg_offset;
4285 sa_size = alpha_sa_size ();
4287 frame_size = get_frame_size ();
4288 if (TARGET_OPEN_VMS)
4289 frame_size = ALPHA_ROUND (sa_size
4290 + (vms_is_stack_procedure ? 8 : 0)
4292 + current_function_pretend_args_size);
4294 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4296 + ALPHA_ROUND (frame_size
4297 + current_function_pretend_args_size));
4299 if (TARGET_OPEN_VMS)
4302 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4304 alpha_sa_mask (&imask, &fmask);
4306 /* Emit an insn to reload GP, if needed. */
4307 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
4309 alpha_function_needs_gp = alpha_does_function_need_gp ();
4310 if (alpha_function_needs_gp)
4311 emit_insn (gen_prologue_ldgp ());
4314 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
4315 the call to mcount ourselves, rather than having the linker do it
4316 magically in response to -pg. Since _mcount has special linkage,
4317 don't represent the call as a call. */
4318 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4319 emit_insn (gen_prologue_mcount ());
4321 /* Adjust the stack by the frame size. If the frame size is > 4096
4322 bytes, we need to be sure we probe somewhere in the first and last
4323 4096 bytes (we can probably get away without the latter test) and
4324 every 8192 bytes in between. If the frame size is > 32768, we
4325 do this in a loop. Otherwise, we generate the explicit probe
4328 Note that we are only allowed to adjust sp once in the prologue. */
4330 if (frame_size <= 32768)
4332 if (frame_size > 4096)
4337 emit_insn (gen_probe_stack (GEN_INT (-probed)));
4338 while ((probed += 8192) < frame_size);
4340 /* We only have to do this probe if we aren't saving registers. */
4341 if (sa_size == 0 && probed + 4096 < frame_size)
4342 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
4345 if (frame_size != 0)
4347 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
4348 GEN_INT (-frame_size))));
4353 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
4354 number of 8192 byte blocks to probe. We then probe each block
4355 in the loop and then set SP to the proper location. If the
4356 amount remaining is > 4096, we have to do one more probe if we
4357 are not saving any registers. */
4359 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
4360 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
4361 rtx ptr = gen_rtx_REG (DImode, 22);
4362 rtx count = gen_rtx_REG (DImode, 23);
4365 emit_move_insn (count, GEN_INT (blocks));
4366 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
4368 /* Because of the difficulty in emitting a new basic block this
4369 late in the compilation, generate the loop as a single insn. */
4370 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
4372 if (leftover > 4096 && sa_size == 0)
4374 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
4375 MEM_VOLATILE_P (last) = 1;
4376 emit_move_insn (last, const0_rtx);
4379 if (TARGET_WINDOWS_NT)
4381 /* For NT stack unwind (done by 'reverse execution'), it's
4382 not OK to take the result of a loop, even though the value
4383 is already in ptr, so we reload it via a single operation
4384 and subtract it to sp.
4386 Yes, that's correct -- we have to reload the whole constant
4387 into a temporary via ldah+lda then subtract from sp. To
4388 ensure we get ldah+lda, we use a special pattern. */
4390 HOST_WIDE_INT lo, hi;
4391 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4392 hi = frame_size - lo;
4394 emit_move_insn (ptr, GEN_INT (hi));
4395 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
4396 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
4401 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
4402 GEN_INT (-leftover)));
4405 /* This alternative is special, because the DWARF code cannot
4406 possibly intuit through the loop above. So we invent this
4407 note it looks at instead. */
4408 RTX_FRAME_RELATED_P (seq) = 1;
4410 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4411 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4412 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4413 GEN_INT (-frame_size))),
4417 /* Cope with very large offsets to the register save area. */
4418 sa_reg = stack_pointer_rtx;
4419 if (reg_offset + sa_size > 0x8000)
4421 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4424 if (low + sa_size <= 0x8000)
4425 bias = reg_offset - low, reg_offset = low;
4427 bias = reg_offset, reg_offset = 0;
4429 sa_reg = gen_rtx_REG (DImode, 24);
4430 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
4433 /* Save regs in stack order. Beginning with VMS PV. */
4434 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4436 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
4437 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4438 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
4441 /* Save register RA next. */
4442 if (imask & (1L << REG_RA))
4444 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4445 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4446 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
4447 imask &= ~(1L << REG_RA);
4451 /* Now save any other registers required to be saved. */
4452 for (i = 0; i < 32; i++)
4453 if (imask & (1L << i))
4455 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4456 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4457 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
4461 for (i = 0; i < 32; i++)
4462 if (fmask & (1L << i))
4464 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
4465 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4466 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
4470 if (TARGET_OPEN_VMS)
4472 if (!vms_is_stack_procedure)
4474 /* Register frame procedures fave the fp. */
4475 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
4476 hard_frame_pointer_rtx));
4479 if (vms_base_regno != REG_PV)
4480 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
4481 gen_rtx_REG (DImode, REG_PV)));
4483 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4485 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4488 /* If we have to allocate space for outgoing args, do it now. */
4489 if (current_function_outgoing_args_size != 0)
4491 FRP (emit_move_insn (stack_pointer_rtx,
4492 plus_constant (hard_frame_pointer_rtx,
4493 - ALPHA_ROUND (current_function_outgoing_args_size))));
4498 /* If we need a frame pointer, set it from the stack pointer. */
4499 if (frame_pointer_needed)
4501 if (TARGET_CAN_FAULT_IN_PROLOGUE)
4502 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4505 /* This must always be the last instruction in the
4506 prologue, thus we emit a special move + clobber. */
4507 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
4508 stack_pointer_rtx, sa_reg)));
4513 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
4514 the prologue, for exception handling reasons, we cannot do this for
4515 any insn that might fault. We could prevent this for mems with a
4516 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
4517 have to prevent all such scheduling with a blockage.
4519 Linux, on the other hand, never bothered to implement OSF/1's
4520 exception handling, and so doesn't care about such things. Anyone
4521 planning to use dwarf2 frame-unwind info can also omit the blockage. */
4523 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
4524 emit_insn (gen_blockage ());
4527 /* Output the textual info surrounding the prologue. */
4530 alpha_start_function (file, fnname, decl)
4533 tree decl ATTRIBUTE_UNUSED;
4535 unsigned long imask = 0;
4536 unsigned long fmask = 0;
4537 /* Stack space needed for pushing registers clobbered by us. */
4538 HOST_WIDE_INT sa_size;
4539 /* Complete stack size needed. */
4540 HOST_WIDE_INT frame_size;
4541 /* Offset from base reg to register save area. */
4542 HOST_WIDE_INT reg_offset;
4543 char *entry_label = (char *) alloca (strlen (fnname) + 6);
4546 alpha_fnname = fnname;
4547 sa_size = alpha_sa_size ();
4549 frame_size = get_frame_size ();
4550 if (TARGET_OPEN_VMS)
4551 frame_size = ALPHA_ROUND (sa_size
4552 + (vms_is_stack_procedure ? 8 : 0)
4554 + current_function_pretend_args_size);
4556 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4558 + ALPHA_ROUND (frame_size
4559 + current_function_pretend_args_size));
4561 if (TARGET_OPEN_VMS)
4564 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4566 alpha_sa_mask (&imask, &fmask);
4568 /* Ecoff can handle multiple .file directives, so put out file and lineno.
4569 We have to do that before the .ent directive as we cannot switch
4570 files within procedures with native ecoff because line numbers are
4571 linked to procedure descriptors.
4572 Outputting the lineno helps debugging of one line functions as they
4573 would otherwise get no line number at all. Please note that we would
4574 like to put out last_linenum from final.c, but it is not accessible. */
4576 if (write_symbols == SDB_DEBUG)
4578 ASM_OUTPUT_SOURCE_FILENAME (file,
4579 DECL_SOURCE_FILE (current_function_decl));
4580 if (debug_info_level != DINFO_LEVEL_TERSE)
4581 ASM_OUTPUT_SOURCE_LINE (file,
4582 DECL_SOURCE_LINE (current_function_decl));
4585 /* Issue function start and label. */
4586 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
4588 fputs ("\t.ent ", file);
4589 assemble_name (file, fnname);
4592 /* If the function needs GP, we'll write the "..ng" label there.
4593 Otherwise, do it here. */
4594 if (! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT
4595 && ! alpha_function_needs_gp)
4598 assemble_name (file, fnname);
4599 fputs ("..ng:\n", file);
4603 strcpy (entry_label, fnname);
4604 if (TARGET_OPEN_VMS)
4605 strcat (entry_label, "..en");
4606 ASM_OUTPUT_LABEL (file, entry_label);
4607 inside_function = TRUE;
4609 if (TARGET_OPEN_VMS)
4610 fprintf (file, "\t.base $%d\n", vms_base_regno);
4612 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
4613 && !flag_inhibit_size_directive)
4615 /* Set flags in procedure descriptor to request IEEE-conformant
4616 math-library routines. The value we set it to is PDSC_EXC_IEEE
4617 (/usr/include/pdsc.h). */
4618 fputs ("\t.eflag 48\n", file);
4621 /* Set up offsets to alpha virtual arg/local debugging pointer. */
4622 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
4623 alpha_arg_offset = -frame_size + 48;
4625 /* Describe our frame. If the frame size is larger than an integer,
4626 print it as zero to avoid an assembler error. We won't be
4627 properly describing such a frame, but that's the best we can do. */
4628 if (TARGET_OPEN_VMS)
4630 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
4631 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4632 frame_size >= (1l << 31) ? 0 : frame_size);
4633 fputs (",$26,", file);
4634 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
4637 else if (!flag_inhibit_size_directive)
4639 fprintf (file, "\t.frame $%d,",
4640 (frame_pointer_needed
4641 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
4642 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4643 frame_size >= (1l << 31) ? 0 : frame_size);
4644 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
4647 /* Describe which registers were spilled. */
4648 if (TARGET_OPEN_VMS)
4651 /* ??? Does VMS care if mask contains ra? The old code did'nt
4652 set it, so I don't here. */
4653 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
4655 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
4656 if (!vms_is_stack_procedure)
4657 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
4659 else if (!flag_inhibit_size_directive)
4663 fprintf (file, "\t.mask 0x%lx,", imask);
4664 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4665 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4668 for (i = 0; i < 32; ++i)
4669 if (imask & (1L << i))
4675 fprintf (file, "\t.fmask 0x%lx,", fmask);
4676 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4677 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4683 /* Ifdef'ed cause readonly_section and link_section are only
4685 readonly_section ();
4686 fprintf (file, "\t.align 3\n");
4687 assemble_name (file, fnname); fputs ("..na:\n", file);
4688 fputs ("\t.ascii \"", file);
4689 assemble_name (file, fnname);
4690 fputs ("\\0\"\n", file);
4693 fprintf (file, "\t.align 3\n");
4694 fputs ("\t.name ", file);
4695 assemble_name (file, fnname);
4696 fputs ("..na\n", file);
4697 ASM_OUTPUT_LABEL (file, fnname);
4698 fprintf (file, "\t.pdesc ");
4699 assemble_name (file, fnname);
4700 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
4701 alpha_need_linkage (fnname, 1);
4706 /* Emit the .prologue note at the scheduled end of the prologue. */
4709 output_end_prologue (file)
4712 if (TARGET_OPEN_VMS)
4713 fputs ("\t.prologue\n", file);
4714 else if (TARGET_WINDOWS_NT)
4715 fputs ("\t.prologue 0\n", file);
4716 else if (!flag_inhibit_size_directive)
4717 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
4720 /* Write function epilogue. */
4722 /* ??? At some point we will want to support full unwind, and so will
4723 need to mark the epilogue as well. At the moment, we just confuse
4726 #define FRP(exp) exp
4729 alpha_expand_epilogue ()
4731 /* Registers to save. */
4732 unsigned long imask = 0;
4733 unsigned long fmask = 0;
4734 /* Stack space needed for pushing registers clobbered by us. */
4735 HOST_WIDE_INT sa_size;
4736 /* Complete stack size needed. */
4737 HOST_WIDE_INT frame_size;
4738 /* Offset from base reg to register save area. */
4739 HOST_WIDE_INT reg_offset;
4740 int fp_is_frame_pointer, fp_offset;
4741 rtx sa_reg, sa_reg_exp = NULL;
4742 rtx sp_adj1, sp_adj2, mem;
4746 sa_size = alpha_sa_size ();
4748 frame_size = get_frame_size ();
4749 if (TARGET_OPEN_VMS)
4750 frame_size = ALPHA_ROUND (sa_size
4751 + (vms_is_stack_procedure ? 8 : 0)
4753 + current_function_pretend_args_size);
4755 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4757 + ALPHA_ROUND (frame_size
4758 + current_function_pretend_args_size));
4760 if (TARGET_OPEN_VMS)
4763 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4765 alpha_sa_mask (&imask, &fmask);
4767 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
4768 || (!TARGET_OPEN_VMS && frame_pointer_needed));
4770 sa_reg = stack_pointer_rtx;
4772 eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
4775 /* If we have a frame pointer, restore SP from it. */
4776 if ((TARGET_OPEN_VMS
4777 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4778 || (!TARGET_OPEN_VMS && frame_pointer_needed))
4780 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
4783 /* Cope with very large offsets to the register save area. */
4784 if (reg_offset + sa_size > 0x8000)
4786 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4789 if (low + sa_size <= 0x8000)
4790 bias = reg_offset - low, reg_offset = low;
4792 bias = reg_offset, reg_offset = 0;
4794 sa_reg = gen_rtx_REG (DImode, 22);
4795 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
4797 FRP (emit_move_insn (sa_reg, sa_reg_exp));
4800 /* Restore registers in order, excepting a true frame pointer. */
4804 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4805 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4806 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
4809 imask &= ~(1L << REG_RA);
4811 for (i = 0; i < 32; ++i)
4812 if (imask & (1L << i))
4814 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
4815 fp_offset = reg_offset;
4818 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4819 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4820 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
4825 for (i = 0; i < 32; ++i)
4826 if (fmask & (1L << i))
4828 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
4829 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4830 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
4835 if (frame_size || eh_ofs)
4837 sp_adj1 = stack_pointer_rtx;
4841 sp_adj1 = gen_rtx_REG (DImode, 23);
4842 emit_move_insn (sp_adj1,
4843 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
4846 /* If the stack size is large, begin computation into a temporary
4847 register so as not to interfere with a potential fp restore,
4848 which must be consecutive with an SP restore. */
4849 if (frame_size < 32768)
4850 sp_adj2 = GEN_INT (frame_size);
4851 else if (frame_size < 0x40007fffL)
4853 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4855 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
4856 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
4860 sp_adj1 = gen_rtx_REG (DImode, 23);
4861 FRP (emit_move_insn (sp_adj1, sp_adj2));
4863 sp_adj2 = GEN_INT (low);
4867 rtx tmp = gen_rtx_REG (DImode, 23);
4868 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
4871 /* We can't drop new things to memory this late, afaik,
4872 so build it up by pieces. */
4873 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
4874 -(frame_size < 0)));
4880 /* From now on, things must be in order. So emit blockages. */
4882 /* Restore the frame pointer. */
4883 if (fp_is_frame_pointer)
4885 emit_insn (gen_blockage ());
4886 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
4887 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4888 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
4890 else if (TARGET_OPEN_VMS)
4892 emit_insn (gen_blockage ());
4893 FRP (emit_move_insn (hard_frame_pointer_rtx,
4894 gen_rtx_REG (DImode, vms_save_fp_regno)));
4897 /* Restore the stack pointer. */
4898 emit_insn (gen_blockage ());
4899 FRP (emit_move_insn (stack_pointer_rtx,
4900 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
4904 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4906 emit_insn (gen_blockage ());
4907 FRP (emit_move_insn (hard_frame_pointer_rtx,
4908 gen_rtx_REG (DImode, vms_save_fp_regno)));
4913 /* Output the rest of the textual info surrounding the epilogue. */
4916 alpha_end_function (file, fnname, decl)
4919 tree decl ATTRIBUTE_UNUSED;
4921 /* End the function. */
4922 if (!flag_inhibit_size_directive)
4924 fputs ("\t.end ", file);
4925 assemble_name (file, fnname);
4928 inside_function = FALSE;
4930 /* Show that we know this function if it is called again.
4932 Don't do this for global functions in object files destined for a
4933 shared library because the function may be overridden by the application
4934 or other libraries. Similarly, don't do this for weak functions. */
4936 if (!DECL_WEAK (current_function_decl)
4937 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4938 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4941 /* Debugging support. */
4945 /* Count the number of sdb related labels are generated (to find block
4946 start and end boundaries). */
4948 int sdb_label_count = 0;
4950 /* Next label # for each statement. */
4952 static int sym_lineno = 0;
4954 /* Count the number of .file directives, so that .loc is up to date. */
4956 static int num_source_filenames = 0;
4958 /* Name of the file containing the current function. */
4960 static const char *current_function_file = "";
4962 /* Offsets to alpha virtual arg/local debugging pointers. */
4964 long alpha_arg_offset;
4965 long alpha_auto_offset;
4967 /* Emit a new filename to a stream. */
4970 alpha_output_filename (stream, name)
4974 static int first_time = TRUE;
4975 char ltext_label_name[100];
4980 ++num_source_filenames;
4981 current_function_file = name;
4982 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4983 output_quoted_string (stream, name);
4984 fprintf (stream, "\n");
4985 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4986 fprintf (stream, "\t#@stabs\n");
4989 else if (write_symbols == DBX_DEBUG)
4991 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4992 fprintf (stream, "%s ", ASM_STABS_OP);
4993 output_quoted_string (stream, name);
4994 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
4997 else if (name != current_function_file
4998 && strcmp (name, current_function_file) != 0)
5000 if (inside_function && ! TARGET_GAS)
5001 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
5004 ++num_source_filenames;
5005 current_function_file = name;
5006 fprintf (stream, "\t.file\t%d ", num_source_filenames);
5009 output_quoted_string (stream, name);
5010 fprintf (stream, "\n");
5014 /* Emit a linenumber to a stream. */
5017 alpha_output_lineno (stream, line)
5021 if (write_symbols == DBX_DEBUG)
5023 /* mips-tfile doesn't understand .stabd directives. */
5025 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
5026 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
5029 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
5032 /* Structure to show the current status of registers and memory. */
5034 struct shadow_summary
5037 unsigned int i : 31; /* Mask of int regs */
5038 unsigned int fp : 31; /* Mask of fp regs */
5039 unsigned int mem : 1; /* mem == imem | fpmem */
5043 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
5044 static void alpha_handle_trap_shadows PARAMS ((rtx));
5046 /* Summary the effects of expression X on the machine. Update SUM, a pointer
5047 to the summary structure. SET is nonzero if the insn is setting the
5048 object, otherwise zero. */
5051 summarize_insn (x, sum, set)
5053 struct shadow_summary *sum;
5056 const char *format_ptr;
5062 switch (GET_CODE (x))
5064 /* ??? Note that this case would be incorrect if the Alpha had a
5065 ZERO_EXTRACT in SET_DEST. */
5067 summarize_insn (SET_SRC (x), sum, 0);
5068 summarize_insn (SET_DEST (x), sum, 1);
5072 summarize_insn (XEXP (x, 0), sum, 1);
5076 summarize_insn (XEXP (x, 0), sum, 0);
5080 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
5081 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
5085 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
5086 summarize_insn (XVECEXP (x, 0, i), sum, 0);
5090 summarize_insn (SUBREG_REG (x), sum, 0);
5095 int regno = REGNO (x);
5096 unsigned long mask = 1UL << (regno % 32);
5098 if (regno == 31 || regno == 63)
5104 sum->defd.i |= mask;
5106 sum->defd.fp |= mask;
5111 sum->used.i |= mask;
5113 sum->used.fp |= mask;
5124 /* Find the regs used in memory address computation: */
5125 summarize_insn (XEXP (x, 0), sum, 0);
5128 case CONST_INT: case CONST_DOUBLE:
5129 case SYMBOL_REF: case LABEL_REF: case CONST:
5133 /* Handle common unary and binary ops for efficiency. */
5134 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
5135 case MOD: case UDIV: case UMOD: case AND: case IOR:
5136 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
5137 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
5138 case NE: case EQ: case GE: case GT: case LE:
5139 case LT: case GEU: case GTU: case LEU: case LTU:
5140 summarize_insn (XEXP (x, 0), sum, 0);
5141 summarize_insn (XEXP (x, 1), sum, 0);
5144 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
5145 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
5146 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
5147 case SQRT: case FFS:
5148 summarize_insn (XEXP (x, 0), sum, 0);
5152 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
5153 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5154 switch (format_ptr[i])
5157 summarize_insn (XEXP (x, i), sum, 0);
5161 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
5162 summarize_insn (XVECEXP (x, i, j), sum, 0);
5174 /* Ensure a sufficient number of `trapb' insns are in the code when
5175 the user requests code with a trap precision of functions or
5178 In naive mode, when the user requests a trap-precision of
5179 "instruction", a trapb is needed after every instruction that may
5180 generate a trap. This ensures that the code is resumption safe but
5183 When optimizations are turned on, we delay issuing a trapb as long
5184 as possible. In this context, a trap shadow is the sequence of
5185 instructions that starts with a (potentially) trap generating
5186 instruction and extends to the next trapb or call_pal instruction
5187 (but GCC never generates call_pal by itself). We can delay (and
5188 therefore sometimes omit) a trapb subject to the following
5191 (a) On entry to the trap shadow, if any Alpha register or memory
5192 location contains a value that is used as an operand value by some
5193 instruction in the trap shadow (live on entry), then no instruction
5194 in the trap shadow may modify the register or memory location.
5196 (b) Within the trap shadow, the computation of the base register
5197 for a memory load or store instruction may not involve using the
5198 result of an instruction that might generate an UNPREDICTABLE
5201 (c) Within the trap shadow, no register may be used more than once
5202 as a destination register. (This is to make life easier for the
5205 (d) The trap shadow may not include any branch instructions. */
5208 alpha_handle_trap_shadows (insns)
5211 struct shadow_summary shadow;
5212 int trap_pending, exception_nesting;
5216 exception_nesting = 0;
5219 shadow.used.mem = 0;
5220 shadow.defd = shadow.used;
5222 for (i = insns; i ; i = NEXT_INSN (i))
5224 if (GET_CODE (i) == NOTE)
5226 switch (NOTE_LINE_NUMBER (i))
5228 case NOTE_INSN_EH_REGION_BEG:
5229 exception_nesting++;
5234 case NOTE_INSN_EH_REGION_END:
5235 exception_nesting--;
5240 case NOTE_INSN_EPILOGUE_BEG:
5241 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
5246 else if (trap_pending)
5248 if (alpha_tp == ALPHA_TP_FUNC)
5250 if (GET_CODE (i) == JUMP_INSN
5251 && GET_CODE (PATTERN (i)) == RETURN)
5254 else if (alpha_tp == ALPHA_TP_INSN)
5258 struct shadow_summary sum;
5263 sum.defd = sum.used;
5265 switch (GET_CODE (i))
5268 /* Annoyingly, get_attr_trap will abort on these. */
5269 if (GET_CODE (PATTERN (i)) == USE
5270 || GET_CODE (PATTERN (i)) == CLOBBER)
5273 summarize_insn (PATTERN (i), &sum, 0);
5275 if ((sum.defd.i & shadow.defd.i)
5276 || (sum.defd.fp & shadow.defd.fp))
5278 /* (c) would be violated */
5282 /* Combine shadow with summary of current insn: */
5283 shadow.used.i |= sum.used.i;
5284 shadow.used.fp |= sum.used.fp;
5285 shadow.used.mem |= sum.used.mem;
5286 shadow.defd.i |= sum.defd.i;
5287 shadow.defd.fp |= sum.defd.fp;
5288 shadow.defd.mem |= sum.defd.mem;
5290 if ((sum.defd.i & shadow.used.i)
5291 || (sum.defd.fp & shadow.used.fp)
5292 || (sum.defd.mem & shadow.used.mem))
5294 /* (a) would be violated (also takes care of (b)) */
5295 if (get_attr_trap (i) == TRAP_YES
5296 && ((sum.defd.i & sum.used.i)
5297 || (sum.defd.fp & sum.used.fp)))
5316 n = emit_insn_before (gen_trapb (), i);
5317 PUT_MODE (n, TImode);
5318 PUT_MODE (i, TImode);
5322 shadow.used.mem = 0;
5323 shadow.defd = shadow.used;
5328 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
5329 && GET_CODE (i) == INSN
5330 && GET_CODE (PATTERN (i)) != USE
5331 && GET_CODE (PATTERN (i)) != CLOBBER
5332 && get_attr_trap (i) == TRAP_YES)
5334 if (optimize && !trap_pending)
5335 summarize_insn (PATTERN (i), &shadow, 0);
5341 /* Alpha can only issue instruction groups simultaneously if they are
5342 suitibly aligned. This is very processor-specific. */
5344 enum alphaev4_pipe {
5351 enum alphaev5_pipe {
5362 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
5363 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
5364 static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
5365 static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
5366 static rtx alphaev4_next_nop PARAMS ((int *));
5367 static rtx alphaev5_next_nop PARAMS ((int *));
5369 static void alpha_align_insns
5370 PARAMS ((rtx, unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
5372 static enum alphaev4_pipe
5373 alphaev4_insn_pipe (insn)
5376 if (recog_memoized (insn) < 0)
5378 if (get_attr_length (insn) != 4)
5381 switch (get_attr_type (insn))
5414 static enum alphaev5_pipe
5415 alphaev5_insn_pipe (insn)
5418 if (recog_memoized (insn) < 0)
5420 if (get_attr_length (insn) != 4)
5423 switch (get_attr_type (insn))
5463 /* IN_USE is a mask of the slots currently filled within the insn group.
5464 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
5465 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
5467 LEN is, of course, the length of the group in bytes. */
5470 alphaev4_next_group (insn, pin_use, plen)
5472 int *pin_use, *plen;
5479 || GET_CODE (PATTERN (insn)) == CLOBBER
5480 || GET_CODE (PATTERN (insn)) == USE)
5485 enum alphaev4_pipe pipe;
5487 pipe = alphaev4_insn_pipe (insn);
5491 /* Force complex instructions to start new groups. */
5495 /* If this is a completely unrecognized insn, its an asm.
5496 We don't know how long it is, so record length as -1 to
5497 signal a needed realignment. */
5498 if (recog_memoized (insn) < 0)
5501 len = get_attr_length (insn);
5505 if (in_use & EV4_IB0)
5507 if (in_use & EV4_IB1)
5512 in_use |= EV4_IB0 | EV4_IBX;
5516 if (in_use & EV4_IB0)
5518 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
5526 if (in_use & EV4_IB1)
5536 /* Haifa doesn't do well scheduling branches. */
5537 if (GET_CODE (insn) == JUMP_INSN)
5541 insn = next_nonnote_insn (insn);
5543 if (!insn || ! INSN_P (insn))
5546 /* Let Haifa tell us where it thinks insn group boundaries are. */
5547 if (GET_MODE (insn) == TImode)
5550 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5555 insn = next_nonnote_insn (insn);
5563 /* IN_USE is a mask of the slots currently filled within the insn group.
5564 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
5565 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
5567 LEN is, of course, the length of the group in bytes. */
5570 alphaev5_next_group (insn, pin_use, plen)
5572 int *pin_use, *plen;
5579 || GET_CODE (PATTERN (insn)) == CLOBBER
5580 || GET_CODE (PATTERN (insn)) == USE)
5585 enum alphaev5_pipe pipe;
5587 pipe = alphaev5_insn_pipe (insn);
5591 /* Force complex instructions to start new groups. */
5595 /* If this is a completely unrecognized insn, its an asm.
5596 We don't know how long it is, so record length as -1 to
5597 signal a needed realignment. */
5598 if (recog_memoized (insn) < 0)
5601 len = get_attr_length (insn);
5604 /* ??? Most of the places below, we would like to abort, as
5605 it would indicate an error either in Haifa, or in the
5606 scheduling description. Unfortunately, Haifa never
5607 schedules the last instruction of the BB, so we don't
5608 have an accurate TI bit to go off. */
5610 if (in_use & EV5_E0)
5612 if (in_use & EV5_E1)
5617 in_use |= EV5_E0 | EV5_E01;
5621 if (in_use & EV5_E0)
5623 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
5631 if (in_use & EV5_E1)
5637 if (in_use & EV5_FA)
5639 if (in_use & EV5_FM)
5644 in_use |= EV5_FA | EV5_FAM;
5648 if (in_use & EV5_FA)
5654 if (in_use & EV5_FM)
5667 /* Haifa doesn't do well scheduling branches. */
5668 /* ??? If this is predicted not-taken, slotting continues, except
5669 that no more IBR, FBR, or JSR insns may be slotted. */
5670 if (GET_CODE (insn) == JUMP_INSN)
5674 insn = next_nonnote_insn (insn);
5676 if (!insn || ! INSN_P (insn))
5679 /* Let Haifa tell us where it thinks insn group boundaries are. */
5680 if (GET_MODE (insn) == TImode)
5683 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5688 insn = next_nonnote_insn (insn);
5697 alphaev4_next_nop (pin_use)
5700 int in_use = *pin_use;
5703 if (!(in_use & EV4_IB0))
5708 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
5713 else if (TARGET_FP && !(in_use & EV4_IB1))
5726 alphaev5_next_nop (pin_use)
5729 int in_use = *pin_use;
5732 if (!(in_use & EV5_E1))
5737 else if (TARGET_FP && !(in_use & EV5_FA))
5742 else if (TARGET_FP && !(in_use & EV5_FM))
5754 /* The instruction group alignment main loop. */
5757 alpha_align_insns (insns, max_align, next_group, next_nop)
5759 unsigned int max_align;
5760 rtx (*next_group) PARAMS ((rtx, int *, int *));
5761 rtx (*next_nop) PARAMS ((int *));
5763 /* ALIGN is the known alignment for the insn group. */
5765 /* OFS is the offset of the current insn in the insn group. */
5767 int prev_in_use, in_use, len;
5770 /* Let shorten branches care for assigning alignments to code labels. */
5771 shorten_branches (insns);
5773 align = (FUNCTION_BOUNDARY / BITS_PER_UNIT < max_align
5774 ? FUNCTION_BOUNDARY / BITS_PER_UNIT : max_align);
5776 ofs = prev_in_use = 0;
5778 if (GET_CODE (i) == NOTE)
5779 i = next_nonnote_insn (i);
5783 next = (*next_group) (i, &in_use, &len);
5785 /* When we see a label, resync alignment etc. */
5786 if (GET_CODE (i) == CODE_LABEL)
5788 unsigned int new_align = 1 << label_to_alignment (i);
5790 if (new_align >= align)
5792 align = new_align < max_align ? new_align : max_align;
5796 else if (ofs & (new_align-1))
5797 ofs = (ofs | (new_align-1)) + 1;
5802 /* Handle complex instructions special. */
5803 else if (in_use == 0)
5805 /* Asms will have length < 0. This is a signal that we have
5806 lost alignment knowledge. Assume, however, that the asm
5807 will not mis-align instructions. */
5816 /* If the known alignment is smaller than the recognized insn group,
5817 realign the output. */
5818 else if (align < len)
5820 unsigned int new_log_align = len > 8 ? 4 : 3;
5823 where = prev_nonnote_insn (i);
5824 if (!where || GET_CODE (where) != CODE_LABEL)
5827 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
5828 align = 1 << new_log_align;
5832 /* If the group won't fit in the same INT16 as the previous,
5833 we need to add padding to keep the group together. Rather
5834 than simply leaving the insn filling to the assembler, we
5835 can make use of the knowledge of what sorts of instructions
5836 were issued in the previous group to make sure that all of
5837 the added nops are really free. */
5838 else if (ofs + len > align)
5840 int nop_count = (align - ofs) / 4;
5843 /* Insert nops before labels and branches to truely merge the
5844 execution of the nops with the previous instruction group. */
5845 where = prev_nonnote_insn (i);
5848 if (GET_CODE (where) == CODE_LABEL)
5850 rtx where2 = prev_nonnote_insn (where);
5851 if (where2 && GET_CODE (where2) == JUMP_INSN)
5854 else if (GET_CODE (where) != JUMP_INSN)
5861 emit_insn_before ((*next_nop)(&prev_in_use), where);
5862 while (--nop_count);
5866 ofs = (ofs + len) & (align - 1);
5867 prev_in_use = in_use;
5872 /* Machine dependant reorg pass. */
5878 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
5879 alpha_handle_trap_shadows (insns);
5881 /* Due to the number of extra trapb insns, don't bother fixing up
5882 alignment when trap precision is instruction. Moreover, we can
5883 only do our job when sched2 is run. */
5884 if (optimize && !optimize_size
5885 && alpha_tp != ALPHA_TP_INSN
5886 && flag_schedule_insns_after_reload)
5888 if (alpha_cpu == PROCESSOR_EV4)
5889 alpha_align_insns (insns, 8, alphaev4_next_group, alphaev4_next_nop);
5890 else if (alpha_cpu == PROCESSOR_EV5)
5891 alpha_align_insns (insns, 16, alphaev5_next_group, alphaev5_next_nop);
5895 /* Check a floating-point value for validity for a particular machine mode. */
5897 static const char * const float_strings[] =
5899 /* These are for FLOAT_VAX. */
5900 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5901 "-1.70141173319264430e+38",
5902 "2.93873587705571877e-39", /* 2^-128 */
5903 "-2.93873587705571877e-39",
5904 /* These are for the default broken IEEE mode, which traps
5905 on infinity or denormal numbers. */
5906 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5907 "-3.402823466385288598117e+38",
5908 "1.1754943508222875079687e-38", /* 2^-126 */
5909 "-1.1754943508222875079687e-38",
5912 static REAL_VALUE_TYPE float_values[8];
5913 static int inited_float_values = 0;
5916 check_float_value (mode, d, overflow)
5917 enum machine_mode mode;
5919 int overflow ATTRIBUTE_UNUSED;
5922 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5925 if (inited_float_values == 0)
5928 for (i = 0; i < 8; i++)
5929 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5931 inited_float_values = 1;
5937 REAL_VALUE_TYPE *fvptr;
5939 if (TARGET_FLOAT_VAX)
5940 fvptr = &float_values[0];
5942 fvptr = &float_values[4];
5944 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5945 if (REAL_VALUES_LESS (fvptr[0], r))
5947 bcopy ((char *) &fvptr[0], (char *) d,
5948 sizeof (REAL_VALUE_TYPE));
5951 else if (REAL_VALUES_LESS (r, fvptr[1]))
5953 bcopy ((char *) &fvptr[1], (char *) d,
5954 sizeof (REAL_VALUE_TYPE));
5957 else if (REAL_VALUES_LESS (dconst0, r)
5958 && REAL_VALUES_LESS (r, fvptr[2]))
5960 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5963 else if (REAL_VALUES_LESS (r, dconst0)
5964 && REAL_VALUES_LESS (fvptr[3], r))
5966 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5976 /* Return the VMS argument type corresponding to MODE. */
5979 alpha_arg_type (mode)
5980 enum machine_mode mode;
5985 return TARGET_FLOAT_VAX ? FF : FS;
5987 return TARGET_FLOAT_VAX ? FD : FT;
5993 /* Return an rtx for an integer representing the VMS Argument Information
5997 alpha_arg_info_reg_val (cum)
5998 CUMULATIVE_ARGS cum;
6000 unsigned HOST_WIDE_INT regval = cum.num_args;
6003 for (i = 0; i < 6; i++)
6004 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
6006 return GEN_INT (regval);
6009 #include <splay-tree.h>
6011 /* Structure to collect function names for final output
6014 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
6019 enum links_kind kind;
6022 static splay_tree alpha_links;
6024 static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
6025 static void mark_alpha_links PARAMS ((void *));
6026 static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
6028 /* Protect alpha_links from garbage collection. */
6031 mark_alpha_links_node (node, data)
6032 splay_tree_node node;
6033 void *data ATTRIBUTE_UNUSED;
6035 struct alpha_links *links = (struct alpha_links *) node->value;
6036 ggc_mark_rtx (links->linkage);
6041 mark_alpha_links (ptr)
6044 splay_tree tree = *(splay_tree *) ptr;
6045 splay_tree_foreach (tree, mark_alpha_links_node, NULL);
6048 /* Make (or fake) .linkage entry for function call.
6050 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
6052 Return an SYMBOL_REF rtx for the linkage. */
6055 alpha_need_linkage (name, is_local)
6059 splay_tree_node node;
6060 struct alpha_links *al;
6067 /* Is this name already defined? */
6069 node = splay_tree_lookup (alpha_links, (splay_tree_key) name);
6072 al = (struct alpha_links *) node->value;
6075 /* Defined here but external assumed. */
6076 if (al->kind == KIND_EXTERN)
6077 al->kind = KIND_LOCAL;
6081 /* Used here but unused assumed. */
6082 if (al->kind == KIND_UNUSED)
6083 al->kind = KIND_LOCAL;
6090 alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
6091 (splay_tree_delete_key_fn) free,
6092 (splay_tree_delete_key_fn) free);
6093 ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
6096 al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
6097 name = xstrdup (name);
6099 /* Assume external if no definition. */
6100 al->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
6102 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
6103 get_identifier (name);
6105 /* Construct a SYMBOL_REF for us to call. */
6107 size_t name_len = strlen (name);
6108 char *linksym = ggc_alloc_string (NULL, name_len + 6);
6111 memcpy (linksym + 1, name, name_len);
6112 memcpy (linksym + 1 + name_len, "..lk", 5);
6113 al->linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
6116 splay_tree_insert (alpha_links, (splay_tree_key) name,
6117 (splay_tree_value) al);
6123 alpha_write_one_linkage (node, data)
6124 splay_tree_node node;
6127 const char *name = (const char *) node->key;
6128 struct alpha_links *links = (struct alpha_links *) node->value;
6129 FILE *stream = (FILE *) data;
6131 if (links->kind == KIND_UNUSED
6132 || ! TREE_SYMBOL_REFERENCED (get_identifier (name)))
6135 fprintf (stream, "$%s..lk:\n", name);
6136 if (links->kind == KIND_LOCAL)
6138 /* Local and used, build linkage pair. */
6139 fprintf (stream, "\t.quad %s..en\n", name);
6140 fprintf (stream, "\t.quad %s\n", name);
6144 /* External and used, request linkage pair. */
6145 fprintf (stream, "\t.linkage %s\n", name);
6152 alpha_write_linkage (stream)
6155 readonly_section ();
6156 fprintf (stream, "\t.align 3\n");
6157 splay_tree_foreach (alpha_links, alpha_write_one_linkage, stream);
6163 alpha_need_linkage (name, is_local)
6164 const char *name ATTRIBUTE_UNUSED;
6165 int is_local ATTRIBUTE_UNUSED;
6170 #endif /* OPEN_VMS */