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_tp_string; /* -mtrap-precision=[p|s|i] */
74 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
75 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
76 const char *alpha_mlat_string; /* -mmemory-latency= */
78 /* Save information from a "cmpxx" operation until the branch or scc is
81 struct alpha_compare alpha_compare;
83 /* Non-zero if inside of a function, because the Alpha asm can't
84 handle .files inside of functions. */
86 static int inside_function = FALSE;
88 /* The number of cycles of latency we should assume on memory reads. */
90 int alpha_memory_latency = 3;
92 /* Whether the function needs the GP. */
94 static int alpha_function_needs_gp;
96 /* The alias set for prologue/epilogue register save/restore. */
98 static int alpha_sr_alias_set;
100 /* Declarations of static functions. */
101 static void alpha_set_memflags_1
102 PARAMS ((rtx, int, int, int));
103 static rtx alpha_emit_set_const_1
104 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
105 static void alpha_expand_unaligned_load_words
106 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
107 static void alpha_expand_unaligned_store_words
108 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
109 static void alpha_sa_mask
110 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
111 static int alpha_does_function_need_gp
113 static void alpha_init_machine_status
114 PARAMS ((struct function *p));
115 static void alpha_mark_machine_status
116 PARAMS ((struct function *p));
117 static int alpha_ra_ever_killed
119 static rtx set_frame_related_p
121 static const char *alpha_lookup_xfloating_lib_func
122 PARAMS ((enum rtx_code));
123 static int alpha_compute_xfloating_mode_arg
124 PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
125 static void alpha_emit_xfloating_libcall
126 PARAMS ((const char *, rtx, rtx[], int, rtx));
127 static rtx alpha_emit_xfloating_compare
128 PARAMS ((enum rtx_code, rtx, rtx));
130 /* Get the number of args of a function in one of two ways. */
132 #define NUM_ARGS current_function_args_info.num_args
134 #define NUM_ARGS current_function_args_info
140 /* Parse target option strings. */
145 alpha_tp = ALPHA_TP_PROG;
146 alpha_fprm = ALPHA_FPRM_NORM;
147 alpha_fptm = ALPHA_FPTM_N;
151 alpha_tp = ALPHA_TP_INSN;
152 alpha_fptm = ALPHA_FPTM_SU;
155 if (TARGET_IEEE_WITH_INEXACT)
157 alpha_tp = ALPHA_TP_INSN;
158 alpha_fptm = ALPHA_FPTM_SUI;
163 if (! strcmp (alpha_tp_string, "p"))
164 alpha_tp = ALPHA_TP_PROG;
165 else if (! strcmp (alpha_tp_string, "f"))
166 alpha_tp = ALPHA_TP_FUNC;
167 else if (! strcmp (alpha_tp_string, "i"))
168 alpha_tp = ALPHA_TP_INSN;
170 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
173 if (alpha_fprm_string)
175 if (! strcmp (alpha_fprm_string, "n"))
176 alpha_fprm = ALPHA_FPRM_NORM;
177 else if (! strcmp (alpha_fprm_string, "m"))
178 alpha_fprm = ALPHA_FPRM_MINF;
179 else if (! strcmp (alpha_fprm_string, "c"))
180 alpha_fprm = ALPHA_FPRM_CHOP;
181 else if (! strcmp (alpha_fprm_string,"d"))
182 alpha_fprm = ALPHA_FPRM_DYN;
184 error ("bad value `%s' for -mfp-rounding-mode switch",
188 if (alpha_fptm_string)
190 if (strcmp (alpha_fptm_string, "n") == 0)
191 alpha_fptm = ALPHA_FPTM_N;
192 else if (strcmp (alpha_fptm_string, "u") == 0)
193 alpha_fptm = ALPHA_FPTM_U;
194 else if (strcmp (alpha_fptm_string, "su") == 0)
195 alpha_fptm = ALPHA_FPTM_SU;
196 else if (strcmp (alpha_fptm_string, "sui") == 0)
197 alpha_fptm = ALPHA_FPTM_SUI;
199 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
203 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
204 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
206 if (alpha_cpu_string)
208 if (! strcmp (alpha_cpu_string, "ev4")
209 || ! strcmp (alpha_cpu_string, "ev45")
210 || ! strcmp (alpha_cpu_string, "21064"))
212 alpha_cpu = PROCESSOR_EV4;
213 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
215 else if (! strcmp (alpha_cpu_string, "ev5")
216 || ! strcmp (alpha_cpu_string, "21164"))
218 alpha_cpu = PROCESSOR_EV5;
219 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
221 else if (! strcmp (alpha_cpu_string, "ev56")
222 || ! strcmp (alpha_cpu_string, "21164a"))
224 alpha_cpu = PROCESSOR_EV5;
225 target_flags |= MASK_BWX;
226 target_flags &= ~ (MASK_MAX | MASK_FIX | MASK_CIX);
228 else if (! strcmp (alpha_cpu_string, "pca56")
229 || ! strcmp (alpha_cpu_string, "21164PC")
230 || ! strcmp (alpha_cpu_string, "21164pc"))
232 alpha_cpu = PROCESSOR_EV5;
233 target_flags |= MASK_BWX | MASK_MAX;
234 target_flags &= ~ (MASK_FIX | MASK_CIX);
236 else if (! strcmp (alpha_cpu_string, "ev6")
237 || ! strcmp (alpha_cpu_string, "21264"))
239 alpha_cpu = PROCESSOR_EV6;
240 target_flags |= MASK_BWX | MASK_MAX | MASK_FIX;
241 target_flags &= ~ (MASK_CIX);
243 else if (! strcmp (alpha_cpu_string, "ev67")
244 || ! strcmp (alpha_cpu_string, "21264a"))
246 alpha_cpu = PROCESSOR_EV6;
247 target_flags |= MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX;
250 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
253 /* Do some sanity checks on the above options. */
255 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
256 && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
258 warning ("fp software completion requires -mtrap-precision=i");
259 alpha_tp = ALPHA_TP_INSN;
262 if (alpha_cpu == PROCESSOR_EV6)
264 /* Except for EV6 pass 1 (not released), we always have precise
265 arithmetic traps. Which means we can do software completion
266 without minding trap shadows. */
267 alpha_tp = ALPHA_TP_PROG;
270 if (TARGET_FLOAT_VAX)
272 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
274 warning ("rounding mode not supported for VAX floats");
275 alpha_fprm = ALPHA_FPRM_NORM;
277 if (alpha_fptm == ALPHA_FPTM_SUI)
279 warning ("trap mode not supported for VAX floats");
280 alpha_fptm = ALPHA_FPTM_SU;
288 if (!alpha_mlat_string)
289 alpha_mlat_string = "L1";
291 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
292 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
294 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
295 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
296 && alpha_mlat_string[2] == '\0')
298 static int const cache_latency[][4] =
300 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
301 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
302 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
305 lat = alpha_mlat_string[1] - '0';
306 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
308 warning ("L%d cache latency unknown for %s",
309 lat, alpha_cpu_name[alpha_cpu]);
313 lat = cache_latency[alpha_cpu][lat-1];
315 else if (! strcmp (alpha_mlat_string, "main"))
317 /* Most current memories have about 370ns latency. This is
318 a reasonable guess for a fast cpu. */
323 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
327 alpha_memory_latency = lat;
330 /* Default the definition of "small data" to 8 bytes. */
334 /* Acquire a unique set number for our register saves and restores. */
335 alpha_sr_alias_set = new_alias_set ();
337 /* Set up function hooks. */
338 init_machine_status = alpha_init_machine_status;
339 mark_machine_status = alpha_mark_machine_status;
342 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
350 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
352 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
358 /* Returns 1 if OP is either the constant zero or a register. If a
359 register, it must be in the proper mode unless MODE is VOIDmode. */
362 reg_or_0_operand (op, mode)
364 enum machine_mode mode;
366 return op == const0_rtx || register_operand (op, mode);
369 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
373 reg_or_6bit_operand (op, mode)
375 enum machine_mode mode;
377 return ((GET_CODE (op) == CONST_INT
378 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
379 || register_operand (op, mode));
383 /* Return 1 if OP is an 8-bit constant or any register. */
386 reg_or_8bit_operand (op, mode)
388 enum machine_mode mode;
390 return ((GET_CODE (op) == CONST_INT
391 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
392 || register_operand (op, mode));
395 /* Return 1 if OP is an 8-bit constant. */
398 cint8_operand (op, mode)
400 enum machine_mode mode ATTRIBUTE_UNUSED;
402 return ((GET_CODE (op) == CONST_INT
403 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
406 /* Return 1 if the operand is a valid second operand to an add insn. */
409 add_operand (op, mode)
411 enum machine_mode mode;
413 if (GET_CODE (op) == CONST_INT)
414 /* Constraints I, J, O and P are covered by K. */
415 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
416 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
418 return register_operand (op, mode);
421 /* Return 1 if the operand is a valid second operand to a sign-extending
425 sext_add_operand (op, mode)
427 enum machine_mode mode;
429 if (GET_CODE (op) == CONST_INT)
430 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
431 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
433 return reg_not_elim_operand (op, mode);
436 /* Return 1 if OP is the constant 4 or 8. */
439 const48_operand (op, mode)
441 enum machine_mode mode ATTRIBUTE_UNUSED;
443 return (GET_CODE (op) == CONST_INT
444 && (INTVAL (op) == 4 || INTVAL (op) == 8));
447 /* Return 1 if OP is a valid first operand to an AND insn. */
450 and_operand (op, mode)
452 enum machine_mode mode;
454 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
455 return (zap_mask (CONST_DOUBLE_LOW (op))
456 && zap_mask (CONST_DOUBLE_HIGH (op)));
458 if (GET_CODE (op) == CONST_INT)
459 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
460 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
461 || zap_mask (INTVAL (op)));
463 return register_operand (op, mode);
466 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
469 or_operand (op, mode)
471 enum machine_mode mode;
473 if (GET_CODE (op) == CONST_INT)
474 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
475 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
477 return register_operand (op, mode);
480 /* Return 1 if OP is a constant that is the width, in bits, of an integral
481 mode smaller than DImode. */
484 mode_width_operand (op, mode)
486 enum machine_mode mode ATTRIBUTE_UNUSED;
488 return (GET_CODE (op) == CONST_INT
489 && (INTVAL (op) == 8 || INTVAL (op) == 16
490 || INTVAL (op) == 32 || INTVAL (op) == 64));
493 /* Return 1 if OP is a constant that is the width of an integral machine mode
494 smaller than an integer. */
497 mode_mask_operand (op, mode)
499 enum machine_mode mode ATTRIBUTE_UNUSED;
501 #if HOST_BITS_PER_WIDE_INT == 32
502 if (GET_CODE (op) == CONST_DOUBLE)
503 return (CONST_DOUBLE_LOW (op) == -1
504 && (CONST_DOUBLE_HIGH (op) == -1
505 || CONST_DOUBLE_HIGH (op) == 0));
507 if (GET_CODE (op) == CONST_DOUBLE)
508 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
511 return (GET_CODE (op) == CONST_INT
512 && (INTVAL (op) == 0xff
513 || INTVAL (op) == 0xffff
514 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
515 #if HOST_BITS_PER_WIDE_INT == 64
521 /* Return 1 if OP is a multiple of 8 less than 64. */
524 mul8_operand (op, mode)
526 enum machine_mode mode ATTRIBUTE_UNUSED;
528 return (GET_CODE (op) == CONST_INT
529 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
530 && (INTVAL (op) & 7) == 0);
533 /* Return 1 if OP is the constant zero in floating-point. */
536 fp0_operand (op, mode)
538 enum machine_mode mode;
540 return (GET_MODE (op) == mode
541 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
544 /* Return 1 if OP is the floating-point constant zero or a register. */
547 reg_or_fp0_operand (op, mode)
549 enum machine_mode mode;
551 return fp0_operand (op, mode) || register_operand (op, mode);
554 /* Return 1 if OP is a hard floating-point register. */
557 hard_fp_register_operand (op, mode)
559 enum machine_mode mode;
561 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
562 || (GET_CODE (op) == SUBREG
563 && hard_fp_register_operand (SUBREG_REG (op), mode)));
566 /* Return 1 if OP is a register or a constant integer. */
570 reg_or_cint_operand (op, mode)
572 enum machine_mode mode;
574 return (GET_CODE (op) == CONST_INT
575 || register_operand (op, mode));
578 /* Return 1 if OP is something that can be reloaded into a register;
579 if it is a MEM, it need not be valid. */
582 some_operand (op, mode)
584 enum machine_mode mode;
586 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
589 switch (GET_CODE (op))
591 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
592 case SYMBOL_REF: case CONST:
596 return some_operand (SUBREG_REG (op), VOIDmode);
605 /* Likewise, but don't accept constants. */
608 some_ni_operand (op, mode)
610 enum machine_mode mode;
612 if (GET_MODE (op) != mode && mode != VOIDmode)
615 if (GET_CODE (op) == SUBREG)
616 op = SUBREG_REG (op);
618 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
621 /* Return 1 if OP is a valid operand for the source of a move insn. */
624 input_operand (op, mode)
626 enum machine_mode mode;
628 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
631 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
634 switch (GET_CODE (op))
639 /* This handles both the Windows/NT and OSF cases. */
640 return mode == ptr_mode || mode == DImode;
647 if (register_operand (op, mode))
649 /* ... fall through ... */
651 return ((TARGET_BWX || (mode != HImode && mode != QImode))
652 && general_operand (op, mode));
655 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
658 return mode == QImode || mode == HImode || add_operand (op, mode);
670 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
674 current_file_function_operand (op, mode)
676 enum machine_mode mode ATTRIBUTE_UNUSED;
678 return (GET_CODE (op) == SYMBOL_REF
679 && ! profile_flag && ! profile_block_flag
680 && (SYMBOL_REF_FLAG (op)
681 || op == XEXP (DECL_RTL (current_function_decl), 0)));
684 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
687 call_operand (op, mode)
689 enum machine_mode mode;
694 return (GET_CODE (op) == SYMBOL_REF
695 || (GET_CODE (op) == REG
696 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
699 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
700 comparisons are valid in which insn. */
703 alpha_comparison_operator (op, mode)
705 enum machine_mode mode;
707 enum rtx_code code = GET_CODE (op);
709 if (mode != GET_MODE (op) && mode != VOIDmode)
712 return (code == EQ || code == LE || code == LT
713 || (mode == DImode && (code == LEU || code == LTU)));
716 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
719 alpha_swapped_comparison_operator (op, mode)
721 enum machine_mode mode;
723 enum rtx_code code = GET_CODE (op);
725 if ((mode != GET_MODE (op) && mode != VOIDmode)
726 || GET_RTX_CLASS (code) != '<')
729 code = swap_condition (code);
730 return (code == EQ || code == LE || code == LT
731 || (mode == DImode && (code == LEU || code == LTU)));
734 /* Return 1 if OP is a signed comparison operation. */
737 signed_comparison_operator (op, mode)
739 enum machine_mode mode ATTRIBUTE_UNUSED;
741 enum rtx_code code = GET_CODE (op);
743 if (mode != GET_MODE (op) && mode != VOIDmode)
746 return (code == EQ || code == NE
747 || code == LE || code == LT
748 || code == GE || code == GT);
751 /* Return 1 if OP is a valid Alpha floating point comparison operator.
752 Here we know which comparisons are valid in which insn. */
755 alpha_fp_comparison_operator (op, mode)
757 enum machine_mode mode;
759 enum rtx_code code = GET_CODE (op);
761 if (mode != GET_MODE (op) && mode != VOIDmode)
764 return (code == EQ || code == LE || code == LT || code == UNORDERED);
767 /* Return 1 if this is a divide or modulus operator. */
770 divmod_operator (op, mode)
772 enum machine_mode mode ATTRIBUTE_UNUSED;
774 switch (GET_CODE (op))
776 case DIV: case MOD: case UDIV: case UMOD:
786 /* Return 1 if this memory address is a known aligned register plus
787 a constant. It must be a valid address. This means that we can do
788 this as an aligned reference plus some offset.
790 Take into account what reload will do. */
793 aligned_memory_operand (op, mode)
795 enum machine_mode mode;
799 if (reload_in_progress)
802 if (GET_CODE (tmp) == SUBREG)
803 tmp = SUBREG_REG (tmp);
804 if (GET_CODE (tmp) == REG
805 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
807 op = reg_equiv_memory_loc[REGNO (tmp)];
813 if (GET_CODE (op) != MEM
814 || GET_MODE (op) != mode)
818 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
819 sorts of constructs. Dig for the real base register. */
820 if (reload_in_progress
821 && GET_CODE (op) == PLUS
822 && GET_CODE (XEXP (op, 0)) == PLUS)
823 base = XEXP (XEXP (op, 0), 0);
826 if (! memory_address_p (mode, op))
828 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
831 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
834 /* Similar, but return 1 if OP is a MEM which is not alignable. */
837 unaligned_memory_operand (op, mode)
839 enum machine_mode mode;
843 if (reload_in_progress)
846 if (GET_CODE (tmp) == SUBREG)
847 tmp = SUBREG_REG (tmp);
848 if (GET_CODE (tmp) == REG
849 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
851 op = reg_equiv_memory_loc[REGNO (tmp)];
857 if (GET_CODE (op) != MEM
858 || GET_MODE (op) != mode)
862 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
863 sorts of constructs. Dig for the real base register. */
864 if (reload_in_progress
865 && GET_CODE (op) == PLUS
866 && GET_CODE (XEXP (op, 0)) == PLUS)
867 base = XEXP (XEXP (op, 0), 0);
870 if (! memory_address_p (mode, op))
872 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
875 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
878 /* Return 1 if OP is either a register or an unaligned memory location. */
881 reg_or_unaligned_mem_operand (op, mode)
883 enum machine_mode mode;
885 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
888 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
891 any_memory_operand (op, mode)
893 enum machine_mode mode ATTRIBUTE_UNUSED;
895 return (GET_CODE (op) == MEM
896 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
897 || (reload_in_progress && GET_CODE (op) == REG
898 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
899 || (reload_in_progress && GET_CODE (op) == SUBREG
900 && GET_CODE (SUBREG_REG (op)) == REG
901 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
904 /* Returns 1 if OP is not an eliminable register.
906 This exists to cure a pathological abort in the s8addq (et al) patterns,
908 long foo () { long t; bar(); return (long) &t * 26107; }
910 which run afoul of a hack in reload to cure a (presumably) similar
911 problem with lea-type instructions on other targets. But there is
912 one of us and many of them, so work around the problem by selectively
913 preventing combine from making the optimization. */
916 reg_not_elim_operand (op, mode)
918 enum machine_mode mode;
921 if (GET_CODE (op) == SUBREG)
922 inner = SUBREG_REG (op);
923 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
926 return register_operand (op, mode);
929 /* Return 1 is OP is a memory location that is not a reference (using
930 an AND) to an unaligned location. Take into account what reload
934 normal_memory_operand (op, mode)
936 enum machine_mode mode ATTRIBUTE_UNUSED;
938 if (reload_in_progress)
941 if (GET_CODE (tmp) == SUBREG)
942 tmp = SUBREG_REG (tmp);
943 if (GET_CODE (tmp) == REG
944 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
946 op = reg_equiv_memory_loc[REGNO (tmp)];
948 /* This may not have been assigned an equivalent address if it will
949 be eliminated. In that case, it doesn't matter what we do. */
955 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
958 /* Accept a register, but not a subreg of any kind. This allows us to
959 avoid pathological cases in reload wrt data movement common in
960 int->fp conversion. */
963 reg_no_subreg_operand (op, mode)
965 enum machine_mode mode;
967 if (GET_CODE (op) == SUBREG)
969 return register_operand (op, mode);
972 /* Recognize a addition operation that includes a constant. Used to
973 convince reload to canonize (plus (plus reg c1) c2) during register
977 addition_operation (op, mode)
979 enum machine_mode mode;
981 if (GET_MODE (op) != mode && mode != VOIDmode)
983 if (GET_CODE (op) == PLUS
984 && register_operand (XEXP (op, 0), mode)
985 && GET_CODE (XEXP (op, 1)) == CONST_INT
986 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
991 /* Return 1 if this function can directly return via $26. */
996 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
997 && get_frame_size () == 0
998 && current_function_outgoing_args_size == 0
999 && current_function_pretend_args_size == 0);
1002 /* REF is an alignable memory location. Place an aligned SImode
1003 reference into *PALIGNED_MEM and the number of bits to shift into
1004 *PBITNUM. SCRATCH is a free register for use in reloading out
1005 of range stack slots. */
1008 get_aligned_mem (ref, paligned_mem, pbitnum)
1010 rtx *paligned_mem, *pbitnum;
1013 HOST_WIDE_INT offset = 0;
1015 if (GET_CODE (ref) != MEM)
1018 if (reload_in_progress
1019 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1021 base = find_replacement (&XEXP (ref, 0));
1023 if (! memory_address_p (GET_MODE (ref), base))
1028 base = XEXP (ref, 0);
1031 if (GET_CODE (base) == PLUS)
1032 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1034 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1035 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1037 /* Sadly, we cannot use alias sets here because we may overlap other
1038 data in a different alias set. */
1039 MEM_ALIAS_SET (*paligned_mem) = 0;
1041 *pbitnum = GEN_INT ((offset & 3) * 8);
1044 /* Similar, but just get the address. Handle the two reload cases.
1045 Add EXTRA_OFFSET to the address we return. */
1048 get_unaligned_address (ref, extra_offset)
1053 HOST_WIDE_INT offset = 0;
1055 if (GET_CODE (ref) != MEM)
1058 if (reload_in_progress
1059 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1061 base = find_replacement (&XEXP (ref, 0));
1063 if (! memory_address_p (GET_MODE (ref), base))
1068 base = XEXP (ref, 0);
1071 if (GET_CODE (base) == PLUS)
1072 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1074 return plus_constant (base, offset + extra_offset);
1077 /* Loading and storing HImode or QImode values to and from memory
1078 usually requires a scratch register. The exceptions are loading
1079 QImode and HImode from an aligned address to a general register
1080 unless byte instructions are permitted.
1082 We also cannot load an unaligned address or a paradoxical SUBREG
1083 into an FP register.
1085 We also cannot do integral arithmetic into FP regs, as might result
1086 from register elimination into a DImode fp register. */
1089 secondary_reload_class (class, mode, x, in)
1090 enum reg_class class;
1091 enum machine_mode mode;
1095 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1097 if (GET_CODE (x) == MEM
1098 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1099 || (GET_CODE (x) == SUBREG
1100 && (GET_CODE (SUBREG_REG (x)) == MEM
1101 || (GET_CODE (SUBREG_REG (x)) == REG
1102 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1104 if (!in || !aligned_memory_operand(x, mode))
1105 return GENERAL_REGS;
1109 if (class == FLOAT_REGS)
1111 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1112 return GENERAL_REGS;
1114 if (GET_CODE (x) == SUBREG
1115 && (GET_MODE_SIZE (GET_MODE (x))
1116 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1117 return GENERAL_REGS;
1119 if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
1120 return GENERAL_REGS;
1126 /* Subfunction of the following function. Update the flags of any MEM
1127 found in part of X. */
1130 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1132 int in_struct_p, volatile_p, unchanging_p;
1136 switch (GET_CODE (x))
1140 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1141 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1146 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1151 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1153 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1158 MEM_IN_STRUCT_P (x) = in_struct_p;
1159 MEM_VOLATILE_P (x) = volatile_p;
1160 RTX_UNCHANGING_P (x) = unchanging_p;
1161 /* Sadly, we cannot use alias sets because the extra aliasing
1162 produced by the AND interferes. Given that two-byte quantities
1163 are the only thing we would be able to differentiate anyway,
1164 there does not seem to be any point in convoluting the early
1165 out of the alias check. */
1166 /* MEM_ALIAS_SET (x) = alias_set; */
1174 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1175 perform a memory operation, look for any MEMs in either a SET_DEST or
1176 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1177 REF into each of the MEMs found. If REF is not a MEM, don't do
1181 alpha_set_memflags (insn, ref)
1185 int in_struct_p, volatile_p, unchanging_p;
1187 if (GET_CODE (ref) != MEM)
1190 in_struct_p = MEM_IN_STRUCT_P (ref);
1191 volatile_p = MEM_VOLATILE_P (ref);
1192 unchanging_p = RTX_UNCHANGING_P (ref);
1194 /* This is only called from alpha.md, after having had something
1195 generated from one of the insn patterns. So if everything is
1196 zero, the pattern is already up-to-date. */
1197 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1200 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1203 /* Try to output insns to set TARGET equal to the constant C if it can be
1204 done in less than N insns. Do all computations in MODE. Returns the place
1205 where the output has been placed if it can be done and the insns have been
1206 emitted. If it would take more than N insns, zero is returned and no
1207 insns and emitted. */
1210 alpha_emit_set_const (target, mode, c, n)
1212 enum machine_mode mode;
1219 /* Try 1 insn, then 2, then up to N. */
1220 for (i = 1; i <= n; i++)
1221 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1227 /* Internal routine for the above to check for N or below insns. */
1230 alpha_emit_set_const_1 (target, mode, c, n)
1232 enum machine_mode mode;
1238 /* Use a pseudo if highly optimizing and still generating RTL. */
1240 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1244 #if HOST_BITS_PER_WIDE_INT == 64
1245 /* We are only called for SImode and DImode. If this is SImode, ensure that
1246 we are sign extended to a full word. This does not make any sense when
1247 cross-compiling on a narrow machine. */
1250 c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1253 /* If this is a sign-extended 32-bit constant, we can do this in at most
1254 three insns, so do it if we have enough insns left. We always have
1255 a sign-extended 32-bit constant when compiling on a narrow machine. */
1257 if (HOST_BITS_PER_WIDE_INT != 64
1258 || c >> 31 == -1 || c >> 31 == 0)
1260 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1261 HOST_WIDE_INT tmp1 = c - low;
1262 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1263 HOST_WIDE_INT extra = 0;
1265 /* If HIGH will be interpreted as negative but the constant is
1266 positive, we must adjust it to do two ldha insns. */
1268 if ((high & 0x8000) != 0 && c >= 0)
1272 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1275 if (c == low || (low == 0 && extra == 0))
1277 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1278 but that meant that we can't handle INT_MIN on 32-bit machines
1279 (like NT/Alpha), because we recurse indefinitely through
1280 emit_move_insn to gen_movdi. So instead, since we know exactly
1281 what we want, create it explicitly. */
1284 target = gen_reg_rtx (mode);
1285 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1288 else if (n >= 2 + (extra != 0))
1290 temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
1293 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1294 subtarget, 0, OPTAB_WIDEN);
1296 return expand_binop (mode, add_optab, temp, GEN_INT (low),
1297 target, 0, OPTAB_WIDEN);
1301 /* If we couldn't do it that way, try some other methods. But if we have
1302 no instructions left, don't bother. Likewise, if this is SImode and
1303 we can't make pseudos, we can't do anything since the expand_binop
1304 and expand_unop calls will widen and try to make pseudos. */
1307 || (mode == SImode && ! rtx_equal_function_value_matters))
1310 /* Next, see if we can load a related constant and then shift and possibly
1311 negate it to get the constant we want. Try this once each increasing
1312 numbers of insns. */
1314 for (i = 1; i < n; i++)
1316 /* First, see if minus some low bits, we've an easy load of
1319 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1321 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
1322 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1323 target, 0, OPTAB_WIDEN);
1325 /* Next try complementing. */
1326 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1327 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1329 /* Next try to form a constant and do a left shift. We can do this
1330 if some low-order bits are zero; the exact_log2 call below tells
1331 us that information. The bits we are shifting out could be any
1332 value, but here we'll just try the 0- and sign-extended forms of
1333 the constant. To try to increase the chance of having the same
1334 constant in more than one insn, start at the highest number of
1335 bits to shift, but try all possibilities in case a ZAPNOT will
1338 if ((bits = exact_log2 (c & - c)) > 0)
1339 for (; bits > 0; bits--)
1340 if ((temp = (alpha_emit_set_const
1341 (subtarget, mode, c >> bits, i))) != 0
1342 || ((temp = (alpha_emit_set_const
1344 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1346 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1347 target, 0, OPTAB_WIDEN);
1349 /* Now try high-order zero bits. Here we try the shifted-in bits as
1350 all zero and all ones. Be careful to avoid shifting outside the
1351 mode and to avoid shifting outside the host wide int size. */
1352 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1353 confuse the recursive call and set all of the high 32 bits. */
1355 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1356 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1357 for (; bits > 0; bits--)
1358 if ((temp = alpha_emit_set_const (subtarget, mode,
1360 || ((temp = (alpha_emit_set_const
1362 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1365 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1366 target, 1, OPTAB_WIDEN);
1368 /* Now try high-order 1 bits. We get that with a sign-extension.
1369 But one bit isn't enough here. Be careful to avoid shifting outside
1370 the mode and to avoid shifting outside the host wide int size. */
1372 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1373 - floor_log2 (~ c) - 2)) > 0)
1374 for (; bits > 0; bits--)
1375 if ((temp = alpha_emit_set_const (subtarget, mode,
1377 || ((temp = (alpha_emit_set_const
1379 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1382 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1383 target, 0, OPTAB_WIDEN);
1386 #if HOST_BITS_PER_WIDE_INT == 64
1387 /* Finally, see if can load a value into the target that is the same as the
1388 constant except that all bytes that are 0 are changed to be 0xff. If we
1389 can, then we can do a ZAPNOT to obtain the desired constant. */
1392 for (i = 0; i < 64; i += 8)
1393 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1394 new |= (HOST_WIDE_INT) 0xff << i;
1396 /* We are only called for SImode and DImode. If this is SImode, ensure that
1397 we are sign extended to a full word. */
1400 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1402 if (new != c && new != -1
1403 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1404 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1405 target, 0, OPTAB_WIDEN);
1411 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1412 fall back to a straight forward decomposition. We do this to avoid
1413 exponential run times encountered when looking for longer sequences
1414 with alpha_emit_set_const. */
1417 alpha_emit_set_long_const (target, c1, c2)
1419 HOST_WIDE_INT c1, c2;
1421 HOST_WIDE_INT d1, d2, d3, d4;
1423 /* Decompose the entire word */
1424 #if HOST_BITS_PER_WIDE_INT >= 64
1425 if (c2 != -(c1 < 0))
1427 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1429 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1430 c1 = (c1 - d2) >> 32;
1431 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1433 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1437 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1439 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1443 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1445 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1450 /* Construct the high word */
1453 emit_move_insn (target, GEN_INT (d4));
1455 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1458 emit_move_insn (target, GEN_INT (d3));
1460 /* Shift it into place */
1461 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1463 /* Add in the low bits. */
1465 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1467 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1472 /* Generate an unsigned DImode to FP conversion. This is the same code
1473 optabs would emit if we didn't have TFmode patterns.
1475 For SFmode, this is the only construction I've found that can pass
1476 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
1477 intermediates will work, because you'll get intermediate rounding
1478 that ruins the end result. Some of this could be fixed by turning
1479 on round-to-positive-infinity, but that requires diddling the fpsr,
1480 which kills performance. I tried turning this around and converting
1481 to a negative number, so that I could turn on /m, but either I did
1482 it wrong or there's something else cause I wound up with the exact
1483 same single-bit error. There is a branch-less form of this same code:
1494 fcmoveq $f10,$f11,$f0
1496 I'm not using it because it's the same number of instructions as
1497 this branch-full form, and it has more serialized long latency
1498 instructions on the critical path.
1500 For DFmode, we can avoid rounding errors by breaking up the word
1501 into two pieces, converting them separately, and adding them back:
1503 LC0: .long 0,0x5f800000
1508 cpyse $f11,$f31,$f10
1509 cpyse $f31,$f11,$f11
1517 This doesn't seem to be a clear-cut win over the optabs form.
1518 It probably all depends on the distribution of numbers being
1519 converted -- in the optabs form, all but high-bit-set has a
1520 much lower minimum execution time. */
1523 alpha_emit_floatuns (operands)
1526 rtx neglab, donelab, i0, i1, f0, in, out;
1527 enum machine_mode mode;
1530 in = force_reg (DImode, operands[1]);
1531 mode = GET_MODE (out);
1532 neglab = gen_label_rtx ();
1533 donelab = gen_label_rtx ();
1534 i0 = gen_reg_rtx (DImode);
1535 i1 = gen_reg_rtx (DImode);
1536 f0 = gen_reg_rtx (mode);
1538 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0,
1541 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
1542 emit_jump_insn (gen_jump (donelab));
1545 emit_label (neglab);
1547 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
1548 emit_insn (gen_anddi3 (i1, in, const1_rtx));
1549 emit_insn (gen_iordi3 (i0, i0, i1));
1550 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
1551 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
1553 emit_label (donelab);
1556 /* Generate the comparison for a conditional branch. */
1559 alpha_emit_conditional_branch (code)
1562 enum rtx_code cmp_code, branch_code;
1563 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1564 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1567 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
1569 if (! TARGET_HAS_XFLOATING_LIBS)
1572 /* X_floating library comparison functions return
1576 Convert the compare against the raw return value. */
1578 op0 = alpha_emit_xfloating_compare (code, op0, op1);
1580 alpha_compare.fp_p = 0;
1584 /* The general case: fold the comparison code to the types of compares
1585 that we have, choosing the branch as necessary. */
1588 case EQ: case LE: case LT: case LEU: case LTU:
1590 /* We have these compares: */
1591 cmp_code = code, branch_code = NE;
1596 /* These must be reversed. */
1597 cmp_code = reverse_condition (code), branch_code = EQ;
1600 case GE: case GT: case GEU: case GTU:
1601 /* For FP, we swap them, for INT, we reverse them. */
1602 if (alpha_compare.fp_p)
1604 cmp_code = swap_condition (code);
1606 tem = op0, op0 = op1, op1 = tem;
1610 cmp_code = reverse_condition (code);
1619 if (alpha_compare.fp_p)
1624 /* When we are not as concerned about non-finite values, and we
1625 are comparing against zero, we can branch directly. */
1626 if (op1 == CONST0_RTX (DFmode))
1627 cmp_code = NIL, branch_code = code;
1628 else if (op0 == CONST0_RTX (DFmode))
1630 /* Undo the swap we probably did just above. */
1631 tem = op0, op0 = op1, op1 = tem;
1632 branch_code = swap_condition (cmp_code);
1638 /* ??? We mark the the branch mode to be CCmode to prevent the
1639 compare and branch from being combined, since the compare
1640 insn follows IEEE rules that the branch does not. */
1641 branch_mode = CCmode;
1648 /* The following optimizations are only for signed compares. */
1649 if (code != LEU && code != LTU && code != GEU && code != GTU)
1651 /* Whee. Compare and branch against 0 directly. */
1652 if (op1 == const0_rtx)
1653 cmp_code = NIL, branch_code = code;
1655 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1656 bypass between logicals and br/cmov on EV5. But we don't want to
1657 force valid immediate constants into registers needlessly. */
1658 else if (GET_CODE (op1) == CONST_INT)
1660 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1662 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1663 && (CONST_OK_FOR_LETTER_P (n, 'K')
1664 || CONST_OK_FOR_LETTER_P (n, 'L')))
1666 cmp_code = PLUS, branch_code = code;
1673 /* Force op0 into a register. */
1674 if (GET_CODE (op0) != REG)
1675 op0 = force_reg (cmp_mode, op0);
1677 /* Emit an initial compare instruction, if necessary. */
1679 if (cmp_code != NIL)
1681 tem = gen_reg_rtx (cmp_mode);
1682 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1685 /* Zero the operands. */
1686 memset (&alpha_compare, 0, sizeof (alpha_compare));
1688 /* Return the branch comparison. */
1689 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1693 /* Rewrite a comparison against zero CMP of the form
1694 (CODE (cc0) (const_int 0)) so it can be written validly in
1695 a conditional move (if_then_else CMP ...).
1696 If both of the operands that set cc0 are non-zero we must emit
1697 an insn to perform the compare (it can't be done within
1698 the conditional move). */
1700 alpha_emit_conditional_move (cmp, mode)
1702 enum machine_mode mode;
1704 enum rtx_code code = GET_CODE (cmp);
1705 enum rtx_code cmov_code = NE;
1706 rtx op0 = alpha_compare.op0;
1707 rtx op1 = alpha_compare.op1;
1708 int fp_p = alpha_compare.fp_p;
1709 enum machine_mode cmp_mode
1710 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1711 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1712 enum machine_mode cmov_mode = VOIDmode;
1713 int local_fast_math = flag_fast_math;
1716 /* Zero the operands. */
1717 memset (&alpha_compare, 0, sizeof (alpha_compare));
1719 if (fp_p != FLOAT_MODE_P (mode))
1721 enum rtx_code cmp_code;
1726 /* If we have fp<->int register move instructions, do a cmov by
1727 performing the comparison in fp registers, and move the
1728 zero/non-zero value to integer registers, where we can then
1729 use a normal cmov, or vice-versa. */
1733 case EQ: case LE: case LT: case LEU: case LTU:
1734 /* We have these compares. */
1735 cmp_code = code, code = NE;
1739 /* This must be reversed. */
1740 cmp_code = EQ, code = EQ;
1743 case GE: case GT: case GEU: case GTU:
1744 /* These must be swapped. */
1745 cmp_code = swap_condition (code);
1747 tem = op0, op0 = op1, op1 = tem;
1754 tem = gen_reg_rtx (cmp_op_mode);
1755 emit_insn (gen_rtx_SET (VOIDmode, tem,
1756 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1759 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1760 op0 = gen_lowpart (cmp_op_mode, tem);
1761 op1 = CONST0_RTX (cmp_op_mode);
1763 local_fast_math = 1;
1766 /* We may be able to use a conditional move directly.
1767 This avoids emitting spurious compares. */
1768 if (signed_comparison_operator (cmp, VOIDmode)
1769 && (!fp_p || local_fast_math)
1770 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1771 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1773 /* We can't put the comparison inside the conditional move;
1774 emit a compare instruction and put that inside the
1775 conditional move. Make sure we emit only comparisons we have;
1776 swap or reverse as necessary. */
1783 case EQ: case LE: case LT: case LEU: case LTU:
1784 /* We have these compares: */
1788 /* This must be reversed. */
1789 code = reverse_condition (code);
1793 case GE: case GT: case GEU: case GTU:
1794 /* These must be swapped. Make sure the new first operand is in
1796 code = swap_condition (code);
1797 tem = op0, op0 = op1, op1 = tem;
1798 op0 = force_reg (cmp_mode, op0);
1805 /* ??? We mark the branch mode to be CCmode to prevent the compare
1806 and cmov from being combined, since the compare insn follows IEEE
1807 rules that the cmov does not. */
1808 if (fp_p && !local_fast_math)
1811 tem = gen_reg_rtx (cmp_op_mode);
1812 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1813 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1816 /* Look up the function X_floating library function name for the
1820 alpha_lookup_xfloating_lib_func (code)
1829 static const struct xfloating_op vms_xfloating_ops[] =
1831 { PLUS, "OTS$ADD_X" },
1832 { MINUS, "OTS$SUB_X" },
1833 { MULT, "OTS$MUL_X" },
1834 { DIV, "OTS$DIV_X" },
1835 { EQ, "OTS$EQL_X" },
1836 { NE, "OTS$NEQ_X" },
1837 { LT, "OTS$LSS_X" },
1838 { LE, "OTS$LEQ_X" },
1839 { GT, "OTS$GTR_X" },
1840 { GE, "OTS$GEQ_X" },
1841 { FIX, "OTS$CVTXQ" },
1842 { FLOAT, "OTS$CVTQX" },
1843 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
1844 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
1845 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
1848 static const struct xfloating_op osf_xfloating_ops[] =
1850 { PLUS, "_OtsAddX" },
1851 { MINUS, "_OtsSubX" },
1852 { MULT, "_OtsMulX" },
1853 { DIV, "_OtsDivX" },
1860 { FIX, "_OtsCvtXQ" },
1861 { FLOAT, "_OtsCvtQX" },
1862 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
1863 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
1864 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
1867 const struct xfloating_op *ops;
1868 const long n = sizeof(osf_xfloating_ops) / sizeof(osf_xfloating_ops[0]);
1871 /* How irritating. Nothing to key off for the table. Hardcode
1872 knowledge of the G_floating routines. */
1873 if (TARGET_FLOAT_VAX)
1875 if (TARGET_OPEN_VMS)
1877 if (code == FLOAT_EXTEND)
1878 return "OTS$CVT_FLOAT_G_X";
1879 if (code == FLOAT_TRUNCATE)
1880 return "OTS$CVT_FLOAT_X_G";
1884 if (code == FLOAT_EXTEND)
1885 return "_OtsConvertFloatGX";
1886 if (code == FLOAT_TRUNCATE)
1887 return "_OtsConvertFloatXG";
1891 if (TARGET_OPEN_VMS)
1892 ops = vms_xfloating_ops;
1894 ops = osf_xfloating_ops;
1896 for (i = 0; i < n; ++i)
1897 if (ops[i].code == code)
1903 /* Most X_floating operations take the rounding mode as an argument.
1904 Compute that here. */
1907 alpha_compute_xfloating_mode_arg (code, round)
1909 enum alpha_fp_rounding_mode round;
1915 case ALPHA_FPRM_NORM:
1918 case ALPHA_FPRM_MINF:
1921 case ALPHA_FPRM_CHOP:
1924 case ALPHA_FPRM_DYN:
1930 /* XXX For reference, round to +inf is mode = 3. */
1933 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
1939 /* Emit an X_floating library function call.
1941 Note that these functions do not follow normal calling conventions:
1942 TFmode arguments are passed in two integer registers (as opposed to
1943 indirect); TFmode return values appear in R16+R17.
1945 FUNC is the function name to call.
1946 TARGET is where the output belongs.
1947 OPERANDS are the inputs.
1948 NOPERANDS is the count of inputs.
1949 EQUIV is the expression equivalent for the function.
1953 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
1960 rtx usage = NULL_RTX, tmp, reg;
1965 for (i = 0; i < noperands; ++i)
1967 switch (GET_MODE (operands[i]))
1970 reg = gen_rtx_REG (TFmode, regno);
1975 reg = gen_rtx_REG (DFmode, regno + 32);
1980 if (GET_CODE (operands[i]) != CONST_INT)
1984 reg = gen_rtx_REG (DImode, regno);
1992 emit_move_insn (reg, operands[i]);
1993 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
1996 switch (GET_MODE (target))
1999 reg = gen_rtx_REG (TFmode, 16);
2002 reg = gen_rtx_REG (DFmode, 32);
2005 reg = gen_rtx_REG (DImode, 0);
2011 tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
2012 tmp = emit_call_insn (gen_call_value (reg, tmp, const0_rtx,
2013 const0_rtx, const0_rtx));
2014 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2019 emit_libcall_block (tmp, target, reg, equiv);
2022 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2025 alpha_emit_xfloating_arith (code, operands)
2031 rtx out_operands[3];
2033 func = alpha_lookup_xfloating_lib_func (code);
2034 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2036 out_operands[0] = operands[1];
2037 out_operands[1] = operands[2];
2038 out_operands[2] = GEN_INT (mode);
2039 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2040 gen_rtx_fmt_ee (code, TFmode, operands[1],
2044 /* Emit an X_floating library function call for a comparison. */
2047 alpha_emit_xfloating_compare (code, op0, op1)
2052 rtx out, operands[2];
2054 func = alpha_lookup_xfloating_lib_func (code);
2058 out = gen_reg_rtx (DImode);
2060 /* ??? Strange equiv cause what's actually returned is -1,0,1, not a
2061 proper boolean value. */
2062 alpha_emit_xfloating_libcall (func, out, operands, 2,
2063 gen_rtx_COMPARE (TFmode, op0, op1));
2068 /* Emit an X_floating library function call for a conversion. */
2071 alpha_emit_xfloating_cvt (code, operands)
2075 int noperands = 1, mode;
2076 rtx out_operands[2];
2079 func = alpha_lookup_xfloating_lib_func (code);
2081 out_operands[0] = operands[1];
2086 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2087 out_operands[1] = GEN_INT (mode);
2090 case FLOAT_TRUNCATE:
2091 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2092 out_operands[1] = GEN_INT (mode);
2099 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
2100 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
2105 alpha_split_tfmode_pair (operands)
2108 if (GET_CODE (operands[1]) == REG)
2110 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
2111 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
2113 else if (GET_CODE (operands[1]) == MEM)
2115 operands[3] = change_address (operands[1], DImode,
2116 plus_constant (XEXP (operands[1], 0), 8));
2117 operands[2] = change_address (operands[1], DImode, NULL_RTX);
2119 else if (operands[1] == CONST0_RTX (TFmode))
2120 operands[2] = operands[3] = const0_rtx;
2124 if (GET_CODE (operands[0]) == REG)
2126 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
2127 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
2129 else if (GET_CODE (operands[0]) == MEM)
2131 operands[1] = change_address (operands[0], DImode,
2132 plus_constant (XEXP (operands[0], 0), 8));
2133 operands[0] = change_address (operands[0], DImode, NULL_RTX);
2139 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
2143 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
2144 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
2145 lda r3,X(r11) lda r3,X+2(r11)
2146 extwl r1,r3,r1 extql r1,r3,r1
2147 extwh r2,r3,r2 extqh r2,r3,r2
2148 or r1.r2.r1 or r1,r2,r1
2151 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
2152 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
2153 lda r3,X(r11) lda r3,X(r11)
2154 extll r1,r3,r1 extll r1,r3,r1
2155 extlh r2,r3,r2 extlh r2,r3,r2
2156 or r1.r2.r1 addl r1,r2,r1
2158 quad: ldq_u r1,X(r11)
2167 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
2169 HOST_WIDE_INT size, ofs;
2172 rtx meml, memh, addr, extl, exth;
2173 enum machine_mode mode;
2175 meml = gen_reg_rtx (DImode);
2176 memh = gen_reg_rtx (DImode);
2177 addr = gen_reg_rtx (DImode);
2178 extl = gen_reg_rtx (DImode);
2179 exth = gen_reg_rtx (DImode);
2181 emit_move_insn (meml,
2182 change_address (mem, DImode,
2183 gen_rtx_AND (DImode,
2184 plus_constant (XEXP (mem, 0),
2188 emit_move_insn (memh,
2189 change_address (mem, DImode,
2190 gen_rtx_AND (DImode,
2191 plus_constant (XEXP (mem, 0),
2195 if (sign && size == 2)
2197 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
2199 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
2200 emit_insn (gen_extqh (exth, memh, addr));
2202 /* We must use tgt here for the target. Alpha-vms port fails if we use
2203 addr for the target, because addr is marked as a pointer and combine
2204 knows that pointers are always sign-extended 32 bit values. */
2205 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
2206 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
2207 addr, 1, OPTAB_WIDEN);
2211 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
2212 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
2216 emit_insn (gen_extwh (exth, memh, addr));
2221 emit_insn (gen_extlh (exth, memh, addr));
2226 emit_insn (gen_extqh (exth, memh, addr));
2234 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
2235 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
2240 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
2243 /* Similarly, use ins and msk instructions to perform unaligned stores. */
2246 alpha_expand_unaligned_store (dst, src, size, ofs)
2248 HOST_WIDE_INT size, ofs;
2250 rtx dstl, dsth, addr, insl, insh, meml, memh;
2252 dstl = gen_reg_rtx (DImode);
2253 dsth = gen_reg_rtx (DImode);
2254 insl = gen_reg_rtx (DImode);
2255 insh = gen_reg_rtx (DImode);
2257 meml = change_address (dst, DImode,
2258 gen_rtx_AND (DImode,
2259 plus_constant (XEXP (dst, 0), ofs),
2261 memh = change_address (dst, DImode,
2262 gen_rtx_AND (DImode,
2263 plus_constant (XEXP (dst, 0),
2267 emit_move_insn (dsth, memh);
2268 emit_move_insn (dstl, meml);
2269 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
2271 if (src != const0_rtx)
2273 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
2274 GEN_INT (size*8), addr));
2279 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
2282 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
2285 emit_insn (gen_insql (insl, src, addr));
2290 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
2295 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
2298 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
2302 #if HOST_BITS_PER_WIDE_INT == 32
2303 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
2305 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
2307 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
2312 if (src != const0_rtx)
2314 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
2315 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
2318 /* Must store high before low for degenerate case of aligned. */
2319 emit_move_insn (memh, dsth);
2320 emit_move_insn (meml, dstl);
2323 /* The block move code tries to maximize speed by separating loads and
2324 stores at the expense of register pressure: we load all of the data
2325 before we store it back out. There are two secondary effects worth
2326 mentioning, that this speeds copying to/from aligned and unaligned
2327 buffers, and that it makes the code significantly easier to write. */
2329 #define MAX_MOVE_WORDS 8
2331 /* Load an integral number of consecutive unaligned quadwords. */
2334 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
2337 HOST_WIDE_INT words, ofs;
2339 rtx const im8 = GEN_INT (-8);
2340 rtx const i64 = GEN_INT (64);
2341 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
2345 /* Generate all the tmp registers we need. */
2346 for (i = 0; i < words; ++i)
2348 data_regs[i] = out_regs[i];
2349 ext_tmps[i] = gen_reg_rtx (DImode);
2351 data_regs[words] = gen_reg_rtx (DImode);
2354 smem = change_address (smem, GET_MODE (smem),
2355 plus_constant (XEXP (smem, 0), ofs));
2357 /* Load up all of the source data. */
2358 for (i = 0; i < words; ++i)
2360 emit_move_insn (data_regs[i],
2361 change_address (smem, DImode,
2362 gen_rtx_AND (DImode,
2363 plus_constant (XEXP(smem,0),
2367 emit_move_insn (data_regs[words],
2368 change_address (smem, DImode,
2369 gen_rtx_AND (DImode,
2370 plus_constant (XEXP(smem,0),
2374 /* Extract the half-word fragments. Unfortunately DEC decided to make
2375 extxh with offset zero a noop instead of zeroing the register, so
2376 we must take care of that edge condition ourselves with cmov. */
2378 sreg = copy_addr_to_reg (XEXP (smem, 0));
2379 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
2381 for (i = 0; i < words; ++i)
2383 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
2385 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
2386 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
2387 gen_rtx_IF_THEN_ELSE (DImode,
2388 gen_rtx_EQ (DImode, areg,
2390 const0_rtx, ext_tmps[i])));
2393 /* Merge the half-words into whole words. */
2394 for (i = 0; i < words; ++i)
2396 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
2397 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
2401 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
2402 may be NULL to store zeros. */
2405 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
2408 HOST_WIDE_INT words, ofs;
2410 rtx const im8 = GEN_INT (-8);
2411 rtx const i64 = GEN_INT (64);
2412 #if HOST_BITS_PER_WIDE_INT == 32
2413 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
2415 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
2417 rtx ins_tmps[MAX_MOVE_WORDS];
2418 rtx st_tmp_1, st_tmp_2, dreg;
2419 rtx st_addr_1, st_addr_2;
2422 /* Generate all the tmp registers we need. */
2423 if (data_regs != NULL)
2424 for (i = 0; i < words; ++i)
2425 ins_tmps[i] = gen_reg_rtx(DImode);
2426 st_tmp_1 = gen_reg_rtx(DImode);
2427 st_tmp_2 = gen_reg_rtx(DImode);
2430 dmem = change_address (dmem, GET_MODE (dmem),
2431 plus_constant (XEXP (dmem, 0), ofs));
2434 st_addr_2 = change_address (dmem, DImode,
2435 gen_rtx_AND (DImode,
2436 plus_constant (XEXP(dmem,0),
2439 st_addr_1 = change_address (dmem, DImode,
2440 gen_rtx_AND (DImode,
2444 /* Load up the destination end bits. */
2445 emit_move_insn (st_tmp_2, st_addr_2);
2446 emit_move_insn (st_tmp_1, st_addr_1);
2448 /* Shift the input data into place. */
2449 dreg = copy_addr_to_reg (XEXP (dmem, 0));
2450 if (data_regs != NULL)
2452 for (i = words-1; i >= 0; --i)
2454 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
2455 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2457 for (i = words-1; i > 0; --i)
2459 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2460 ins_tmps[i-1], ins_tmps[i-1], 1,
2465 /* Split and merge the ends with the destination data. */
2466 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2467 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2469 if (data_regs != NULL)
2471 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2472 st_tmp_2, 1, OPTAB_WIDEN);
2473 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2474 st_tmp_1, 1, OPTAB_WIDEN);
2478 emit_move_insn (st_addr_2, st_tmp_2);
2479 for (i = words-1; i > 0; --i)
2481 emit_move_insn (change_address (dmem, DImode,
2482 gen_rtx_AND (DImode,
2483 plus_constant(XEXP (dmem,0),
2486 data_regs ? ins_tmps[i-1] : const0_rtx);
2488 emit_move_insn (st_addr_1, st_tmp_1);
2492 /* Expand string/block move operations.
2494 operands[0] is the pointer to the destination.
2495 operands[1] is the pointer to the source.
2496 operands[2] is the number of bytes to move.
2497 operands[3] is the alignment. */
2500 alpha_expand_block_move (operands)
2503 rtx bytes_rtx = operands[2];
2504 rtx align_rtx = operands[3];
2505 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2506 unsigned HOST_WIDE_INT bytes = orig_bytes;
2507 unsigned HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
2508 unsigned HOST_WIDE_INT dst_align = src_align;
2509 rtx orig_src = operands[1];
2510 rtx orig_dst = operands[0];
2511 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
2513 unsigned int i, words, ofs, nregs = 0;
2515 if (orig_bytes <= 0)
2517 else if (bytes > MAX_MOVE_WORDS * BITS_PER_UNIT)
2520 /* Look for additional alignment information from recorded register info. */
2522 tmp = XEXP (orig_src, 0);
2523 if (GET_CODE (tmp) == REG)
2524 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2525 else if (GET_CODE (tmp) == PLUS
2526 && GET_CODE (XEXP (tmp, 0)) == REG
2527 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2529 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2530 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2534 if (a >= 64 && c % 8 == 0)
2536 else if (a >= 32 && c % 4 == 0)
2538 else if (a >= 16 && c % 2 == 0)
2543 tmp = XEXP (orig_dst, 0);
2544 if (GET_CODE (tmp) == REG)
2545 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2546 else if (GET_CODE (tmp) == PLUS
2547 && GET_CODE (XEXP (tmp, 0)) == REG
2548 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2550 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2551 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2555 if (a >= 64 && c % 8 == 0)
2557 else if (a >= 32 && c % 4 == 0)
2559 else if (a >= 16 && c % 2 == 0)
2564 /* Load the entire block into registers. */
2565 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2567 enum machine_mode mode;
2569 tmp = XEXP (XEXP (orig_src, 0), 0);
2571 /* Don't use the existing register if we're reading more than
2572 is held in the register. Nor if there is not a mode that
2573 handles the exact size. */
2574 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2576 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2580 data_regs[nregs] = gen_lowpart (DImode, tmp);
2581 data_regs[nregs+1] = gen_highpart (DImode, tmp);
2585 data_regs[nregs++] = gen_lowpart (mode, tmp);
2590 /* No appropriate mode; fall back on memory. */
2591 orig_src = change_address (orig_src, GET_MODE (orig_src),
2592 copy_addr_to_reg (XEXP (orig_src, 0)));
2596 if (src_align >= 64 && bytes >= 8)
2600 for (i = 0; i < words; ++i)
2601 data_regs[nregs + i] = gen_reg_rtx(DImode);
2603 for (i = 0; i < words; ++i)
2604 emit_move_insn (data_regs[nregs + i],
2605 change_address (orig_src, DImode,
2606 plus_constant (XEXP (orig_src, 0),
2614 if (src_align >= 32 && bytes >= 4)
2618 for (i = 0; i < words; ++i)
2619 data_regs[nregs + i] = gen_reg_rtx(SImode);
2621 for (i = 0; i < words; ++i)
2622 emit_move_insn (data_regs[nregs + i],
2623 change_address (orig_src, SImode,
2624 plus_constant (XEXP (orig_src, 0),
2636 for (i = 0; i < words+1; ++i)
2637 data_regs[nregs + i] = gen_reg_rtx(DImode);
2639 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2647 if (! TARGET_BWX && bytes >= 8)
2649 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2650 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2655 if (! TARGET_BWX && bytes >= 4)
2657 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2658 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2665 if (src_align >= 16)
2668 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2669 emit_move_insn (tmp,
2670 change_address (orig_src, HImode,
2671 plus_constant (XEXP (orig_src, 0),
2675 } while (bytes >= 2);
2678 else if (! TARGET_BWX)
2680 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2681 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2689 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2690 emit_move_insn (tmp,
2691 change_address (orig_src, QImode,
2692 plus_constant (XEXP (orig_src, 0),
2700 if (nregs > sizeof data_regs / sizeof *data_regs)
2703 /* Now save it back out again. */
2707 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2709 enum machine_mode mode;
2710 tmp = XEXP (XEXP (orig_dst, 0), 0);
2712 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2713 if (GET_MODE (tmp) == mode)
2717 emit_move_insn (tmp, data_regs[0]);
2722 else if (nregs == 2 && mode == TImode)
2724 /* Undo the subregging done above when copying between
2725 two TImode registers. */
2726 if (GET_CODE (data_regs[0]) == SUBREG
2727 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
2728 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
2734 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
2735 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
2739 emit_no_conflict_block (seq, tmp, data_regs[0],
2740 data_regs[1], NULL_RTX);
2748 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2749 /* ??? Optimize mode < dst_mode with strict_low_part. */
2751 /* No appropriate mode; fall back on memory. We can speed things
2752 up by recognizing extra alignment information. */
2753 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2754 copy_addr_to_reg (XEXP (orig_dst, 0)));
2755 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2758 /* Write out the data in whatever chunks reading the source allowed. */
2759 if (dst_align >= 64)
2761 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2763 emit_move_insn (change_address (orig_dst, DImode,
2764 plus_constant (XEXP (orig_dst, 0),
2772 if (dst_align >= 32)
2774 /* If the source has remaining DImode regs, write them out in
2776 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2778 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2779 NULL_RTX, 1, OPTAB_WIDEN);
2781 emit_move_insn (change_address (orig_dst, SImode,
2782 plus_constant (XEXP (orig_dst, 0),
2784 gen_lowpart (SImode, data_regs[i]));
2785 emit_move_insn (change_address (orig_dst, SImode,
2786 plus_constant (XEXP (orig_dst, 0),
2788 gen_lowpart (SImode, tmp));
2793 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2795 emit_move_insn (change_address(orig_dst, SImode,
2796 plus_constant (XEXP (orig_dst, 0),
2804 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2806 /* Write out a remaining block of words using unaligned methods. */
2808 for (words = 1; i + words < nregs; words++)
2809 if (GET_MODE (data_regs[i + words]) != DImode)
2813 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2815 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
2822 /* Due to the above, this won't be aligned. */
2823 /* ??? If we have more than one of these, consider constructing full
2824 words in registers and using alpha_expand_unaligned_store_words. */
2825 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2827 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2832 if (dst_align >= 16)
2833 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2835 emit_move_insn (change_address (orig_dst, HImode,
2836 plus_constant (XEXP (orig_dst, 0),
2843 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2845 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2850 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2852 emit_move_insn (change_address (orig_dst, QImode,
2853 plus_constant (XEXP (orig_dst, 0),
2869 alpha_expand_block_clear (operands)
2872 rtx bytes_rtx = operands[1];
2873 rtx align_rtx = operands[2];
2874 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2875 unsigned HOST_WIDE_INT bytes = orig_bytes;
2876 unsigned HOST_WIDE_INT align = INTVAL (align_rtx);
2877 rtx orig_dst = operands[0];
2879 unsigned HOST_WIDE_INT i, words, ofs = 0;
2881 if (orig_bytes <= 0)
2883 if (bytes > MAX_MOVE_WORDS*8)
2886 /* Look for stricter alignment. */
2887 tmp = XEXP (orig_dst, 0);
2888 if (GET_CODE (tmp) == REG)
2889 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2890 else if (GET_CODE (tmp) == PLUS
2891 && GET_CODE (XEXP (tmp, 0)) == REG
2892 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2894 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2895 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2899 if (a >= 64 && c % 8 == 0)
2901 else if (a >= 32 && c % 4 == 0)
2903 else if (a >= 16 && c % 2 == 0)
2908 else if (GET_CODE (tmp) == ADDRESSOF)
2910 enum machine_mode mode;
2912 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2913 if (GET_MODE (XEXP (tmp, 0)) == mode)
2915 emit_move_insn (XEXP (tmp, 0), const0_rtx);
2919 /* No appropriate mode; fall back on memory. */
2920 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2921 copy_addr_to_reg (tmp));
2922 align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));
2925 /* Handle a block of contiguous words first. */
2927 if (align >= 64 && bytes >= 8)
2931 for (i = 0; i < words; ++i)
2932 emit_move_insn (change_address(orig_dst, DImode,
2933 plus_constant (XEXP (orig_dst, 0),
2941 if (align >= 16 && bytes >= 4)
2945 for (i = 0; i < words; ++i)
2946 emit_move_insn (change_address (orig_dst, SImode,
2947 plus_constant (XEXP (orig_dst, 0),
2959 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2965 /* Next clean up any trailing pieces. We know from the contiguous
2966 block move that there are no aligned SImode or DImode hunks left. */
2968 if (! TARGET_BWX && bytes >= 8)
2970 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2975 if (!TARGET_BWX && bytes >= 4)
2977 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2987 emit_move_insn (change_address (orig_dst, HImode,
2988 plus_constant (XEXP (orig_dst, 0),
2993 } while (bytes >= 2);
2995 else if (! TARGET_BWX)
2997 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
3005 emit_move_insn (change_address (orig_dst, QImode,
3006 plus_constant (XEXP (orig_dst, 0),
3016 /* Adjust the cost of a scheduling dependency. Return the new cost of
3017 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
3020 alpha_adjust_cost (insn, link, dep_insn, cost)
3027 enum attr_type insn_type, dep_insn_type;
3029 /* If the dependence is an anti-dependence, there is no cost. For an
3030 output dependence, there is sometimes a cost, but it doesn't seem
3031 worth handling those few cases. */
3033 if (REG_NOTE_KIND (link) != 0)
3036 /* If we can't recognize the insns, we can't really do anything. */
3037 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3040 insn_type = get_attr_type (insn);
3041 dep_insn_type = get_attr_type (dep_insn);
3043 /* Bring in the user-defined memory latency. */
3044 if (dep_insn_type == TYPE_ILD
3045 || dep_insn_type == TYPE_FLD
3046 || dep_insn_type == TYPE_LDSYM)
3047 cost += alpha_memory_latency-1;
3052 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
3053 being stored, we can sometimes lower the cost. */
3055 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
3056 && (set = single_set (dep_insn)) != 0
3057 && GET_CODE (PATTERN (insn)) == SET
3058 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
3060 switch (dep_insn_type)
3064 /* No savings here. */
3068 /* In these cases, we save one cycle. */
3072 /* In all other cases, we save two cycles. */
3073 return MAX (0, cost - 2);
3077 /* Another case that needs adjustment is an arithmetic or logical
3078 operation. It's cost is usually one cycle, but we default it to
3079 two in the MD file. The only case that it is actually two is
3080 for the address in loads, stores, and jumps. */
3082 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
3097 /* The final case is when a compare feeds into an integer branch;
3098 the cost is only one cycle in that case. */
3100 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
3105 /* And the lord DEC saith: "A special bypass provides an effective
3106 latency of 0 cycles for an ICMP or ILOG insn producing the test
3107 operand of an IBR or ICMOV insn." */
3109 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
3110 && (set = single_set (dep_insn)) != 0)
3112 /* A branch only has one input. This must be it. */
3113 if (insn_type == TYPE_IBR)
3115 /* A conditional move has three, make sure it is the test. */
3116 if (insn_type == TYPE_ICMOV
3117 && GET_CODE (set_src = PATTERN (insn)) == SET
3118 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
3119 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
3123 /* "The multiplier is unable to receive data from IEU bypass paths.
3124 The instruction issues at the expected time, but its latency is
3125 increased by the time it takes for the input data to become
3126 available to the multiplier" -- which happens in pipeline stage
3127 six, when results are comitted to the register file. */
3129 if (insn_type == TYPE_IMUL)
3131 switch (dep_insn_type)
3133 /* These insns produce their results in pipeline stage five. */
3140 /* Other integer insns produce results in pipeline stage four. */
3148 /* There is additional latency to move the result of (most) FP
3149 operations anywhere but the FP register file. */
3151 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
3152 && (dep_insn_type == TYPE_FADD ||
3153 dep_insn_type == TYPE_FMUL ||
3154 dep_insn_type == TYPE_FCMOV))
3160 /* Otherwise, return the default cost. */
3164 /* Functions to save and restore alpha_return_addr_rtx. */
3167 alpha_init_machine_status (p)
3171 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
3175 alpha_mark_machine_status (p)
3178 struct machine_function *machine = p->machine;
3180 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
3181 ggc_mark_rtx (machine->ra_rtx);
3184 /* Start the ball rolling with RETURN_ADDR_RTX. */
3187 alpha_return_addr (count, frame)
3189 rtx frame ATTRIBUTE_UNUSED;
3196 reg = cfun->machine->ra_rtx;
3199 /* No rtx yet. Invent one, and initialize it from $26 in
3201 reg = gen_reg_rtx (Pmode);
3202 cfun->machine->ra_rtx = reg;
3203 init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
3205 /* Emit the insn to the prologue with the other argument copies. */
3206 push_topmost_sequence ();
3207 emit_insn_after (init, get_insns ());
3208 pop_topmost_sequence ();
3215 alpha_ra_ever_killed ()
3219 #ifdef ASM_OUTPUT_MI_THUNK
3220 if (current_function_is_thunk)
3223 if (!cfun->machine->ra_rtx)
3224 return regs_ever_live[REG_RA];
3226 push_topmost_sequence ();
3228 pop_topmost_sequence ();
3230 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
3234 /* Print an operand. Recognize special options, documented below. */
3237 print_operand (file, x, code)
3247 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
3248 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
3249 mode. alpha_fprm controls which suffix is generated. */
3252 case ALPHA_FPRM_NORM:
3254 case ALPHA_FPRM_MINF:
3257 case ALPHA_FPRM_CHOP:
3260 case ALPHA_FPRM_DYN:
3269 /* Generates trap-mode suffix for instructions that accept the su
3270 suffix only (cmpt et al). */
3271 if (alpha_fptm >= ALPHA_FPTM_SU)
3276 /* Generates trap-mode suffix for instructions that accept the
3277 v and sv suffix. The only instruction that needs this is cvtql. */
3286 case ALPHA_FPTM_SUI:
3293 /* Generates trap-mode suffix for instructions that accept the
3294 v, sv, and svi suffix. The only instruction that needs this
3306 case ALPHA_FPTM_SUI:
3307 fputs ("svi", file);
3313 /* Generates trap-mode suffix for instructions that accept the u, su,
3314 and sui suffix. This is the bulk of the IEEE floating point
3315 instructions (addt et al). */
3326 case ALPHA_FPTM_SUI:
3327 fputs ("sui", file);
3333 /* Generates trap-mode suffix for instructions that accept the sui
3334 suffix (cvtqt and cvtqs). */
3339 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
3341 case ALPHA_FPTM_SUI:
3342 fputs ("sui", file);
3348 /* Generates single precision instruction suffix. */
3349 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
3353 /* Generates double precision instruction suffix. */
3354 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
3358 /* If this operand is the constant zero, write it as "$31". */
3359 if (GET_CODE (x) == REG)
3360 fprintf (file, "%s", reg_names[REGNO (x)]);
3361 else if (x == CONST0_RTX (GET_MODE (x)))
3362 fprintf (file, "$31");
3364 output_operand_lossage ("invalid %%r value");
3369 /* Similar, but for floating-point. */
3370 if (GET_CODE (x) == REG)
3371 fprintf (file, "%s", reg_names[REGNO (x)]);
3372 else if (x == CONST0_RTX (GET_MODE (x)))
3373 fprintf (file, "$f31");
3375 output_operand_lossage ("invalid %%R value");
3380 /* Write the 1's complement of a constant. */
3381 if (GET_CODE (x) != CONST_INT)
3382 output_operand_lossage ("invalid %%N value");
3384 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
3388 /* Write 1 << C, for a constant C. */
3389 if (GET_CODE (x) != CONST_INT)
3390 output_operand_lossage ("invalid %%P value");
3392 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
3396 /* Write the high-order 16 bits of a constant, sign-extended. */
3397 if (GET_CODE (x) != CONST_INT)
3398 output_operand_lossage ("invalid %%h value");
3400 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
3404 /* Write the low-order 16 bits of a constant, sign-extended. */
3405 if (GET_CODE (x) != CONST_INT)
3406 output_operand_lossage ("invalid %%L value");
3408 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3409 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
3413 /* Write mask for ZAP insn. */
3414 if (GET_CODE (x) == CONST_DOUBLE)
3416 HOST_WIDE_INT mask = 0;
3417 HOST_WIDE_INT value;
3419 value = CONST_DOUBLE_LOW (x);
3420 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3425 value = CONST_DOUBLE_HIGH (x);
3426 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3429 mask |= (1 << (i + sizeof (int)));
3431 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
3434 else if (GET_CODE (x) == CONST_INT)
3436 HOST_WIDE_INT mask = 0, value = INTVAL (x);
3438 for (i = 0; i < 8; i++, value >>= 8)
3442 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
3445 output_operand_lossage ("invalid %%m value");
3449 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
3450 if (GET_CODE (x) != CONST_INT
3451 || (INTVAL (x) != 8 && INTVAL (x) != 16
3452 && INTVAL (x) != 32 && INTVAL (x) != 64))
3453 output_operand_lossage ("invalid %%M value");
3455 fprintf (file, "%s",
3456 (INTVAL (x) == 8 ? "b"
3457 : INTVAL (x) == 16 ? "w"
3458 : INTVAL (x) == 32 ? "l"
3463 /* Similar, except do it from the mask. */
3464 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3465 fprintf (file, "b");
3466 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3467 fprintf (file, "w");
3468 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3469 fprintf (file, "l");
3470 #if HOST_BITS_PER_WIDE_INT == 32
3471 else if (GET_CODE (x) == CONST_DOUBLE
3472 && CONST_DOUBLE_HIGH (x) == 0
3473 && CONST_DOUBLE_LOW (x) == -1)
3474 fprintf (file, "l");
3475 else if (GET_CODE (x) == CONST_DOUBLE
3476 && CONST_DOUBLE_HIGH (x) == -1
3477 && CONST_DOUBLE_LOW (x) == -1)
3478 fprintf (file, "q");
3480 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3481 fprintf (file, "q");
3482 else if (GET_CODE (x) == CONST_DOUBLE
3483 && CONST_DOUBLE_HIGH (x) == 0
3484 && CONST_DOUBLE_LOW (x) == -1)
3485 fprintf (file, "q");
3488 output_operand_lossage ("invalid %%U value");
3492 /* Write the constant value divided by 8. */
3493 if (GET_CODE (x) != CONST_INT
3494 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3495 && (INTVAL (x) & 7) != 8)
3496 output_operand_lossage ("invalid %%s value");
3498 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3502 /* Same, except compute (64 - c) / 8 */
3504 if (GET_CODE (x) != CONST_INT
3505 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3506 && (INTVAL (x) & 7) != 8)
3507 output_operand_lossage ("invalid %%s value");
3509 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
3512 case 'C': case 'D': case 'c': case 'd':
3513 /* Write out comparison name. */
3515 enum rtx_code c = GET_CODE (x);
3517 if (GET_RTX_CLASS (c) != '<')
3518 output_operand_lossage ("invalid %%C value");
3521 c = reverse_condition (c);
3522 else if (code == 'c')
3523 c = swap_condition (c);
3524 else if (code == 'd')
3525 c = swap_condition (reverse_condition (c));
3528 fprintf (file, "ule");
3530 fprintf (file, "ult");
3531 else if (c == UNORDERED)
3532 fprintf (file, "un");
3534 fprintf (file, "%s", GET_RTX_NAME (c));
3539 /* Write the divide or modulus operator. */
3540 switch (GET_CODE (x))
3543 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
3546 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
3549 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
3552 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
3555 output_operand_lossage ("invalid %%E value");
3561 /* Write "_u" for unaligned access. */
3562 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
3563 fprintf (file, "_u");
3567 if (GET_CODE (x) == REG)
3568 fprintf (file, "%s", reg_names[REGNO (x)]);
3569 else if (GET_CODE (x) == MEM)
3570 output_address (XEXP (x, 0));
3572 output_addr_const (file, x);
3576 output_operand_lossage ("invalid %%xn code");
3581 print_operand_address (file, addr)
3586 HOST_WIDE_INT offset = 0;
3588 if (GET_CODE (addr) == AND)
3589 addr = XEXP (addr, 0);
3591 if (GET_CODE (addr) == PLUS
3592 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3594 offset = INTVAL (XEXP (addr, 1));
3595 addr = XEXP (addr, 0);
3597 if (GET_CODE (addr) == REG)
3598 basereg = REGNO (addr);
3599 else if (GET_CODE (addr) == SUBREG
3600 && GET_CODE (SUBREG_REG (addr)) == REG)
3601 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
3602 else if (GET_CODE (addr) == CONST_INT)
3603 offset = INTVAL (addr);
3607 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
3608 fprintf (file, "($%d)", basereg);
3611 /* Emit RTL insns to initialize the variable parts of a trampoline at
3612 TRAMP. FNADDR is an RTX for the address of the function's pure
3613 code. CXT is an RTX for the static chain value for the function.
3615 The three offset parameters are for the individual template's
3616 layout. A JMPOFS < 0 indicates that the trampoline does not
3617 contain instructions at all.
3619 We assume here that a function will be called many more times than
3620 its address is taken (e.g., it might be passed to qsort), so we
3621 take the trouble to initialize the "hint" field in the JMP insn.
3622 Note that the hint field is PC (new) + 4 * bits 13:0. */
3625 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
3626 rtx tramp, fnaddr, cxt;
3627 int fnofs, cxtofs, jmpofs;
3629 rtx temp, temp1, addr;
3630 /* VMS really uses DImode pointers in memory at this point. */
3631 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
3633 #ifdef POINTERS_EXTEND_UNSIGNED
3634 fnaddr = convert_memory_address (mode, fnaddr);
3635 cxt = convert_memory_address (mode, cxt);
3638 /* Store function address and CXT. */
3639 addr = memory_address (mode, plus_constant (tramp, fnofs));
3640 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
3641 addr = memory_address (mode, plus_constant (tramp, cxtofs));
3642 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
3644 /* This has been disabled since the hint only has a 32k range, and in
3645 no existing OS is the stack within 32k of the text segment. */
3646 if (0 && jmpofs >= 0)
3648 /* Compute hint value. */
3649 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3650 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3652 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3653 build_int_2 (2, 0), NULL_RTX, 1);
3654 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3656 /* Merge in the hint. */
3657 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3658 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
3659 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3660 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3662 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
3665 #ifdef TRANSFER_FROM_TRAMPOLINE
3666 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
3667 0, VOIDmode, 1, addr, Pmode);
3671 emit_insn (gen_imb ());
3674 /* Determine where to put an argument to a function.
3675 Value is zero to push the argument on the stack,
3676 or a hard register in which to store the argument.
3678 MODE is the argument's machine mode.
3679 TYPE is the data type of the argument (as a tree).
3680 This is null for libcalls where that information may
3682 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3683 the preceding args and about the function being called.
3684 NAMED is nonzero if this argument is a named parameter
3685 (otherwise it is an extra parameter matching an ellipsis).
3687 On Alpha the first 6 words of args are normally in registers
3688 and the rest are pushed. */
3691 function_arg (cum, mode, type, named)
3692 CUMULATIVE_ARGS cum;
3693 enum machine_mode mode;
3695 int named ATTRIBUTE_UNUSED;
3702 /* VOID is passed as a special flag for "last argument". */
3703 if (type == void_type_node)
3705 else if (MUST_PASS_IN_STACK (mode, type))
3707 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
3709 else if (TARGET_FPREGS
3710 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3711 || GET_MODE_CLASS (mode) == MODE_FLOAT))
3716 return gen_rtx_REG (mode, cum + basereg);
3720 alpha_build_va_list ()
3722 tree base, ofs, record, type_decl;
3724 if (TARGET_OPEN_VMS)
3725 return ptr_type_node;
3727 record = make_lang_type (RECORD_TYPE);
3728 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
3729 TREE_CHAIN (record) = type_decl;
3730 TYPE_NAME (record) = type_decl;
3732 /* C++? SET_IS_AGGR_TYPE (record, 1); */
3734 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
3736 DECL_FIELD_CONTEXT (ofs) = record;
3738 base = build_decl (FIELD_DECL, get_identifier ("__base"),
3740 DECL_FIELD_CONTEXT (base) = record;
3741 TREE_CHAIN (base) = ofs;
3743 TYPE_FIELDS (record) = base;
3744 layout_type (record);
3750 alpha_va_start (stdarg_p, valist, nextarg)
3753 rtx nextarg ATTRIBUTE_UNUSED;
3755 HOST_WIDE_INT offset;
3756 tree t, offset_field, base_field;
3758 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
3761 if (TARGET_OPEN_VMS)
3762 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
3764 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
3765 up by 48, storing fp arg registers in the first 48 bytes, and the
3766 integer arg registers in the next 48 bytes. This is only done,
3767 however, if any integer registers need to be stored.
3769 If no integer registers need be stored, then we must subtract 48
3770 in order to account for the integer arg registers which are counted
3771 in argsize above, but which are not actually stored on the stack. */
3773 if (NUM_ARGS <= 5 + stdarg_p)
3774 offset = 6 * UNITS_PER_WORD;
3776 offset = -6 * UNITS_PER_WORD;
3778 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3779 offset_field = TREE_CHAIN (base_field);
3781 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3782 valist, base_field);
3783 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3784 valist, offset_field);
3786 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3787 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
3788 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
3789 TREE_SIDE_EFFECTS (t) = 1;
3790 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3792 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
3793 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
3794 TREE_SIDE_EFFECTS (t) = 1;
3795 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3799 alpha_va_arg (valist, type)
3802 HOST_WIDE_INT tsize;
3805 tree offset_field, base_field, addr_tree, addend;
3806 tree wide_type, wide_ofs;
3808 if (TARGET_OPEN_VMS)
3809 return std_expand_builtin_va_arg (valist, type);
3811 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
3813 base_field = TYPE_FIELDS (TREE_TYPE (valist));
3814 offset_field = TREE_CHAIN (base_field);
3816 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3817 valist, base_field);
3818 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3819 valist, offset_field);
3821 wide_type = make_signed_type (64);
3822 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
3825 if (FLOAT_TYPE_P (type))
3827 tree fpaddend, cond;
3829 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
3830 addend, build_int_2 (-6*8, 0)));
3832 cond = fold (build (LT_EXPR, integer_type_node,
3833 wide_ofs, build_int_2 (6*8, 0)));
3835 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
3839 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
3840 base_field, addend);
3842 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3843 addr = copy_to_reg (addr);
3845 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
3846 build (PLUS_EXPR, TREE_TYPE (offset_field),
3847 offset_field, build_int_2 (tsize, 0)));
3848 TREE_SIDE_EFFECTS (t) = 1;
3849 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3854 /* This page contains routines that are used to determine what the function
3855 prologue and epilogue code will do and write them out. */
3857 /* Compute the size of the save area in the stack. */
3859 /* These variables are used for communication between the following functions.
3860 They indicate various things about the current function being compiled
3861 that are used to tell what kind of prologue, epilogue and procedure
3862 descriptior to generate. */
3864 /* Nonzero if we need a stack procedure. */
3865 static int vms_is_stack_procedure;
3867 /* Register number (either FP or SP) that is used to unwind the frame. */
3868 static int vms_unwind_regno;
3870 /* Register number used to save FP. We need not have one for RA since
3871 we don't modify it for register procedures. This is only defined
3872 for register frame procedures. */
3873 static int vms_save_fp_regno;
3875 /* Register number used to reference objects off our PV. */
3876 static int vms_base_regno;
3878 /* Compute register masks for saved registers. */
3881 alpha_sa_mask (imaskP, fmaskP)
3882 unsigned long *imaskP;
3883 unsigned long *fmaskP;
3885 unsigned long imask = 0;
3886 unsigned long fmask = 0;
3889 #ifdef ASM_OUTPUT_MI_THUNK
3890 if (!current_function_is_thunk)
3893 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3894 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3896 /* One for every register we have to save. */
3897 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3898 if (! fixed_regs[i] && ! call_used_regs[i]
3899 && regs_ever_live[i] && i != REG_RA)
3904 fmask |= (1L << (i - 32));
3907 if (imask || fmask || alpha_ra_ever_killed ())
3908 imask |= (1L << REG_RA);
3921 #ifdef ASM_OUTPUT_MI_THUNK
3922 if (current_function_is_thunk)
3927 /* One for every register we have to save. */
3928 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3929 if (! fixed_regs[i] && ! call_used_regs[i]
3930 && regs_ever_live[i] && i != REG_RA)
3934 if (TARGET_OPEN_VMS)
3936 /* Start by assuming we can use a register procedure if we don't
3937 make any calls (REG_RA not used) or need to save any
3938 registers and a stack procedure if we do. */
3939 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3941 /* Decide whether to refer to objects off our PV via FP or PV.
3942 If we need FP for something else or if we receive a nonlocal
3943 goto (which expects PV to contain the value), we must use PV.
3944 Otherwise, start by assuming we can use FP. */
3945 vms_base_regno = (frame_pointer_needed
3946 || current_function_has_nonlocal_label
3947 || vms_is_stack_procedure
3948 || current_function_outgoing_args_size
3949 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3951 /* If we want to copy PV into FP, we need to find some register
3952 in which to save FP. */
3954 vms_save_fp_regno = -1;
3955 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3956 for (i = 0; i < 32; i++)
3957 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3958 vms_save_fp_regno = i;
3960 if (vms_save_fp_regno == -1)
3961 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3963 /* Stack unwinding should be done via FP unless we use it for PV. */
3964 vms_unwind_regno = (vms_base_regno == REG_PV
3965 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3967 /* If this is a stack procedure, allow space for saving FP and RA. */
3968 if (vms_is_stack_procedure)
3973 /* If some registers were saved but not RA, RA must also be saved,
3974 so leave space for it. */
3975 if (sa_size != 0 || alpha_ra_ever_killed ())
3978 /* Our size must be even (multiple of 16 bytes). */
3987 alpha_pv_save_size ()
3990 return vms_is_stack_procedure ? 8 : 0;
3997 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
4001 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
4002 tree decl ATTRIBUTE_UNUSED;
4003 tree attributes ATTRIBUTE_UNUSED;
4007 if (is_attribute_p ("overlaid", identifier))
4008 return (args == NULL_TREE);
4013 alpha_does_function_need_gp ()
4017 /* We never need a GP for Windows/NT or VMS. */
4018 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4021 #ifdef TARGET_PROFILING_NEEDS_GP
4026 #ifdef ASM_OUTPUT_MI_THUNK
4027 if (current_function_is_thunk)
4031 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
4032 Even if we are a static function, we still need to do this in case
4033 our address is taken and passed to something like qsort. */
4035 push_topmost_sequence ();
4036 insn = get_insns ();
4037 pop_topmost_sequence ();
4039 for (; insn; insn = NEXT_INSN (insn))
4040 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
4041 && GET_CODE (PATTERN (insn)) != USE
4042 && GET_CODE (PATTERN (insn)) != CLOBBER)
4044 enum attr_type type = get_attr_type (insn);
4045 if (type == TYPE_LDSYM || type == TYPE_JSR)
4052 /* Write a version stamp. Don't write anything if we are running as a
4053 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
4060 alpha_write_verstamp (file)
4061 FILE *file ATTRIBUTE_UNUSED;
4064 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
4068 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
4072 set_frame_related_p ()
4074 rtx seq = gen_sequence ();
4077 if (GET_CODE (seq) == SEQUENCE)
4079 int i = XVECLEN (seq, 0);
4081 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
4082 return emit_insn (seq);
4086 seq = emit_insn (seq);
4087 RTX_FRAME_RELATED_P (seq) = 1;
4092 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
4094 /* Write function prologue. */
4096 /* On vms we have two kinds of functions:
4098 - stack frame (PROC_STACK)
4099 these are 'normal' functions with local vars and which are
4100 calling other functions
4101 - register frame (PROC_REGISTER)
4102 keeps all data in registers, needs no stack
4104 We must pass this to the assembler so it can generate the
4105 proper pdsc (procedure descriptor)
4106 This is done with the '.pdesc' command.
4108 On not-vms, we don't really differentiate between the two, as we can
4109 simply allocate stack without saving registers. */
4112 alpha_expand_prologue ()
4114 /* Registers to save. */
4115 unsigned long imask = 0;
4116 unsigned long fmask = 0;
4117 /* Stack space needed for pushing registers clobbered by us. */
4118 HOST_WIDE_INT sa_size;
4119 /* Complete stack size needed. */
4120 HOST_WIDE_INT frame_size;
4121 /* Offset from base reg to register save area. */
4122 HOST_WIDE_INT reg_offset;
4126 sa_size = alpha_sa_size ();
4128 frame_size = get_frame_size ();
4129 if (TARGET_OPEN_VMS)
4130 frame_size = ALPHA_ROUND (sa_size
4131 + (vms_is_stack_procedure ? 8 : 0)
4133 + current_function_pretend_args_size);
4135 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4137 + ALPHA_ROUND (frame_size
4138 + current_function_pretend_args_size));
4140 if (TARGET_OPEN_VMS)
4143 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4145 alpha_sa_mask (&imask, &fmask);
4147 /* Adjust the stack by the frame size. If the frame size is > 4096
4148 bytes, we need to be sure we probe somewhere in the first and last
4149 4096 bytes (we can probably get away without the latter test) and
4150 every 8192 bytes in between. If the frame size is > 32768, we
4151 do this in a loop. Otherwise, we generate the explicit probe
4154 Note that we are only allowed to adjust sp once in the prologue. */
4156 if (frame_size <= 32768)
4158 if (frame_size > 4096)
4163 emit_insn (gen_probe_stack (GEN_INT (-probed)));
4164 while ((probed += 8192) < frame_size);
4166 /* We only have to do this probe if we aren't saving registers. */
4167 if (sa_size == 0 && probed + 4096 < frame_size)
4168 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
4171 if (frame_size != 0)
4173 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
4174 GEN_INT (-frame_size))));
4179 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
4180 number of 8192 byte blocks to probe. We then probe each block
4181 in the loop and then set SP to the proper location. If the
4182 amount remaining is > 4096, we have to do one more probe if we
4183 are not saving any registers. */
4185 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
4186 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
4187 rtx ptr = gen_rtx_REG (DImode, 22);
4188 rtx count = gen_rtx_REG (DImode, 23);
4191 emit_move_insn (count, GEN_INT (blocks));
4192 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
4194 /* Because of the difficulty in emitting a new basic block this
4195 late in the compilation, generate the loop as a single insn. */
4196 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
4198 if (leftover > 4096 && sa_size == 0)
4200 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
4201 MEM_VOLATILE_P (last) = 1;
4202 emit_move_insn (last, const0_rtx);
4205 if (TARGET_WINDOWS_NT)
4207 /* For NT stack unwind (done by 'reverse execution'), it's
4208 not OK to take the result of a loop, even though the value
4209 is already in ptr, so we reload it via a single operation
4210 and subtract it to sp.
4212 Yes, that's correct -- we have to reload the whole constant
4213 into a temporary via ldah+lda then subtract from sp. To
4214 ensure we get ldah+lda, we use a special pattern. */
4216 HOST_WIDE_INT lo, hi;
4217 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4218 hi = frame_size - lo;
4220 emit_move_insn (ptr, GEN_INT (hi));
4221 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
4222 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
4227 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
4228 GEN_INT (-leftover)));
4231 /* This alternative is special, because the DWARF code cannot
4232 possibly intuit through the loop above. So we invent this
4233 note it looks at instead. */
4234 RTX_FRAME_RELATED_P (seq) = 1;
4236 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4237 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4238 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4239 GEN_INT (-frame_size))),
4243 /* Cope with very large offsets to the register save area. */
4244 sa_reg = stack_pointer_rtx;
4245 if (reg_offset + sa_size > 0x8000)
4247 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4250 if (low + sa_size <= 0x8000)
4251 bias = reg_offset - low, reg_offset = low;
4253 bias = reg_offset, reg_offset = 0;
4255 sa_reg = gen_rtx_REG (DImode, 24);
4256 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
4259 /* Save regs in stack order. Beginning with VMS PV. */
4260 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4262 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
4263 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4264 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
4267 /* Save register RA next. */
4268 if (imask & (1L << REG_RA))
4270 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4271 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4272 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
4273 imask &= ~(1L << REG_RA);
4277 /* Now save any other registers required to be saved. */
4278 for (i = 0; i < 32; i++)
4279 if (imask & (1L << i))
4281 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4282 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4283 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
4287 for (i = 0; i < 32; i++)
4288 if (fmask & (1L << i))
4290 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
4291 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4292 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
4296 if (TARGET_OPEN_VMS)
4298 if (!vms_is_stack_procedure)
4300 /* Register frame procedures fave the fp. */
4301 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
4302 hard_frame_pointer_rtx));
4305 if (vms_base_regno != REG_PV)
4306 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
4307 gen_rtx_REG (DImode, REG_PV)));
4309 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4311 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4314 /* If we have to allocate space for outgoing args, do it now. */
4315 if (current_function_outgoing_args_size != 0)
4317 FRP (emit_move_insn (stack_pointer_rtx,
4318 plus_constant (hard_frame_pointer_rtx,
4319 - ALPHA_ROUND (current_function_outgoing_args_size))));
4324 /* If we need a frame pointer, set it from the stack pointer. */
4325 if (frame_pointer_needed)
4327 if (TARGET_CAN_FAULT_IN_PROLOGUE)
4328 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4331 /* This must always be the last instruction in the
4332 prologue, thus we emit a special move + clobber. */
4333 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
4334 stack_pointer_rtx, sa_reg)));
4339 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
4340 the prologue, for exception handling reasons, we cannot do this for
4341 any insn that might fault. We could prevent this for mems with a
4342 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
4343 have to prevent all such scheduling with a blockage.
4345 Linux, on the other hand, never bothered to implement OSF/1's
4346 exception handling, and so doesn't care about such things. Anyone
4347 planning to use dwarf2 frame-unwind info can also omit the blockage. */
4349 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
4350 emit_insn (gen_blockage ());
4353 /* Output the textual info surrounding the prologue. */
4356 alpha_start_function (file, fnname, decl)
4359 tree decl ATTRIBUTE_UNUSED;
4361 unsigned long imask = 0;
4362 unsigned long fmask = 0;
4363 /* Stack space needed for pushing registers clobbered by us. */
4364 HOST_WIDE_INT sa_size;
4365 /* Complete stack size needed. */
4366 HOST_WIDE_INT frame_size;
4367 /* Offset from base reg to register save area. */
4368 HOST_WIDE_INT reg_offset;
4369 char *entry_label = (char *) alloca (strlen (fnname) + 6);
4372 sa_size = alpha_sa_size ();
4374 frame_size = get_frame_size ();
4375 if (TARGET_OPEN_VMS)
4376 frame_size = ALPHA_ROUND (sa_size
4377 + (vms_is_stack_procedure ? 8 : 0)
4379 + current_function_pretend_args_size);
4381 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4383 + ALPHA_ROUND (frame_size
4384 + current_function_pretend_args_size));
4386 if (TARGET_OPEN_VMS)
4389 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4391 alpha_sa_mask (&imask, &fmask);
4393 /* Ecoff can handle multiple .file directives, so put out file and lineno.
4394 We have to do that before the .ent directive as we cannot switch
4395 files within procedures with native ecoff because line numbers are
4396 linked to procedure descriptors.
4397 Outputting the lineno helps debugging of one line functions as they
4398 would otherwise get no line number at all. Please note that we would
4399 like to put out last_linenum from final.c, but it is not accessible. */
4401 if (write_symbols == SDB_DEBUG)
4403 ASM_OUTPUT_SOURCE_FILENAME (file,
4404 DECL_SOURCE_FILE (current_function_decl));
4405 if (debug_info_level != DINFO_LEVEL_TERSE)
4406 ASM_OUTPUT_SOURCE_LINE (file,
4407 DECL_SOURCE_LINE (current_function_decl));
4410 /* Issue function start and label. */
4411 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
4413 fputs ("\t.ent ", file);
4414 assemble_name (file, fnname);
4418 strcpy (entry_label, fnname);
4419 if (TARGET_OPEN_VMS)
4420 strcat (entry_label, "..en");
4421 ASM_OUTPUT_LABEL (file, entry_label);
4422 inside_function = TRUE;
4424 if (TARGET_OPEN_VMS)
4425 fprintf (file, "\t.base $%d\n", vms_base_regno);
4427 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
4428 && !flag_inhibit_size_directive)
4430 /* Set flags in procedure descriptor to request IEEE-conformant
4431 math-library routines. The value we set it to is PDSC_EXC_IEEE
4432 (/usr/include/pdsc.h). */
4433 fputs ("\t.eflag 48\n", file);
4436 /* Set up offsets to alpha virtual arg/local debugging pointer. */
4437 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
4438 alpha_arg_offset = -frame_size + 48;
4440 /* Describe our frame. If the frame size is larger than an integer,
4441 print it as zero to avoid an assembler error. We won't be
4442 properly describing such a frame, but that's the best we can do. */
4443 if (TARGET_OPEN_VMS)
4445 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
4446 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4447 frame_size >= (1l << 31) ? 0 : frame_size);
4448 fputs (",$26,", file);
4449 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
4452 else if (!flag_inhibit_size_directive)
4454 fprintf (file, "\t.frame $%d,",
4455 (frame_pointer_needed
4456 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
4457 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4458 frame_size >= (1l << 31) ? 0 : frame_size);
4459 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
4462 /* Describe which registers were spilled. */
4463 if (TARGET_OPEN_VMS)
4466 /* ??? Does VMS care if mask contains ra? The old code did'nt
4467 set it, so I don't here. */
4468 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
4470 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
4471 if (!vms_is_stack_procedure)
4472 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
4474 else if (!flag_inhibit_size_directive)
4478 fprintf (file, "\t.mask 0x%lx,", imask);
4479 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4480 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4483 for (i = 0; i < 32; ++i)
4484 if (imask & (1L << i))
4490 fprintf (file, "\t.fmask 0x%lx,", fmask);
4491 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4492 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4497 /* Emit GP related things. It is rather unfortunate about the alignment
4498 issues surrounding a CODE_LABEL that forces us to do the label in
4500 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
4502 alpha_function_needs_gp = alpha_does_function_need_gp ();
4503 if (alpha_function_needs_gp)
4504 fputs ("\tldgp $29,0($27)\n", file);
4507 assemble_name (file, fnname);
4508 fputs ("..ng:\n", file);
4512 /* Ifdef'ed cause readonly_section and link_section are only
4514 readonly_section ();
4515 fprintf (file, "\t.align 3\n");
4516 assemble_name (file, fnname); fputs ("..na:\n", file);
4517 fputs ("\t.ascii \"", file);
4518 assemble_name (file, fnname);
4519 fputs ("\\0\"\n", file);
4522 fprintf (file, "\t.align 3\n");
4523 fputs ("\t.name ", file);
4524 assemble_name (file, fnname);
4525 fputs ("..na\n", file);
4526 ASM_OUTPUT_LABEL (file, fnname);
4527 fprintf (file, "\t.pdesc ");
4528 assemble_name (file, fnname);
4529 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
4530 alpha_need_linkage (fnname, 1);
4535 /* Emit the .prologue note at the scheduled end of the prologue. */
4538 output_end_prologue (file)
4541 if (TARGET_OPEN_VMS)
4542 fputs ("\t.prologue\n", file);
4543 else if (TARGET_WINDOWS_NT)
4544 fputs ("\t.prologue 0\n", file);
4545 else if (!flag_inhibit_size_directive)
4546 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
4549 /* Write function epilogue. */
4551 /* ??? At some point we will want to support full unwind, and so will
4552 need to mark the epilogue as well. At the moment, we just confuse
4555 #define FRP(exp) exp
4558 alpha_expand_epilogue ()
4560 /* Registers to save. */
4561 unsigned long imask = 0;
4562 unsigned long fmask = 0;
4563 /* Stack space needed for pushing registers clobbered by us. */
4564 HOST_WIDE_INT sa_size;
4565 /* Complete stack size needed. */
4566 HOST_WIDE_INT frame_size;
4567 /* Offset from base reg to register save area. */
4568 HOST_WIDE_INT reg_offset;
4569 int fp_is_frame_pointer, fp_offset;
4570 rtx sa_reg, sa_reg_exp = NULL;
4571 rtx sp_adj1, sp_adj2, mem;
4575 sa_size = alpha_sa_size ();
4577 frame_size = get_frame_size ();
4578 if (TARGET_OPEN_VMS)
4579 frame_size = ALPHA_ROUND (sa_size
4580 + (vms_is_stack_procedure ? 8 : 0)
4582 + current_function_pretend_args_size);
4584 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4586 + ALPHA_ROUND (frame_size
4587 + current_function_pretend_args_size));
4589 if (TARGET_OPEN_VMS)
4592 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4594 alpha_sa_mask (&imask, &fmask);
4596 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
4597 || (!TARGET_OPEN_VMS && frame_pointer_needed));
4599 sa_reg = stack_pointer_rtx;
4601 eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
4604 /* If we have a frame pointer, restore SP from it. */
4605 if ((TARGET_OPEN_VMS
4606 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4607 || (!TARGET_OPEN_VMS && frame_pointer_needed))
4609 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
4612 /* Cope with very large offsets to the register save area. */
4613 if (reg_offset + sa_size > 0x8000)
4615 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4618 if (low + sa_size <= 0x8000)
4619 bias = reg_offset - low, reg_offset = low;
4621 bias = reg_offset, reg_offset = 0;
4623 sa_reg = gen_rtx_REG (DImode, 22);
4624 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
4626 FRP (emit_move_insn (sa_reg, sa_reg_exp));
4629 /* Restore registers in order, excepting a true frame pointer. */
4633 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4634 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4635 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
4638 imask &= ~(1L << REG_RA);
4640 for (i = 0; i < 32; ++i)
4641 if (imask & (1L << i))
4643 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
4644 fp_offset = reg_offset;
4647 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4648 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4649 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
4654 for (i = 0; i < 32; ++i)
4655 if (fmask & (1L << i))
4657 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
4658 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4659 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
4664 if (frame_size || eh_ofs)
4666 sp_adj1 = stack_pointer_rtx;
4670 sp_adj1 = gen_rtx_REG (DImode, 23);
4671 emit_move_insn (sp_adj1,
4672 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
4675 /* If the stack size is large, begin computation into a temporary
4676 register so as not to interfere with a potential fp restore,
4677 which must be consecutive with an SP restore. */
4678 if (frame_size < 32768)
4679 sp_adj2 = GEN_INT (frame_size);
4680 else if (frame_size < 0x40007fffL)
4682 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4684 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
4685 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
4689 sp_adj1 = gen_rtx_REG (DImode, 23);
4690 FRP (emit_move_insn (sp_adj1, sp_adj2));
4692 sp_adj2 = GEN_INT (low);
4696 rtx tmp = gen_rtx_REG (DImode, 23);
4697 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
4700 /* We can't drop new things to memory this late, afaik,
4701 so build it up by pieces. */
4702 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
4703 -(frame_size < 0)));
4709 /* From now on, things must be in order. So emit blockages. */
4711 /* Restore the frame pointer. */
4712 if (fp_is_frame_pointer)
4714 emit_insn (gen_blockage ());
4715 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
4716 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4717 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
4719 else if (TARGET_OPEN_VMS)
4721 emit_insn (gen_blockage ());
4722 FRP (emit_move_insn (hard_frame_pointer_rtx,
4723 gen_rtx_REG (DImode, vms_save_fp_regno)));
4726 /* Restore the stack pointer. */
4727 emit_insn (gen_blockage ());
4728 FRP (emit_move_insn (stack_pointer_rtx,
4729 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
4733 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4735 emit_insn (gen_blockage ());
4736 FRP (emit_move_insn (hard_frame_pointer_rtx,
4737 gen_rtx_REG (DImode, vms_save_fp_regno)));
4742 /* Output the rest of the textual info surrounding the epilogue. */
4745 alpha_end_function (file, fnname, decl)
4748 tree decl ATTRIBUTE_UNUSED;
4750 /* End the function. */
4751 if (!flag_inhibit_size_directive)
4753 fputs ("\t.end ", file);
4754 assemble_name (file, fnname);
4757 inside_function = FALSE;
4759 /* Show that we know this function if it is called again.
4761 Don't do this for global functions in object files destined for a
4762 shared library because the function may be overridden by the application
4763 or other libraries. Similarly, don't do this for weak functions. */
4765 if (!DECL_WEAK (current_function_decl)
4766 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4767 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4770 /* Debugging support. */
4774 /* Count the number of sdb related labels are generated (to find block
4775 start and end boundaries). */
4777 int sdb_label_count = 0;
4779 /* Next label # for each statement. */
4781 static int sym_lineno = 0;
4783 /* Count the number of .file directives, so that .loc is up to date. */
4785 static int num_source_filenames = 0;
4787 /* Name of the file containing the current function. */
4789 static const char *current_function_file = "";
4791 /* Offsets to alpha virtual arg/local debugging pointers. */
4793 long alpha_arg_offset;
4794 long alpha_auto_offset;
4796 /* Emit a new filename to a stream. */
4799 alpha_output_filename (stream, name)
4803 static int first_time = TRUE;
4804 char ltext_label_name[100];
4809 ++num_source_filenames;
4810 current_function_file = name;
4811 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4812 output_quoted_string (stream, name);
4813 fprintf (stream, "\n");
4814 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4815 fprintf (stream, "\t#@stabs\n");
4818 else if (write_symbols == DBX_DEBUG)
4820 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4821 fprintf (stream, "%s ", ASM_STABS_OP);
4822 output_quoted_string (stream, name);
4823 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
4826 else if (name != current_function_file
4827 && strcmp (name, current_function_file) != 0)
4829 if (inside_function && ! TARGET_GAS)
4830 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4833 ++num_source_filenames;
4834 current_function_file = name;
4835 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4838 output_quoted_string (stream, name);
4839 fprintf (stream, "\n");
4843 /* Emit a linenumber to a stream. */
4846 alpha_output_lineno (stream, line)
4850 if (write_symbols == DBX_DEBUG)
4852 /* mips-tfile doesn't understand .stabd directives. */
4854 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4855 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4858 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4861 /* Structure to show the current status of registers and memory. */
4863 struct shadow_summary
4866 unsigned long i : 31; /* Mask of int regs */
4867 unsigned long fp : 31; /* Mask of fp regs */
4868 unsigned long mem : 1; /* mem == imem | fpmem */
4872 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
4873 static void alpha_handle_trap_shadows PARAMS ((rtx));
4875 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4876 to the summary structure. SET is nonzero if the insn is setting the
4877 object, otherwise zero. */
4880 summarize_insn (x, sum, set)
4882 struct shadow_summary *sum;
4885 const char *format_ptr;
4891 switch (GET_CODE (x))
4893 /* ??? Note that this case would be incorrect if the Alpha had a
4894 ZERO_EXTRACT in SET_DEST. */
4896 summarize_insn (SET_SRC (x), sum, 0);
4897 summarize_insn (SET_DEST (x), sum, 1);
4901 summarize_insn (XEXP (x, 0), sum, 1);
4905 summarize_insn (XEXP (x, 0), sum, 0);
4909 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4910 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4914 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4915 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4919 summarize_insn (SUBREG_REG (x), sum, 0);
4924 int regno = REGNO (x);
4925 unsigned long mask = 1UL << (regno % 32);
4927 if (regno == 31 || regno == 63)
4933 sum->defd.i |= mask;
4935 sum->defd.fp |= mask;
4940 sum->used.i |= mask;
4942 sum->used.fp |= mask;
4953 /* Find the regs used in memory address computation: */
4954 summarize_insn (XEXP (x, 0), sum, 0);
4957 case CONST_INT: case CONST_DOUBLE:
4958 case SYMBOL_REF: case LABEL_REF: case CONST:
4961 /* Handle common unary and binary ops for efficiency. */
4962 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4963 case MOD: case UDIV: case UMOD: case AND: case IOR:
4964 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4965 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4966 case NE: case EQ: case GE: case GT: case LE:
4967 case LT: case GEU: case GTU: case LEU: case LTU:
4968 summarize_insn (XEXP (x, 0), sum, 0);
4969 summarize_insn (XEXP (x, 1), sum, 0);
4972 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4973 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4974 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4975 case SQRT: case FFS:
4976 summarize_insn (XEXP (x, 0), sum, 0);
4980 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4981 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4982 switch (format_ptr[i])
4985 summarize_insn (XEXP (x, i), sum, 0);
4989 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4990 summarize_insn (XVECEXP (x, i, j), sum, 0);
5002 /* Ensure a sufficient number of `trapb' insns are in the code when
5003 the user requests code with a trap precision of functions or
5006 In naive mode, when the user requests a trap-precision of
5007 "instruction", a trapb is needed after every instruction that may
5008 generate a trap. This ensures that the code is resumption safe but
5011 When optimizations are turned on, we delay issuing a trapb as long
5012 as possible. In this context, a trap shadow is the sequence of
5013 instructions that starts with a (potentially) trap generating
5014 instruction and extends to the next trapb or call_pal instruction
5015 (but GCC never generates call_pal by itself). We can delay (and
5016 therefore sometimes omit) a trapb subject to the following
5019 (a) On entry to the trap shadow, if any Alpha register or memory
5020 location contains a value that is used as an operand value by some
5021 instruction in the trap shadow (live on entry), then no instruction
5022 in the trap shadow may modify the register or memory location.
5024 (b) Within the trap shadow, the computation of the base register
5025 for a memory load or store instruction may not involve using the
5026 result of an instruction that might generate an UNPREDICTABLE
5029 (c) Within the trap shadow, no register may be used more than once
5030 as a destination register. (This is to make life easier for the
5033 (d) The trap shadow may not include any branch instructions. */
5036 alpha_handle_trap_shadows (insns)
5039 struct shadow_summary shadow;
5040 int trap_pending, exception_nesting;
5044 exception_nesting = 0;
5047 shadow.used.mem = 0;
5048 shadow.defd = shadow.used;
5050 for (i = insns; i ; i = NEXT_INSN (i))
5052 if (GET_CODE (i) == NOTE)
5054 switch (NOTE_LINE_NUMBER (i))
5056 case NOTE_INSN_EH_REGION_BEG:
5057 exception_nesting++;
5062 case NOTE_INSN_EH_REGION_END:
5063 exception_nesting--;
5068 case NOTE_INSN_EPILOGUE_BEG:
5069 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
5074 else if (trap_pending)
5076 if (alpha_tp == ALPHA_TP_FUNC)
5078 if (GET_CODE (i) == JUMP_INSN
5079 && GET_CODE (PATTERN (i)) == RETURN)
5082 else if (alpha_tp == ALPHA_TP_INSN)
5086 struct shadow_summary sum;
5091 sum.defd = sum.used;
5093 switch (GET_CODE (i))
5096 /* Annoyingly, get_attr_trap will abort on these. */
5097 if (GET_CODE (PATTERN (i)) == USE
5098 || GET_CODE (PATTERN (i)) == CLOBBER)
5101 summarize_insn (PATTERN (i), &sum, 0);
5103 if ((sum.defd.i & shadow.defd.i)
5104 || (sum.defd.fp & shadow.defd.fp))
5106 /* (c) would be violated */
5110 /* Combine shadow with summary of current insn: */
5111 shadow.used.i |= sum.used.i;
5112 shadow.used.fp |= sum.used.fp;
5113 shadow.used.mem |= sum.used.mem;
5114 shadow.defd.i |= sum.defd.i;
5115 shadow.defd.fp |= sum.defd.fp;
5116 shadow.defd.mem |= sum.defd.mem;
5118 if ((sum.defd.i & shadow.used.i)
5119 || (sum.defd.fp & shadow.used.fp)
5120 || (sum.defd.mem & shadow.used.mem))
5122 /* (a) would be violated (also takes care of (b)) */
5123 if (get_attr_trap (i) == TRAP_YES
5124 && ((sum.defd.i & sum.used.i)
5125 || (sum.defd.fp & sum.used.fp)))
5144 n = emit_insn_before (gen_trapb (), i);
5145 PUT_MODE (n, TImode);
5146 PUT_MODE (i, TImode);
5150 shadow.used.mem = 0;
5151 shadow.defd = shadow.used;
5156 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
5157 && GET_CODE (i) == INSN
5158 && GET_CODE (PATTERN (i)) != USE
5159 && GET_CODE (PATTERN (i)) != CLOBBER
5160 && get_attr_trap (i) == TRAP_YES)
5162 if (optimize && !trap_pending)
5163 summarize_insn (PATTERN (i), &shadow, 0);
5170 /* Alpha can only issue instruction groups simultaneously if they are
5171 suitibly aligned. This is very processor-specific. */
5173 enum alphaev4_pipe {
5180 enum alphaev5_pipe {
5191 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
5192 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
5193 static rtx alphaev4_next_group PARAMS ((rtx, int*, int*));
5194 static rtx alphaev5_next_group PARAMS ((rtx, int*, int*));
5195 static rtx alphaev4_next_nop PARAMS ((int*));
5196 static rtx alphaev5_next_nop PARAMS ((int*));
5198 static void alpha_align_insns
5199 PARAMS ((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
5201 static enum alphaev4_pipe
5202 alphaev4_insn_pipe (insn)
5205 if (recog_memoized (insn) < 0)
5207 if (get_attr_length (insn) != 4)
5210 switch (get_attr_type (insn))
5243 static enum alphaev5_pipe
5244 alphaev5_insn_pipe (insn)
5247 if (recog_memoized (insn) < 0)
5249 if (get_attr_length (insn) != 4)
5252 switch (get_attr_type (insn))
5292 /* IN_USE is a mask of the slots currently filled within the insn group.
5293 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
5294 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
5296 LEN is, of course, the length of the group in bytes. */
5299 alphaev4_next_group (insn, pin_use, plen)
5301 int *pin_use, *plen;
5307 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
5308 || GET_CODE (PATTERN (insn)) == CLOBBER
5309 || GET_CODE (PATTERN (insn)) == USE)
5314 enum alphaev4_pipe pipe;
5316 pipe = alphaev4_insn_pipe (insn);
5320 /* Force complex instructions to start new groups. */
5324 /* If this is a completely unrecognized insn, its an asm.
5325 We don't know how long it is, so record length as -1 to
5326 signal a needed realignment. */
5327 if (recog_memoized (insn) < 0)
5330 len = get_attr_length (insn);
5334 if (in_use & EV4_IB0)
5336 if (in_use & EV4_IB1)
5341 in_use |= EV4_IB0 | EV4_IBX;
5345 if (in_use & EV4_IB0)
5347 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
5355 if (in_use & EV4_IB1)
5365 /* Haifa doesn't do well scheduling branches. */
5366 if (GET_CODE (insn) == JUMP_INSN)
5370 insn = next_nonnote_insn (insn);
5372 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
5375 /* Let Haifa tell us where it thinks insn group boundaries are. */
5376 if (GET_MODE (insn) == TImode)
5379 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5384 insn = next_nonnote_insn (insn);
5392 /* IN_USE is a mask of the slots currently filled within the insn group.
5393 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
5394 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
5396 LEN is, of course, the length of the group in bytes. */
5399 alphaev5_next_group (insn, pin_use, plen)
5401 int *pin_use, *plen;
5407 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
5408 || GET_CODE (PATTERN (insn)) == CLOBBER
5409 || GET_CODE (PATTERN (insn)) == USE)
5414 enum alphaev5_pipe pipe;
5416 pipe = alphaev5_insn_pipe (insn);
5420 /* Force complex instructions to start new groups. */
5424 /* If this is a completely unrecognized insn, its an asm.
5425 We don't know how long it is, so record length as -1 to
5426 signal a needed realignment. */
5427 if (recog_memoized (insn) < 0)
5430 len = get_attr_length (insn);
5433 /* ??? Most of the places below, we would like to abort, as
5434 it would indicate an error either in Haifa, or in the
5435 scheduling description. Unfortunately, Haifa never
5436 schedules the last instruction of the BB, so we don't
5437 have an accurate TI bit to go off. */
5439 if (in_use & EV5_E0)
5441 if (in_use & EV5_E1)
5446 in_use |= EV5_E0 | EV5_E01;
5450 if (in_use & EV5_E0)
5452 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
5460 if (in_use & EV5_E1)
5466 if (in_use & EV5_FA)
5468 if (in_use & EV5_FM)
5473 in_use |= EV5_FA | EV5_FAM;
5477 if (in_use & EV5_FA)
5483 if (in_use & EV5_FM)
5496 /* Haifa doesn't do well scheduling branches. */
5497 /* ??? If this is predicted not-taken, slotting continues, except
5498 that no more IBR, FBR, or JSR insns may be slotted. */
5499 if (GET_CODE (insn) == JUMP_INSN)
5503 insn = next_nonnote_insn (insn);
5505 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
5508 /* Let Haifa tell us where it thinks insn group boundaries are. */
5509 if (GET_MODE (insn) == TImode)
5512 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5517 insn = next_nonnote_insn (insn);
5526 alphaev4_next_nop (pin_use)
5529 int in_use = *pin_use;
5532 if (!(in_use & EV4_IB0))
5537 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
5542 else if (TARGET_FP && !(in_use & EV4_IB1))
5555 alphaev5_next_nop (pin_use)
5558 int in_use = *pin_use;
5561 if (!(in_use & EV5_E1))
5566 else if (TARGET_FP && !(in_use & EV5_FA))
5571 else if (TARGET_FP && !(in_use & EV5_FM))
5583 /* The instruction group alignment main loop. */
5586 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
5589 rtx (*next_group) PARAMS ((rtx, int*, int*));
5590 rtx (*next_nop) PARAMS ((int*));
5593 /* ALIGN is the known alignment for the insn group. */
5595 /* OFS is the offset of the current insn in the insn group. */
5597 int prev_in_use, in_use, len;
5600 /* Let shorten branches care for assigning alignments to code labels. */
5601 shorten_branches (insns);
5603 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
5604 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
5606 /* Account for the initial GP load, which happens before the scheduled
5607 prologue we emitted as RTL. */
5608 ofs = prev_in_use = 0;
5609 if (alpha_does_function_need_gp())
5611 ofs = 8 & (align - 1);
5612 prev_in_use = gp_in_use;
5616 if (GET_CODE (i) == NOTE)
5617 i = next_nonnote_insn (i);
5621 next = (*next_group)(i, &in_use, &len);
5623 /* When we see a label, resync alignment etc. */
5624 if (GET_CODE (i) == CODE_LABEL)
5626 int new_align = 1 << label_to_alignment (i);
5627 if (new_align >= align)
5629 align = new_align < max_align ? new_align : max_align;
5632 else if (ofs & (new_align-1))
5633 ofs = (ofs | (new_align-1)) + 1;
5638 /* Handle complex instructions special. */
5639 else if (in_use == 0)
5641 /* Asms will have length < 0. This is a signal that we have
5642 lost alignment knowledge. Assume, however, that the asm
5643 will not mis-align instructions. */
5652 /* If the known alignment is smaller than the recognized insn group,
5653 realign the output. */
5654 else if (align < len)
5656 int new_log_align = len > 8 ? 4 : 3;
5659 where = prev_nonnote_insn (i);
5660 if (!where || GET_CODE (where) != CODE_LABEL)
5663 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
5664 align = 1 << new_log_align;
5668 /* If the group won't fit in the same INT16 as the previous,
5669 we need to add padding to keep the group together. Rather
5670 than simply leaving the insn filling to the assembler, we
5671 can make use of the knowledge of what sorts of instructions
5672 were issued in the previous group to make sure that all of
5673 the added nops are really free. */
5674 else if (ofs + len > align)
5676 int nop_count = (align - ofs) / 4;
5679 /* Insert nops before labels and branches to truely merge the
5680 execution of the nops with the previous instruction group. */
5681 where = prev_nonnote_insn (i);
5684 if (GET_CODE (where) == CODE_LABEL)
5686 rtx where2 = prev_nonnote_insn (where);
5687 if (where2 && GET_CODE (where2) == JUMP_INSN)
5690 else if (GET_CODE (where) != JUMP_INSN)
5697 emit_insn_before ((*next_nop)(&prev_in_use), where);
5698 while (--nop_count);
5702 ofs = (ofs + len) & (align - 1);
5703 prev_in_use = in_use;
5709 /* Machine dependant reorg pass. */
5715 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
5716 alpha_handle_trap_shadows (insns);
5719 /* Due to the number of extra trapb insns, don't bother fixing up
5720 alignment when trap precision is instruction. Moreover, we can
5721 only do our job when sched2 is run and Haifa is our scheduler. */
5722 if (optimize && !optimize_size
5723 && alpha_tp != ALPHA_TP_INSN
5724 && flag_schedule_insns_after_reload)
5726 if (alpha_cpu == PROCESSOR_EV4)
5727 alpha_align_insns (insns, 8, alphaev4_next_group,
5728 alphaev4_next_nop, EV4_IB0);
5729 else if (alpha_cpu == PROCESSOR_EV5)
5730 alpha_align_insns (insns, 16, alphaev5_next_group,
5731 alphaev5_next_nop, EV5_E01 | EV5_E0);
5737 /* Check a floating-point value for validity for a particular machine mode. */
5739 static const char * const float_strings[] =
5741 /* These are for FLOAT_VAX. */
5742 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5743 "-1.70141173319264430e+38",
5744 "2.93873587705571877e-39", /* 2^-128 */
5745 "-2.93873587705571877e-39",
5746 /* These are for the default broken IEEE mode, which traps
5747 on infinity or denormal numbers. */
5748 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5749 "-3.402823466385288598117e+38",
5750 "1.1754943508222875079687e-38", /* 2^-126 */
5751 "-1.1754943508222875079687e-38",
5754 static REAL_VALUE_TYPE float_values[8];
5755 static int inited_float_values = 0;
5758 check_float_value (mode, d, overflow)
5759 enum machine_mode mode;
5761 int overflow ATTRIBUTE_UNUSED;
5764 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5767 if (inited_float_values == 0)
5770 for (i = 0; i < 8; i++)
5771 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5773 inited_float_values = 1;
5779 REAL_VALUE_TYPE *fvptr;
5781 if (TARGET_FLOAT_VAX)
5782 fvptr = &float_values[0];
5784 fvptr = &float_values[4];
5786 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5787 if (REAL_VALUES_LESS (fvptr[0], r))
5789 bcopy ((char *) &fvptr[0], (char *) d,
5790 sizeof (REAL_VALUE_TYPE));
5793 else if (REAL_VALUES_LESS (r, fvptr[1]))
5795 bcopy ((char *) &fvptr[1], (char *) d,
5796 sizeof (REAL_VALUE_TYPE));
5799 else if (REAL_VALUES_LESS (dconst0, r)
5800 && REAL_VALUES_LESS (r, fvptr[2]))
5802 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5805 else if (REAL_VALUES_LESS (r, dconst0)
5806 && REAL_VALUES_LESS (fvptr[3], r))
5808 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5818 /* Return the VMS argument type corresponding to MODE. */
5821 alpha_arg_type (mode)
5822 enum machine_mode mode;
5827 return TARGET_FLOAT_VAX ? FF : FS;
5829 return TARGET_FLOAT_VAX ? FD : FT;
5835 /* Return an rtx for an integer representing the VMS Argument Information
5839 alpha_arg_info_reg_val (cum)
5840 CUMULATIVE_ARGS cum;
5842 unsigned HOST_WIDE_INT regval = cum.num_args;
5845 for (i = 0; i < 6; i++)
5846 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5848 return GEN_INT (regval);
5851 /* Structure to collect function names for final output
5854 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5857 struct alpha_links {
5858 struct alpha_links *next;
5860 enum links_kind kind;
5863 static struct alpha_links *alpha_links_base = 0;
5865 /* Make (or fake) .linkage entry for function call.
5867 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5870 alpha_need_linkage (name, is_local)
5875 struct alpha_links *lptr, *nptr;
5880 /* Is this name already defined ? */
5882 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5883 if (strcmp (lptr->name, name) == 0)
5887 /* Defined here but external assumed. */
5888 if (lptr->kind == KIND_EXTERN)
5889 lptr->kind = KIND_LOCAL;
5893 /* Used here but unused assumed. */
5894 if (lptr->kind == KIND_UNUSED)
5895 lptr->kind = KIND_LOCAL;
5900 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5901 nptr->next = alpha_links_base;
5902 nptr->name = xstrdup (name);
5904 /* Assume external if no definition. */
5905 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5907 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5908 get_identifier (name);
5910 alpha_links_base = nptr;
5917 alpha_write_linkage (stream)
5920 struct alpha_links *lptr, *nptr;
5922 readonly_section ();
5924 fprintf (stream, "\t.align 3\n");
5926 for (lptr = alpha_links_base; lptr; lptr = nptr)
5930 if (lptr->kind == KIND_UNUSED
5931 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5934 fprintf (stream, "$%s..lk:\n", lptr->name);
5935 if (lptr->kind == KIND_LOCAL)
5937 /* Local and used, build linkage pair. */
5938 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5939 fprintf (stream, "\t.quad %s\n", lptr->name);
5942 /* External and used, request linkage pair. */
5943 fprintf (stream, "\t.linkage %s\n", lptr->name);
5950 alpha_need_linkage (name, is_local)
5951 const char *name ATTRIBUTE_UNUSED;
5952 int is_local ATTRIBUTE_UNUSED;
5956 #endif /* OPEN_VMS */