1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998, 1999 Free Software
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"
46 extern char *version_string;
47 extern int rtx_equal_function_value_matters;
49 /* Specify which cpu to schedule for. */
51 enum processor_type alpha_cpu;
52 static const char * const alpha_cpu_name[] =
57 /* Specify how accurate floating-point traps need to be. */
59 enum alpha_trap_precision alpha_tp;
61 /* Specify the floating-point rounding mode. */
63 enum alpha_fp_rounding_mode alpha_fprm;
65 /* Specify which things cause traps. */
67 enum alpha_fp_trap_mode alpha_fptm;
69 /* Strings decoded into the above options. */
71 const char *alpha_cpu_string; /* -mcpu= */
72 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
73 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
74 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
75 const char *alpha_mlat_string; /* -mmemory-latency= */
77 /* Save information from a "cmpxx" operation until the branch or scc is
80 rtx alpha_compare_op0, alpha_compare_op1;
81 int alpha_compare_fp_p;
83 /* Define the information needed to modify the epilogue for EH. */
85 rtx alpha_eh_epilogue_sp_ofs;
87 /* Non-zero if inside of a function, because the Alpha asm can't
88 handle .files inside of functions. */
90 static int inside_function = FALSE;
92 /* If non-null, this rtx holds the return address for the function. */
94 static rtx alpha_return_addr_rtx;
96 /* The number of cycles of latency we should assume on memory reads. */
98 int alpha_memory_latency = 3;
100 /* Whether the function needs the GP. */
102 static int alpha_function_needs_gp;
104 /* The alias set for prologue/epilogue register save/restore. */
106 static int alpha_sr_alias_set;
108 /* Declarations of static functions. */
109 static void alpha_set_memflags_1
110 PROTO((rtx, int, int, int));
111 static rtx alpha_emit_set_const_1
112 PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int));
113 static void alpha_expand_unaligned_load_words
114 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
115 static void alpha_expand_unaligned_store_words
116 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
117 static void alpha_sa_mask
118 PROTO((unsigned long *imaskP, unsigned long *fmaskP));
119 static int alpha_does_function_need_gp
123 /* Get the number of args of a function in one of two ways. */
125 #define NUM_ARGS current_function_args_info.num_args
127 #define NUM_ARGS current_function_args_info
133 /* Parse target option strings. */
139 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
140 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
142 if (alpha_cpu_string)
144 if (! strcmp (alpha_cpu_string, "ev4")
145 || ! strcmp (alpha_cpu_string, "21064"))
147 alpha_cpu = PROCESSOR_EV4;
148 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
150 else if (! strcmp (alpha_cpu_string, "ev5")
151 || ! strcmp (alpha_cpu_string, "21164"))
153 alpha_cpu = PROCESSOR_EV5;
154 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
156 else if (! strcmp (alpha_cpu_string, "ev56")
157 || ! strcmp (alpha_cpu_string, "21164a"))
159 alpha_cpu = PROCESSOR_EV5;
160 target_flags |= MASK_BWX;
161 target_flags &= ~ (MASK_CIX | MASK_MAX);
163 else if (! strcmp (alpha_cpu_string, "pca56")
164 || ! strcmp (alpha_cpu_string, "21164PC")
165 || ! strcmp (alpha_cpu_string, "21164pc"))
167 alpha_cpu = PROCESSOR_EV5;
168 target_flags |= MASK_BWX | MASK_MAX;
169 target_flags &= ~ MASK_CIX;
171 else if (! strcmp (alpha_cpu_string, "ev6")
172 || ! strcmp (alpha_cpu_string, "21264"))
174 alpha_cpu = PROCESSOR_EV6;
175 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
178 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
181 alpha_tp = ALPHA_TP_PROG;
182 alpha_fprm = ALPHA_FPRM_NORM;
183 alpha_fptm = ALPHA_FPTM_N;
187 alpha_tp = ALPHA_TP_INSN;
188 alpha_fptm = ALPHA_FPTM_SU;
191 if (TARGET_IEEE_WITH_INEXACT)
193 alpha_tp = ALPHA_TP_INSN;
194 alpha_fptm = ALPHA_FPTM_SUI;
199 if (! strcmp (alpha_tp_string, "p"))
200 alpha_tp = ALPHA_TP_PROG;
201 else if (! strcmp (alpha_tp_string, "f"))
202 alpha_tp = ALPHA_TP_FUNC;
203 else if (! strcmp (alpha_tp_string, "i"))
204 alpha_tp = ALPHA_TP_INSN;
206 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
209 if (alpha_fprm_string)
211 if (! strcmp (alpha_fprm_string, "n"))
212 alpha_fprm = ALPHA_FPRM_NORM;
213 else if (! strcmp (alpha_fprm_string, "m"))
214 alpha_fprm = ALPHA_FPRM_MINF;
215 else if (! strcmp (alpha_fprm_string, "c"))
216 alpha_fprm = ALPHA_FPRM_CHOP;
217 else if (! strcmp (alpha_fprm_string,"d"))
218 alpha_fprm = ALPHA_FPRM_DYN;
220 error ("bad value `%s' for -mfp-rounding-mode switch",
224 if (alpha_fptm_string)
226 if (strcmp (alpha_fptm_string, "n") == 0)
227 alpha_fptm = ALPHA_FPTM_N;
228 else if (strcmp (alpha_fptm_string, "u") == 0)
229 alpha_fptm = ALPHA_FPTM_U;
230 else if (strcmp (alpha_fptm_string, "su") == 0)
231 alpha_fptm = ALPHA_FPTM_SU;
232 else if (strcmp (alpha_fptm_string, "sui") == 0)
233 alpha_fptm = ALPHA_FPTM_SUI;
235 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
238 /* Do some sanity checks on the above option. */
240 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
241 && alpha_tp != ALPHA_TP_INSN)
243 warning ("fp software completion requires -mtrap-precision=i");
244 alpha_tp = ALPHA_TP_INSN;
247 if (TARGET_FLOAT_VAX)
249 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
251 warning ("rounding mode not supported for VAX floats");
252 alpha_fprm = ALPHA_FPRM_NORM;
254 if (alpha_fptm == ALPHA_FPTM_SUI)
256 warning ("trap mode not supported for VAX floats");
257 alpha_fptm = ALPHA_FPTM_SU;
265 if (!alpha_mlat_string)
266 alpha_mlat_string = "L1";
268 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
269 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
271 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
272 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
273 && alpha_mlat_string[2] == '\0')
275 static int const cache_latency[][4] =
277 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
278 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
279 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
282 lat = alpha_mlat_string[1] - '0';
283 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
285 warning ("L%d cache latency unknown for %s",
286 lat, alpha_cpu_name[alpha_cpu]);
290 lat = cache_latency[alpha_cpu][lat-1];
292 else if (! strcmp (alpha_mlat_string, "main"))
294 /* Most current memories have about 370ns latency. This is
295 a reasonable guess for a fast cpu. */
300 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
304 alpha_memory_latency = lat;
307 /* Default the definition of "small data" to 8 bytes. */
311 /* Acquire a unique set number for our register saves and restores. */
312 alpha_sr_alias_set = new_alias_set ();
315 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
323 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
325 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
331 /* Returns 1 if OP is either the constant zero or a register. If a
332 register, it must be in the proper mode unless MODE is VOIDmode. */
335 reg_or_0_operand (op, mode)
337 enum machine_mode mode;
339 return op == const0_rtx || register_operand (op, mode);
342 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
346 reg_or_6bit_operand (op, mode)
348 enum machine_mode mode;
350 return ((GET_CODE (op) == CONST_INT
351 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
352 || register_operand (op, mode));
356 /* Return 1 if OP is an 8-bit constant or any register. */
359 reg_or_8bit_operand (op, mode)
361 enum machine_mode mode;
363 return ((GET_CODE (op) == CONST_INT
364 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
365 || register_operand (op, mode));
368 /* Return 1 if OP is an 8-bit constant. */
371 cint8_operand (op, mode)
373 enum machine_mode mode ATTRIBUTE_UNUSED;
375 return ((GET_CODE (op) == CONST_INT
376 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
379 /* Return 1 if the operand is a valid second operand to an add insn. */
382 add_operand (op, mode)
384 enum machine_mode mode;
386 if (GET_CODE (op) == CONST_INT)
387 /* Constraints I, J, O and P are covered by K. */
388 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
389 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
391 return register_operand (op, mode);
394 /* Return 1 if the operand is a valid second operand to a sign-extending
398 sext_add_operand (op, mode)
400 enum machine_mode mode;
402 if (GET_CODE (op) == CONST_INT)
403 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
404 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
406 return register_operand (op, mode);
409 /* Return 1 if OP is the constant 4 or 8. */
412 const48_operand (op, mode)
414 enum machine_mode mode ATTRIBUTE_UNUSED;
416 return (GET_CODE (op) == CONST_INT
417 && (INTVAL (op) == 4 || INTVAL (op) == 8));
420 /* Return 1 if OP is a valid first operand to an AND insn. */
423 and_operand (op, mode)
425 enum machine_mode mode;
427 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
428 return (zap_mask (CONST_DOUBLE_LOW (op))
429 && zap_mask (CONST_DOUBLE_HIGH (op)));
431 if (GET_CODE (op) == CONST_INT)
432 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
433 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
434 || zap_mask (INTVAL (op)));
436 return register_operand (op, mode);
439 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
442 or_operand (op, mode)
444 enum machine_mode mode;
446 if (GET_CODE (op) == CONST_INT)
447 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
448 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
450 return register_operand (op, mode);
453 /* Return 1 if OP is a constant that is the width, in bits, of an integral
454 mode smaller than DImode. */
457 mode_width_operand (op, mode)
459 enum machine_mode mode ATTRIBUTE_UNUSED;
461 return (GET_CODE (op) == CONST_INT
462 && (INTVAL (op) == 8 || INTVAL (op) == 16
463 || INTVAL (op) == 32 || INTVAL (op) == 64));
466 /* Return 1 if OP is a constant that is the width of an integral machine mode
467 smaller than an integer. */
470 mode_mask_operand (op, mode)
472 enum machine_mode mode ATTRIBUTE_UNUSED;
474 #if HOST_BITS_PER_WIDE_INT == 32
475 if (GET_CODE (op) == CONST_DOUBLE)
476 return (CONST_DOUBLE_LOW (op) == -1
477 && (CONST_DOUBLE_HIGH (op) == -1
478 || CONST_DOUBLE_HIGH (op) == 0));
480 if (GET_CODE (op) == CONST_DOUBLE)
481 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
484 return (GET_CODE (op) == CONST_INT
485 && (INTVAL (op) == 0xff
486 || INTVAL (op) == 0xffff
487 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
488 #if HOST_BITS_PER_WIDE_INT == 64
494 /* Return 1 if OP is a multiple of 8 less than 64. */
497 mul8_operand (op, mode)
499 enum machine_mode mode ATTRIBUTE_UNUSED;
501 return (GET_CODE (op) == CONST_INT
502 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
503 && (INTVAL (op) & 7) == 0);
506 /* Return 1 if OP is the constant zero in floating-point. */
509 fp0_operand (op, mode)
511 enum machine_mode mode;
513 return (GET_MODE (op) == mode
514 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
517 /* Return 1 if OP is the floating-point constant zero or a register. */
520 reg_or_fp0_operand (op, mode)
522 enum machine_mode mode;
524 return fp0_operand (op, mode) || register_operand (op, mode);
527 /* Return 1 if OP is a hard floating-point register. */
530 hard_fp_register_operand (op, mode)
532 enum machine_mode mode;
534 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
535 || (GET_CODE (op) == SUBREG
536 && hard_fp_register_operand (SUBREG_REG (op), mode)));
539 /* Return 1 if OP is a register or a constant integer. */
543 reg_or_cint_operand (op, mode)
545 enum machine_mode mode;
547 return (GET_CODE (op) == CONST_INT
548 || register_operand (op, mode));
551 /* Return 1 if OP is something that can be reloaded into a register;
552 if it is a MEM, it need not be valid. */
555 some_operand (op, mode)
557 enum machine_mode mode;
559 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
562 switch (GET_CODE (op))
564 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
565 case SYMBOL_REF: case CONST:
569 return some_operand (SUBREG_REG (op), VOIDmode);
578 /* Return 1 if OP is a valid operand for the source of a move insn. */
581 input_operand (op, mode)
583 enum machine_mode mode;
585 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
588 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
591 switch (GET_CODE (op))
596 /* This handles both the Windows/NT and OSF cases. */
597 return mode == ptr_mode || mode == DImode;
603 if (register_operand (op, mode))
605 /* ... fall through ... */
607 return ((TARGET_BWX || (mode != HImode && mode != QImode))
608 && general_operand (op, mode));
611 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
614 return mode == QImode || mode == HImode || add_operand (op, mode);
626 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
630 current_file_function_operand (op, mode)
632 enum machine_mode mode ATTRIBUTE_UNUSED;
634 return (GET_CODE (op) == SYMBOL_REF
635 && ! profile_flag && ! profile_block_flag
636 && (SYMBOL_REF_FLAG (op)
637 || op == XEXP (DECL_RTL (current_function_decl), 0)));
640 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
643 call_operand (op, mode)
645 enum machine_mode mode;
650 return (GET_CODE (op) == SYMBOL_REF
651 || (GET_CODE (op) == REG
652 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
655 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
656 comparisons are valid in which insn. */
659 alpha_comparison_operator (op, mode)
661 enum machine_mode mode;
663 enum rtx_code code = GET_CODE (op);
665 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
668 return (code == EQ || code == LE || code == LT
669 || (mode == DImode && (code == LEU || code == LTU)));
672 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
675 alpha_swapped_comparison_operator (op, mode)
677 enum machine_mode mode;
679 enum rtx_code code = GET_CODE (op);
681 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
684 code = swap_condition (code);
685 return (code == EQ || code == LE || code == LT
686 || (mode == DImode && (code == LEU || code == LTU)));
689 /* Return 1 if OP is a signed comparison operation. */
692 signed_comparison_operator (op, mode)
694 enum machine_mode mode ATTRIBUTE_UNUSED;
696 switch (GET_CODE (op))
698 case EQ: case NE: case LE: case LT: case GE: case GT:
708 /* Return 1 if this is a divide or modulus operator. */
711 divmod_operator (op, mode)
713 enum machine_mode mode ATTRIBUTE_UNUSED;
715 switch (GET_CODE (op))
717 case DIV: case MOD: case UDIV: case UMOD:
727 /* Return 1 if this memory address is a known aligned register plus
728 a constant. It must be a valid address. This means that we can do
729 this as an aligned reference plus some offset.
731 Take into account what reload will do. */
734 aligned_memory_operand (op, mode)
736 enum machine_mode mode;
740 if (reload_in_progress)
743 if (GET_CODE (tmp) == SUBREG)
744 tmp = SUBREG_REG (tmp);
745 if (GET_CODE (tmp) == REG
746 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
748 op = reg_equiv_memory_loc[REGNO (tmp)];
754 if (GET_CODE (op) != MEM
755 || GET_MODE (op) != mode)
759 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
760 sorts of constructs. Dig for the real base register. */
761 if (reload_in_progress
762 && GET_CODE (op) == PLUS
763 && GET_CODE (XEXP (op, 0)) == PLUS)
764 base = XEXP (XEXP (op, 0), 0);
767 if (! memory_address_p (mode, op))
769 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
772 return (GET_CODE (base) == REG
773 && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
776 /* Similar, but return 1 if OP is a MEM which is not alignable. */
779 unaligned_memory_operand (op, mode)
781 enum machine_mode mode;
785 if (reload_in_progress)
788 if (GET_CODE (tmp) == SUBREG)
789 tmp = SUBREG_REG (tmp);
790 if (GET_CODE (tmp) == REG
791 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
793 op = reg_equiv_memory_loc[REGNO (tmp)];
799 if (GET_CODE (op) != MEM
800 || GET_MODE (op) != mode)
804 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
805 sorts of constructs. Dig for the real base register. */
806 if (reload_in_progress
807 && GET_CODE (op) == PLUS
808 && GET_CODE (XEXP (op, 0)) == PLUS)
809 base = XEXP (XEXP (op, 0), 0);
812 if (! memory_address_p (mode, op))
814 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
817 return (GET_CODE (base) == REG
818 && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
821 /* Return 1 if OP is either a register or an unaligned memory location. */
824 reg_or_unaligned_mem_operand (op, mode)
826 enum machine_mode mode;
828 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
831 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
834 any_memory_operand (op, mode)
836 enum machine_mode mode ATTRIBUTE_UNUSED;
838 return (GET_CODE (op) == MEM
839 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
840 || (reload_in_progress && GET_CODE (op) == REG
841 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
842 || (reload_in_progress && GET_CODE (op) == SUBREG
843 && GET_CODE (SUBREG_REG (op)) == REG
844 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
847 /* Returns 1 if OP is not an eliminable register.
849 This exists to cure a pathological abort in the s8addq (et al) patterns,
851 long foo () { long t; bar(); return (long) &t * 26107; }
853 which run afoul of a hack in reload to cure a (presumably) similar
854 problem with lea-type instructions on other targets. But there is
855 one of us and many of them, so work around the problem by selectively
856 preventing combine from making the optimization. */
859 reg_not_elim_operand (op, mode)
861 enum machine_mode mode;
864 if (GET_CODE (op) == SUBREG)
865 inner = SUBREG_REG (op);
866 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
869 return register_operand (op, mode);
872 /* Return 1 is OP is a memory location that is not a reference (using
873 an AND) to an unaligned location. Take into account what reload
877 normal_memory_operand (op, mode)
879 enum machine_mode mode ATTRIBUTE_UNUSED;
881 if (reload_in_progress)
884 if (GET_CODE (tmp) == SUBREG)
885 tmp = SUBREG_REG (tmp);
886 if (GET_CODE (tmp) == REG
887 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
889 op = reg_equiv_memory_loc[REGNO (tmp)];
891 /* This may not have been assigned an equivalent address if it will
892 be eliminated. In that case, it doesn't matter what we do. */
898 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
901 /* Accept a register, but not a subreg of any kind. This allows us to
902 avoid pathological cases in reload wrt data movement common in
903 int->fp conversion. */
906 reg_no_subreg_operand (op, mode)
908 enum machine_mode mode;
910 if (GET_CODE (op) == SUBREG)
912 return register_operand (op, mode);
915 /* Return 1 if this function can directly return via $26. */
920 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
921 && get_frame_size () == 0
922 && current_function_outgoing_args_size == 0
923 && current_function_pretend_args_size == 0);
926 /* REF is an alignable memory location. Place an aligned SImode
927 reference into *PALIGNED_MEM and the number of bits to shift into
928 *PBITNUM. SCRATCH is a free register for use in reloading out
929 of range stack slots. */
932 get_aligned_mem (ref, paligned_mem, pbitnum)
934 rtx *paligned_mem, *pbitnum;
937 HOST_WIDE_INT offset = 0;
939 if (GET_CODE (ref) != MEM)
942 if (reload_in_progress
943 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
945 base = find_replacement (&XEXP (ref, 0));
947 if (! memory_address_p (GET_MODE (ref), base))
952 base = XEXP (ref, 0);
955 if (GET_CODE (base) == PLUS)
956 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
958 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
959 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
960 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
962 /* Sadly, we cannot use alias sets here because we may overlap other
963 data in a different alias set. */
964 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
966 *pbitnum = GEN_INT ((offset & 3) * 8);
969 /* Similar, but just get the address. Handle the two reload cases.
970 Add EXTRA_OFFSET to the address we return. */
973 get_unaligned_address (ref, extra_offset)
978 HOST_WIDE_INT offset = 0;
980 if (GET_CODE (ref) != MEM)
983 if (reload_in_progress
984 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
986 base = find_replacement (&XEXP (ref, 0));
988 if (! memory_address_p (GET_MODE (ref), base))
993 base = XEXP (ref, 0);
996 if (GET_CODE (base) == PLUS)
997 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
999 return plus_constant (base, offset + extra_offset);
1002 /* Subfunction of the following function. Update the flags of any MEM
1003 found in part of X. */
1006 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1008 int in_struct_p, volatile_p, unchanging_p;
1012 switch (GET_CODE (x))
1016 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1017 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1022 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1027 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1029 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1034 MEM_IN_STRUCT_P (x) = in_struct_p;
1035 MEM_VOLATILE_P (x) = volatile_p;
1036 RTX_UNCHANGING_P (x) = unchanging_p;
1037 /* Sadly, we cannot use alias sets because the extra aliasing
1038 produced by the AND interferes. Given that two-byte quantities
1039 are the only thing we would be able to differentiate anyway,
1040 there does not seem to be any point in convoluting the early
1041 out of the alias check. */
1042 /* MEM_ALIAS_SET (x) = alias_set; */
1050 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1051 perform a memory operation, look for any MEMs in either a SET_DEST or
1052 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1053 REF into each of the MEMs found. If REF is not a MEM, don't do
1057 alpha_set_memflags (insn, ref)
1061 int in_struct_p, volatile_p, unchanging_p;
1063 if (GET_CODE (ref) != MEM)
1066 in_struct_p = MEM_IN_STRUCT_P (ref);
1067 volatile_p = MEM_VOLATILE_P (ref);
1068 unchanging_p = RTX_UNCHANGING_P (ref);
1070 /* This is only called from alpha.md, after having had something
1071 generated from one of the insn patterns. So if everything is
1072 zero, the pattern is already up-to-date. */
1073 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1076 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1079 /* Try to output insns to set TARGET equal to the constant C if it can be
1080 done in less than N insns. Do all computations in MODE. Returns the place
1081 where the output has been placed if it can be done and the insns have been
1082 emitted. If it would take more than N insns, zero is returned and no
1083 insns and emitted. */
1086 alpha_emit_set_const (target, mode, c, n)
1088 enum machine_mode mode;
1095 /* Try 1 insn, then 2, then up to N. */
1096 for (i = 1; i <= n; i++)
1097 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1103 /* Internal routine for the above to check for N or below insns. */
1106 alpha_emit_set_const_1 (target, mode, c, n)
1108 enum machine_mode mode;
1112 HOST_WIDE_INT new = c;
1114 /* Use a pseudo if highly optimizing and still generating RTL. */
1116 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1120 #if HOST_BITS_PER_WIDE_INT == 64
1121 /* We are only called for SImode and DImode. If this is SImode, ensure that
1122 we are sign extended to a full word. This does not make any sense when
1123 cross-compiling on a narrow machine. */
1126 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1129 /* If this is a sign-extended 32-bit constant, we can do this in at most
1130 three insns, so do it if we have enough insns left. We always have
1131 a sign-extended 32-bit constant when compiling on a narrow machine. */
1133 if (HOST_BITS_PER_WIDE_INT != 64
1134 || c >> 31 == -1 || c >> 31 == 0)
1136 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1137 HOST_WIDE_INT tmp1 = c - low;
1139 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1140 HOST_WIDE_INT extra = 0;
1142 /* If HIGH will be interpreted as negative but the constant is
1143 positive, we must adjust it to do two ldha insns. */
1145 if ((high & 0x8000) != 0 && c >= 0)
1149 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1152 if (c == low || (low == 0 && extra == 0))
1154 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1155 but that meant that we can't handle INT_MIN on 32-bit machines
1156 (like NT/Alpha), because we recurse indefinitely through
1157 emit_move_insn to gen_movdi. So instead, since we know exactly
1158 what we want, create it explicitly. */
1161 target = gen_reg_rtx (mode);
1162 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1165 else if (n >= 2 + (extra != 0))
1167 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1170 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1171 subtarget, 0, OPTAB_WIDEN);
1173 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1174 target, 0, OPTAB_WIDEN);
1178 /* If we couldn't do it that way, try some other methods. But if we have
1179 no instructions left, don't bother. Likewise, if this is SImode and
1180 we can't make pseudos, we can't do anything since the expand_binop
1181 and expand_unop calls will widen and try to make pseudos. */
1184 || (mode == SImode && ! rtx_equal_function_value_matters))
1187 #if HOST_BITS_PER_WIDE_INT == 64
1188 /* First, see if can load a value into the target that is the same as the
1189 constant except that all bytes that are 0 are changed to be 0xff. If we
1190 can, then we can do a ZAPNOT to obtain the desired constant. */
1192 for (i = 0; i < 64; i += 8)
1193 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1194 new |= (HOST_WIDE_INT) 0xff << i;
1196 /* We are only called for SImode and DImode. If this is SImode, ensure that
1197 we are sign extended to a full word. */
1200 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1203 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1204 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1205 target, 0, OPTAB_WIDEN);
1208 /* Next, see if we can load a related constant and then shift and possibly
1209 negate it to get the constant we want. Try this once each increasing
1210 numbers of insns. */
1212 for (i = 1; i < n; i++)
1214 /* First try complementing. */
1215 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1216 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1218 /* Next try to form a constant and do a left shift. We can do this
1219 if some low-order bits are zero; the exact_log2 call below tells
1220 us that information. The bits we are shifting out could be any
1221 value, but here we'll just try the 0- and sign-extended forms of
1222 the constant. To try to increase the chance of having the same
1223 constant in more than one insn, start at the highest number of
1224 bits to shift, but try all possibilities in case a ZAPNOT will
1227 if ((bits = exact_log2 (c & - c)) > 0)
1228 for (; bits > 0; bits--)
1229 if ((temp = (alpha_emit_set_const
1231 (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1232 || ((temp = (alpha_emit_set_const
1234 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1236 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1237 target, 0, OPTAB_WIDEN);
1239 /* Now try high-order zero bits. Here we try the shifted-in bits as
1240 all zero and all ones. Be careful to avoid shifting outside the
1241 mode and to avoid shifting outside the host wide int size. */
1242 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1243 confuse the recursive call and set all of the high 32 bits. */
1245 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1246 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1247 for (; bits > 0; bits--)
1248 if ((temp = alpha_emit_set_const (subtarget, mode,
1250 || ((temp = (alpha_emit_set_const
1252 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1255 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1256 target, 1, OPTAB_WIDEN);
1258 /* Now try high-order 1 bits. We get that with a sign-extension.
1259 But one bit isn't enough here. Be careful to avoid shifting outside
1260 the mode and to avoid shifting outside the host wide int size. */
1262 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1263 - floor_log2 (~ c) - 2)) > 0)
1264 for (; bits > 0; bits--)
1265 if ((temp = alpha_emit_set_const (subtarget, mode,
1267 || ((temp = (alpha_emit_set_const
1269 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1272 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1273 target, 0, OPTAB_WIDEN);
1279 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1280 fall back to a straight forward decomposition. We do this to avoid
1281 exponential run times encountered when looking for longer sequences
1282 with alpha_emit_set_const. */
1285 alpha_emit_set_long_const (target, c1, c2)
1287 HOST_WIDE_INT c1, c2;
1289 HOST_WIDE_INT d1, d2, d3, d4;
1291 /* Decompose the entire word */
1292 #if HOST_BITS_PER_WIDE_INT >= 64
1293 if (c2 != -(c1 < 0))
1295 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1297 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1298 c1 = (c1 - d2) >> 32;
1299 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1301 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1305 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1307 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1311 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1313 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1318 /* Construct the high word */
1321 emit_move_insn (target, GEN_INT (d4));
1323 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1326 emit_move_insn (target, GEN_INT (d3));
1328 /* Shift it into place */
1329 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1331 /* Add in the low bits. */
1333 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1335 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1340 /* Generate the comparison for a conditional branch. */
1343 alpha_emit_conditional_branch (code)
1346 enum rtx_code cmp_code, branch_code;
1347 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1348 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1351 /* The general case: fold the comparison code to the types of compares
1352 that we have, choosing the branch as necessary. */
1355 case EQ: case LE: case LT: case LEU: case LTU:
1356 /* We have these compares: */
1357 cmp_code = code, branch_code = NE;
1361 /* This must be reversed. */
1362 cmp_code = EQ, branch_code = EQ;
1365 case GE: case GT: case GEU: case GTU:
1366 /* For FP, we swap them, for INT, we reverse them. */
1367 if (alpha_compare_fp_p)
1369 cmp_code = swap_condition (code);
1371 tem = op0, op0 = op1, op1 = tem;
1375 cmp_code = reverse_condition (code);
1384 if (alpha_compare_fp_p)
1389 /* When we are not as concerned about non-finite values, and we
1390 are comparing against zero, we can branch directly. */
1391 if (op1 == CONST0_RTX (DFmode))
1392 cmp_code = NIL, branch_code = code;
1393 else if (op0 == CONST0_RTX (DFmode))
1395 /* Undo the swap we probably did just above. */
1396 tem = op0, op0 = op1, op1 = tem;
1397 branch_code = swap_condition (cmp_code);
1403 /* ??? We mark the the branch mode to be CCmode to prevent the
1404 compare and branch from being combined, since the compare
1405 insn follows IEEE rules that the branch does not. */
1406 branch_mode = CCmode;
1413 /* The following optimizations are only for signed compares. */
1414 if (code != LEU && code != LTU && code != GEU && code != GTU)
1416 /* Whee. Compare and branch against 0 directly. */
1417 if (op1 == const0_rtx)
1418 cmp_code = NIL, branch_code = code;
1420 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1421 bypass between logicals and br/cmov on EV5. But we don't want to
1422 force valid immediate constants into registers needlessly. */
1423 else if (GET_CODE (op1) == CONST_INT)
1425 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1427 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1428 && (CONST_OK_FOR_LETTER_P (n, 'K')
1429 || CONST_OK_FOR_LETTER_P (n, 'L')))
1431 cmp_code = PLUS, branch_code = code;
1438 /* Force op0 into a register. */
1439 if (GET_CODE (op0) != REG)
1440 op0 = force_reg (cmp_mode, op0);
1442 /* Emit an initial compare instruction, if necessary. */
1444 if (cmp_code != NIL)
1446 tem = gen_reg_rtx (cmp_mode);
1447 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1450 /* Return the branch comparison. */
1451 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1455 /* Rewrite a comparison against zero CMP of the form
1456 (CODE (cc0) (const_int 0)) so it can be written validly in
1457 a conditional move (if_then_else CMP ...).
1458 If both of the operands that set cc0 are non-zero we must emit
1459 an insn to perform the compare (it can't be done within
1460 the conditional move). */
1462 alpha_emit_conditional_move (cmp, mode)
1464 enum machine_mode mode;
1466 enum rtx_code code = GET_CODE (cmp);
1467 enum rtx_code cmov_code = NE;
1468 rtx op0 = alpha_compare_op0;
1469 rtx op1 = alpha_compare_op1;
1470 enum machine_mode cmp_mode
1471 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1472 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1473 enum machine_mode cmov_mode = VOIDmode;
1476 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1479 /* We may be able to use a conditional move directly.
1480 This avoids emitting spurious compares. */
1481 if (signed_comparison_operator (cmp, cmp_op_mode)
1482 && (!alpha_compare_fp_p || flag_fast_math)
1483 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1484 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1486 /* We can't put the comparison insides a conditional move;
1487 emit a compare instruction and put that inside the
1488 conditional move. Make sure we emit only comparisons we have;
1489 swap or reverse as necessary. */
1493 case EQ: case LE: case LT: case LEU: case LTU:
1494 /* We have these compares: */
1498 /* This must be reversed. */
1499 code = reverse_condition (code);
1503 case GE: case GT: case GEU: case GTU:
1504 /* These must be swapped. Make sure the new first operand is in
1506 code = swap_condition (code);
1507 tem = op0, op0 = op1, op1 = tem;
1508 op0 = force_reg (cmp_mode, op0);
1515 /* ??? We mark the branch mode to be CCmode to prevent the compare
1516 and cmov from being combined, since the compare insn follows IEEE
1517 rules that the cmov does not. */
1518 if (alpha_compare_fp_p && !flag_fast_math)
1521 tem = gen_reg_rtx (cmp_op_mode);
1522 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1523 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1526 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1530 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1531 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1532 lda r3,X(r11) lda r3,X+2(r11)
1533 extwl r1,r3,r1 extql r1,r3,r1
1534 extwh r2,r3,r2 extqh r2,r3,r2
1535 or r1.r2.r1 or r1,r2,r1
1538 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1539 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1540 lda r3,X(r11) lda r3,X(r11)
1541 extll r1,r3,r1 extll r1,r3,r1
1542 extlh r2,r3,r2 extlh r2,r3,r2
1543 or r1.r2.r1 addl r1,r2,r1
1545 quad: ldq_u r1,X(r11)
1554 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1556 HOST_WIDE_INT size, ofs;
1559 rtx meml, memh, addr, extl, exth;
1560 enum machine_mode mode;
1562 meml = gen_reg_rtx (DImode);
1563 memh = gen_reg_rtx (DImode);
1564 addr = gen_reg_rtx (DImode);
1565 extl = gen_reg_rtx (DImode);
1566 exth = gen_reg_rtx (DImode);
1568 emit_move_insn (meml,
1569 change_address (mem, DImode,
1570 gen_rtx_AND (DImode,
1571 plus_constant (XEXP (mem, 0),
1575 emit_move_insn (memh,
1576 change_address (mem, DImode,
1577 gen_rtx_AND (DImode,
1578 plus_constant (XEXP (mem, 0),
1582 if (sign && size == 2)
1584 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1586 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1587 emit_insn (gen_extqh (exth, memh, addr));
1589 /* We must use tgt here for the target. Alpha-vms port fails if we use
1590 addr for the target, because addr is marked as a pointer and combine
1591 knows that pointers are always sign-extended 32 bit values. */
1592 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1593 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1594 addr, 1, OPTAB_WIDEN);
1598 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1599 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1603 emit_insn (gen_extwh (exth, memh, addr));
1608 emit_insn (gen_extlh (exth, memh, addr));
1613 emit_insn (gen_extqh (exth, memh, addr));
1620 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1621 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1626 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1629 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1632 alpha_expand_unaligned_store (dst, src, size, ofs)
1634 HOST_WIDE_INT size, ofs;
1636 rtx dstl, dsth, addr, insl, insh, meml, memh;
1638 dstl = gen_reg_rtx (DImode);
1639 dsth = gen_reg_rtx (DImode);
1640 insl = gen_reg_rtx (DImode);
1641 insh = gen_reg_rtx (DImode);
1643 meml = change_address (dst, DImode,
1644 gen_rtx_AND (DImode,
1645 plus_constant (XEXP (dst, 0), ofs),
1647 memh = change_address (dst, DImode,
1648 gen_rtx_AND (DImode,
1649 plus_constant (XEXP (dst, 0),
1653 emit_move_insn (dsth, memh);
1654 emit_move_insn (dstl, meml);
1655 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1657 if (src != const0_rtx)
1659 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1660 GEN_INT (size*8), addr));
1665 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1668 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1671 emit_insn (gen_insql (insl, src, addr));
1676 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1681 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1684 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1688 #if HOST_BITS_PER_WIDE_INT == 32
1689 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1691 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1693 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1698 if (src != const0_rtx)
1700 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1701 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1704 /* Must store high before low for degenerate case of aligned. */
1705 emit_move_insn (memh, dsth);
1706 emit_move_insn (meml, dstl);
1709 /* The block move code tries to maximize speed by separating loads and
1710 stores at the expense of register pressure: we load all of the data
1711 before we store it back out. There are two secondary effects worth
1712 mentioning, that this speeds copying to/from aligned and unaligned
1713 buffers, and that it makes the code significantly easier to write. */
1715 #define MAX_MOVE_WORDS 8
1717 /* Load an integral number of consecutive unaligned quadwords. */
1720 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1723 HOST_WIDE_INT words, ofs;
1725 rtx const im8 = GEN_INT (-8);
1726 rtx const i64 = GEN_INT (64);
1727 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1731 /* Generate all the tmp registers we need. */
1732 for (i = 0; i < words; ++i)
1734 data_regs[i] = out_regs[i];
1735 ext_tmps[i] = gen_reg_rtx (DImode);
1737 data_regs[words] = gen_reg_rtx (DImode);
1740 smem = change_address (smem, GET_MODE (smem),
1741 plus_constant (XEXP (smem, 0), ofs));
1743 /* Load up all of the source data. */
1744 for (i = 0; i < words; ++i)
1746 emit_move_insn (data_regs[i],
1747 change_address (smem, DImode,
1748 gen_rtx_AND (DImode,
1749 plus_constant (XEXP(smem,0),
1753 emit_move_insn (data_regs[words],
1754 change_address (smem, DImode,
1755 gen_rtx_AND (DImode,
1756 plus_constant (XEXP(smem,0),
1760 /* Extract the half-word fragments. Unfortunately DEC decided to make
1761 extxh with offset zero a noop instead of zeroing the register, so
1762 we must take care of that edge condition ourselves with cmov. */
1764 sreg = copy_addr_to_reg (XEXP (smem, 0));
1765 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1767 for (i = 0; i < words; ++i)
1769 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1771 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1772 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1773 gen_rtx_IF_THEN_ELSE (DImode,
1774 gen_rtx_EQ (DImode, areg,
1776 const0_rtx, ext_tmps[i])));
1779 /* Merge the half-words into whole words. */
1780 for (i = 0; i < words; ++i)
1782 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1783 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1787 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1788 may be NULL to store zeros. */
1791 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1794 HOST_WIDE_INT words, ofs;
1796 rtx const im8 = GEN_INT (-8);
1797 rtx const i64 = GEN_INT (64);
1798 #if HOST_BITS_PER_WIDE_INT == 32
1799 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1801 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1803 rtx ins_tmps[MAX_MOVE_WORDS];
1804 rtx st_tmp_1, st_tmp_2, dreg;
1805 rtx st_addr_1, st_addr_2;
1808 /* Generate all the tmp registers we need. */
1809 if (data_regs != NULL)
1810 for (i = 0; i < words; ++i)
1811 ins_tmps[i] = gen_reg_rtx(DImode);
1812 st_tmp_1 = gen_reg_rtx(DImode);
1813 st_tmp_2 = gen_reg_rtx(DImode);
1816 dmem = change_address (dmem, GET_MODE (dmem),
1817 plus_constant (XEXP (dmem, 0), ofs));
1820 st_addr_2 = change_address (dmem, DImode,
1821 gen_rtx_AND (DImode,
1822 plus_constant (XEXP(dmem,0),
1825 st_addr_1 = change_address (dmem, DImode,
1826 gen_rtx_AND (DImode,
1830 /* Load up the destination end bits. */
1831 emit_move_insn (st_tmp_2, st_addr_2);
1832 emit_move_insn (st_tmp_1, st_addr_1);
1834 /* Shift the input data into place. */
1835 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1836 if (data_regs != NULL)
1838 for (i = words-1; i >= 0; --i)
1840 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1841 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1843 for (i = words-1; i > 0; --i)
1845 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1846 ins_tmps[i-1], ins_tmps[i-1], 1,
1851 /* Split and merge the ends with the destination data. */
1852 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1853 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1855 if (data_regs != NULL)
1857 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1858 st_tmp_2, 1, OPTAB_WIDEN);
1859 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1860 st_tmp_1, 1, OPTAB_WIDEN);
1864 emit_move_insn (st_addr_2, st_tmp_2);
1865 for (i = words-1; i > 0; --i)
1867 emit_move_insn (change_address (dmem, DImode,
1868 gen_rtx_AND (DImode,
1869 plus_constant(XEXP (dmem,0),
1872 data_regs ? ins_tmps[i-1] : const0_rtx);
1874 emit_move_insn (st_addr_1, st_tmp_1);
1878 /* Expand string/block move operations.
1880 operands[0] is the pointer to the destination.
1881 operands[1] is the pointer to the source.
1882 operands[2] is the number of bytes to move.
1883 operands[3] is the alignment. */
1886 alpha_expand_block_move (operands)
1889 rtx bytes_rtx = operands[2];
1890 rtx align_rtx = operands[3];
1891 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
1892 HOST_WIDE_INT bytes = orig_bytes;
1893 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1894 HOST_WIDE_INT dst_align = src_align;
1895 rtx orig_src = operands[1];
1896 rtx orig_dst = operands[0];
1897 rtx data_regs[2*MAX_MOVE_WORDS+16];
1899 int i, words, ofs, nregs = 0;
1903 if (bytes > MAX_MOVE_WORDS*8)
1906 /* Look for additional alignment information from recorded register info. */
1908 tmp = XEXP (orig_src, 0);
1909 if (GET_CODE (tmp) == REG)
1911 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1912 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1914 else if (GET_CODE (tmp) == PLUS
1915 && GET_CODE (XEXP (tmp, 0)) == REG
1916 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1918 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1919 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1923 if (a >= 8 && c % 8 == 0)
1925 else if (a >= 4 && c % 4 == 0)
1927 else if (a >= 2 && c % 2 == 0)
1932 tmp = XEXP (orig_dst, 0);
1933 if (GET_CODE (tmp) == REG)
1935 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1936 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1938 else if (GET_CODE (tmp) == PLUS
1939 && GET_CODE (XEXP (tmp, 0)) == REG
1940 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1942 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1943 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1947 if (a >= 8 && c % 8 == 0)
1949 else if (a >= 4 && c % 4 == 0)
1951 else if (a >= 2 && c % 2 == 0)
1957 * Load the entire block into registers.
1960 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1962 enum machine_mode mode;
1963 tmp = XEXP (XEXP (orig_src, 0), 0);
1965 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
1967 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1969 /* Whee! Optimize the load to use the existing register. */
1970 data_regs[nregs++] = gen_lowpart (mode, tmp);
1974 /* ??? We could potentially be copying 3 bytes or whatnot from
1975 a wider reg. Probably not worth worrying about. */
1976 /* No appropriate mode; fall back on memory. */
1977 orig_src = change_address (orig_src, GET_MODE (orig_src),
1978 copy_addr_to_reg (XEXP (orig_src, 0)));
1982 if (src_align >= 8 && bytes >= 8)
1986 for (i = 0; i < words; ++i)
1987 data_regs[nregs+i] = gen_reg_rtx(DImode);
1989 for (i = 0; i < words; ++i)
1991 emit_move_insn (data_regs[nregs+i],
1992 change_address(orig_src, DImode,
1993 plus_constant (XEXP (orig_src, 0),
2001 if (src_align >= 4 && bytes >= 4)
2005 for (i = 0; i < words; ++i)
2006 data_regs[nregs+i] = gen_reg_rtx(SImode);
2008 for (i = 0; i < words; ++i)
2010 emit_move_insn (data_regs[nregs+i],
2011 change_address(orig_src, SImode,
2012 plus_constant (XEXP (orig_src, 0),
2024 for (i = 0; i < words+1; ++i)
2025 data_regs[nregs+i] = gen_reg_rtx(DImode);
2027 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
2033 if (!TARGET_BWX && bytes >= 8)
2035 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2036 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2040 if (!TARGET_BWX && bytes >= 4)
2042 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2043 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2052 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2053 emit_move_insn (tmp,
2054 change_address (orig_src, HImode,
2055 plus_constant (XEXP (orig_src, 0),
2059 } while (bytes >= 2);
2061 else if (!TARGET_BWX)
2063 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2064 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2071 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2072 emit_move_insn (tmp,
2073 change_address (orig_src, QImode,
2074 plus_constant (XEXP (orig_src, 0),
2081 if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2085 * Now save it back out again.
2090 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2092 enum machine_mode mode;
2093 tmp = XEXP (XEXP (orig_dst, 0), 0);
2095 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2096 if (GET_MODE (tmp) == mode && nregs == 1)
2098 emit_move_insn (tmp, data_regs[0]);
2103 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2104 /* ??? Optimize mode < dst_mode with strict_low_part. */
2106 /* No appropriate mode; fall back on memory. We can speed things
2107 up by recognizing extra alignment information. */
2108 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2109 copy_addr_to_reg (XEXP (orig_dst, 0)));
2110 dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2113 /* Write out the data in whatever chunks reading the source allowed. */
2116 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2118 emit_move_insn (change_address(orig_dst, DImode,
2119 plus_constant (XEXP (orig_dst, 0),
2128 /* If the source has remaining DImode regs, write them out in
2130 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2132 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2133 NULL_RTX, 1, OPTAB_WIDEN);
2135 emit_move_insn (change_address(orig_dst, SImode,
2136 plus_constant (XEXP (orig_dst, 0),
2138 gen_lowpart (SImode, data_regs[i]));
2139 emit_move_insn (change_address(orig_dst, SImode,
2140 plus_constant (XEXP (orig_dst, 0),
2142 gen_lowpart (SImode, tmp));
2147 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2149 emit_move_insn (change_address(orig_dst, SImode,
2150 plus_constant (XEXP (orig_dst, 0),
2157 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2159 /* Write out a remaining block of words using unaligned methods. */
2161 for (words = 1; i+words < nregs ; ++words)
2162 if (GET_MODE (data_regs[i+words]) != DImode)
2166 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2168 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2174 /* Due to the above, this won't be aligned. */
2175 /* ??? If we have more than one of these, consider constructing full
2176 words in registers and using alpha_expand_unaligned_store_words. */
2177 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2179 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2185 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2187 emit_move_insn (change_address (orig_dst, HImode,
2188 plus_constant (XEXP (orig_dst, 0),
2195 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2197 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2201 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2203 emit_move_insn (change_address (orig_dst, QImode,
2204 plus_constant (XEXP (orig_dst, 0),
2219 alpha_expand_block_clear (operands)
2222 rtx bytes_rtx = operands[1];
2223 rtx align_rtx = operands[2];
2224 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2225 HOST_WIDE_INT align = INTVAL (align_rtx);
2226 rtx orig_dst = operands[0];
2228 HOST_WIDE_INT i, words, ofs = 0;
2232 if (bytes > MAX_MOVE_WORDS*8)
2235 /* Look for stricter alignment. */
2237 tmp = XEXP (orig_dst, 0);
2238 if (GET_CODE (tmp) == REG)
2240 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2241 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2243 else if (GET_CODE (tmp) == PLUS
2244 && GET_CODE (XEXP (tmp, 0)) == REG
2245 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2247 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2248 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2252 if (a >= 8 && c % 8 == 0)
2254 else if (a >= 4 && c % 4 == 0)
2256 else if (a >= 2 && c % 2 == 0)
2261 /* Handle a block of contiguous words first. */
2263 if (align >= 8 && bytes >= 8)
2267 for (i = 0; i < words; ++i)
2269 emit_move_insn (change_address(orig_dst, DImode,
2270 plus_constant (XEXP (orig_dst, 0),
2278 if (align >= 4 && bytes >= 4)
2282 for (i = 0; i < words; ++i)
2284 emit_move_insn (change_address(orig_dst, SImode,
2285 plus_constant (XEXP (orig_dst, 0),
2297 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2303 /* Next clean up any trailing pieces. We know from the contiguous
2304 block move that there are no aligned SImode or DImode hunks left. */
2306 if (!TARGET_BWX && bytes >= 8)
2308 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2312 if (!TARGET_BWX && bytes >= 4)
2314 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2323 emit_move_insn (change_address (orig_dst, HImode,
2324 plus_constant (XEXP (orig_dst, 0),
2329 } while (bytes >= 2);
2331 else if (!TARGET_BWX)
2333 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2340 emit_move_insn (change_address (orig_dst, QImode,
2341 plus_constant (XEXP (orig_dst, 0),
2352 /* Adjust the cost of a scheduling dependency. Return the new cost of
2353 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2356 alpha_adjust_cost (insn, link, dep_insn, cost)
2363 enum attr_type insn_type, dep_insn_type;
2365 /* If the dependence is an anti-dependence, there is no cost. For an
2366 output dependence, there is sometimes a cost, but it doesn't seem
2367 worth handling those few cases. */
2369 if (REG_NOTE_KIND (link) != 0)
2372 /* If we can't recognize the insns, we can't really do anything. */
2373 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2376 insn_type = get_attr_type (insn);
2377 dep_insn_type = get_attr_type (dep_insn);
2379 /* Bring in the user-defined memory latency. */
2380 if (dep_insn_type == TYPE_ILD
2381 || dep_insn_type == TYPE_FLD
2382 || dep_insn_type == TYPE_LDSYM)
2383 cost += alpha_memory_latency-1;
2388 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2389 being stored, we can sometimes lower the cost. */
2391 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2392 && (set = single_set (dep_insn)) != 0
2393 && GET_CODE (PATTERN (insn)) == SET
2394 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2396 switch (dep_insn_type)
2400 /* No savings here. */
2404 /* In these cases, we save one cycle. */
2408 /* In all other cases, we save two cycles. */
2409 return MAX (0, cost - 2);
2413 /* Another case that needs adjustment is an arithmetic or logical
2414 operation. It's cost is usually one cycle, but we default it to
2415 two in the MD file. The only case that it is actually two is
2416 for the address in loads, stores, and jumps. */
2418 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2433 /* The final case is when a compare feeds into an integer branch;
2434 the cost is only one cycle in that case. */
2436 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2441 /* And the lord DEC saith: "A special bypass provides an effective
2442 latency of 0 cycles for an ICMP or ILOG insn producing the test
2443 operand of an IBR or ICMOV insn." */
2445 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2446 && (set = single_set (dep_insn)) != 0)
2448 /* A branch only has one input. This must be it. */
2449 if (insn_type == TYPE_IBR)
2451 /* A conditional move has three, make sure it is the test. */
2452 if (insn_type == TYPE_ICMOV
2453 && GET_CODE (set_src = PATTERN (insn)) == SET
2454 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2455 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2459 /* "The multiplier is unable to receive data from IEU bypass paths.
2460 The instruction issues at the expected time, but its latency is
2461 increased by the time it takes for the input data to become
2462 available to the multiplier" -- which happens in pipeline stage
2463 six, when results are comitted to the register file. */
2465 if (insn_type == TYPE_IMUL)
2467 switch (dep_insn_type)
2469 /* These insns produce their results in pipeline stage five. */
2476 /* Other integer insns produce results in pipeline stage four. */
2484 /* There is additional latency to move the result of (most) FP
2485 operations anywhere but the FP register file. */
2487 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2488 && (dep_insn_type == TYPE_FADD ||
2489 dep_insn_type == TYPE_FMUL ||
2490 dep_insn_type == TYPE_FCMOV))
2496 /* Otherwise, return the default cost. */
2500 /* Functions to save and restore alpha_return_addr_rtx. */
2502 struct machine_function
2508 alpha_save_machine_status (p)
2511 struct machine_function *machine =
2512 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2514 p->machine = machine;
2515 machine->ra_rtx = alpha_return_addr_rtx;
2519 alpha_restore_machine_status (p)
2522 struct machine_function *machine = p->machine;
2524 alpha_return_addr_rtx = machine->ra_rtx;
2527 p->machine = (struct machine_function *)0;
2530 /* Do anything needed before RTL is emitted for each function. */
2533 alpha_init_expanders ()
2535 alpha_return_addr_rtx = NULL_RTX;
2536 alpha_eh_epilogue_sp_ofs = NULL_RTX;
2538 /* Arrange to save and restore machine status around nested functions. */
2539 save_machine_status = alpha_save_machine_status;
2540 restore_machine_status = alpha_restore_machine_status;
2543 /* Start the ball rolling with RETURN_ADDR_RTX. */
2546 alpha_return_addr (count, frame)
2548 rtx frame ATTRIBUTE_UNUSED;
2555 if (alpha_return_addr_rtx)
2556 return alpha_return_addr_rtx;
2558 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2559 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2560 init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
2561 gen_rtx_REG (Pmode, REG_RA));
2563 /* Emit the insn to the prologue with the other argument copies. */
2564 push_topmost_sequence ();
2565 emit_insn_after (init, get_insns ());
2566 pop_topmost_sequence ();
2568 return alpha_return_addr_rtx;
2572 alpha_ra_ever_killed ()
2576 #ifdef ASM_OUTPUT_MI_THUNK
2577 if (current_function_is_thunk)
2580 if (!alpha_return_addr_rtx)
2581 return regs_ever_live[REG_RA];
2583 push_topmost_sequence ();
2585 pop_topmost_sequence ();
2587 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2591 /* Print an operand. Recognize special options, documented below. */
2594 print_operand (file, x, code)
2604 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2605 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2606 mode. alpha_fprm controls which suffix is generated. */
2609 case ALPHA_FPRM_NORM:
2611 case ALPHA_FPRM_MINF:
2614 case ALPHA_FPRM_CHOP:
2617 case ALPHA_FPRM_DYN:
2624 /* Generates trap-mode suffix for instructions that accept the su
2625 suffix only (cmpt et al). */
2626 if (alpha_tp == ALPHA_TP_INSN)
2631 /* Generates trap-mode suffix for instructions that accept the
2632 v and sv suffix. The only instruction that needs this is cvtql. */
2641 case ALPHA_FPTM_SUI:
2648 /* Generates trap-mode suffix for instructions that accept the
2649 v, sv, and svi suffix. The only instruction that needs this
2661 case ALPHA_FPTM_SUI:
2662 fputs ("svi", file);
2668 /* Generates trap-mode suffix for instructions that accept the u, su,
2669 and sui suffix. This is the bulk of the IEEE floating point
2670 instructions (addt et al). */
2681 case ALPHA_FPTM_SUI:
2682 fputs ("sui", file);
2688 /* Generates trap-mode suffix for instructions that accept the sui
2689 suffix (cvtqt and cvtqs). */
2694 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2696 case ALPHA_FPTM_SUI:
2697 fputs ("sui", file);
2703 /* Generates single precision instruction suffix. */
2704 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2708 /* Generates double precision instruction suffix. */
2709 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2713 /* If this operand is the constant zero, write it as "$31". */
2714 if (GET_CODE (x) == REG)
2715 fprintf (file, "%s", reg_names[REGNO (x)]);
2716 else if (x == CONST0_RTX (GET_MODE (x)))
2717 fprintf (file, "$31");
2719 output_operand_lossage ("invalid %%r value");
2724 /* Similar, but for floating-point. */
2725 if (GET_CODE (x) == REG)
2726 fprintf (file, "%s", reg_names[REGNO (x)]);
2727 else if (x == CONST0_RTX (GET_MODE (x)))
2728 fprintf (file, "$f31");
2730 output_operand_lossage ("invalid %%R value");
2735 /* Write the 1's complement of a constant. */
2736 if (GET_CODE (x) != CONST_INT)
2737 output_operand_lossage ("invalid %%N value");
2739 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2743 /* Write 1 << C, for a constant C. */
2744 if (GET_CODE (x) != CONST_INT)
2745 output_operand_lossage ("invalid %%P value");
2747 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2751 /* Write the high-order 16 bits of a constant, sign-extended. */
2752 if (GET_CODE (x) != CONST_INT)
2753 output_operand_lossage ("invalid %%h value");
2755 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2759 /* Write the low-order 16 bits of a constant, sign-extended. */
2760 if (GET_CODE (x) != CONST_INT)
2761 output_operand_lossage ("invalid %%L value");
2763 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2764 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2768 /* Write mask for ZAP insn. */
2769 if (GET_CODE (x) == CONST_DOUBLE)
2771 HOST_WIDE_INT mask = 0;
2772 HOST_WIDE_INT value;
2774 value = CONST_DOUBLE_LOW (x);
2775 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2780 value = CONST_DOUBLE_HIGH (x);
2781 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2784 mask |= (1 << (i + sizeof (int)));
2786 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2789 else if (GET_CODE (x) == CONST_INT)
2791 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2793 for (i = 0; i < 8; i++, value >>= 8)
2797 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2800 output_operand_lossage ("invalid %%m value");
2804 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2805 if (GET_CODE (x) != CONST_INT
2806 || (INTVAL (x) != 8 && INTVAL (x) != 16
2807 && INTVAL (x) != 32 && INTVAL (x) != 64))
2808 output_operand_lossage ("invalid %%M value");
2810 fprintf (file, "%s",
2811 (INTVAL (x) == 8 ? "b"
2812 : INTVAL (x) == 16 ? "w"
2813 : INTVAL (x) == 32 ? "l"
2818 /* Similar, except do it from the mask. */
2819 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2820 fprintf (file, "b");
2821 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2822 fprintf (file, "w");
2823 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2824 fprintf (file, "l");
2825 #if HOST_BITS_PER_WIDE_INT == 32
2826 else if (GET_CODE (x) == CONST_DOUBLE
2827 && CONST_DOUBLE_HIGH (x) == 0
2828 && CONST_DOUBLE_LOW (x) == -1)
2829 fprintf (file, "l");
2830 else if (GET_CODE (x) == CONST_DOUBLE
2831 && CONST_DOUBLE_HIGH (x) == -1
2832 && CONST_DOUBLE_LOW (x) == -1)
2833 fprintf (file, "q");
2835 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
2836 fprintf (file, "q");
2837 else if (GET_CODE (x) == CONST_DOUBLE
2838 && CONST_DOUBLE_HIGH (x) == 0
2839 && CONST_DOUBLE_LOW (x) == -1)
2840 fprintf (file, "q");
2843 output_operand_lossage ("invalid %%U value");
2847 /* Write the constant value divided by 8. */
2848 if (GET_CODE (x) != CONST_INT
2849 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2850 && (INTVAL (x) & 7) != 8)
2851 output_operand_lossage ("invalid %%s value");
2853 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2857 /* Same, except compute (64 - c) / 8 */
2859 if (GET_CODE (x) != CONST_INT
2860 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2861 && (INTVAL (x) & 7) != 8)
2862 output_operand_lossage ("invalid %%s value");
2864 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2867 case 'C': case 'D': case 'c': case 'd':
2868 /* Write out comparison name. */
2870 enum rtx_code c = GET_CODE (x);
2872 if (GET_RTX_CLASS (c) != '<')
2873 output_operand_lossage ("invalid %%C value");
2876 c = reverse_condition (c);
2877 else if (code == 'c')
2878 c = swap_condition (c);
2879 else if (code == 'd')
2880 c = swap_condition (reverse_condition (c));
2883 fprintf (file, "ule");
2885 fprintf (file, "ult");
2887 fprintf (file, "%s", GET_RTX_NAME (c));
2892 /* Write the divide or modulus operator. */
2893 switch (GET_CODE (x))
2896 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2899 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2902 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2905 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2908 output_operand_lossage ("invalid %%E value");
2914 /* Write "_u" for unaligned access. */
2915 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2916 fprintf (file, "_u");
2920 if (GET_CODE (x) == REG)
2921 fprintf (file, "%s", reg_names[REGNO (x)]);
2922 else if (GET_CODE (x) == MEM)
2923 output_address (XEXP (x, 0));
2925 output_addr_const (file, x);
2929 output_operand_lossage ("invalid %%xn code");
2933 /* Emit RTL insns to initialize the variable parts of a trampoline at
2934 TRAMP. FNADDR is an RTX for the address of the function's pure
2935 code. CXT is an RTX for the static chain value for the function.
2937 The three offset parameters are for the individual template's
2938 layout. A JMPOFS < 0 indicates that the trampoline does not
2939 contain instructions at all.
2941 We assume here that a function will be called many more times than
2942 its address is taken (e.g., it might be passed to qsort), so we
2943 take the trouble to initialize the "hint" field in the JMP insn.
2944 Note that the hint field is PC (new) + 4 * bits 13:0. */
2947 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2948 rtx tramp, fnaddr, cxt;
2949 int fnofs, cxtofs, jmpofs;
2951 rtx temp, temp1, addr;
2952 /* VMS really uses DImode pointers in memory at this point. */
2953 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2955 #ifdef POINTERS_EXTEND_UNSIGNED
2956 fnaddr = convert_memory_address (mode, fnaddr);
2957 cxt = convert_memory_address (mode, cxt);
2960 /* Store function address and CXT. */
2961 addr = memory_address (mode, plus_constant (tramp, fnofs));
2962 emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2963 addr = memory_address (mode, plus_constant (tramp, cxtofs));
2964 emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2966 /* This has been disabled since the hint only has a 32k range, and in
2967 no existing OS is the stack within 32k of the text segment. */
2968 if (0 && jmpofs >= 0)
2970 /* Compute hint value. */
2971 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
2972 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
2974 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
2975 build_int_2 (2, 0), NULL_RTX, 1);
2976 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
2978 /* Merge in the hint. */
2979 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
2980 temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
2981 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
2982 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
2984 emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
2987 #ifdef TRANSFER_FROM_TRAMPOLINE
2988 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
2989 0, VOIDmode, 1, addr, Pmode);
2993 emit_insn (gen_imb ());
2996 /* Do what is necessary for `va_start'. The argument is ignored;
2997 We look at the current function to determine if stdarg or varargs
2998 is used and fill in an initial va_list. A pointer to this constructor
3002 alpha_builtin_saveregs (arglist)
3003 tree arglist ATTRIBUTE_UNUSED;
3005 rtx block, addr, dest, argsize;
3006 tree fntype = TREE_TYPE (current_function_decl);
3007 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
3008 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3009 != void_type_node));
3011 /* Compute the current position into the args, taking into account
3012 both registers and memory. Both of these are already included in
3015 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
3017 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
3018 storing fp arg registers in the first 48 bytes, and the integer arg
3019 registers in the next 48 bytes. This is only done, however, if any
3020 integer registers need to be stored.
3022 If no integer registers need be stored, then we must subtract 48 in
3023 order to account for the integer arg registers which are counted in
3024 argsize above, but which are not actually stored on the stack. */
3026 if (TARGET_OPEN_VMS)
3027 addr = plus_constant (virtual_incoming_args_rtx,
3028 NUM_ARGS <= 5 + stdarg
3029 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
3031 addr = (NUM_ARGS <= 5 + stdarg
3032 ? plus_constant (virtual_incoming_args_rtx,
3034 : plus_constant (virtual_incoming_args_rtx,
3035 - (6 * UNITS_PER_WORD)));
3037 /* For VMS, we include the argsize, while on Unix, it's handled as
3038 a separate field. */
3039 if (TARGET_OPEN_VMS)
3040 addr = plus_constant (addr, INTVAL (argsize));
3042 addr = force_operand (addr, NULL_RTX);
3044 #ifdef POINTERS_EXTEND_UNSIGNED
3045 addr = convert_memory_address (ptr_mode, addr);
3048 if (TARGET_OPEN_VMS)
3052 /* Allocate the va_list constructor */
3053 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
3054 RTX_UNCHANGING_P (block) = 1;
3055 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
3057 /* Store the address of the first integer register in the __base
3060 dest = change_address (block, ptr_mode, XEXP (block, 0));
3061 emit_move_insn (dest, addr);
3063 if (current_function_check_memory_usage)
3064 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3066 GEN_INT (GET_MODE_SIZE (ptr_mode)),
3067 TYPE_MODE (sizetype),
3068 GEN_INT (MEMORY_USE_RW),
3069 TYPE_MODE (integer_type_node));
3071 /* Store the argsize as the __va_offset member. */
3072 dest = change_address (block, TYPE_MODE (integer_type_node),
3073 plus_constant (XEXP (block, 0),
3074 POINTER_SIZE/BITS_PER_UNIT));
3075 emit_move_insn (dest, argsize);
3077 if (current_function_check_memory_usage)
3078 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3080 GEN_INT (GET_MODE_SIZE
3081 (TYPE_MODE (integer_type_node))),
3082 TYPE_MODE (sizetype),
3083 GEN_INT (MEMORY_USE_RW),
3084 TYPE_MODE (integer_type_node));
3086 /* Return the address of the va_list constructor, but don't put it in a
3087 register. Doing so would fail when not optimizing and produce worse
3088 code when optimizing. */
3089 return XEXP (block, 0);
3093 /* This page contains routines that are used to determine what the function
3094 prologue and epilogue code will do and write them out. */
3096 /* Compute the size of the save area in the stack. */
3098 /* These variables are used for communication between the following functions.
3099 They indicate various things about the current function being compiled
3100 that are used to tell what kind of prologue, epilogue and procedure
3101 descriptior to generate. */
3103 /* Nonzero if we need a stack procedure. */
3104 static int vms_is_stack_procedure;
3106 /* Register number (either FP or SP) that is used to unwind the frame. */
3107 static int vms_unwind_regno;
3109 /* Register number used to save FP. We need not have one for RA since
3110 we don't modify it for register procedures. This is only defined
3111 for register frame procedures. */
3112 static int vms_save_fp_regno;
3114 /* Register number used to reference objects off our PV. */
3115 static int vms_base_regno;
3117 /* Compute register masks for saved registers. */
3120 alpha_sa_mask (imaskP, fmaskP)
3121 unsigned long *imaskP;
3122 unsigned long *fmaskP;
3124 unsigned long imask = 0;
3125 unsigned long fmask = 0;
3128 #ifdef ASM_OUTPUT_MI_THUNK
3129 if (!current_function_is_thunk)
3132 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3133 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3135 /* One for every register we have to save. */
3136 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3137 if (! fixed_regs[i] && ! call_used_regs[i]
3138 && regs_ever_live[i] && i != REG_RA)
3143 fmask |= (1L << (i - 32));
3146 if (imask || fmask || alpha_ra_ever_killed ())
3147 imask |= (1L << REG_RA);
3160 #ifdef ASM_OUTPUT_MI_THUNK
3161 if (current_function_is_thunk)
3166 /* One for every register we have to save. */
3167 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3168 if (! fixed_regs[i] && ! call_used_regs[i]
3169 && regs_ever_live[i] && i != REG_RA)
3173 if (TARGET_OPEN_VMS)
3175 /* Start by assuming we can use a register procedure if we don't
3176 make any calls (REG_RA not used) or need to save any
3177 registers and a stack procedure if we do. */
3178 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3180 /* Decide whether to refer to objects off our PV via FP or PV.
3181 If we need FP for something else or if we receive a nonlocal
3182 goto (which expects PV to contain the value), we must use PV.
3183 Otherwise, start by assuming we can use FP. */
3184 vms_base_regno = (frame_pointer_needed
3185 || current_function_has_nonlocal_label
3186 || vms_is_stack_procedure
3187 || current_function_outgoing_args_size
3188 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3190 /* If we want to copy PV into FP, we need to find some register
3191 in which to save FP. */
3193 vms_save_fp_regno = -1;
3194 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3195 for (i = 0; i < 32; i++)
3196 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3197 vms_save_fp_regno = i;
3199 if (vms_save_fp_regno == -1)
3200 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3202 /* Stack unwinding should be done via FP unless we use it for PV. */
3203 vms_unwind_regno = (vms_base_regno == REG_PV
3204 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3206 /* If this is a stack procedure, allow space for saving FP and RA. */
3207 if (vms_is_stack_procedure)
3212 /* If some registers were saved but not RA, RA must also be saved,
3213 so leave space for it. */
3214 if (sa_size != 0 || alpha_ra_ever_killed ())
3217 /* Our size must be even (multiple of 16 bytes). */
3226 alpha_pv_save_size ()
3229 return vms_is_stack_procedure ? 8 : 0;
3236 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3240 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3241 tree decl ATTRIBUTE_UNUSED;
3242 tree attributes ATTRIBUTE_UNUSED;
3246 if (is_attribute_p ("overlaid", identifier))
3247 return (args == NULL_TREE);
3252 alpha_does_function_need_gp ()
3256 /* We never need a GP for Windows/NT or VMS. */
3257 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3260 #ifdef TARGET_PROFILING_NEEDS_GP
3265 #ifdef ASM_OUTPUT_MI_THUNK
3266 if (current_function_is_thunk)
3270 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3271 Even if we are a static function, we still need to do this in case
3272 our address is taken and passed to something like qsort. */
3274 push_topmost_sequence ();
3275 insn = get_insns ();
3276 pop_topmost_sequence ();
3278 for (; insn; insn = NEXT_INSN (insn))
3279 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3280 && GET_CODE (PATTERN (insn)) != USE
3281 && GET_CODE (PATTERN (insn)) != CLOBBER)
3283 enum attr_type type = get_attr_type (insn);
3284 if (type == TYPE_LDSYM || type == TYPE_JSR)
3291 /* Write a version stamp. Don't write anything if we are running as a
3292 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3299 alpha_write_verstamp (file)
3303 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3307 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3311 set_frame_related_p ()
3313 rtx seq = gen_sequence ();
3316 if (GET_CODE (seq) == SEQUENCE)
3318 int i = XVECLEN (seq, 0);
3320 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3321 return emit_insn (seq);
3325 seq = emit_insn (seq);
3326 RTX_FRAME_RELATED_P (seq) = 1;
3331 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3333 /* Write function prologue. */
3335 /* On vms we have two kinds of functions:
3337 - stack frame (PROC_STACK)
3338 these are 'normal' functions with local vars and which are
3339 calling other functions
3340 - register frame (PROC_REGISTER)
3341 keeps all data in registers, needs no stack
3343 We must pass this to the assembler so it can generate the
3344 proper pdsc (procedure descriptor)
3345 This is done with the '.pdesc' command.
3347 On not-vms, we don't really differentiate between the two, as we can
3348 simply allocate stack without saving registers. */
3351 alpha_expand_prologue ()
3353 /* Registers to save. */
3354 unsigned long imask = 0;
3355 unsigned long fmask = 0;
3356 /* Stack space needed for pushing registers clobbered by us. */
3357 HOST_WIDE_INT sa_size;
3358 /* Complete stack size needed. */
3359 HOST_WIDE_INT frame_size;
3360 /* Offset from base reg to register save area. */
3361 HOST_WIDE_INT reg_offset;
3365 sa_size = alpha_sa_size ();
3367 frame_size = get_frame_size ();
3368 if (TARGET_OPEN_VMS)
3369 frame_size = ALPHA_ROUND (sa_size
3370 + (vms_is_stack_procedure ? 8 : 0)
3372 + current_function_pretend_args_size);
3374 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3376 + ALPHA_ROUND (frame_size
3377 + current_function_pretend_args_size));
3379 if (TARGET_OPEN_VMS)
3382 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3384 alpha_sa_mask (&imask, &fmask);
3386 /* Adjust the stack by the frame size. If the frame size is > 4096
3387 bytes, we need to be sure we probe somewhere in the first and last
3388 4096 bytes (we can probably get away without the latter test) and
3389 every 8192 bytes in between. If the frame size is > 32768, we
3390 do this in a loop. Otherwise, we generate the explicit probe
3393 Note that we are only allowed to adjust sp once in the prologue. */
3395 if (frame_size <= 32768)
3397 if (frame_size > 4096)
3402 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3403 while ((probed += 8192) < frame_size);
3405 /* We only have to do this probe if we aren't saving registers. */
3406 if (sa_size == 0 && probed + 4096 < frame_size)
3407 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3410 if (frame_size != 0)
3412 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
3413 GEN_INT (-frame_size))));
3418 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3419 number of 8192 byte blocks to probe. We then probe each block
3420 in the loop and then set SP to the proper location. If the
3421 amount remaining is > 4096, we have to do one more probe if we
3422 are not saving any registers. */
3424 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3425 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3426 rtx ptr = gen_rtx_REG (DImode, 22);
3427 rtx count = gen_rtx_REG (DImode, 23);
3430 emit_move_insn (count, GEN_INT (blocks));
3431 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
3433 /* Because of the difficulty in emitting a new basic block this
3434 late in the compilation, generate the loop as a single insn. */
3435 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3437 if (leftover > 4096 && sa_size == 0)
3439 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3440 MEM_VOLATILE_P (last) = 1;
3441 emit_move_insn (last, const0_rtx);
3444 if (TARGET_WINDOWS_NT)
3446 /* For NT stack unwind (done by 'reverse execution'), it's
3447 not OK to take the result of a loop, even though the value
3448 is already in ptr, so we reload it via a single operation
3449 and subtract it to sp.
3451 Yes, that's correct -- we have to reload the whole constant
3452 into a temporary via ldah+lda then subtract from sp. To
3453 ensure we get ldah+lda, we use a special pattern. */
3455 HOST_WIDE_INT lo, hi;
3456 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3457 hi = frame_size - lo;
3459 emit_move_insn (ptr, GEN_INT (hi));
3460 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
3461 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3466 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
3467 GEN_INT (-leftover)));
3470 /* This alternative is special, because the DWARF code cannot
3471 possibly intuit through the loop above. So we invent this
3472 note it looks at instead. */
3473 RTX_FRAME_RELATED_P (seq) = 1;
3475 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3476 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3477 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3478 GEN_INT (-frame_size))),
3482 /* Cope with very large offsets to the register save area. */
3483 sa_reg = stack_pointer_rtx;
3484 if (reg_offset + sa_size > 0x8000)
3486 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3489 if (low + sa_size <= 0x8000)
3490 bias = reg_offset - low, reg_offset = low;
3492 bias = reg_offset, reg_offset = 0;
3494 sa_reg = gen_rtx_REG (DImode, 24);
3495 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
3498 /* Save regs in stack order. Beginning with VMS PV. */
3499 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3501 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3502 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3503 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3506 /* Save register RA next. */
3507 if (imask & (1L << REG_RA))
3509 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3510 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3511 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3512 imask &= ~(1L << REG_RA);
3516 /* Now save any other registers required to be saved. */
3517 for (i = 0; i < 32; i++)
3518 if (imask & (1L << i))
3520 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3521 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3522 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3526 for (i = 0; i < 32; i++)
3527 if (fmask & (1L << i))
3529 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3530 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3531 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3535 if (TARGET_OPEN_VMS)
3537 if (!vms_is_stack_procedure)
3539 /* Register frame procedures fave the fp. */
3540 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3541 hard_frame_pointer_rtx));
3544 if (vms_base_regno != REG_PV)
3545 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3546 gen_rtx_REG (DImode, REG_PV)));
3548 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3550 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3553 /* If we have to allocate space for outgoing args, do it now. */
3554 if (current_function_outgoing_args_size != 0)
3556 FRP (emit_move_insn (stack_pointer_rtx,
3557 plus_constant (hard_frame_pointer_rtx,
3558 - ALPHA_ROUND (current_function_outgoing_args_size))));
3563 /* If we need a frame pointer, set it from the stack pointer. */
3564 if (frame_pointer_needed)
3566 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3567 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3570 /* This must always be the last instruction in the
3571 prologue, thus we emit a special move + clobber. */
3572 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3573 stack_pointer_rtx, sa_reg)));
3578 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3579 the prologue, for exception handling reasons, we cannot do this for
3580 any insn that might fault. We could prevent this for mems with a
3581 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3582 have to prevent all such scheduling with a blockage.
3584 Linux, on the other hand, never bothered to implement OSF/1's
3585 exception handling, and so doesn't care about such things. Anyone
3586 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3588 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3589 emit_insn (gen_blockage ());
3592 /* Output the textual info surrounding the prologue. */
3595 alpha_start_function (file, fnname, decl)
3598 tree decl ATTRIBUTE_UNUSED;
3600 unsigned long imask = 0;
3601 unsigned long fmask = 0;
3602 /* Stack space needed for pushing registers clobbered by us. */
3603 HOST_WIDE_INT sa_size;
3604 /* Complete stack size needed. */
3605 HOST_WIDE_INT frame_size;
3606 /* Offset from base reg to register save area. */
3607 HOST_WIDE_INT reg_offset;
3608 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3611 sa_size = alpha_sa_size ();
3613 frame_size = get_frame_size ();
3614 if (TARGET_OPEN_VMS)
3615 frame_size = ALPHA_ROUND (sa_size
3616 + (vms_is_stack_procedure ? 8 : 0)
3618 + current_function_pretend_args_size);
3620 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3622 + ALPHA_ROUND (frame_size
3623 + current_function_pretend_args_size));
3625 if (TARGET_OPEN_VMS)
3628 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3630 alpha_sa_mask (&imask, &fmask);
3632 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3633 We have to do that before the .ent directive as we cannot switch
3634 files within procedures with native ecoff because line numbers are
3635 linked to procedure descriptors.
3636 Outputting the lineno helps debugging of one line functions as they
3637 would otherwise get no line number at all. Please note that we would
3638 like to put out last_linenum from final.c, but it is not accessible. */
3640 if (write_symbols == SDB_DEBUG)
3642 ASM_OUTPUT_SOURCE_FILENAME (file,
3643 DECL_SOURCE_FILE (current_function_decl));
3644 if (debug_info_level != DINFO_LEVEL_TERSE)
3645 ASM_OUTPUT_SOURCE_LINE (file,
3646 DECL_SOURCE_LINE (current_function_decl));
3649 /* Issue function start and label. */
3650 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3652 fputs ("\t.ent ", file);
3653 assemble_name (file, fnname);
3657 strcpy (entry_label, fnname);
3658 if (TARGET_OPEN_VMS)
3659 strcat (entry_label, "..en");
3660 ASM_OUTPUT_LABEL (file, entry_label);
3661 inside_function = TRUE;
3663 if (TARGET_OPEN_VMS)
3664 fprintf (file, "\t.base $%d\n", vms_base_regno);
3666 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3667 && !flag_inhibit_size_directive)
3669 /* Set flags in procedure descriptor to request IEEE-conformant
3670 math-library routines. The value we set it to is PDSC_EXC_IEEE
3671 (/usr/include/pdsc.h). */
3672 fputs ("\t.eflag 48\n", file);
3675 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3676 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3677 alpha_arg_offset = -frame_size + 48;
3679 /* Describe our frame. If the frame size is larger than an integer,
3680 print it as zero to avoid an assembler error. We won't be
3681 properly describing such a frame, but that's the best we can do. */
3682 if (TARGET_OPEN_VMS)
3684 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3685 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3686 frame_size >= (1l << 31) ? 0 : frame_size);
3687 fputs (",$26,", file);
3688 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3691 else if (!flag_inhibit_size_directive)
3693 fprintf (file, "\t.frame $%d,",
3694 (frame_pointer_needed
3695 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3696 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3697 frame_size >= (1l << 31) ? 0 : frame_size);
3698 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3701 /* Describe which registers were spilled. */
3702 if (TARGET_OPEN_VMS)
3705 /* ??? Does VMS care if mask contains ra? The old code did'nt
3706 set it, so I don't here. */
3707 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3709 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3710 if (!vms_is_stack_procedure)
3711 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3713 else if (!flag_inhibit_size_directive)
3717 fprintf (file, "\t.mask 0x%lx,", imask);
3718 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3719 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3722 for (i = 0; i < 32; ++i)
3723 if (imask & (1L << i))
3729 fprintf (file, "\t.fmask 0x%lx,", fmask);
3730 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3731 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3736 /* Emit GP related things. It is rather unfortunate about the alignment
3737 issues surrounding a CODE_LABEL that forces us to do the label in
3739 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3741 alpha_function_needs_gp = alpha_does_function_need_gp ();
3742 if (alpha_function_needs_gp)
3743 fputs ("\tldgp $29,0($27)\n", file);
3746 assemble_name (file, fnname);
3747 fputs ("..ng:\n", file);
3751 /* Ifdef'ed cause readonly_section and link_section are only
3753 readonly_section ();
3754 fprintf (file, "\t.align 3\n");
3755 assemble_name (file, fnname); fputs ("..na:\n", file);
3756 fputs ("\t.ascii \"", file);
3757 assemble_name (file, fnname);
3758 fputs ("\\0\"\n", file);
3761 fprintf (file, "\t.align 3\n");
3762 fputs ("\t.name ", file);
3763 assemble_name (file, fnname);
3764 fputs ("..na\n", file);
3765 ASM_OUTPUT_LABEL (file, fnname);
3766 fprintf (file, "\t.pdesc ");
3767 assemble_name (file, fnname);
3768 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3769 alpha_need_linkage (fnname, 1);
3774 /* Emit the .prologue note at the scheduled end of the prologue. */
3777 output_end_prologue (file)
3780 if (TARGET_OPEN_VMS)
3781 fputs ("\t.prologue\n", file);
3782 else if (TARGET_WINDOWS_NT)
3783 fputs ("\t.prologue 0\n", file);
3784 else if (!flag_inhibit_size_directive)
3785 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3788 /* Write function epilogue. */
3790 /* ??? At some point we will want to support full unwind, and so will
3791 need to mark the epilogue as well. At the moment, we just confuse
3794 #define FRP(exp) exp
3797 alpha_expand_epilogue ()
3799 /* Registers to save. */
3800 unsigned long imask = 0;
3801 unsigned long fmask = 0;
3802 /* Stack space needed for pushing registers clobbered by us. */
3803 HOST_WIDE_INT sa_size;
3804 /* Complete stack size needed. */
3805 HOST_WIDE_INT frame_size;
3806 /* Offset from base reg to register save area. */
3807 HOST_WIDE_INT reg_offset;
3808 int fp_is_frame_pointer, fp_offset;
3809 rtx sa_reg, sa_reg_exp = NULL;
3810 rtx sp_adj1, sp_adj2, mem;
3813 sa_size = alpha_sa_size ();
3815 frame_size = get_frame_size ();
3816 if (TARGET_OPEN_VMS)
3817 frame_size = ALPHA_ROUND (sa_size
3818 + (vms_is_stack_procedure ? 8 : 0)
3820 + current_function_pretend_args_size);
3822 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3824 + ALPHA_ROUND (frame_size
3825 + current_function_pretend_args_size));
3827 if (TARGET_OPEN_VMS)
3830 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3832 alpha_sa_mask (&imask, &fmask);
3834 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3835 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3839 /* If we have a frame pointer, restore SP from it. */
3840 if ((TARGET_OPEN_VMS
3841 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3842 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3844 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
3847 /* Cope with very large offsets to the register save area. */
3848 sa_reg = stack_pointer_rtx;
3849 if (reg_offset + sa_size > 0x8000)
3851 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3854 if (low + sa_size <= 0x8000)
3855 bias = reg_offset - low, reg_offset = low;
3857 bias = reg_offset, reg_offset = 0;
3859 sa_reg = gen_rtx_REG (DImode, 22);
3860 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3862 FRP (emit_move_insn (sa_reg, sa_reg_exp));
3865 /* Restore registers in order, excepting a true frame pointer. */
3867 if (! alpha_eh_epilogue_sp_ofs)
3869 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3870 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3871 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
3874 imask &= ~(1L << REG_RA);
3876 for (i = 0; i < 32; ++i)
3877 if (imask & (1L << i))
3879 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3880 fp_offset = reg_offset;
3883 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3884 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3885 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
3890 for (i = 0; i < 32; ++i)
3891 if (fmask & (1L << i))
3893 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
3894 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3895 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
3900 if (frame_size || alpha_eh_epilogue_sp_ofs)
3902 sp_adj1 = stack_pointer_rtx;
3904 if (alpha_eh_epilogue_sp_ofs)
3906 sp_adj1 = gen_rtx_REG (DImode, 23);
3907 emit_move_insn (sp_adj1,
3908 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3909 alpha_eh_epilogue_sp_ofs));
3912 /* If the stack size is large, begin computation into a temporary
3913 register so as not to interfere with a potential fp restore,
3914 which must be consecutive with an SP restore. */
3915 if (frame_size < 32768)
3916 sp_adj2 = GEN_INT (frame_size);
3917 else if (frame_size < 0x40007fffL)
3919 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3921 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
3922 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3926 sp_adj1 = gen_rtx_REG (DImode, 23);
3927 FRP (emit_move_insn (sp_adj1, sp_adj2));
3929 sp_adj2 = GEN_INT (low);
3933 rtx tmp = gen_rtx_REG (DImode, 23);
3934 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
3937 /* We can't drop new things to memory this late, afaik,
3938 so build it up by pieces. */
3939 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
3940 -(frame_size < 0)));
3946 /* From now on, things must be in order. So emit blockages. */
3948 /* Restore the frame pointer. */
3949 if (fp_is_frame_pointer)
3951 emit_insn (gen_blockage ());
3952 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
3953 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3954 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
3956 else if (TARGET_OPEN_VMS)
3958 emit_insn (gen_blockage ());
3959 FRP (emit_move_insn (hard_frame_pointer_rtx,
3960 gen_rtx_REG (DImode, vms_save_fp_regno)));
3963 /* Restore the stack pointer. */
3964 emit_insn (gen_blockage ());
3965 FRP (emit_move_insn (stack_pointer_rtx,
3966 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
3970 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
3972 emit_insn (gen_blockage ());
3973 FRP (emit_move_insn (hard_frame_pointer_rtx,
3974 gen_rtx_REG (DImode, vms_save_fp_regno)));
3979 emit_jump_insn (gen_return_internal ());
3982 /* Output the rest of the textual info surrounding the epilogue. */
3985 alpha_end_function (file, fnname, decl)
3988 tree decl ATTRIBUTE_UNUSED;
3990 /* End the function. */
3991 if (!flag_inhibit_size_directive)
3993 fputs ("\t.end ", file);
3994 assemble_name (file, fnname);
3997 inside_function = FALSE;
3999 /* Show that we know this function if it is called again.
4001 Don't do this for global functions in object files destined for a
4002 shared library because the function may be overridden by the application
4003 or other libraries. Similarly, don't do this for weak functions. */
4005 if (!DECL_WEAK (current_function_decl)
4006 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4007 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4010 /* Debugging support. */
4014 /* Count the number of sdb related labels are generated (to find block
4015 start and end boundaries). */
4017 int sdb_label_count = 0;
4019 /* Next label # for each statement. */
4021 static int sym_lineno = 0;
4023 /* Count the number of .file directives, so that .loc is up to date. */
4025 static int num_source_filenames = 0;
4027 /* Name of the file containing the current function. */
4029 static const char *current_function_file = "";
4031 /* Offsets to alpha virtual arg/local debugging pointers. */
4033 long alpha_arg_offset;
4034 long alpha_auto_offset;
4036 /* Emit a new filename to a stream. */
4039 alpha_output_filename (stream, name)
4043 static int first_time = TRUE;
4044 char ltext_label_name[100];
4049 ++num_source_filenames;
4050 current_function_file = name;
4051 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4052 output_quoted_string (stream, name);
4053 fprintf (stream, "\n");
4054 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4055 fprintf (stream, "\t#@stabs\n");
4058 else if (write_symbols == DBX_DEBUG)
4060 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4061 fprintf (stream, "%s ", ASM_STABS_OP);
4062 output_quoted_string (stream, name);
4063 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
4066 else if (name != current_function_file
4067 && strcmp (name, current_function_file) != 0)
4069 if (inside_function && ! TARGET_GAS)
4070 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4073 ++num_source_filenames;
4074 current_function_file = name;
4075 fprintf (stream, "\t.file\t%d ", num_source_filenames);
4078 output_quoted_string (stream, name);
4079 fprintf (stream, "\n");
4083 /* Emit a linenumber to a stream. */
4086 alpha_output_lineno (stream, line)
4090 if (write_symbols == DBX_DEBUG)
4092 /* mips-tfile doesn't understand .stabd directives. */
4094 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4095 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4098 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4101 /* Structure to show the current status of registers and memory. */
4103 struct shadow_summary
4106 unsigned long i : 31; /* Mask of int regs */
4107 unsigned long fp : 31; /* Mask of fp regs */
4108 unsigned long mem : 1; /* mem == imem | fpmem */
4112 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
4113 static void alpha_handle_trap_shadows PROTO((rtx));
4115 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4116 to the summary structure. SET is nonzero if the insn is setting the
4117 object, otherwise zero. */
4120 summarize_insn (x, sum, set)
4122 struct shadow_summary *sum;
4131 switch (GET_CODE (x))
4133 /* ??? Note that this case would be incorrect if the Alpha had a
4134 ZERO_EXTRACT in SET_DEST. */
4136 summarize_insn (SET_SRC (x), sum, 0);
4137 summarize_insn (SET_DEST (x), sum, 1);
4141 summarize_insn (XEXP (x, 0), sum, 1);
4145 summarize_insn (XEXP (x, 0), sum, 0);
4149 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4150 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4154 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4155 summarize_insn (XVECEXP (x, 0, i), sum, 0);
4159 summarize_insn (SUBREG_REG (x), sum, 0);
4164 int regno = REGNO (x);
4165 unsigned long mask = 1UL << (regno % 32);
4167 if (regno == 31 || regno == 63)
4173 sum->defd.i |= mask;
4175 sum->defd.fp |= mask;
4180 sum->used.i |= mask;
4182 sum->used.fp |= mask;
4193 /* Find the regs used in memory address computation: */
4194 summarize_insn (XEXP (x, 0), sum, 0);
4197 case CONST_INT: case CONST_DOUBLE:
4198 case SYMBOL_REF: case LABEL_REF: case CONST:
4201 /* Handle common unary and binary ops for efficiency. */
4202 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4203 case MOD: case UDIV: case UMOD: case AND: case IOR:
4204 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4205 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4206 case NE: case EQ: case GE: case GT: case LE:
4207 case LT: case GEU: case GTU: case LEU: case LTU:
4208 summarize_insn (XEXP (x, 0), sum, 0);
4209 summarize_insn (XEXP (x, 1), sum, 0);
4212 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4213 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4214 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4215 case SQRT: case FFS:
4216 summarize_insn (XEXP (x, 0), sum, 0);
4220 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4221 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4222 switch (format_ptr[i])
4225 summarize_insn (XEXP (x, i), sum, 0);
4229 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4230 summarize_insn (XVECEXP (x, i, j), sum, 0);
4242 /* Ensure a sufficient number of `trapb' insns are in the code when
4243 the user requests code with a trap precision of functions or
4246 In naive mode, when the user requests a trap-precision of
4247 "instruction", a trapb is needed after every instruction that may
4248 generate a trap. This ensures that the code is resumption safe but
4251 When optimizations are turned on, we delay issuing a trapb as long
4252 as possible. In this context, a trap shadow is the sequence of
4253 instructions that starts with a (potentially) trap generating
4254 instruction and extends to the next trapb or call_pal instruction
4255 (but GCC never generates call_pal by itself). We can delay (and
4256 therefore sometimes omit) a trapb subject to the following
4259 (a) On entry to the trap shadow, if any Alpha register or memory
4260 location contains a value that is used as an operand value by some
4261 instruction in the trap shadow (live on entry), then no instruction
4262 in the trap shadow may modify the register or memory location.
4264 (b) Within the trap shadow, the computation of the base register
4265 for a memory load or store instruction may not involve using the
4266 result of an instruction that might generate an UNPREDICTABLE
4269 (c) Within the trap shadow, no register may be used more than once
4270 as a destination register. (This is to make life easier for the
4273 (d) The trap shadow may not include any branch instructions. */
4276 alpha_handle_trap_shadows (insns)
4279 struct shadow_summary shadow;
4280 int trap_pending, exception_nesting;
4284 exception_nesting = 0;
4287 shadow.used.mem = 0;
4288 shadow.defd = shadow.used;
4290 for (i = insns; i ; i = NEXT_INSN (i))
4292 if (GET_CODE (i) == NOTE)
4294 switch (NOTE_LINE_NUMBER (i))
4296 case NOTE_INSN_EH_REGION_BEG:
4297 exception_nesting++;
4302 case NOTE_INSN_EH_REGION_END:
4303 exception_nesting--;
4308 case NOTE_INSN_EPILOGUE_BEG:
4309 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4314 else if (trap_pending)
4316 if (alpha_tp == ALPHA_TP_FUNC)
4318 if (GET_CODE (i) == JUMP_INSN
4319 && GET_CODE (PATTERN (i)) == RETURN)
4322 else if (alpha_tp == ALPHA_TP_INSN)
4326 struct shadow_summary sum;
4331 sum.defd = sum.used;
4333 switch (GET_CODE (i))
4336 /* Annoyingly, get_attr_trap will abort on these. */
4337 if (GET_CODE (PATTERN (i)) == USE
4338 || GET_CODE (PATTERN (i)) == CLOBBER)
4341 summarize_insn (PATTERN (i), &sum, 0);
4343 if ((sum.defd.i & shadow.defd.i)
4344 || (sum.defd.fp & shadow.defd.fp))
4346 /* (c) would be violated */
4350 /* Combine shadow with summary of current insn: */
4351 shadow.used.i |= sum.used.i;
4352 shadow.used.fp |= sum.used.fp;
4353 shadow.used.mem |= sum.used.mem;
4354 shadow.defd.i |= sum.defd.i;
4355 shadow.defd.fp |= sum.defd.fp;
4356 shadow.defd.mem |= sum.defd.mem;
4358 if ((sum.defd.i & shadow.used.i)
4359 || (sum.defd.fp & shadow.used.fp)
4360 || (sum.defd.mem & shadow.used.mem))
4362 /* (a) would be violated (also takes care of (b)) */
4363 if (get_attr_trap (i) == TRAP_YES
4364 && ((sum.defd.i & sum.used.i)
4365 || (sum.defd.fp & sum.used.fp)))
4384 n = emit_insn_before (gen_trapb (), i);
4385 PUT_MODE (n, TImode);
4386 PUT_MODE (i, TImode);
4390 shadow.used.mem = 0;
4391 shadow.defd = shadow.used;
4396 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4397 && GET_CODE (i) == INSN
4398 && GET_CODE (PATTERN (i)) != USE
4399 && GET_CODE (PATTERN (i)) != CLOBBER
4400 && get_attr_trap (i) == TRAP_YES)
4402 if (optimize && !trap_pending)
4403 summarize_insn (PATTERN (i), &shadow, 0);
4410 /* Alpha can only issue instruction groups simultaneously if they are
4411 suitibly aligned. This is very processor-specific. */
4413 enum alphaev4_pipe {
4420 enum alphaev5_pipe {
4431 static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx));
4432 static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx));
4433 static rtx alphaev4_next_group PROTO((rtx, int*, int*));
4434 static rtx alphaev5_next_group PROTO((rtx, int*, int*));
4435 static rtx alphaev4_next_nop PROTO((int*));
4436 static rtx alphaev5_next_nop PROTO((int*));
4438 static void alpha_align_insns
4439 PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4441 static enum alphaev4_pipe
4442 alphaev4_insn_pipe (insn)
4445 if (recog_memoized (insn) < 0)
4447 if (get_attr_length (insn) != 4)
4450 switch (get_attr_type (insn))
4483 static enum alphaev5_pipe
4484 alphaev5_insn_pipe (insn)
4487 if (recog_memoized (insn) < 0)
4489 if (get_attr_length (insn) != 4)
4492 switch (get_attr_type (insn))
4532 /* IN_USE is a mask of the slots currently filled within the insn group.
4533 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4534 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4536 LEN is, of course, the length of the group in bytes. */
4539 alphaev4_next_group (insn, pin_use, plen)
4541 int *pin_use, *plen;
4547 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4548 || GET_CODE (PATTERN (insn)) == CLOBBER
4549 || GET_CODE (PATTERN (insn)) == USE)
4554 enum alphaev4_pipe pipe;
4556 pipe = alphaev4_insn_pipe (insn);
4560 /* Force complex instructions to start new groups. */
4564 /* If this is a completely unrecognized insn, its an asm.
4565 We don't know how long it is, so record length as -1 to
4566 signal a needed realignment. */
4567 if (recog_memoized (insn) < 0)
4570 len = get_attr_length (insn);
4574 if (in_use & EV4_IB0)
4576 if (in_use & EV4_IB1)
4581 in_use |= EV4_IB0 | EV4_IBX;
4585 if (in_use & EV4_IB0)
4587 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4595 if (in_use & EV4_IB1)
4605 /* Haifa doesn't do well scheduling branches. */
4606 if (GET_CODE (insn) == JUMP_INSN)
4610 insn = next_nonnote_insn (insn);
4612 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4615 /* Let Haifa tell us where it thinks insn group boundaries are. */
4616 if (GET_MODE (insn) == TImode)
4619 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4624 insn = next_nonnote_insn (insn);
4632 /* IN_USE is a mask of the slots currently filled within the insn group.
4633 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4634 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4636 LEN is, of course, the length of the group in bytes. */
4639 alphaev5_next_group (insn, pin_use, plen)
4641 int *pin_use, *plen;
4647 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4648 || GET_CODE (PATTERN (insn)) == CLOBBER
4649 || GET_CODE (PATTERN (insn)) == USE)
4654 enum alphaev5_pipe pipe;
4656 pipe = alphaev5_insn_pipe (insn);
4660 /* Force complex instructions to start new groups. */
4664 /* If this is a completely unrecognized insn, its an asm.
4665 We don't know how long it is, so record length as -1 to
4666 signal a needed realignment. */
4667 if (recog_memoized (insn) < 0)
4670 len = get_attr_length (insn);
4673 /* ??? Most of the places below, we would like to abort, as
4674 it would indicate an error either in Haifa, or in the
4675 scheduling description. Unfortunately, Haifa never
4676 schedules the last instruction of the BB, so we don't
4677 have an accurate TI bit to go off. */
4679 if (in_use & EV5_E0)
4681 if (in_use & EV5_E1)
4686 in_use |= EV5_E0 | EV5_E01;
4690 if (in_use & EV5_E0)
4692 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4700 if (in_use & EV5_E1)
4706 if (in_use & EV5_FA)
4708 if (in_use & EV5_FM)
4713 in_use |= EV5_FA | EV5_FAM;
4717 if (in_use & EV5_FA)
4723 if (in_use & EV5_FM)
4736 /* Haifa doesn't do well scheduling branches. */
4737 /* ??? If this is predicted not-taken, slotting continues, except
4738 that no more IBR, FBR, or JSR insns may be slotted. */
4739 if (GET_CODE (insn) == JUMP_INSN)
4743 insn = next_nonnote_insn (insn);
4745 if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4748 /* Let Haifa tell us where it thinks insn group boundaries are. */
4749 if (GET_MODE (insn) == TImode)
4752 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4757 insn = next_nonnote_insn (insn);
4766 alphaev4_next_nop (pin_use)
4769 int in_use = *pin_use;
4772 if (!(in_use & EV4_IB0))
4777 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
4782 else if (TARGET_FP && !(in_use & EV4_IB1))
4795 alphaev5_next_nop (pin_use)
4798 int in_use = *pin_use;
4801 if (!(in_use & EV5_E1))
4806 else if (TARGET_FP && !(in_use & EV5_FA))
4811 else if (TARGET_FP && !(in_use & EV5_FM))
4823 /* The instruction group alignment main loop. */
4826 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
4829 rtx (*next_group) PROTO((rtx, int*, int*));
4830 rtx (*next_nop) PROTO((int*));
4833 /* ALIGN is the known alignment for the insn group. */
4835 /* OFS is the offset of the current insn in the insn group. */
4837 int prev_in_use, in_use, len;
4840 /* Let shorten branches care for assigning alignments to code labels. */
4841 shorten_branches (insns);
4843 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
4844 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
4846 /* Account for the initial GP load, which happens before the scheduled
4847 prologue we emitted as RTL. */
4848 ofs = prev_in_use = 0;
4849 if (alpha_does_function_need_gp())
4851 ofs = 8 & (align - 1);
4852 prev_in_use = gp_in_use;
4856 if (GET_CODE (i) == NOTE)
4857 i = next_nonnote_insn (i);
4861 next = (*next_group)(i, &in_use, &len);
4863 /* When we see a label, resync alignment etc. */
4864 if (GET_CODE (i) == CODE_LABEL)
4866 int new_align = 1 << label_to_alignment (i);
4867 if (new_align >= align)
4869 align = new_align < max_align ? new_align : max_align;
4872 else if (ofs & (new_align-1))
4873 ofs = (ofs | (new_align-1)) + 1;
4878 /* Handle complex instructions special. */
4879 else if (in_use == 0)
4881 /* Asms will have length < 0. This is a signal that we have
4882 lost alignment knowledge. Assume, however, that the asm
4883 will not mis-align instructions. */
4892 /* If the known alignment is smaller than the recognized insn group,
4893 realign the output. */
4894 else if (align < len)
4896 int new_log_align = len > 8 ? 4 : 3;
4899 where = prev_nonnote_insn (i);
4900 if (!where || GET_CODE (where) != CODE_LABEL)
4903 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4904 align = 1 << new_log_align;
4908 /* If the group won't fit in the same INT16 as the previous,
4909 we need to add padding to keep the group together. Rather
4910 than simply leaving the insn filling to the assembler, we
4911 can make use of the knowledge of what sorts of instructions
4912 were issued in the previous group to make sure that all of
4913 the added nops are really free. */
4914 else if (ofs + len > align)
4916 int nop_count = (align - ofs) / 4;
4919 /* Insert nops before labels and branches to truely merge the
4920 execution of the nops with the previous instruction group. */
4921 where = prev_nonnote_insn (i);
4924 if (GET_CODE (where) == CODE_LABEL)
4926 rtx where2 = prev_nonnote_insn (where);
4927 if (where2 && GET_CODE (where2) == JUMP_INSN)
4930 else if (GET_CODE (where) != JUMP_INSN)
4937 emit_insn_before ((*next_nop)(&prev_in_use), where);
4938 while (--nop_count);
4942 ofs = (ofs + len) & (align - 1);
4943 prev_in_use = in_use;
4949 /* Machine dependant reorg pass. */
4955 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4956 alpha_handle_trap_shadows (insns);
4959 /* Due to the number of extra trapb insns, don't bother fixing up
4960 alignment when trap precision is instruction. Moreover, we can
4961 only do our job when sched2 is run and Haifa is our scheduler. */
4962 if (optimize && !optimize_size
4963 && alpha_tp != ALPHA_TP_INSN
4964 && flag_schedule_insns_after_reload)
4966 if (alpha_cpu == PROCESSOR_EV4)
4967 alpha_align_insns (insns, 8, alphaev4_next_group,
4968 alphaev4_next_nop, EV4_IB0);
4969 else if (alpha_cpu == PROCESSOR_EV5)
4970 alpha_align_insns (insns, 16, alphaev5_next_group,
4971 alphaev5_next_nop, EV5_E01 | EV5_E0);
4977 /* Check a floating-point value for validity for a particular machine mode. */
4979 static char * const float_strings[] =
4981 /* These are for FLOAT_VAX. */
4982 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4983 "-1.70141173319264430e+38",
4984 "2.93873587705571877e-39", /* 2^-128 */
4985 "-2.93873587705571877e-39",
4986 /* These are for the default broken IEEE mode, which traps
4987 on infinity or denormal numbers. */
4988 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4989 "-3.402823466385288598117e+38",
4990 "1.1754943508222875079687e-38", /* 2^-126 */
4991 "-1.1754943508222875079687e-38",
4994 static REAL_VALUE_TYPE float_values[8];
4995 static int inited_float_values = 0;
4998 check_float_value (mode, d, overflow)
4999 enum machine_mode mode;
5001 int overflow ATTRIBUTE_UNUSED;
5004 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5007 if (inited_float_values == 0)
5010 for (i = 0; i < 8; i++)
5011 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5013 inited_float_values = 1;
5019 REAL_VALUE_TYPE *fvptr;
5021 if (TARGET_FLOAT_VAX)
5022 fvptr = &float_values[0];
5024 fvptr = &float_values[4];
5026 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5027 if (REAL_VALUES_LESS (fvptr[0], r))
5029 bcopy ((char *) &fvptr[0], (char *) d,
5030 sizeof (REAL_VALUE_TYPE));
5033 else if (REAL_VALUES_LESS (r, fvptr[1]))
5035 bcopy ((char *) &fvptr[1], (char *) d,
5036 sizeof (REAL_VALUE_TYPE));
5039 else if (REAL_VALUES_LESS (dconst0, r)
5040 && REAL_VALUES_LESS (r, fvptr[2]))
5042 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5045 else if (REAL_VALUES_LESS (r, dconst0)
5046 && REAL_VALUES_LESS (fvptr[3], r))
5048 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5058 /* Return the VMS argument type corresponding to MODE. */
5061 alpha_arg_type (mode)
5062 enum machine_mode mode;
5067 return TARGET_FLOAT_VAX ? FF : FS;
5069 return TARGET_FLOAT_VAX ? FD : FT;
5075 /* Return an rtx for an integer representing the VMS Argument Information
5079 alpha_arg_info_reg_val (cum)
5080 CUMULATIVE_ARGS cum;
5082 unsigned HOST_WIDE_INT regval = cum.num_args;
5085 for (i = 0; i < 6; i++)
5086 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5088 return GEN_INT (regval);
5091 /* Structure to collect function names for final output
5094 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5097 struct alpha_links {
5098 struct alpha_links *next;
5100 enum links_kind kind;
5103 static struct alpha_links *alpha_links_base = 0;
5105 /* Make (or fake) .linkage entry for function call.
5107 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5110 alpha_need_linkage (name, is_local)
5115 struct alpha_links *lptr, *nptr;
5120 /* Is this name already defined ? */
5122 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5123 if (strcmp (lptr->name, name) == 0)
5127 /* Defined here but external assumed. */
5128 if (lptr->kind == KIND_EXTERN)
5129 lptr->kind = KIND_LOCAL;
5133 /* Used here but unused assumed. */
5134 if (lptr->kind == KIND_UNUSED)
5135 lptr->kind = KIND_LOCAL;
5140 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5141 nptr->next = alpha_links_base;
5142 nptr->name = xstrdup (name);
5144 /* Assume external if no definition. */
5145 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5147 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5148 get_identifier (name);
5150 alpha_links_base = nptr;
5157 alpha_write_linkage (stream)
5160 struct alpha_links *lptr, *nptr;
5162 readonly_section ();
5164 fprintf (stream, "\t.align 3\n");
5166 for (lptr = alpha_links_base; lptr; lptr = nptr)
5170 if (lptr->kind == KIND_UNUSED
5171 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5174 fprintf (stream, "$%s..lk:\n", lptr->name);
5175 if (lptr->kind == KIND_LOCAL)
5177 /* Local and used, build linkage pair. */
5178 fprintf (stream, "\t.quad %s..en\n", lptr->name);
5179 fprintf (stream, "\t.quad %s\n", lptr->name);
5182 /* External and used, request linkage pair. */
5183 fprintf (stream, "\t.linkage %s\n", lptr->name);
5190 alpha_need_linkage (name, is_local)
5191 char *name ATTRIBUTE_UNUSED;
5192 int is_local ATTRIBUTE_UNUSED;
5196 #endif /* OPEN_VMS */