1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
48 extern int rtx_equal_function_value_matters;
50 /* Specify which cpu to schedule for. */
52 enum processor_type alpha_cpu;
53 static const char * const alpha_cpu_name[] =
58 /* Specify how accurate floating-point traps need to be. */
60 enum alpha_trap_precision alpha_tp;
62 /* Specify the floating-point rounding mode. */
64 enum alpha_fp_rounding_mode alpha_fprm;
66 /* Specify which things cause traps. */
68 enum alpha_fp_trap_mode alpha_fptm;
70 /* Strings decoded into the above options. */
72 const char *alpha_cpu_string; /* -mcpu= */
73 const char *alpha_tune_string; /* -mtune= */
74 const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
75 const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
76 const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
77 const char *alpha_mlat_string; /* -mmemory-latency= */
79 /* Save information from a "cmpxx" operation until the branch or scc is
82 struct alpha_compare alpha_compare;
84 /* Non-zero if inside of a function, because the Alpha asm can't
85 handle .files inside of functions. */
87 static int inside_function = FALSE;
89 /* The number of cycles of latency we should assume on memory reads. */
91 int alpha_memory_latency = 3;
93 /* Whether the function needs the GP. */
95 static int alpha_function_needs_gp;
97 /* The alias set for prologue/epilogue register save/restore. */
99 static int alpha_sr_alias_set;
101 /* The assembler name of the current function. */
103 static const char *alpha_fnname;
105 /* Declarations of static functions. */
106 static void alpha_set_memflags_1
107 PARAMS ((rtx, int, int, int));
108 static rtx alpha_emit_set_const_1
109 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
110 static void alpha_expand_unaligned_load_words
111 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
112 static void alpha_expand_unaligned_store_words
113 PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
114 static void alpha_sa_mask
115 PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
116 static int alpha_does_function_need_gp
118 static void alpha_init_machine_status
119 PARAMS ((struct function *p));
120 static void alpha_mark_machine_status
121 PARAMS ((struct function *p));
122 static void alpha_free_machine_status
123 PARAMS ((struct function *p));
124 static int alpha_ra_ever_killed
126 static rtx set_frame_related_p
128 static const char *alpha_lookup_xfloating_lib_func
129 PARAMS ((enum rtx_code));
130 static int alpha_compute_xfloating_mode_arg
131 PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
132 static void alpha_emit_xfloating_libcall
133 PARAMS ((const char *, rtx, rtx[], int, rtx));
134 static rtx alpha_emit_xfloating_compare
135 PARAMS ((enum rtx_code, rtx, rtx));
137 /* Get the number of args of a function in one of two ways. */
139 #define NUM_ARGS current_function_args_info.num_args
141 #define NUM_ARGS current_function_args_info
147 /* Parse target option strings. */
153 static struct cpu_table {
155 enum processor_type processor;
158 #define EV5_MASK (MASK_CPU_EV5)
159 #define EV6_MASK (MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX)
160 { "ev4", PROCESSOR_EV4, 0 },
161 { "ev45", PROCESSOR_EV4, 0 },
162 { "21064", PROCESSOR_EV4, 0 },
163 { "ev5", PROCESSOR_EV5, EV5_MASK },
164 { "21164", PROCESSOR_EV5, EV5_MASK },
165 { "ev56", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
166 { "21164a", PROCESSOR_EV5, EV5_MASK|MASK_BWX },
167 { "pca56", PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
168 { "21164PC",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
169 { "21164pc",PROCESSOR_EV5, EV5_MASK|MASK_BWX|MASK_MAX },
170 { "ev6", PROCESSOR_EV6, EV6_MASK },
171 { "21264", PROCESSOR_EV6, EV6_MASK },
172 { "ev67", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
173 { "21264a", PROCESSOR_EV6, EV6_MASK|MASK_CIX },
177 alpha_tp = ALPHA_TP_PROG;
178 alpha_fprm = ALPHA_FPRM_NORM;
179 alpha_fptm = ALPHA_FPTM_N;
183 alpha_tp = ALPHA_TP_INSN;
184 alpha_fptm = ALPHA_FPTM_SU;
187 if (TARGET_IEEE_WITH_INEXACT)
189 alpha_tp = ALPHA_TP_INSN;
190 alpha_fptm = ALPHA_FPTM_SUI;
195 if (! strcmp (alpha_tp_string, "p"))
196 alpha_tp = ALPHA_TP_PROG;
197 else if (! strcmp (alpha_tp_string, "f"))
198 alpha_tp = ALPHA_TP_FUNC;
199 else if (! strcmp (alpha_tp_string, "i"))
200 alpha_tp = ALPHA_TP_INSN;
202 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
205 if (alpha_fprm_string)
207 if (! strcmp (alpha_fprm_string, "n"))
208 alpha_fprm = ALPHA_FPRM_NORM;
209 else if (! strcmp (alpha_fprm_string, "m"))
210 alpha_fprm = ALPHA_FPRM_MINF;
211 else if (! strcmp (alpha_fprm_string, "c"))
212 alpha_fprm = ALPHA_FPRM_CHOP;
213 else if (! strcmp (alpha_fprm_string,"d"))
214 alpha_fprm = ALPHA_FPRM_DYN;
216 error ("bad value `%s' for -mfp-rounding-mode switch",
220 if (alpha_fptm_string)
222 if (strcmp (alpha_fptm_string, "n") == 0)
223 alpha_fptm = ALPHA_FPTM_N;
224 else if (strcmp (alpha_fptm_string, "u") == 0)
225 alpha_fptm = ALPHA_FPTM_U;
226 else if (strcmp (alpha_fptm_string, "su") == 0)
227 alpha_fptm = ALPHA_FPTM_SU;
228 else if (strcmp (alpha_fptm_string, "sui") == 0)
229 alpha_fptm = ALPHA_FPTM_SUI;
231 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
235 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
236 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
238 if (alpha_cpu_string)
240 for (i = 0; cpu_table [i].name; i++)
241 if (! strcmp (alpha_cpu_string, cpu_table [i].name))
243 alpha_cpu = cpu_table [i].processor;
244 target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX
245 | MASK_CPU_EV5 | MASK_CPU_EV6);
246 target_flags |= cpu_table [i].flags;
249 if (! cpu_table [i].name)
250 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
253 if (alpha_tune_string)
255 for (i = 0; cpu_table [i].name; i++)
256 if (! strcmp (alpha_tune_string, cpu_table [i].name))
258 alpha_cpu = cpu_table [i].processor;
261 if (! cpu_table [i].name)
262 error ("bad value `%s' for -mcpu switch", alpha_tune_string);
265 /* Do some sanity checks on the above options. */
267 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
268 && alpha_tp != ALPHA_TP_INSN && ! TARGET_CPU_EV6)
270 warning ("fp software completion requires -mtrap-precision=i");
271 alpha_tp = ALPHA_TP_INSN;
276 /* Except for EV6 pass 1 (not released), we always have precise
277 arithmetic traps. Which means we can do software completion
278 without minding trap shadows. */
279 alpha_tp = ALPHA_TP_PROG;
282 if (TARGET_FLOAT_VAX)
284 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
286 warning ("rounding mode not supported for VAX floats");
287 alpha_fprm = ALPHA_FPRM_NORM;
289 if (alpha_fptm == ALPHA_FPTM_SUI)
291 warning ("trap mode not supported for VAX floats");
292 alpha_fptm = ALPHA_FPTM_SU;
300 if (!alpha_mlat_string)
301 alpha_mlat_string = "L1";
303 if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
304 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
306 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
307 && ISDIGIT ((unsigned char)alpha_mlat_string[1])
308 && alpha_mlat_string[2] == '\0')
310 static int const cache_latency[][4] =
312 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
313 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
314 { 3, 12, 30 }, /* ev6 -- Bcache from DS20 LMbench. */
317 lat = alpha_mlat_string[1] - '0';
318 if (lat <= 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
320 warning ("L%d cache latency unknown for %s",
321 lat, alpha_cpu_name[alpha_cpu]);
325 lat = cache_latency[alpha_cpu][lat-1];
327 else if (! strcmp (alpha_mlat_string, "main"))
329 /* Most current memories have about 370ns latency. This is
330 a reasonable guess for a fast cpu. */
335 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
339 alpha_memory_latency = lat;
342 /* Default the definition of "small data" to 8 bytes. */
346 /* Acquire a unique set number for our register saves and restores. */
347 alpha_sr_alias_set = new_alias_set ();
349 /* Set up function hooks. */
350 init_machine_status = alpha_init_machine_status;
351 mark_machine_status = alpha_mark_machine_status;
352 free_machine_status = alpha_free_machine_status;
355 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
363 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
365 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
371 /* Returns 1 if OP is either the constant zero or a register. If a
372 register, it must be in the proper mode unless MODE is VOIDmode. */
375 reg_or_0_operand (op, mode)
377 enum machine_mode mode;
379 return op == const0_rtx || register_operand (op, mode);
382 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
386 reg_or_6bit_operand (op, mode)
388 enum machine_mode mode;
390 return ((GET_CODE (op) == CONST_INT
391 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
392 || register_operand (op, mode));
396 /* Return 1 if OP is an 8-bit constant or any register. */
399 reg_or_8bit_operand (op, mode)
401 enum machine_mode mode;
403 return ((GET_CODE (op) == CONST_INT
404 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
405 || register_operand (op, mode));
408 /* Return 1 if OP is an 8-bit constant. */
411 cint8_operand (op, mode)
413 enum machine_mode mode ATTRIBUTE_UNUSED;
415 return ((GET_CODE (op) == CONST_INT
416 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
419 /* Return 1 if the operand is a valid second operand to an add insn. */
422 add_operand (op, mode)
424 enum machine_mode mode;
426 if (GET_CODE (op) == CONST_INT)
427 /* Constraints I, J, O and P are covered by K. */
428 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
429 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
431 return register_operand (op, mode);
434 /* Return 1 if the operand is a valid second operand to a sign-extending
438 sext_add_operand (op, mode)
440 enum machine_mode mode;
442 if (GET_CODE (op) == CONST_INT)
443 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
444 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
446 return reg_not_elim_operand (op, mode);
449 /* Return 1 if OP is the constant 4 or 8. */
452 const48_operand (op, mode)
454 enum machine_mode mode ATTRIBUTE_UNUSED;
456 return (GET_CODE (op) == CONST_INT
457 && (INTVAL (op) == 4 || INTVAL (op) == 8));
460 /* Return 1 if OP is a valid first operand to an AND insn. */
463 and_operand (op, mode)
465 enum machine_mode mode;
467 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
468 return (zap_mask (CONST_DOUBLE_LOW (op))
469 && zap_mask (CONST_DOUBLE_HIGH (op)));
471 if (GET_CODE (op) == CONST_INT)
472 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
473 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
474 || zap_mask (INTVAL (op)));
476 return register_operand (op, mode);
479 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
482 or_operand (op, mode)
484 enum machine_mode mode;
486 if (GET_CODE (op) == CONST_INT)
487 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
488 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
490 return register_operand (op, mode);
493 /* Return 1 if OP is a constant that is the width, in bits, of an integral
494 mode smaller than DImode. */
497 mode_width_operand (op, mode)
499 enum machine_mode mode ATTRIBUTE_UNUSED;
501 return (GET_CODE (op) == CONST_INT
502 && (INTVAL (op) == 8 || INTVAL (op) == 16
503 || INTVAL (op) == 32 || INTVAL (op) == 64));
506 /* Return 1 if OP is a constant that is the width of an integral machine mode
507 smaller than an integer. */
510 mode_mask_operand (op, mode)
512 enum machine_mode mode ATTRIBUTE_UNUSED;
514 #if HOST_BITS_PER_WIDE_INT == 32
515 if (GET_CODE (op) == CONST_DOUBLE)
516 return (CONST_DOUBLE_LOW (op) == -1
517 && (CONST_DOUBLE_HIGH (op) == -1
518 || CONST_DOUBLE_HIGH (op) == 0));
520 if (GET_CODE (op) == CONST_DOUBLE)
521 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
524 return (GET_CODE (op) == CONST_INT
525 && (INTVAL (op) == 0xff
526 || INTVAL (op) == 0xffff
527 || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
528 #if HOST_BITS_PER_WIDE_INT == 64
534 /* Return 1 if OP is a multiple of 8 less than 64. */
537 mul8_operand (op, mode)
539 enum machine_mode mode ATTRIBUTE_UNUSED;
541 return (GET_CODE (op) == CONST_INT
542 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
543 && (INTVAL (op) & 7) == 0);
546 /* Return 1 if OP is the constant zero in floating-point. */
549 fp0_operand (op, mode)
551 enum machine_mode mode;
553 return (GET_MODE (op) == mode
554 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
557 /* Return 1 if OP is the floating-point constant zero or a register. */
560 reg_or_fp0_operand (op, mode)
562 enum machine_mode mode;
564 return fp0_operand (op, mode) || register_operand (op, mode);
567 /* Return 1 if OP is a hard floating-point register. */
570 hard_fp_register_operand (op, mode)
572 enum machine_mode mode;
574 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
577 if (GET_CODE (op) == SUBREG)
578 op = SUBREG_REG (op);
579 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;
582 /* Return 1 if OP is a hard general register. */
585 hard_int_register_operand (op, mode)
587 enum machine_mode mode;
589 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
592 if (GET_CODE (op) == SUBREG)
593 op = SUBREG_REG (op);
594 return GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;
597 /* Return 1 if OP is a register or a constant integer. */
601 reg_or_cint_operand (op, mode)
603 enum machine_mode mode;
605 return (GET_CODE (op) == CONST_INT
606 || register_operand (op, mode));
609 /* Return 1 if OP is something that can be reloaded into a register;
610 if it is a MEM, it need not be valid. */
613 some_operand (op, mode)
615 enum machine_mode mode;
617 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
620 switch (GET_CODE (op))
622 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
623 case SYMBOL_REF: case CONST:
627 return some_operand (SUBREG_REG (op), VOIDmode);
636 /* Likewise, but don't accept constants. */
639 some_ni_operand (op, mode)
641 enum machine_mode mode;
643 if (GET_MODE (op) != mode && mode != VOIDmode)
646 if (GET_CODE (op) == SUBREG)
647 op = SUBREG_REG (op);
649 return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
652 /* Return 1 if OP is a valid operand for the source of a move insn. */
655 input_operand (op, mode)
657 enum machine_mode mode;
659 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
662 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
665 switch (GET_CODE (op))
670 /* This handles both the Windows/NT and OSF cases. */
671 return mode == ptr_mode || mode == DImode;
678 if (register_operand (op, mode))
680 /* ... fall through ... */
682 return ((TARGET_BWX || (mode != HImode && mode != QImode))
683 && general_operand (op, mode));
686 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
689 return mode == QImode || mode == HImode || add_operand (op, mode);
701 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
705 current_file_function_operand (op, mode)
707 enum machine_mode mode ATTRIBUTE_UNUSED;
709 return (GET_CODE (op) == SYMBOL_REF
710 && ! profile_flag && ! profile_block_flag
711 && (SYMBOL_REF_FLAG (op)
712 || op == XEXP (DECL_RTL (current_function_decl), 0)));
715 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
718 call_operand (op, mode)
720 enum machine_mode mode;
725 return (GET_CODE (op) == SYMBOL_REF
726 || (GET_CODE (op) == REG
727 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
730 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
731 comparisons are valid in which insn. */
734 alpha_comparison_operator (op, mode)
736 enum machine_mode mode;
738 enum rtx_code code = GET_CODE (op);
740 if (mode != GET_MODE (op) && mode != VOIDmode)
743 return (code == EQ || code == LE || code == LT
744 || code == LEU || code == LTU);
747 /* Return 1 if OP is a valid Alpha comparison operator against zero.
748 Here we know which comparisons are valid in which insn. */
751 alpha_zero_comparison_operator (op, mode)
753 enum machine_mode mode;
755 enum rtx_code code = GET_CODE (op);
757 if (mode != GET_MODE (op) && mode != VOIDmode)
760 return (code == EQ || code == NE || code == LE || code == LT
761 || code == LEU || code == LTU);
764 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
767 alpha_swapped_comparison_operator (op, mode)
769 enum machine_mode mode;
771 enum rtx_code code = GET_CODE (op);
773 if ((mode != GET_MODE (op) && mode != VOIDmode)
774 || GET_RTX_CLASS (code) != '<')
777 code = swap_condition (code);
778 return (code == EQ || code == LE || code == LT
779 || code == LEU || code == LTU);
782 /* Return 1 if OP is a signed comparison operation. */
785 signed_comparison_operator (op, mode)
787 enum machine_mode mode ATTRIBUTE_UNUSED;
789 enum rtx_code code = GET_CODE (op);
791 if (mode != GET_MODE (op) && mode != VOIDmode)
794 return (code == EQ || code == NE
795 || code == LE || code == LT
796 || code == GE || code == GT);
799 /* Return 1 if OP is a valid Alpha floating point comparison operator.
800 Here we know which comparisons are valid in which insn. */
803 alpha_fp_comparison_operator (op, mode)
805 enum machine_mode mode;
807 enum rtx_code code = GET_CODE (op);
809 if (mode != GET_MODE (op) && mode != VOIDmode)
812 return (code == EQ || code == LE || code == LT || code == UNORDERED);
815 /* Return 1 if this is a divide or modulus operator. */
818 divmod_operator (op, mode)
820 enum machine_mode mode ATTRIBUTE_UNUSED;
822 switch (GET_CODE (op))
824 case DIV: case MOD: case UDIV: case UMOD:
834 /* Return 1 if this memory address is a known aligned register plus
835 a constant. It must be a valid address. This means that we can do
836 this as an aligned reference plus some offset.
838 Take into account what reload will do. */
841 aligned_memory_operand (op, mode)
843 enum machine_mode mode;
847 if (reload_in_progress)
850 if (GET_CODE (tmp) == SUBREG)
851 tmp = SUBREG_REG (tmp);
852 if (GET_CODE (tmp) == REG
853 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
855 op = reg_equiv_memory_loc[REGNO (tmp)];
861 if (GET_CODE (op) != MEM
862 || GET_MODE (op) != mode)
866 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
867 sorts of constructs. Dig for the real base register. */
868 if (reload_in_progress
869 && GET_CODE (op) == PLUS
870 && GET_CODE (XEXP (op, 0)) == PLUS)
871 base = XEXP (XEXP (op, 0), 0);
874 if (! memory_address_p (mode, op))
876 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
879 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
882 /* Similar, but return 1 if OP is a MEM which is not alignable. */
885 unaligned_memory_operand (op, mode)
887 enum machine_mode mode;
891 if (reload_in_progress)
894 if (GET_CODE (tmp) == SUBREG)
895 tmp = SUBREG_REG (tmp);
896 if (GET_CODE (tmp) == REG
897 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
899 op = reg_equiv_memory_loc[REGNO (tmp)];
905 if (GET_CODE (op) != MEM
906 || GET_MODE (op) != mode)
910 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
911 sorts of constructs. Dig for the real base register. */
912 if (reload_in_progress
913 && GET_CODE (op) == PLUS
914 && GET_CODE (XEXP (op, 0)) == PLUS)
915 base = XEXP (XEXP (op, 0), 0);
918 if (! memory_address_p (mode, op))
920 base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
923 return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
926 /* Return 1 if OP is either a register or an unaligned memory location. */
929 reg_or_unaligned_mem_operand (op, mode)
931 enum machine_mode mode;
933 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
936 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
939 any_memory_operand (op, mode)
941 enum machine_mode mode ATTRIBUTE_UNUSED;
943 return (GET_CODE (op) == MEM
944 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
945 || (reload_in_progress && GET_CODE (op) == REG
946 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
947 || (reload_in_progress && GET_CODE (op) == SUBREG
948 && GET_CODE (SUBREG_REG (op)) == REG
949 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
952 /* Returns 1 if OP is not an eliminable register.
954 This exists to cure a pathological abort in the s8addq (et al) patterns,
956 long foo () { long t; bar(); return (long) &t * 26107; }
958 which run afoul of a hack in reload to cure a (presumably) similar
959 problem with lea-type instructions on other targets. But there is
960 one of us and many of them, so work around the problem by selectively
961 preventing combine from making the optimization. */
964 reg_not_elim_operand (op, mode)
966 enum machine_mode mode;
969 if (GET_CODE (op) == SUBREG)
970 inner = SUBREG_REG (op);
971 if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
974 return register_operand (op, mode);
977 /* Return 1 is OP is a memory location that is not a reference (using
978 an AND) to an unaligned location. Take into account what reload
982 normal_memory_operand (op, mode)
984 enum machine_mode mode ATTRIBUTE_UNUSED;
986 if (reload_in_progress)
989 if (GET_CODE (tmp) == SUBREG)
990 tmp = SUBREG_REG (tmp);
991 if (GET_CODE (tmp) == REG
992 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
994 op = reg_equiv_memory_loc[REGNO (tmp)];
996 /* This may not have been assigned an equivalent address if it will
997 be eliminated. In that case, it doesn't matter what we do. */
1003 return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
1006 /* Accept a register, but not a subreg of any kind. This allows us to
1007 avoid pathological cases in reload wrt data movement common in
1008 int->fp conversion. */
1011 reg_no_subreg_operand (op, mode)
1013 enum machine_mode mode;
1015 if (GET_CODE (op) == SUBREG)
1017 return register_operand (op, mode);
1020 /* Recognize a addition operation that includes a constant. Used to
1021 convince reload to canonize (plus (plus reg c1) c2) during register
1025 addition_operation (op, mode)
1027 enum machine_mode mode;
1029 if (GET_MODE (op) != mode && mode != VOIDmode)
1031 if (GET_CODE (op) == PLUS
1032 && register_operand (XEXP (op, 0), mode)
1033 && GET_CODE (XEXP (op, 1)) == CONST_INT
1034 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
1039 /* Return 1 if this function can directly return via $26. */
1044 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
1045 && get_frame_size () == 0
1046 && current_function_outgoing_args_size == 0
1047 && current_function_pretend_args_size == 0);
1050 /* REF is an alignable memory location. Place an aligned SImode
1051 reference into *PALIGNED_MEM and the number of bits to shift into
1052 *PBITNUM. SCRATCH is a free register for use in reloading out
1053 of range stack slots. */
1056 get_aligned_mem (ref, paligned_mem, pbitnum)
1058 rtx *paligned_mem, *pbitnum;
1061 HOST_WIDE_INT offset = 0;
1063 if (GET_CODE (ref) != MEM)
1066 if (reload_in_progress
1067 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1069 base = find_replacement (&XEXP (ref, 0));
1071 if (! memory_address_p (GET_MODE (ref), base))
1076 base = XEXP (ref, 0);
1079 if (GET_CODE (base) == PLUS)
1080 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1082 *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1083 MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1085 /* Sadly, we cannot use alias sets here because we may overlap other
1086 data in a different alias set. */
1087 MEM_ALIAS_SET (*paligned_mem) = 0;
1089 *pbitnum = GEN_INT ((offset & 3) * 8);
1092 /* Similar, but just get the address. Handle the two reload cases.
1093 Add EXTRA_OFFSET to the address we return. */
1096 get_unaligned_address (ref, extra_offset)
1101 HOST_WIDE_INT offset = 0;
1103 if (GET_CODE (ref) != MEM)
1106 if (reload_in_progress
1107 && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1109 base = find_replacement (&XEXP (ref, 0));
1111 if (! memory_address_p (GET_MODE (ref), base))
1116 base = XEXP (ref, 0);
1119 if (GET_CODE (base) == PLUS)
1120 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1122 return plus_constant (base, offset + extra_offset);
1125 /* Loading and storing HImode or QImode values to and from memory
1126 usually requires a scratch register. The exceptions are loading
1127 QImode and HImode from an aligned address to a general register
1128 unless byte instructions are permitted.
1130 We also cannot load an unaligned address or a paradoxical SUBREG
1131 into an FP register.
1133 We also cannot do integral arithmetic into FP regs, as might result
1134 from register elimination into a DImode fp register. */
1137 secondary_reload_class (class, mode, x, in)
1138 enum reg_class class;
1139 enum machine_mode mode;
1143 if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1145 if (GET_CODE (x) == MEM
1146 || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1147 || (GET_CODE (x) == SUBREG
1148 && (GET_CODE (SUBREG_REG (x)) == MEM
1149 || (GET_CODE (SUBREG_REG (x)) == REG
1150 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1152 if (!in || !aligned_memory_operand(x, mode))
1153 return GENERAL_REGS;
1157 if (class == FLOAT_REGS)
1159 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1160 return GENERAL_REGS;
1162 if (GET_CODE (x) == SUBREG
1163 && (GET_MODE_SIZE (GET_MODE (x))
1164 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1165 return GENERAL_REGS;
1167 if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
1168 return GENERAL_REGS;
1174 /* Subfunction of the following function. Update the flags of any MEM
1175 found in part of X. */
1178 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1180 int in_struct_p, volatile_p, unchanging_p;
1184 switch (GET_CODE (x))
1188 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1189 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1194 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1199 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1201 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1206 MEM_IN_STRUCT_P (x) = in_struct_p;
1207 MEM_VOLATILE_P (x) = volatile_p;
1208 RTX_UNCHANGING_P (x) = unchanging_p;
1209 /* Sadly, we cannot use alias sets because the extra aliasing
1210 produced by the AND interferes. Given that two-byte quantities
1211 are the only thing we would be able to differentiate anyway,
1212 there does not seem to be any point in convoluting the early
1213 out of the alias check. */
1214 /* MEM_ALIAS_SET (x) = alias_set; */
1222 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1223 perform a memory operation, look for any MEMs in either a SET_DEST or
1224 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1225 REF into each of the MEMs found. If REF is not a MEM, don't do
1229 alpha_set_memflags (insn, ref)
1233 int in_struct_p, volatile_p, unchanging_p;
1235 if (GET_CODE (ref) != MEM)
1238 in_struct_p = MEM_IN_STRUCT_P (ref);
1239 volatile_p = MEM_VOLATILE_P (ref);
1240 unchanging_p = RTX_UNCHANGING_P (ref);
1242 /* This is only called from alpha.md, after having had something
1243 generated from one of the insn patterns. So if everything is
1244 zero, the pattern is already up-to-date. */
1245 if (! in_struct_p && ! volatile_p && ! unchanging_p)
1248 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1251 /* Try to output insns to set TARGET equal to the constant C if it can be
1252 done in less than N insns. Do all computations in MODE. Returns the place
1253 where the output has been placed if it can be done and the insns have been
1254 emitted. If it would take more than N insns, zero is returned and no
1255 insns and emitted. */
1258 alpha_emit_set_const (target, mode, c, n)
1260 enum machine_mode mode;
1267 /* Try 1 insn, then 2, then up to N. */
1268 for (i = 1; i <= n; i++)
1269 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1275 /* Internal routine for the above to check for N or below insns. */
1278 alpha_emit_set_const_1 (target, mode, c, n)
1280 enum machine_mode mode;
1286 /* Use a pseudo if highly optimizing and still generating RTL. */
1288 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1292 #if HOST_BITS_PER_WIDE_INT == 64
1293 /* We are only called for SImode and DImode. If this is SImode, ensure that
1294 we are sign extended to a full word. This does not make any sense when
1295 cross-compiling on a narrow machine. */
1298 c = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1301 /* If this is a sign-extended 32-bit constant, we can do this in at most
1302 three insns, so do it if we have enough insns left. We always have
1303 a sign-extended 32-bit constant when compiling on a narrow machine. */
1305 if (HOST_BITS_PER_WIDE_INT != 64
1306 || c >> 31 == -1 || c >> 31 == 0)
1308 HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1309 HOST_WIDE_INT tmp1 = c - low;
1310 HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1311 HOST_WIDE_INT extra = 0;
1313 /* If HIGH will be interpreted as negative but the constant is
1314 positive, we must adjust it to do two ldha insns. */
1316 if ((high & 0x8000) != 0 && c >= 0)
1320 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1323 if (c == low || (low == 0 && extra == 0))
1325 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1326 but that meant that we can't handle INT_MIN on 32-bit machines
1327 (like NT/Alpha), because we recurse indefinitely through
1328 emit_move_insn to gen_movdi. So instead, since we know exactly
1329 what we want, create it explicitly. */
1332 target = gen_reg_rtx (mode);
1333 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1336 else if (n >= 2 + (extra != 0))
1338 temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
1341 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1342 subtarget, 0, OPTAB_WIDEN);
1344 return expand_binop (mode, add_optab, temp, GEN_INT (low),
1345 target, 0, OPTAB_WIDEN);
1349 /* If we couldn't do it that way, try some other methods. But if we have
1350 no instructions left, don't bother. Likewise, if this is SImode and
1351 we can't make pseudos, we can't do anything since the expand_binop
1352 and expand_unop calls will widen and try to make pseudos. */
1355 || (mode == SImode && ! rtx_equal_function_value_matters))
1358 /* Next, see if we can load a related constant and then shift and possibly
1359 negate it to get the constant we want. Try this once each increasing
1360 numbers of insns. */
1362 for (i = 1; i < n; i++)
1364 /* First, see if minus some low bits, we've an easy load of
1367 new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1369 && (temp = alpha_emit_set_const (subtarget, mode, c - new, i)) != 0)
1370 return expand_binop (mode, add_optab, temp, GEN_INT (new),
1371 target, 0, OPTAB_WIDEN);
1373 /* Next try complementing. */
1374 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1375 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1377 /* Next try to form a constant and do a left shift. We can do this
1378 if some low-order bits are zero; the exact_log2 call below tells
1379 us that information. The bits we are shifting out could be any
1380 value, but here we'll just try the 0- and sign-extended forms of
1381 the constant. To try to increase the chance of having the same
1382 constant in more than one insn, start at the highest number of
1383 bits to shift, but try all possibilities in case a ZAPNOT will
1386 if ((bits = exact_log2 (c & - c)) > 0)
1387 for (; bits > 0; bits--)
1388 if ((temp = (alpha_emit_set_const
1389 (subtarget, mode, c >> bits, i))) != 0
1390 || ((temp = (alpha_emit_set_const
1392 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1394 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1395 target, 0, OPTAB_WIDEN);
1397 /* Now try high-order zero bits. Here we try the shifted-in bits as
1398 all zero and all ones. Be careful to avoid shifting outside the
1399 mode and to avoid shifting outside the host wide int size. */
1400 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1401 confuse the recursive call and set all of the high 32 bits. */
1403 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1404 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1405 for (; bits > 0; bits--)
1406 if ((temp = alpha_emit_set_const (subtarget, mode,
1408 || ((temp = (alpha_emit_set_const
1410 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1413 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1414 target, 1, OPTAB_WIDEN);
1416 /* Now try high-order 1 bits. We get that with a sign-extension.
1417 But one bit isn't enough here. Be careful to avoid shifting outside
1418 the mode and to avoid shifting outside the host wide int size. */
1420 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1421 - floor_log2 (~ c) - 2)) > 0)
1422 for (; bits > 0; bits--)
1423 if ((temp = alpha_emit_set_const (subtarget, mode,
1425 || ((temp = (alpha_emit_set_const
1427 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1430 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1431 target, 0, OPTAB_WIDEN);
1434 #if HOST_BITS_PER_WIDE_INT == 64
1435 /* Finally, see if can load a value into the target that is the same as the
1436 constant except that all bytes that are 0 are changed to be 0xff. If we
1437 can, then we can do a ZAPNOT to obtain the desired constant. */
1440 for (i = 0; i < 64; i += 8)
1441 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1442 new |= (HOST_WIDE_INT) 0xff << i;
1444 /* We are only called for SImode and DImode. If this is SImode, ensure that
1445 we are sign extended to a full word. */
1448 new = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1450 if (new != c && new != -1
1451 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1452 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1453 target, 0, OPTAB_WIDEN);
1459 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1460 fall back to a straight forward decomposition. We do this to avoid
1461 exponential run times encountered when looking for longer sequences
1462 with alpha_emit_set_const. */
1465 alpha_emit_set_long_const (target, c1, c2)
1467 HOST_WIDE_INT c1, c2;
1469 HOST_WIDE_INT d1, d2, d3, d4;
1471 /* Decompose the entire word */
1472 #if HOST_BITS_PER_WIDE_INT >= 64
1473 if (c2 != -(c1 < 0))
1475 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1477 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1478 c1 = (c1 - d2) >> 32;
1479 d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1481 d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1485 d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1487 d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1491 d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1493 d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1498 /* Construct the high word */
1501 emit_move_insn (target, GEN_INT (d4));
1503 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1506 emit_move_insn (target, GEN_INT (d3));
1508 /* Shift it into place */
1509 emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1511 /* Add in the low bits. */
1513 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1515 emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1520 /* Generate an unsigned DImode to FP conversion. This is the same code
1521 optabs would emit if we didn't have TFmode patterns.
1523 For SFmode, this is the only construction I've found that can pass
1524 gcc.c-torture/execute/ieee/rbug.c. No scenario that uses DFmode
1525 intermediates will work, because you'll get intermediate rounding
1526 that ruins the end result. Some of this could be fixed by turning
1527 on round-to-positive-infinity, but that requires diddling the fpsr,
1528 which kills performance. I tried turning this around and converting
1529 to a negative number, so that I could turn on /m, but either I did
1530 it wrong or there's something else cause I wound up with the exact
1531 same single-bit error. There is a branch-less form of this same code:
1542 fcmoveq $f10,$f11,$f0
1544 I'm not using it because it's the same number of instructions as
1545 this branch-full form, and it has more serialized long latency
1546 instructions on the critical path.
1548 For DFmode, we can avoid rounding errors by breaking up the word
1549 into two pieces, converting them separately, and adding them back:
1551 LC0: .long 0,0x5f800000
1556 cpyse $f11,$f31,$f10
1557 cpyse $f31,$f11,$f11
1565 This doesn't seem to be a clear-cut win over the optabs form.
1566 It probably all depends on the distribution of numbers being
1567 converted -- in the optabs form, all but high-bit-set has a
1568 much lower minimum execution time. */
1571 alpha_emit_floatuns (operands)
1574 rtx neglab, donelab, i0, i1, f0, in, out;
1575 enum machine_mode mode;
1578 in = force_reg (DImode, operands[1]);
1579 mode = GET_MODE (out);
1580 neglab = gen_label_rtx ();
1581 donelab = gen_label_rtx ();
1582 i0 = gen_reg_rtx (DImode);
1583 i1 = gen_reg_rtx (DImode);
1584 f0 = gen_reg_rtx (mode);
1586 emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0,
1589 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
1590 emit_jump_insn (gen_jump (donelab));
1593 emit_label (neglab);
1595 emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
1596 emit_insn (gen_anddi3 (i1, in, const1_rtx));
1597 emit_insn (gen_iordi3 (i0, i0, i1));
1598 emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
1599 emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
1601 emit_label (donelab);
1604 /* Generate the comparison for a conditional branch. */
1607 alpha_emit_conditional_branch (code)
1610 enum rtx_code cmp_code, branch_code;
1611 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1612 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1615 if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
1617 if (! TARGET_HAS_XFLOATING_LIBS)
1620 /* X_floating library comparison functions return
1624 Convert the compare against the raw return value. */
1626 if (code == UNORDERED || code == ORDERED)
1631 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
1633 alpha_compare.fp_p = 0;
1635 if (code == UNORDERED)
1637 else if (code == ORDERED)
1643 /* The general case: fold the comparison code to the types of compares
1644 that we have, choosing the branch as necessary. */
1647 case EQ: case LE: case LT: case LEU: case LTU:
1649 /* We have these compares: */
1650 cmp_code = code, branch_code = NE;
1655 /* These must be reversed. */
1656 cmp_code = reverse_condition (code), branch_code = EQ;
1659 case GE: case GT: case GEU: case GTU:
1660 /* For FP, we swap them, for INT, we reverse them. */
1661 if (alpha_compare.fp_p)
1663 cmp_code = swap_condition (code);
1665 tem = op0, op0 = op1, op1 = tem;
1669 cmp_code = reverse_condition (code);
1678 if (alpha_compare.fp_p)
1683 /* When we are not as concerned about non-finite values, and we
1684 are comparing against zero, we can branch directly. */
1685 if (op1 == CONST0_RTX (DFmode))
1686 cmp_code = NIL, branch_code = code;
1687 else if (op0 == CONST0_RTX (DFmode))
1689 /* Undo the swap we probably did just above. */
1690 tem = op0, op0 = op1, op1 = tem;
1691 branch_code = swap_condition (cmp_code);
1697 /* ??? We mark the the branch mode to be CCmode to prevent the
1698 compare and branch from being combined, since the compare
1699 insn follows IEEE rules that the branch does not. */
1700 branch_mode = CCmode;
1707 /* The following optimizations are only for signed compares. */
1708 if (code != LEU && code != LTU && code != GEU && code != GTU)
1710 /* Whee. Compare and branch against 0 directly. */
1711 if (op1 == const0_rtx)
1712 cmp_code = NIL, branch_code = code;
1714 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1715 bypass between logicals and br/cmov on EV5. But we don't want to
1716 force valid immediate constants into registers needlessly. */
1717 else if (GET_CODE (op1) == CONST_INT)
1719 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1721 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1722 && (CONST_OK_FOR_LETTER_P (n, 'K')
1723 || CONST_OK_FOR_LETTER_P (n, 'L')))
1725 cmp_code = PLUS, branch_code = code;
1731 if (!reg_or_0_operand (op0, DImode))
1732 op0 = force_reg (DImode, op0);
1733 if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
1734 op1 = force_reg (DImode, op1);
1737 /* Emit an initial compare instruction, if necessary. */
1739 if (cmp_code != NIL)
1741 tem = gen_reg_rtx (cmp_mode);
1742 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1745 /* Zero the operands. */
1746 memset (&alpha_compare, 0, sizeof (alpha_compare));
1748 /* Return the branch comparison. */
1749 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1752 /* Certain simplifications can be done to make invalid setcc operations
1753 valid. Return the final comparison, or NULL if we can't work. */
1756 alpha_emit_setcc (code)
1759 enum rtx_code cmp_code;
1760 rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1761 int fp_p = alpha_compare.fp_p;
1764 /* Zero the operands. */
1765 memset (&alpha_compare, 0, sizeof (alpha_compare));
1767 if (fp_p && GET_MODE (op0) == TFmode)
1769 if (! TARGET_HAS_XFLOATING_LIBS)
1772 /* X_floating library comparison functions return
1776 Convert the compare against the raw return value. */
1778 if (code == UNORDERED || code == ORDERED)
1783 op0 = alpha_emit_xfloating_compare (cmp_code, op0, op1);
1787 if (code == UNORDERED)
1789 else if (code == ORDERED)
1795 if (fp_p && !TARGET_FIX)
1798 /* The general case: fold the comparison code to the types of compares
1799 that we have, choosing the branch as necessary. */
1804 case EQ: case LE: case LT: case LEU: case LTU:
1806 /* We have these compares. */
1808 cmp_code = code, code = NE;
1812 if (!fp_p && op1 == const0_rtx)
1817 cmp_code = reverse_condition (code);
1821 case GE: case GT: case GEU: case GTU:
1822 /* These are normally need swapping, but for integer zero we have
1823 special patterns that recognize swapped operands. */
1824 if (!fp_p && op1 == const0_rtx)
1826 code = swap_condition (code);
1828 cmp_code = code, code = NE;
1829 tmp = op0, op0 = op1, op1 = tmp;
1838 if (!register_operand (op0, DImode))
1839 op0 = force_reg (DImode, op0);
1840 if (!reg_or_8bit_operand (op1, DImode))
1841 op1 = force_reg (DImode, op1);
1844 /* Emit an initial compare instruction, if necessary. */
1845 if (cmp_code != NIL)
1847 enum machine_mode mode = fp_p ? DFmode : DImode;
1849 tmp = gen_reg_rtx (mode);
1850 emit_insn (gen_rtx_SET (VOIDmode, tmp,
1851 gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
1853 op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
1857 /* Return the setcc comparison. */
1858 return gen_rtx_fmt_ee (code, DImode, op0, op1);
1862 /* Rewrite a comparison against zero CMP of the form
1863 (CODE (cc0) (const_int 0)) so it can be written validly in
1864 a conditional move (if_then_else CMP ...).
1865 If both of the operands that set cc0 are non-zero we must emit
1866 an insn to perform the compare (it can't be done within
1867 the conditional move). */
1869 alpha_emit_conditional_move (cmp, mode)
1871 enum machine_mode mode;
1873 enum rtx_code code = GET_CODE (cmp);
1874 enum rtx_code cmov_code = NE;
1875 rtx op0 = alpha_compare.op0;
1876 rtx op1 = alpha_compare.op1;
1877 int fp_p = alpha_compare.fp_p;
1878 enum machine_mode cmp_mode
1879 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1880 enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1881 enum machine_mode cmov_mode = VOIDmode;
1882 int local_fast_math = flag_fast_math;
1885 /* Zero the operands. */
1886 memset (&alpha_compare, 0, sizeof (alpha_compare));
1888 if (fp_p != FLOAT_MODE_P (mode))
1890 enum rtx_code cmp_code;
1895 /* If we have fp<->int register move instructions, do a cmov by
1896 performing the comparison in fp registers, and move the
1897 zero/non-zero value to integer registers, where we can then
1898 use a normal cmov, or vice-versa. */
1902 case EQ: case LE: case LT: case LEU: case LTU:
1903 /* We have these compares. */
1904 cmp_code = code, code = NE;
1908 /* This must be reversed. */
1909 cmp_code = EQ, code = EQ;
1912 case GE: case GT: case GEU: case GTU:
1913 /* These must be swapped. */
1914 if (op1 == CONST0_RTX (cmp_mode))
1915 cmp_code = code, code = NE;
1918 cmp_code = swap_condition (code);
1920 tem = op0, op0 = op1, op1 = tem;
1928 tem = gen_reg_rtx (cmp_op_mode);
1929 emit_insn (gen_rtx_SET (VOIDmode, tem,
1930 gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1933 cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1934 op0 = gen_lowpart (cmp_op_mode, tem);
1935 op1 = CONST0_RTX (cmp_op_mode);
1937 local_fast_math = 1;
1940 /* We may be able to use a conditional move directly.
1941 This avoids emitting spurious compares. */
1942 if (signed_comparison_operator (cmp, VOIDmode)
1943 && (!fp_p || local_fast_math)
1944 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1945 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1947 /* We can't put the comparison inside the conditional move;
1948 emit a compare instruction and put that inside the
1949 conditional move. Make sure we emit only comparisons we have;
1950 swap or reverse as necessary. */
1957 case EQ: case LE: case LT: case LEU: case LTU:
1958 /* We have these compares: */
1962 /* This must be reversed. */
1963 code = reverse_condition (code);
1967 case GE: case GT: case GEU: case GTU:
1968 /* These must be swapped. */
1969 if (op1 != CONST0_RTX (cmp_mode))
1971 code = swap_condition (code);
1972 tem = op0, op0 = op1, op1 = tem;
1982 if (!reg_or_0_operand (op0, DImode))
1983 op0 = force_reg (DImode, op0);
1984 if (!reg_or_8bit_operand (op1, DImode))
1985 op1 = force_reg (DImode, op1);
1988 /* ??? We mark the branch mode to be CCmode to prevent the compare
1989 and cmov from being combined, since the compare insn follows IEEE
1990 rules that the cmov does not. */
1991 if (fp_p && !local_fast_math)
1994 tem = gen_reg_rtx (cmp_op_mode);
1995 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1996 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1999 /* Simplify a conditional move of two constants into a setcc with
2000 arithmetic. This is done with a splitter since combine would
2001 just undo the work if done during code generation. It also catches
2002 cases we wouldn't have before cse. */
2005 alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
2007 rtx dest, cond, t_rtx, f_rtx;
2009 HOST_WIDE_INT t, f, diff;
2010 enum machine_mode mode;
2011 rtx target, subtarget, tmp;
2013 mode = GET_MODE (dest);
2018 if (((code == NE || code == EQ) && diff < 0)
2019 || (code == GE || code == GT))
2021 code = reverse_condition (code);
2022 diff = t, t = f, f = diff;
2026 subtarget = target = dest;
2029 target = gen_lowpart (DImode, dest);
2030 if (! no_new_pseudos)
2031 subtarget = gen_reg_rtx (DImode);
2036 if (f == 0 && exact_log2 (diff) > 0
2037 /* On EV6, we've got enough shifters to make non-arithmatic shifts
2038 viable over a longer latency cmove. On EV5, the E0 slot is a
2039 scarce resource, and on EV4 shift has the same latency as a cmove. */
2040 && (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
2042 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2043 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2045 tmp = gen_rtx_ASHIFT (DImode, subtarget, GEN_INT (exact_log2 (t)));
2046 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2048 else if (f == 0 && t == -1)
2050 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2051 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2053 emit_insn (gen_negdi2 (target, subtarget));
2055 else if (diff == 1 || diff == 4 || diff == 8)
2059 tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2060 emit_insn (gen_rtx_SET (VOIDmode, subtarget, tmp));
2063 emit_insn (gen_adddi3 (target, subtarget, GEN_INT (f)));
2066 add_op = GEN_INT (f);
2067 if (sext_add_operand (add_op, mode))
2069 tmp = gen_rtx_MULT (DImode, subtarget, GEN_INT (diff));
2070 tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2071 emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2083 /* Look up the function X_floating library function name for the
2087 alpha_lookup_xfloating_lib_func (code)
2096 static const struct xfloating_op vms_xfloating_ops[] =
2098 { PLUS, "OTS$ADD_X" },
2099 { MINUS, "OTS$SUB_X" },
2100 { MULT, "OTS$MUL_X" },
2101 { DIV, "OTS$DIV_X" },
2102 { EQ, "OTS$EQL_X" },
2103 { NE, "OTS$NEQ_X" },
2104 { LT, "OTS$LSS_X" },
2105 { LE, "OTS$LEQ_X" },
2106 { GT, "OTS$GTR_X" },
2107 { GE, "OTS$GEQ_X" },
2108 { FIX, "OTS$CVTXQ" },
2109 { FLOAT, "OTS$CVTQX" },
2110 { UNSIGNED_FLOAT, "OTS$CVTQUX" },
2111 { FLOAT_EXTEND, "OTS$CVT_FLOAT_T_X" },
2112 { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
2115 static const struct xfloating_op osf_xfloating_ops[] =
2117 { PLUS, "_OtsAddX" },
2118 { MINUS, "_OtsSubX" },
2119 { MULT, "_OtsMulX" },
2120 { DIV, "_OtsDivX" },
2127 { FIX, "_OtsCvtXQ" },
2128 { FLOAT, "_OtsCvtQX" },
2129 { UNSIGNED_FLOAT, "_OtsCvtQUX" },
2130 { FLOAT_EXTEND, "_OtsConvertFloatTX" },
2131 { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
2134 const struct xfloating_op *ops;
2135 const long n = ARRAY_SIZE (osf_xfloating_ops);
2138 /* How irritating. Nothing to key off for the table. Hardcode
2139 knowledge of the G_floating routines. */
2140 if (TARGET_FLOAT_VAX)
2142 if (TARGET_OPEN_VMS)
2144 if (code == FLOAT_EXTEND)
2145 return "OTS$CVT_FLOAT_G_X";
2146 if (code == FLOAT_TRUNCATE)
2147 return "OTS$CVT_FLOAT_X_G";
2151 if (code == FLOAT_EXTEND)
2152 return "_OtsConvertFloatGX";
2153 if (code == FLOAT_TRUNCATE)
2154 return "_OtsConvertFloatXG";
2158 if (TARGET_OPEN_VMS)
2159 ops = vms_xfloating_ops;
2161 ops = osf_xfloating_ops;
2163 for (i = 0; i < n; ++i)
2164 if (ops[i].code == code)
2170 /* Most X_floating operations take the rounding mode as an argument.
2171 Compute that here. */
2174 alpha_compute_xfloating_mode_arg (code, round)
2176 enum alpha_fp_rounding_mode round;
2182 case ALPHA_FPRM_NORM:
2185 case ALPHA_FPRM_MINF:
2188 case ALPHA_FPRM_CHOP:
2191 case ALPHA_FPRM_DYN:
2197 /* XXX For reference, round to +inf is mode = 3. */
2200 if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2206 /* Emit an X_floating library function call.
2208 Note that these functions do not follow normal calling conventions:
2209 TFmode arguments are passed in two integer registers (as opposed to
2210 indirect); TFmode return values appear in R16+R17.
2212 FUNC is the function name to call.
2213 TARGET is where the output belongs.
2214 OPERANDS are the inputs.
2215 NOPERANDS is the count of inputs.
2216 EQUIV is the expression equivalent for the function.
2220 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
2227 rtx usage = NULL_RTX, tmp, reg;
2232 for (i = 0; i < noperands; ++i)
2234 switch (GET_MODE (operands[i]))
2237 reg = gen_rtx_REG (TFmode, regno);
2242 reg = gen_rtx_REG (DFmode, regno + 32);
2247 if (GET_CODE (operands[i]) != CONST_INT)
2251 reg = gen_rtx_REG (DImode, regno);
2259 emit_move_insn (reg, operands[i]);
2260 usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
2263 switch (GET_MODE (target))
2266 reg = gen_rtx_REG (TFmode, 16);
2269 reg = gen_rtx_REG (DFmode, 32);
2272 reg = gen_rtx_REG (DImode, 0);
2278 tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
2279 tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
2280 const0_rtx, const0_rtx));
2281 CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2286 emit_libcall_block (tmp, target, reg, equiv);
2289 /* Emit an X_floating library function call for arithmetic (+,-,*,/). */
2292 alpha_emit_xfloating_arith (code, operands)
2298 rtx out_operands[3];
2300 func = alpha_lookup_xfloating_lib_func (code);
2301 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2303 out_operands[0] = operands[1];
2304 out_operands[1] = operands[2];
2305 out_operands[2] = GEN_INT (mode);
2306 alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
2307 gen_rtx_fmt_ee (code, TFmode, operands[1],
2311 /* Emit an X_floating library function call for a comparison. */
2314 alpha_emit_xfloating_compare (code, op0, op1)
2319 rtx out, operands[2];
2321 func = alpha_lookup_xfloating_lib_func (code);
2325 out = gen_reg_rtx (DImode);
2327 /* ??? Strange equiv cause what's actually returned is -1,0,1, not a
2328 proper boolean value. */
2329 alpha_emit_xfloating_libcall (func, out, operands, 2,
2330 gen_rtx_COMPARE (TFmode, op0, op1));
2335 /* Emit an X_floating library function call for a conversion. */
2338 alpha_emit_xfloating_cvt (code, operands)
2342 int noperands = 1, mode;
2343 rtx out_operands[2];
2346 func = alpha_lookup_xfloating_lib_func (code);
2348 out_operands[0] = operands[1];
2353 mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2354 out_operands[1] = GEN_INT (mode);
2357 case FLOAT_TRUNCATE:
2358 mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2359 out_operands[1] = GEN_INT (mode);
2366 alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
2367 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
2371 /* Split a TFmode OP[1] into DImode OP[2,3] and likewise for
2372 OP[0] into OP[0,1]. Naturally, output operand ordering is
2376 alpha_split_tfmode_pair (operands)
2379 if (GET_CODE (operands[1]) == REG)
2381 operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
2382 operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
2384 else if (GET_CODE (operands[1]) == MEM)
2386 operands[3] = change_address (operands[1], DImode,
2387 plus_constant (XEXP (operands[1], 0), 8));
2388 operands[2] = change_address (operands[1], DImode, NULL_RTX);
2390 else if (operands[1] == CONST0_RTX (TFmode))
2391 operands[2] = operands[3] = const0_rtx;
2395 if (GET_CODE (operands[0]) == REG)
2397 operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
2398 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
2400 else if (GET_CODE (operands[0]) == MEM)
2402 operands[1] = change_address (operands[0], DImode,
2403 plus_constant (XEXP (operands[0], 0), 8));
2404 operands[0] = change_address (operands[0], DImode, NULL_RTX);
2410 /* Implement negtf2 or abstf2. Op0 is destination, op1 is source,
2411 op2 is a register containing the sign bit, operation is the
2412 logical operation to be performed. */
2415 alpha_split_tfmode_frobsign (operands, operation)
2417 rtx (*operation) PARAMS ((rtx, rtx, rtx));
2419 rtx high_bit = operands[2];
2423 alpha_split_tfmode_pair (operands);
2425 /* Detect three flavours of operand overlap. */
2427 if (rtx_equal_p (operands[0], operands[2]))
2429 else if (rtx_equal_p (operands[1], operands[2]))
2431 if (rtx_equal_p (operands[0], high_bit))
2438 emit_move_insn (operands[0], operands[2]);
2440 /* ??? If the destination overlaps both source tf and high_bit, then
2441 assume source tf is dead in its entirety and use the other half
2442 for a scratch register. Otherwise "scratch" is just the proper
2443 destination register. */
2444 scratch = operands[move < 2 ? 1 : 3];
2446 emit_insn ((*operation) (scratch, high_bit, operands[3]));
2450 emit_move_insn (operands[0], operands[2]);
2452 emit_move_insn (operands[1], scratch);
2456 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
2460 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
2461 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
2462 lda r3,X(r11) lda r3,X+2(r11)
2463 extwl r1,r3,r1 extql r1,r3,r1
2464 extwh r2,r3,r2 extqh r2,r3,r2
2465 or r1.r2.r1 or r1,r2,r1
2468 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
2469 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
2470 lda r3,X(r11) lda r3,X(r11)
2471 extll r1,r3,r1 extll r1,r3,r1
2472 extlh r2,r3,r2 extlh r2,r3,r2
2473 or r1.r2.r1 addl r1,r2,r1
2475 quad: ldq_u r1,X(r11)
2484 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
2486 HOST_WIDE_INT size, ofs;
2489 rtx meml, memh, addr, extl, exth, tmp;
2490 enum machine_mode mode;
2492 meml = gen_reg_rtx (DImode);
2493 memh = gen_reg_rtx (DImode);
2494 addr = gen_reg_rtx (DImode);
2495 extl = gen_reg_rtx (DImode);
2496 exth = gen_reg_rtx (DImode);
2498 /* AND addresses cannot be in any alias set, since they may implicitly
2499 alias surrounding code. Ideally we'd have some alias set that
2500 covered all types except those with alignment 8 or higher. */
2502 tmp = change_address (mem, DImode,
2503 gen_rtx_AND (DImode,
2504 plus_constant (XEXP (mem, 0), ofs),
2506 MEM_ALIAS_SET (tmp) = 0;
2507 emit_move_insn (meml, tmp);
2509 tmp = change_address (mem, DImode,
2510 gen_rtx_AND (DImode,
2511 plus_constant (XEXP (mem, 0),
2514 MEM_ALIAS_SET (tmp) = 0;
2515 emit_move_insn (memh, tmp);
2517 if (sign && size == 2)
2519 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
2521 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
2522 emit_insn (gen_extqh (exth, memh, addr));
2524 /* We must use tgt here for the target. Alpha-vms port fails if we use
2525 addr for the target, because addr is marked as a pointer and combine
2526 knows that pointers are always sign-extended 32 bit values. */
2527 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
2528 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
2529 addr, 1, OPTAB_WIDEN);
2533 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
2534 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
2538 emit_insn (gen_extwh (exth, memh, addr));
2543 emit_insn (gen_extlh (exth, memh, addr));
2548 emit_insn (gen_extqh (exth, memh, addr));
2556 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
2557 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
2562 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
2565 /* Similarly, use ins and msk instructions to perform unaligned stores. */
2568 alpha_expand_unaligned_store (dst, src, size, ofs)
2570 HOST_WIDE_INT size, ofs;
2572 rtx dstl, dsth, addr, insl, insh, meml, memh;
2574 dstl = gen_reg_rtx (DImode);
2575 dsth = gen_reg_rtx (DImode);
2576 insl = gen_reg_rtx (DImode);
2577 insh = gen_reg_rtx (DImode);
2579 /* AND addresses cannot be in any alias set, since they may implicitly
2580 alias surrounding code. Ideally we'd have some alias set that
2581 covered all types except those with alignment 8 or higher. */
2583 meml = change_address (dst, DImode,
2584 gen_rtx_AND (DImode,
2585 plus_constant (XEXP (dst, 0), ofs),
2587 MEM_ALIAS_SET (meml) = 0;
2589 memh = change_address (dst, DImode,
2590 gen_rtx_AND (DImode,
2591 plus_constant (XEXP (dst, 0),
2594 MEM_ALIAS_SET (memh) = 0;
2596 emit_move_insn (dsth, memh);
2597 emit_move_insn (dstl, meml);
2598 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
2600 if (src != const0_rtx)
2602 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
2603 GEN_INT (size*8), addr));
2608 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
2611 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
2614 emit_insn (gen_insql (insl, src, addr));
2619 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
2624 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
2627 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
2631 #if HOST_BITS_PER_WIDE_INT == 32
2632 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
2634 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
2636 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
2641 if (src != const0_rtx)
2643 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
2644 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
2647 /* Must store high before low for degenerate case of aligned. */
2648 emit_move_insn (memh, dsth);
2649 emit_move_insn (meml, dstl);
2652 /* The block move code tries to maximize speed by separating loads and
2653 stores at the expense of register pressure: we load all of the data
2654 before we store it back out. There are two secondary effects worth
2655 mentioning, that this speeds copying to/from aligned and unaligned
2656 buffers, and that it makes the code significantly easier to write. */
2658 #define MAX_MOVE_WORDS 8
2660 /* Load an integral number of consecutive unaligned quadwords. */
2663 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
2666 HOST_WIDE_INT words, ofs;
2668 rtx const im8 = GEN_INT (-8);
2669 rtx const i64 = GEN_INT (64);
2670 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
2671 rtx sreg, areg, tmp;
2674 /* Generate all the tmp registers we need. */
2675 for (i = 0; i < words; ++i)
2677 data_regs[i] = out_regs[i];
2678 ext_tmps[i] = gen_reg_rtx (DImode);
2680 data_regs[words] = gen_reg_rtx (DImode);
2683 smem = change_address (smem, GET_MODE (smem),
2684 plus_constant (XEXP (smem, 0), ofs));
2686 /* Load up all of the source data. */
2687 for (i = 0; i < words; ++i)
2689 tmp = change_address (smem, DImode,
2690 gen_rtx_AND (DImode,
2691 plus_constant (XEXP(smem,0), 8*i),
2693 MEM_ALIAS_SET (tmp) = 0;
2694 emit_move_insn (data_regs[i], tmp);
2697 tmp = change_address (smem, DImode,
2698 gen_rtx_AND (DImode,
2699 plus_constant (XEXP(smem,0), 8*words - 1),
2701 MEM_ALIAS_SET (tmp) = 0;
2702 emit_move_insn (data_regs[words], tmp);
2704 /* Extract the half-word fragments. Unfortunately DEC decided to make
2705 extxh with offset zero a noop instead of zeroing the register, so
2706 we must take care of that edge condition ourselves with cmov. */
2708 sreg = copy_addr_to_reg (XEXP (smem, 0));
2709 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
2711 for (i = 0; i < words; ++i)
2713 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
2715 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
2716 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
2717 gen_rtx_IF_THEN_ELSE (DImode,
2718 gen_rtx_EQ (DImode, areg,
2720 const0_rtx, ext_tmps[i])));
2723 /* Merge the half-words into whole words. */
2724 for (i = 0; i < words; ++i)
2726 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
2727 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
2731 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
2732 may be NULL to store zeros. */
2735 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
2738 HOST_WIDE_INT words, ofs;
2740 rtx const im8 = GEN_INT (-8);
2741 rtx const i64 = GEN_INT (64);
2742 #if HOST_BITS_PER_WIDE_INT == 32
2743 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
2745 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
2747 rtx ins_tmps[MAX_MOVE_WORDS];
2748 rtx st_tmp_1, st_tmp_2, dreg;
2749 rtx st_addr_1, st_addr_2;
2752 /* Generate all the tmp registers we need. */
2753 if (data_regs != NULL)
2754 for (i = 0; i < words; ++i)
2755 ins_tmps[i] = gen_reg_rtx(DImode);
2756 st_tmp_1 = gen_reg_rtx(DImode);
2757 st_tmp_2 = gen_reg_rtx(DImode);
2760 dmem = change_address (dmem, GET_MODE (dmem),
2761 plus_constant (XEXP (dmem, 0), ofs));
2764 st_addr_2 = change_address (dmem, DImode,
2765 gen_rtx_AND (DImode,
2766 plus_constant (XEXP(dmem,0),
2769 MEM_ALIAS_SET (st_addr_2) = 0;
2771 st_addr_1 = change_address (dmem, DImode,
2772 gen_rtx_AND (DImode,
2775 MEM_ALIAS_SET (st_addr_1) = 0;
2777 /* Load up the destination end bits. */
2778 emit_move_insn (st_tmp_2, st_addr_2);
2779 emit_move_insn (st_tmp_1, st_addr_1);
2781 /* Shift the input data into place. */
2782 dreg = copy_addr_to_reg (XEXP (dmem, 0));
2783 if (data_regs != NULL)
2785 for (i = words-1; i >= 0; --i)
2787 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
2788 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2790 for (i = words-1; i > 0; --i)
2792 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2793 ins_tmps[i-1], ins_tmps[i-1], 1,
2798 /* Split and merge the ends with the destination data. */
2799 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2800 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2802 if (data_regs != NULL)
2804 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2805 st_tmp_2, 1, OPTAB_WIDEN);
2806 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2807 st_tmp_1, 1, OPTAB_WIDEN);
2811 emit_move_insn (st_addr_2, st_tmp_2);
2812 for (i = words-1; i > 0; --i)
2814 rtx tmp = change_address (dmem, DImode,
2815 gen_rtx_AND (DImode,
2816 plus_constant(XEXP (dmem,0), i*8),
2818 MEM_ALIAS_SET (tmp) = 0;
2819 emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
2821 emit_move_insn (st_addr_1, st_tmp_1);
2825 /* Expand string/block move operations.
2827 operands[0] is the pointer to the destination.
2828 operands[1] is the pointer to the source.
2829 operands[2] is the number of bytes to move.
2830 operands[3] is the alignment. */
2833 alpha_expand_block_move (operands)
2836 rtx bytes_rtx = operands[2];
2837 rtx align_rtx = operands[3];
2838 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2839 HOST_WIDE_INT bytes = orig_bytes;
2840 HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
2841 HOST_WIDE_INT dst_align = src_align;
2842 rtx orig_src = operands[1];
2843 rtx orig_dst = operands[0];
2844 rtx data_regs[2 * MAX_MOVE_WORDS + 16];
2846 int i, words, ofs, nregs = 0;
2848 if (orig_bytes <= 0)
2850 else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
2853 /* Look for additional alignment information from recorded register info. */
2855 tmp = XEXP (orig_src, 0);
2856 if (GET_CODE (tmp) == REG)
2857 src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2858 else if (GET_CODE (tmp) == PLUS
2859 && GET_CODE (XEXP (tmp, 0)) == REG
2860 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2862 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2863 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2867 if (a >= 64 && c % 8 == 0)
2869 else if (a >= 32 && c % 4 == 0)
2871 else if (a >= 16 && c % 2 == 0)
2876 tmp = XEXP (orig_dst, 0);
2877 if (GET_CODE (tmp) == REG)
2878 dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
2879 else if (GET_CODE (tmp) == PLUS
2880 && GET_CODE (XEXP (tmp, 0)) == REG
2881 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2883 unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2884 unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2888 if (a >= 64 && c % 8 == 0)
2890 else if (a >= 32 && c % 4 == 0)
2892 else if (a >= 16 && c % 2 == 0)
2897 /* Load the entire block into registers. */
2898 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2900 enum machine_mode mode;
2902 tmp = XEXP (XEXP (orig_src, 0), 0);
2904 /* Don't use the existing register if we're reading more than
2905 is held in the register. Nor if there is not a mode that
2906 handles the exact size. */
2907 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2909 && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2913 data_regs[nregs] = gen_lowpart (DImode, tmp);
2914 data_regs[nregs+1] = gen_highpart (DImode, tmp);
2918 data_regs[nregs++] = gen_lowpart (mode, tmp);
2923 /* No appropriate mode; fall back on memory. */
2924 orig_src = change_address (orig_src, GET_MODE (orig_src),
2925 copy_addr_to_reg (XEXP (orig_src, 0)));
2926 src_align = GET_MODE_BITSIZE (GET_MODE (tmp));
2930 if (src_align >= 64 && bytes >= 8)
2934 for (i = 0; i < words; ++i)
2935 data_regs[nregs + i] = gen_reg_rtx(DImode);
2937 for (i = 0; i < words; ++i)
2938 emit_move_insn (data_regs[nregs + i],
2939 change_address (orig_src, DImode,
2940 plus_constant (XEXP (orig_src, 0),
2948 if (src_align >= 32 && bytes >= 4)
2952 for (i = 0; i < words; ++i)
2953 data_regs[nregs + i] = gen_reg_rtx(SImode);
2955 for (i = 0; i < words; ++i)
2956 emit_move_insn (data_regs[nregs + i],
2957 change_address (orig_src, SImode,
2958 plus_constant (XEXP (orig_src, 0),
2970 for (i = 0; i < words+1; ++i)
2971 data_regs[nregs + i] = gen_reg_rtx(DImode);
2973 alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2981 if (! TARGET_BWX && bytes >= 4)
2983 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2984 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2991 if (src_align >= 16)
2994 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2995 emit_move_insn (tmp,
2996 change_address (orig_src, HImode,
2997 plus_constant (XEXP (orig_src, 0),
3001 } while (bytes >= 2);
3003 else if (! TARGET_BWX)
3005 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3006 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3014 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3015 emit_move_insn (tmp,
3016 change_address (orig_src, QImode,
3017 plus_constant (XEXP (orig_src, 0),
3025 if (nregs > ARRAY_SIZE (data_regs))
3028 /* Now save it back out again. */
3032 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
3034 enum machine_mode mode;
3035 tmp = XEXP (XEXP (orig_dst, 0), 0);
3037 mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
3038 if (GET_MODE (tmp) == mode)
3042 emit_move_insn (tmp, data_regs[0]);
3047 else if (nregs == 2 && mode == TImode)
3049 /* Undo the subregging done above when copying between
3050 two TImode registers. */
3051 if (GET_CODE (data_regs[0]) == SUBREG
3052 && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
3053 emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
3059 emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
3060 emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
3064 emit_no_conflict_block (seq, tmp, data_regs[0],
3065 data_regs[1], NULL_RTX);
3073 /* ??? If nregs > 1, consider reconstructing the word in regs. */
3074 /* ??? Optimize mode < dst_mode with strict_low_part. */
3076 /* No appropriate mode; fall back on memory. We can speed things
3077 up by recognizing extra alignment information. */
3078 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
3079 copy_addr_to_reg (XEXP (orig_dst, 0)));
3080 dst_align = GET_MODE_BITSIZE (GET_MODE (tmp));
3083 /* Write out the data in whatever chunks reading the source allowed. */
3084 if (dst_align >= 64)
3086 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3088 emit_move_insn (change_address (orig_dst, DImode,
3089 plus_constant (XEXP (orig_dst, 0),
3097 if (dst_align >= 32)
3099 /* If the source has remaining DImode regs, write them out in
3101 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3103 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3104 NULL_RTX, 1, OPTAB_WIDEN);
3106 emit_move_insn (change_address (orig_dst, SImode,
3107 plus_constant (XEXP (orig_dst, 0),
3109 gen_lowpart (SImode, data_regs[i]));
3110 emit_move_insn (change_address (orig_dst, SImode,
3111 plus_constant (XEXP (orig_dst, 0),
3113 gen_lowpart (SImode, tmp));
3118 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3120 emit_move_insn (change_address(orig_dst, SImode,
3121 plus_constant (XEXP (orig_dst, 0),
3129 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3131 /* Write out a remaining block of words using unaligned methods. */
3133 for (words = 1; i + words < nregs; words++)
3134 if (GET_MODE (data_regs[i + words]) != DImode)
3138 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3140 alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3147 /* Due to the above, this won't be aligned. */
3148 /* ??? If we have more than one of these, consider constructing full
3149 words in registers and using alpha_expand_unaligned_store_words. */
3150 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3152 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3157 if (dst_align >= 16)
3158 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3160 emit_move_insn (change_address (orig_dst, HImode,
3161 plus_constant (XEXP (orig_dst, 0),
3168 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3170 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3175 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
3177 emit_move_insn (change_address (orig_dst, QImode,
3178 plus_constant (XEXP (orig_dst, 0),
3194 alpha_expand_block_clear (operands)
3197 rtx bytes_rtx = operands[1];
3198 rtx align_rtx = operands[2];
3199 HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3200 HOST_WIDE_INT bytes = orig_bytes;
3201 HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
3202 HOST_WIDE_INT alignofs = 0;
3203 rtx orig_dst = operands[0];
3205 int i, words, ofs = 0;
3207 if (orig_bytes <= 0)
3209 if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3212 /* Look for stricter alignment. */
3213 tmp = XEXP (orig_dst, 0);
3214 if (GET_CODE (tmp) == REG)
3215 align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3216 else if (GET_CODE (tmp) == PLUS
3217 && GET_CODE (XEXP (tmp, 0)) == REG
3218 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
3220 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3221 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3226 align = a, alignofs = 8 - c % 8;
3228 align = a, alignofs = 4 - c % 4;
3230 align = a, alignofs = 2 - c % 2;
3233 else if (GET_CODE (tmp) == ADDRESSOF)
3235 enum machine_mode mode;
3237 mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
3238 if (GET_MODE (XEXP (tmp, 0)) == mode)
3240 emit_move_insn (XEXP (tmp, 0), const0_rtx);
3244 /* No appropriate mode; fall back on memory. */
3245 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
3246 copy_addr_to_reg (tmp));
3247 align = GET_MODE_BITSIZE (GET_MODE (XEXP (tmp, 0)));
3250 /* Handle an unaligned prefix first. */
3254 #if HOST_BITS_PER_WIDE_INT >= 64
3255 /* Given that alignofs is bounded by align, the only time BWX could
3256 generate three stores is for a 7 byte fill. Prefer two individual
3257 stores over a load/mask/store sequence. */
3258 if ((!TARGET_BWX || alignofs == 7)
3260 && !(alignofs == 4 && bytes >= 4))
3262 enum machine_mode mode = (align >= 64 ? DImode : SImode);
3263 int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
3267 mem = change_address (orig_dst, mode,
3268 plus_constant (XEXP (orig_dst, 0),
3269 ofs - inv_alignofs));
3270 MEM_ALIAS_SET (mem) = 0;
3272 mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
3273 if (bytes < alignofs)
3275 mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
3286 tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
3287 NULL_RTX, 1, OPTAB_WIDEN);
3289 emit_move_insn (mem, tmp);
3293 if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
3295 emit_move_insn (change_address (orig_dst, QImode,
3296 plus_constant (XEXP (orig_dst, 0),
3303 if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
3305 emit_move_insn (change_address (orig_dst, HImode,
3306 plus_constant (XEXP (orig_dst, 0),
3313 if (alignofs == 4 && bytes >= 4)
3315 emit_move_insn (change_address (orig_dst, SImode,
3316 plus_constant (XEXP (orig_dst, 0),
3324 /* If we've not used the extra lead alignment information by now,
3325 we won't be able to. Downgrade align to match what's left over. */
3328 alignofs = alignofs & -alignofs;
3329 align = MIN (align, alignofs * BITS_PER_UNIT);
3333 /* Handle a block of contiguous long-words. */
3335 if (align >= 64 && bytes >= 8)
3339 for (i = 0; i < words; ++i)
3340 emit_move_insn (change_address(orig_dst, DImode,
3341 plus_constant (XEXP (orig_dst, 0),
3349 /* If the block is large and appropriately aligned, emit a single
3350 store followed by a sequence of stq_u insns. */
3352 if (align >= 32 && bytes > 16)
3354 emit_move_insn (change_address (orig_dst, SImode,
3355 plus_constant (XEXP (orig_dst, 0), ofs)),
3361 for (i = 0; i < words; ++i)
3364 mem = change_address (orig_dst, DImode,
3365 gen_rtx_AND (DImode,
3366 plus_constant (XEXP (orig_dst, 0),
3369 MEM_ALIAS_SET (mem) = 0;
3370 emit_move_insn (mem, const0_rtx);
3373 /* Depending on the alignment, the first stq_u may have overlapped
3374 with the initial stl, which means that the last stq_u didn't
3375 write as much as it would appear. Leave those questionable bytes
3377 bytes -= words * 8 - 4;
3378 ofs += words * 8 - 4;
3381 /* Handle a smaller block of aligned words. */
3383 if ((align >= 64 && bytes == 4)
3384 || (align == 32 && bytes >= 4))
3388 for (i = 0; i < words; ++i)
3389 emit_move_insn (change_address (orig_dst, SImode,
3390 plus_constant (XEXP (orig_dst, 0),
3398 /* An unaligned block uses stq_u stores for as many as possible. */
3404 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
3410 /* Next clean up any trailing pieces. */
3412 #if HOST_BITS_PER_WIDE_INT >= 64
3413 /* Count the number of bits in BYTES for which aligned stores could
3416 for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
3420 /* If we have appropriate alignment (and it wouldn't take too many
3421 instructions otherwise), mask out the bytes we need. */
3422 if (TARGET_BWX ? words > 2 : bytes > 0)
3429 mem = change_address (orig_dst, DImode,
3430 plus_constant (XEXP (orig_dst, 0), ofs));
3431 MEM_ALIAS_SET (mem) = 0;
3433 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
3435 tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
3436 NULL_RTX, 1, OPTAB_WIDEN);
3438 emit_move_insn (mem, tmp);
3441 else if (align >= 32 && bytes < 4)
3446 mem = change_address (orig_dst, SImode,
3447 plus_constant (XEXP (orig_dst, 0), ofs));
3448 MEM_ALIAS_SET (mem) = 0;
3450 mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
3452 tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
3453 NULL_RTX, 1, OPTAB_WIDEN);
3455 emit_move_insn (mem, tmp);
3461 if (!TARGET_BWX && bytes >= 4)
3463 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
3473 emit_move_insn (change_address (orig_dst, HImode,
3474 plus_constant (XEXP (orig_dst, 0),
3479 } while (bytes >= 2);
3481 else if (! TARGET_BWX)
3483 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
3491 emit_move_insn (change_address (orig_dst, QImode,
3492 plus_constant (XEXP (orig_dst, 0),
3502 /* Adjust the cost of a scheduling dependency. Return the new cost of
3503 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
3506 alpha_adjust_cost (insn, link, dep_insn, cost)
3513 enum attr_type insn_type, dep_insn_type;
3515 /* If the dependence is an anti-dependence, there is no cost. For an
3516 output dependence, there is sometimes a cost, but it doesn't seem
3517 worth handling those few cases. */
3519 if (REG_NOTE_KIND (link) != 0)
3522 /* If we can't recognize the insns, we can't really do anything. */
3523 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3526 insn_type = get_attr_type (insn);
3527 dep_insn_type = get_attr_type (dep_insn);
3529 /* Bring in the user-defined memory latency. */
3530 if (dep_insn_type == TYPE_ILD
3531 || dep_insn_type == TYPE_FLD
3532 || dep_insn_type == TYPE_LDSYM)
3533 cost += alpha_memory_latency-1;
3538 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
3539 being stored, we can sometimes lower the cost. */
3541 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
3542 && (set = single_set (dep_insn)) != 0
3543 && GET_CODE (PATTERN (insn)) == SET
3544 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
3546 switch (dep_insn_type)
3550 /* No savings here. */
3554 /* In these cases, we save one cycle. */
3558 /* In all other cases, we save two cycles. */
3559 return MAX (0, cost - 2);
3563 /* Another case that needs adjustment is an arithmetic or logical
3564 operation. It's cost is usually one cycle, but we default it to
3565 two in the MD file. The only case that it is actually two is
3566 for the address in loads, stores, and jumps. */
3568 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
3583 /* The final case is when a compare feeds into an integer branch;
3584 the cost is only one cycle in that case. */
3586 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
3591 /* And the lord DEC saith: "A special bypass provides an effective
3592 latency of 0 cycles for an ICMP or ILOG insn producing the test
3593 operand of an IBR or ICMOV insn." */
3595 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
3596 && (set = single_set (dep_insn)) != 0)
3598 /* A branch only has one input. This must be it. */
3599 if (insn_type == TYPE_IBR)
3601 /* A conditional move has three, make sure it is the test. */
3602 if (insn_type == TYPE_ICMOV
3603 && GET_CODE (set_src = PATTERN (insn)) == SET
3604 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
3605 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
3609 /* "The multiplier is unable to receive data from IEU bypass paths.
3610 The instruction issues at the expected time, but its latency is
3611 increased by the time it takes for the input data to become
3612 available to the multiplier" -- which happens in pipeline stage
3613 six, when results are comitted to the register file. */
3615 if (insn_type == TYPE_IMUL)
3617 switch (dep_insn_type)
3619 /* These insns produce their results in pipeline stage five. */
3626 /* Other integer insns produce results in pipeline stage four. */
3634 /* There is additional latency to move the result of (most) FP
3635 operations anywhere but the FP register file. */
3637 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
3638 && (dep_insn_type == TYPE_FADD ||
3639 dep_insn_type == TYPE_FMUL ||
3640 dep_insn_type == TYPE_FCMOV))
3646 /* Otherwise, return the default cost. */
3650 /* Functions to save and restore alpha_return_addr_rtx. */
3653 alpha_init_machine_status (p)
3657 (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
3661 alpha_mark_machine_status (p)
3664 struct machine_function *machine = p->machine;
3668 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
3669 ggc_mark_rtx (machine->ra_rtx);
3674 alpha_free_machine_status (p)
3681 /* Start the ball rolling with RETURN_ADDR_RTX. */
3684 alpha_return_addr (count, frame)
3686 rtx frame ATTRIBUTE_UNUSED;
3693 reg = cfun->machine->ra_rtx;
3696 /* No rtx yet. Invent one, and initialize it from $26 in
3698 reg = gen_reg_rtx (Pmode);
3699 cfun->machine->ra_rtx = reg;
3700 init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
3702 /* Emit the insn to the prologue with the other argument copies. */
3703 push_topmost_sequence ();
3704 emit_insn_after (init, get_insns ());
3705 pop_topmost_sequence ();
3712 alpha_ra_ever_killed ()
3716 #ifdef ASM_OUTPUT_MI_THUNK
3717 if (current_function_is_thunk)
3720 if (!cfun->machine->ra_rtx)
3721 return regs_ever_live[REG_RA];
3723 push_topmost_sequence ();
3725 pop_topmost_sequence ();
3727 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
3731 /* Print an operand. Recognize special options, documented below. */
3734 print_operand (file, x, code)
3744 /* Print the assembler name of the current function. */
3745 assemble_name (file, alpha_fnname);
3749 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
3750 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
3751 mode. alpha_fprm controls which suffix is generated. */
3754 case ALPHA_FPRM_NORM:
3756 case ALPHA_FPRM_MINF:
3759 case ALPHA_FPRM_CHOP:
3762 case ALPHA_FPRM_DYN:
3771 /* Generates trap-mode suffix for instructions that accept the su
3772 suffix only (cmpt et al). */
3773 if (alpha_fptm >= ALPHA_FPTM_SU)
3778 /* Generates trap-mode suffix for instructions that accept the
3779 v and sv suffix. The only instruction that needs this is cvtql. */
3788 case ALPHA_FPTM_SUI:
3795 /* Generates trap-mode suffix for instructions that accept the
3796 v, sv, and svi suffix. The only instruction that needs this
3808 case ALPHA_FPTM_SUI:
3809 fputs ("svi", file);
3815 /* Generates trap-mode suffix for instructions that accept the u, su,
3816 and sui suffix. This is the bulk of the IEEE floating point
3817 instructions (addt et al). */
3828 case ALPHA_FPTM_SUI:
3829 fputs ("sui", file);
3835 /* Generates trap-mode suffix for instructions that accept the sui
3836 suffix (cvtqt and cvtqs). */
3841 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
3843 case ALPHA_FPTM_SUI:
3844 fputs ("sui", file);
3850 /* Generates single precision instruction suffix. */
3851 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
3855 /* Generates double precision instruction suffix. */
3856 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
3860 /* If this operand is the constant zero, write it as "$31". */
3861 if (GET_CODE (x) == REG)
3862 fprintf (file, "%s", reg_names[REGNO (x)]);
3863 else if (x == CONST0_RTX (GET_MODE (x)))
3864 fprintf (file, "$31");
3866 output_operand_lossage ("invalid %%r value");
3871 /* Similar, but for floating-point. */
3872 if (GET_CODE (x) == REG)
3873 fprintf (file, "%s", reg_names[REGNO (x)]);
3874 else if (x == CONST0_RTX (GET_MODE (x)))
3875 fprintf (file, "$f31");
3877 output_operand_lossage ("invalid %%R value");
3882 /* Write the 1's complement of a constant. */
3883 if (GET_CODE (x) != CONST_INT)
3884 output_operand_lossage ("invalid %%N value");
3886 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
3890 /* Write 1 << C, for a constant C. */
3891 if (GET_CODE (x) != CONST_INT)
3892 output_operand_lossage ("invalid %%P value");
3894 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
3898 /* Write the high-order 16 bits of a constant, sign-extended. */
3899 if (GET_CODE (x) != CONST_INT)
3900 output_operand_lossage ("invalid %%h value");
3902 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
3906 /* Write the low-order 16 bits of a constant, sign-extended. */
3907 if (GET_CODE (x) != CONST_INT)
3908 output_operand_lossage ("invalid %%L value");
3910 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3911 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
3915 /* Write mask for ZAP insn. */
3916 if (GET_CODE (x) == CONST_DOUBLE)
3918 HOST_WIDE_INT mask = 0;
3919 HOST_WIDE_INT value;
3921 value = CONST_DOUBLE_LOW (x);
3922 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3927 value = CONST_DOUBLE_HIGH (x);
3928 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3931 mask |= (1 << (i + sizeof (int)));
3933 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
3936 else if (GET_CODE (x) == CONST_INT)
3938 HOST_WIDE_INT mask = 0, value = INTVAL (x);
3940 for (i = 0; i < 8; i++, value >>= 8)
3944 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
3947 output_operand_lossage ("invalid %%m value");
3951 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
3952 if (GET_CODE (x) != CONST_INT
3953 || (INTVAL (x) != 8 && INTVAL (x) != 16
3954 && INTVAL (x) != 32 && INTVAL (x) != 64))
3955 output_operand_lossage ("invalid %%M value");
3957 fprintf (file, "%s",
3958 (INTVAL (x) == 8 ? "b"
3959 : INTVAL (x) == 16 ? "w"
3960 : INTVAL (x) == 32 ? "l"
3965 /* Similar, except do it from the mask. */
3966 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3967 fprintf (file, "b");
3968 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3969 fprintf (file, "w");
3970 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3971 fprintf (file, "l");
3972 #if HOST_BITS_PER_WIDE_INT == 32
3973 else if (GET_CODE (x) == CONST_DOUBLE
3974 && CONST_DOUBLE_HIGH (x) == 0
3975 && CONST_DOUBLE_LOW (x) == -1)
3976 fprintf (file, "l");
3977 else if (GET_CODE (x) == CONST_DOUBLE
3978 && CONST_DOUBLE_HIGH (x) == -1
3979 && CONST_DOUBLE_LOW (x) == -1)
3980 fprintf (file, "q");
3982 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3983 fprintf (file, "q");
3984 else if (GET_CODE (x) == CONST_DOUBLE
3985 && CONST_DOUBLE_HIGH (x) == 0
3986 && CONST_DOUBLE_LOW (x) == -1)
3987 fprintf (file, "q");
3990 output_operand_lossage ("invalid %%U value");
3994 /* Write the constant value divided by 8. */
3995 if (GET_CODE (x) != CONST_INT
3996 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3997 && (INTVAL (x) & 7) != 8)
3998 output_operand_lossage ("invalid %%s value");
4000 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
4004 /* Same, except compute (64 - c) / 8 */
4006 if (GET_CODE (x) != CONST_INT
4007 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
4008 && (INTVAL (x) & 7) != 8)
4009 output_operand_lossage ("invalid %%s value");
4011 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
4014 case 'C': case 'D': case 'c': case 'd':
4015 /* Write out comparison name. */
4017 enum rtx_code c = GET_CODE (x);
4019 if (GET_RTX_CLASS (c) != '<')
4020 output_operand_lossage ("invalid %%C value");
4022 else if (code == 'D')
4023 c = reverse_condition (c);
4024 else if (code == 'c')
4025 c = swap_condition (c);
4026 else if (code == 'd')
4027 c = swap_condition (reverse_condition (c));
4030 fprintf (file, "ule");
4032 fprintf (file, "ult");
4033 else if (c == UNORDERED)
4034 fprintf (file, "un");
4036 fprintf (file, "%s", GET_RTX_NAME (c));
4041 /* Write the divide or modulus operator. */
4042 switch (GET_CODE (x))
4045 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
4048 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
4051 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
4054 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
4057 output_operand_lossage ("invalid %%E value");
4063 /* Write "_u" for unaligned access. */
4064 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
4065 fprintf (file, "_u");
4069 if (GET_CODE (x) == REG)
4070 fprintf (file, "%s", reg_names[REGNO (x)]);
4071 else if (GET_CODE (x) == MEM)
4072 output_address (XEXP (x, 0));
4074 output_addr_const (file, x);
4078 output_operand_lossage ("invalid %%xn code");
4083 print_operand_address (file, addr)
4088 HOST_WIDE_INT offset = 0;
4090 if (GET_CODE (addr) == AND)
4091 addr = XEXP (addr, 0);
4093 if (GET_CODE (addr) == PLUS
4094 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
4096 offset = INTVAL (XEXP (addr, 1));
4097 addr = XEXP (addr, 0);
4099 if (GET_CODE (addr) == REG)
4100 basereg = REGNO (addr);
4101 else if (GET_CODE (addr) == SUBREG
4102 && GET_CODE (SUBREG_REG (addr)) == REG)
4103 basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
4104 else if (GET_CODE (addr) == CONST_INT)
4105 offset = INTVAL (addr);
4109 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
4110 fprintf (file, "($%d)", basereg);
4113 /* Emit RTL insns to initialize the variable parts of a trampoline at
4114 TRAMP. FNADDR is an RTX for the address of the function's pure
4115 code. CXT is an RTX for the static chain value for the function.
4117 The three offset parameters are for the individual template's
4118 layout. A JMPOFS < 0 indicates that the trampoline does not
4119 contain instructions at all.
4121 We assume here that a function will be called many more times than
4122 its address is taken (e.g., it might be passed to qsort), so we
4123 take the trouble to initialize the "hint" field in the JMP insn.
4124 Note that the hint field is PC (new) + 4 * bits 13:0. */
4127 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
4128 rtx tramp, fnaddr, cxt;
4129 int fnofs, cxtofs, jmpofs;
4131 rtx temp, temp1, addr;
4132 /* VMS really uses DImode pointers in memory at this point. */
4133 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
4135 #ifdef POINTERS_EXTEND_UNSIGNED
4136 fnaddr = convert_memory_address (mode, fnaddr);
4137 cxt = convert_memory_address (mode, cxt);
4140 /* Store function address and CXT. */
4141 addr = memory_address (mode, plus_constant (tramp, fnofs));
4142 emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
4143 addr = memory_address (mode, plus_constant (tramp, cxtofs));
4144 emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
4146 /* This has been disabled since the hint only has a 32k range, and in
4147 no existing OS is the stack within 32k of the text segment. */
4148 if (0 && jmpofs >= 0)
4150 /* Compute hint value. */
4151 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
4152 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
4154 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
4155 build_int_2 (2, 0), NULL_RTX, 1);
4156 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
4158 /* Merge in the hint. */
4159 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
4160 temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
4161 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
4162 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
4164 emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
4167 #ifdef TRANSFER_FROM_TRAMPOLINE
4168 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
4169 0, VOIDmode, 1, addr, Pmode);
4173 emit_insn (gen_imb ());
4176 /* Determine where to put an argument to a function.
4177 Value is zero to push the argument on the stack,
4178 or a hard register in which to store the argument.
4180 MODE is the argument's machine mode.
4181 TYPE is the data type of the argument (as a tree).
4182 This is null for libcalls where that information may
4184 CUM is a variable of type CUMULATIVE_ARGS which gives info about
4185 the preceding args and about the function being called.
4186 NAMED is nonzero if this argument is a named parameter
4187 (otherwise it is an extra parameter matching an ellipsis).
4189 On Alpha the first 6 words of args are normally in registers
4190 and the rest are pushed. */
4193 function_arg (cum, mode, type, named)
4194 CUMULATIVE_ARGS cum;
4195 enum machine_mode mode;
4197 int named ATTRIBUTE_UNUSED;
4207 /* VOID is passed as a special flag for "last argument". */
4208 if (type == void_type_node)
4210 else if (MUST_PASS_IN_STACK (mode, type))
4212 else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
4215 if (mode == VOIDmode)
4216 return alpha_arg_info_reg_val (cum);
4218 num_args = cum.num_args;
4219 if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
4221 #endif /* OPEN_VMS */
4222 else if (TARGET_FPREGS
4223 && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
4224 || GET_MODE_CLASS (mode) == MODE_FLOAT))
4229 return gen_rtx_REG (mode, num_args + basereg);
4233 alpha_build_va_list ()
4235 tree base, ofs, record, type_decl;
4237 if (TARGET_OPEN_VMS)
4238 return ptr_type_node;
4240 record = make_lang_type (RECORD_TYPE);
4241 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
4242 TREE_CHAIN (record) = type_decl;
4243 TYPE_NAME (record) = type_decl;
4245 /* C++? SET_IS_AGGR_TYPE (record, 1); */
4247 ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
4249 DECL_FIELD_CONTEXT (ofs) = record;
4251 base = build_decl (FIELD_DECL, get_identifier ("__base"),
4253 DECL_FIELD_CONTEXT (base) = record;
4254 TREE_CHAIN (base) = ofs;
4256 TYPE_FIELDS (record) = base;
4257 layout_type (record);
4263 alpha_va_start (stdarg_p, valist, nextarg)
4266 rtx nextarg ATTRIBUTE_UNUSED;
4268 HOST_WIDE_INT offset;
4269 tree t, offset_field, base_field;
4271 if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
4274 if (TARGET_OPEN_VMS)
4275 std_expand_builtin_va_start (stdarg_p, valist, nextarg);
4277 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
4278 up by 48, storing fp arg registers in the first 48 bytes, and the
4279 integer arg registers in the next 48 bytes. This is only done,
4280 however, if any integer registers need to be stored.
4282 If no integer registers need be stored, then we must subtract 48
4283 in order to account for the integer arg registers which are counted
4284 in argsize above, but which are not actually stored on the stack. */
4286 if (NUM_ARGS <= 5 + stdarg_p)
4287 offset = 6 * UNITS_PER_WORD;
4289 offset = -6 * UNITS_PER_WORD;
4291 base_field = TYPE_FIELDS (TREE_TYPE (valist));
4292 offset_field = TREE_CHAIN (base_field);
4294 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
4295 valist, base_field);
4296 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
4297 valist, offset_field);
4299 t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
4300 t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
4301 t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
4302 TREE_SIDE_EFFECTS (t) = 1;
4303 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4305 t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
4306 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
4307 TREE_SIDE_EFFECTS (t) = 1;
4308 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4312 alpha_va_arg (valist, type)
4315 HOST_WIDE_INT tsize;
4318 tree offset_field, base_field, addr_tree, addend;
4319 tree wide_type, wide_ofs;
4321 if (TARGET_OPEN_VMS)
4322 return std_expand_builtin_va_arg (valist, type);
4324 tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
4326 base_field = TYPE_FIELDS (TREE_TYPE (valist));
4327 offset_field = TREE_CHAIN (base_field);
4329 base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
4330 valist, base_field);
4331 offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
4332 valist, offset_field);
4334 wide_type = make_signed_type (64);
4335 wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
4338 if (FLOAT_TYPE_P (type))
4340 tree fpaddend, cond;
4342 fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
4343 addend, build_int_2 (-6*8, 0)));
4345 cond = fold (build (LT_EXPR, integer_type_node,
4346 wide_ofs, build_int_2 (6*8, 0)));
4348 addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
4352 addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
4353 base_field, addend);
4355 addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4356 addr = copy_to_reg (addr);
4358 t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
4359 build (PLUS_EXPR, TREE_TYPE (offset_field),
4360 offset_field, build_int_2 (tsize, 0)));
4361 TREE_SIDE_EFFECTS (t) = 1;
4362 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4367 /* This page contains routines that are used to determine what the function
4368 prologue and epilogue code will do and write them out. */
4370 /* Compute the size of the save area in the stack. */
4372 /* These variables are used for communication between the following functions.
4373 They indicate various things about the current function being compiled
4374 that are used to tell what kind of prologue, epilogue and procedure
4375 descriptior to generate. */
4377 /* Nonzero if we need a stack procedure. */
4378 static int vms_is_stack_procedure;
4380 /* Register number (either FP or SP) that is used to unwind the frame. */
4381 static int vms_unwind_regno;
4383 /* Register number used to save FP. We need not have one for RA since
4384 we don't modify it for register procedures. This is only defined
4385 for register frame procedures. */
4386 static int vms_save_fp_regno;
4388 /* Register number used to reference objects off our PV. */
4389 static int vms_base_regno;
4391 /* Compute register masks for saved registers. */
4394 alpha_sa_mask (imaskP, fmaskP)
4395 unsigned long *imaskP;
4396 unsigned long *fmaskP;
4398 unsigned long imask = 0;
4399 unsigned long fmask = 0;
4402 #ifdef ASM_OUTPUT_MI_THUNK
4403 if (!current_function_is_thunk)
4406 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4407 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
4409 /* One for every register we have to save. */
4410 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4411 if (! fixed_regs[i] && ! call_used_regs[i]
4412 && regs_ever_live[i] && i != REG_RA)
4417 fmask |= (1L << (i - 32));
4420 if (imask || fmask || alpha_ra_ever_killed ())
4421 imask |= (1L << REG_RA);
4434 #ifdef ASM_OUTPUT_MI_THUNK
4435 if (current_function_is_thunk)
4440 /* One for every register we have to save. */
4441 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4442 if (! fixed_regs[i] && ! call_used_regs[i]
4443 && regs_ever_live[i] && i != REG_RA)
4447 if (TARGET_OPEN_VMS)
4449 /* Start by assuming we can use a register procedure if we don't
4450 make any calls (REG_RA not used) or need to save any
4451 registers and a stack procedure if we do. */
4452 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
4454 /* Decide whether to refer to objects off our PV via FP or PV.
4455 If we need FP for something else or if we receive a nonlocal
4456 goto (which expects PV to contain the value), we must use PV.
4457 Otherwise, start by assuming we can use FP. */
4458 vms_base_regno = (frame_pointer_needed
4459 || current_function_has_nonlocal_label
4460 || vms_is_stack_procedure
4461 || current_function_outgoing_args_size
4462 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
4464 /* If we want to copy PV into FP, we need to find some register
4465 in which to save FP. */
4467 vms_save_fp_regno = -1;
4468 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
4469 for (i = 0; i < 32; i++)
4470 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
4471 vms_save_fp_regno = i;
4473 if (vms_save_fp_regno == -1)
4474 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
4476 /* Stack unwinding should be done via FP unless we use it for PV. */
4477 vms_unwind_regno = (vms_base_regno == REG_PV
4478 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
4480 /* If this is a stack procedure, allow space for saving FP and RA. */
4481 if (vms_is_stack_procedure)
4486 /* If some registers were saved but not RA, RA must also be saved,
4487 so leave space for it. */
4488 if (sa_size != 0 || alpha_ra_ever_killed ())
4491 /* Our size must be even (multiple of 16 bytes). */
4500 alpha_pv_save_size ()
4503 return vms_is_stack_procedure ? 8 : 0;
4510 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
4514 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
4515 tree decl ATTRIBUTE_UNUSED;
4516 tree attributes ATTRIBUTE_UNUSED;
4520 if (is_attribute_p ("overlaid", identifier))
4521 return (args == NULL_TREE);
4526 alpha_does_function_need_gp ()
4530 /* We never need a GP for Windows/NT or VMS. */
4531 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4534 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4537 #ifdef ASM_OUTPUT_MI_THUNK
4538 if (current_function_is_thunk)
4542 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
4543 Even if we are a static function, we still need to do this in case
4544 our address is taken and passed to something like qsort. */
4546 push_topmost_sequence ();
4547 insn = get_insns ();
4548 pop_topmost_sequence ();
4550 for (; insn; insn = NEXT_INSN (insn))
4552 && GET_CODE (PATTERN (insn)) != USE
4553 && GET_CODE (PATTERN (insn)) != CLOBBER)
4555 enum attr_type type = get_attr_type (insn);
4556 if (type == TYPE_LDSYM || type == TYPE_JSR)
4563 /* Write a version stamp. Don't write anything if we are running as a
4564 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
4571 alpha_write_verstamp (file)
4572 FILE *file ATTRIBUTE_UNUSED;
4575 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
4579 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
4583 set_frame_related_p ()
4585 rtx seq = gen_sequence ();
4588 if (GET_CODE (seq) == SEQUENCE)
4590 int i = XVECLEN (seq, 0);
4592 RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
4593 return emit_insn (seq);
4597 seq = emit_insn (seq);
4598 RTX_FRAME_RELATED_P (seq) = 1;
4603 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
4605 /* Write function prologue. */
4607 /* On vms we have two kinds of functions:
4609 - stack frame (PROC_STACK)
4610 these are 'normal' functions with local vars and which are
4611 calling other functions
4612 - register frame (PROC_REGISTER)
4613 keeps all data in registers, needs no stack
4615 We must pass this to the assembler so it can generate the
4616 proper pdsc (procedure descriptor)
4617 This is done with the '.pdesc' command.
4619 On not-vms, we don't really differentiate between the two, as we can
4620 simply allocate stack without saving registers. */
4623 alpha_expand_prologue ()
4625 /* Registers to save. */
4626 unsigned long imask = 0;
4627 unsigned long fmask = 0;
4628 /* Stack space needed for pushing registers clobbered by us. */
4629 HOST_WIDE_INT sa_size;
4630 /* Complete stack size needed. */
4631 HOST_WIDE_INT frame_size;
4632 /* Offset from base reg to register save area. */
4633 HOST_WIDE_INT reg_offset;
4637 sa_size = alpha_sa_size ();
4639 frame_size = get_frame_size ();
4640 if (TARGET_OPEN_VMS)
4641 frame_size = ALPHA_ROUND (sa_size
4642 + (vms_is_stack_procedure ? 8 : 0)
4644 + current_function_pretend_args_size);
4646 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4648 + ALPHA_ROUND (frame_size
4649 + current_function_pretend_args_size));
4651 if (TARGET_OPEN_VMS)
4654 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4656 alpha_sa_mask (&imask, &fmask);
4658 /* Emit an insn to reload GP, if needed. */
4659 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
4661 alpha_function_needs_gp = alpha_does_function_need_gp ();
4662 if (alpha_function_needs_gp)
4663 emit_insn (gen_prologue_ldgp ());
4666 /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
4667 the call to mcount ourselves, rather than having the linker do it
4668 magically in response to -pg. Since _mcount has special linkage,
4669 don't represent the call as a call. */
4670 if (TARGET_PROFILING_NEEDS_GP && profile_flag)
4671 emit_insn (gen_prologue_mcount ());
4673 /* Adjust the stack by the frame size. If the frame size is > 4096
4674 bytes, we need to be sure we probe somewhere in the first and last
4675 4096 bytes (we can probably get away without the latter test) and
4676 every 8192 bytes in between. If the frame size is > 32768, we
4677 do this in a loop. Otherwise, we generate the explicit probe
4680 Note that we are only allowed to adjust sp once in the prologue. */
4682 if (frame_size <= 32768)
4684 if (frame_size > 4096)
4689 emit_insn (gen_probe_stack (GEN_INT (-probed)));
4690 while ((probed += 8192) < frame_size);
4692 /* We only have to do this probe if we aren't saving registers. */
4693 if (sa_size == 0 && probed + 4096 < frame_size)
4694 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
4697 if (frame_size != 0)
4699 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
4700 GEN_INT (-frame_size))));
4705 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
4706 number of 8192 byte blocks to probe. We then probe each block
4707 in the loop and then set SP to the proper location. If the
4708 amount remaining is > 4096, we have to do one more probe if we
4709 are not saving any registers. */
4711 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
4712 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
4713 rtx ptr = gen_rtx_REG (DImode, 22);
4714 rtx count = gen_rtx_REG (DImode, 23);
4717 emit_move_insn (count, GEN_INT (blocks));
4718 emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
4720 /* Because of the difficulty in emitting a new basic block this
4721 late in the compilation, generate the loop as a single insn. */
4722 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
4724 if (leftover > 4096 && sa_size == 0)
4726 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
4727 MEM_VOLATILE_P (last) = 1;
4728 emit_move_insn (last, const0_rtx);
4731 if (TARGET_WINDOWS_NT)
4733 /* For NT stack unwind (done by 'reverse execution'), it's
4734 not OK to take the result of a loop, even though the value
4735 is already in ptr, so we reload it via a single operation
4736 and subtract it to sp.
4738 Yes, that's correct -- we have to reload the whole constant
4739 into a temporary via ldah+lda then subtract from sp. To
4740 ensure we get ldah+lda, we use a special pattern. */
4742 HOST_WIDE_INT lo, hi;
4743 lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4744 hi = frame_size - lo;
4746 emit_move_insn (ptr, GEN_INT (hi));
4747 emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
4748 seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
4753 seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
4754 GEN_INT (-leftover)));
4757 /* This alternative is special, because the DWARF code cannot
4758 possibly intuit through the loop above. So we invent this
4759 note it looks at instead. */
4760 RTX_FRAME_RELATED_P (seq) = 1;
4762 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4763 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4764 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4765 GEN_INT (-frame_size))),
4769 /* Cope with very large offsets to the register save area. */
4770 sa_reg = stack_pointer_rtx;
4771 if (reg_offset + sa_size > 0x8000)
4773 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4776 if (low + sa_size <= 0x8000)
4777 bias = reg_offset - low, reg_offset = low;
4779 bias = reg_offset, reg_offset = 0;
4781 sa_reg = gen_rtx_REG (DImode, 24);
4782 FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
4785 /* Save regs in stack order. Beginning with VMS PV. */
4786 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4788 mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
4789 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4790 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
4793 /* Save register RA next. */
4794 if (imask & (1L << REG_RA))
4796 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4797 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4798 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
4799 imask &= ~(1L << REG_RA);
4803 /* Now save any other registers required to be saved. */
4804 for (i = 0; i < 32; i++)
4805 if (imask & (1L << i))
4807 mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4808 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4809 FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
4813 for (i = 0; i < 32; i++)
4814 if (fmask & (1L << i))
4816 mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
4817 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4818 FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
4822 if (TARGET_OPEN_VMS)
4824 if (!vms_is_stack_procedure)
4826 /* Register frame procedures fave the fp. */
4827 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
4828 hard_frame_pointer_rtx));
4831 if (vms_base_regno != REG_PV)
4832 FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
4833 gen_rtx_REG (DImode, REG_PV)));
4835 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4837 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4840 /* If we have to allocate space for outgoing args, do it now. */
4841 if (current_function_outgoing_args_size != 0)
4843 FRP (emit_move_insn (stack_pointer_rtx,
4844 plus_constant (hard_frame_pointer_rtx,
4845 - ALPHA_ROUND (current_function_outgoing_args_size))));
4850 /* If we need a frame pointer, set it from the stack pointer. */
4851 if (frame_pointer_needed)
4853 if (TARGET_CAN_FAULT_IN_PROLOGUE)
4854 FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4857 /* This must always be the last instruction in the
4858 prologue, thus we emit a special move + clobber. */
4859 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
4860 stack_pointer_rtx, sa_reg)));
4865 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
4866 the prologue, for exception handling reasons, we cannot do this for
4867 any insn that might fault. We could prevent this for mems with a
4868 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
4869 have to prevent all such scheduling with a blockage.
4871 Linux, on the other hand, never bothered to implement OSF/1's
4872 exception handling, and so doesn't care about such things. Anyone
4873 planning to use dwarf2 frame-unwind info can also omit the blockage. */
4875 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
4876 emit_insn (gen_blockage ());
4879 /* Output the textual info surrounding the prologue. */
4882 alpha_start_function (file, fnname, decl)
4885 tree decl ATTRIBUTE_UNUSED;
4887 unsigned long imask = 0;
4888 unsigned long fmask = 0;
4889 /* Stack space needed for pushing registers clobbered by us. */
4890 HOST_WIDE_INT sa_size;
4891 /* Complete stack size needed. */
4892 HOST_WIDE_INT frame_size;
4893 /* Offset from base reg to register save area. */
4894 HOST_WIDE_INT reg_offset;
4895 char *entry_label = (char *) alloca (strlen (fnname) + 6);
4898 alpha_fnname = fnname;
4899 sa_size = alpha_sa_size ();
4901 frame_size = get_frame_size ();
4902 if (TARGET_OPEN_VMS)
4903 frame_size = ALPHA_ROUND (sa_size
4904 + (vms_is_stack_procedure ? 8 : 0)
4906 + current_function_pretend_args_size);
4908 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4910 + ALPHA_ROUND (frame_size
4911 + current_function_pretend_args_size));
4913 if (TARGET_OPEN_VMS)
4916 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4918 alpha_sa_mask (&imask, &fmask);
4920 /* Ecoff can handle multiple .file directives, so put out file and lineno.
4921 We have to do that before the .ent directive as we cannot switch
4922 files within procedures with native ecoff because line numbers are
4923 linked to procedure descriptors.
4924 Outputting the lineno helps debugging of one line functions as they
4925 would otherwise get no line number at all. Please note that we would
4926 like to put out last_linenum from final.c, but it is not accessible. */
4928 if (write_symbols == SDB_DEBUG)
4930 ASM_OUTPUT_SOURCE_FILENAME (file,
4931 DECL_SOURCE_FILE (current_function_decl));
4932 if (debug_info_level != DINFO_LEVEL_TERSE)
4933 ASM_OUTPUT_SOURCE_LINE (file,
4934 DECL_SOURCE_LINE (current_function_decl));
4937 /* Issue function start and label. */
4938 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
4940 fputs ("\t.ent ", file);
4941 assemble_name (file, fnname);
4944 /* If the function needs GP, we'll write the "..ng" label there.
4945 Otherwise, do it here. */
4946 if (! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT
4947 && ! alpha_function_needs_gp)
4950 assemble_name (file, fnname);
4951 fputs ("..ng:\n", file);
4955 strcpy (entry_label, fnname);
4956 if (TARGET_OPEN_VMS)
4957 strcat (entry_label, "..en");
4958 ASM_OUTPUT_LABEL (file, entry_label);
4959 inside_function = TRUE;
4961 if (TARGET_OPEN_VMS)
4962 fprintf (file, "\t.base $%d\n", vms_base_regno);
4964 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
4965 && !flag_inhibit_size_directive)
4967 /* Set flags in procedure descriptor to request IEEE-conformant
4968 math-library routines. The value we set it to is PDSC_EXC_IEEE
4969 (/usr/include/pdsc.h). */
4970 fputs ("\t.eflag 48\n", file);
4973 /* Set up offsets to alpha virtual arg/local debugging pointer. */
4974 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
4975 alpha_arg_offset = -frame_size + 48;
4977 /* Describe our frame. If the frame size is larger than an integer,
4978 print it as zero to avoid an assembler error. We won't be
4979 properly describing such a frame, but that's the best we can do. */
4980 if (TARGET_OPEN_VMS)
4982 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
4983 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4984 frame_size >= (1l << 31) ? 0 : frame_size);
4985 fputs (",$26,", file);
4986 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
4989 else if (!flag_inhibit_size_directive)
4991 fprintf (file, "\t.frame $%d,",
4992 (frame_pointer_needed
4993 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
4994 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4995 frame_size >= (1l << 31) ? 0 : frame_size);
4996 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
4999 /* Describe which registers were spilled. */
5000 if (TARGET_OPEN_VMS)
5003 /* ??? Does VMS care if mask contains ra? The old code did'nt
5004 set it, so I don't here. */
5005 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
5007 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
5008 if (!vms_is_stack_procedure)
5009 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
5011 else if (!flag_inhibit_size_directive)
5015 fprintf (file, "\t.mask 0x%lx,", imask);
5016 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5017 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
5020 for (i = 0; i < 32; ++i)
5021 if (imask & (1L << i))
5027 fprintf (file, "\t.fmask 0x%lx,", fmask);
5028 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5029 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
5035 /* Ifdef'ed cause readonly_section and link_section are only
5037 readonly_section ();
5038 fprintf (file, "\t.align 3\n");
5039 assemble_name (file, fnname); fputs ("..na:\n", file);
5040 fputs ("\t.ascii \"", file);
5041 assemble_name (file, fnname);
5042 fputs ("\\0\"\n", file);
5045 fprintf (file, "\t.align 3\n");
5046 fputs ("\t.name ", file);
5047 assemble_name (file, fnname);
5048 fputs ("..na\n", file);
5049 ASM_OUTPUT_LABEL (file, fnname);
5050 fprintf (file, "\t.pdesc ");
5051 assemble_name (file, fnname);
5052 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
5053 alpha_need_linkage (fnname, 1);
5058 /* Emit the .prologue note at the scheduled end of the prologue. */
5061 output_end_prologue (file)
5064 if (TARGET_OPEN_VMS)
5065 fputs ("\t.prologue\n", file);
5066 else if (TARGET_WINDOWS_NT)
5067 fputs ("\t.prologue 0\n", file);
5068 else if (!flag_inhibit_size_directive)
5069 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
5072 /* Write function epilogue. */
5074 /* ??? At some point we will want to support full unwind, and so will
5075 need to mark the epilogue as well. At the moment, we just confuse
5078 #define FRP(exp) exp
5081 alpha_expand_epilogue ()
5083 /* Registers to save. */
5084 unsigned long imask = 0;
5085 unsigned long fmask = 0;
5086 /* Stack space needed for pushing registers clobbered by us. */
5087 HOST_WIDE_INT sa_size;
5088 /* Complete stack size needed. */
5089 HOST_WIDE_INT frame_size;
5090 /* Offset from base reg to register save area. */
5091 HOST_WIDE_INT reg_offset;
5092 int fp_is_frame_pointer, fp_offset;
5093 rtx sa_reg, sa_reg_exp = NULL;
5094 rtx sp_adj1, sp_adj2, mem;
5098 sa_size = alpha_sa_size ();
5100 frame_size = get_frame_size ();
5101 if (TARGET_OPEN_VMS)
5102 frame_size = ALPHA_ROUND (sa_size
5103 + (vms_is_stack_procedure ? 8 : 0)
5105 + current_function_pretend_args_size);
5107 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
5109 + ALPHA_ROUND (frame_size
5110 + current_function_pretend_args_size));
5112 if (TARGET_OPEN_VMS)
5115 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
5117 alpha_sa_mask (&imask, &fmask);
5119 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
5120 || (!TARGET_OPEN_VMS && frame_pointer_needed));
5122 sa_reg = stack_pointer_rtx;
5124 eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
5127 /* If we have a frame pointer, restore SP from it. */
5128 if ((TARGET_OPEN_VMS
5129 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
5130 || (!TARGET_OPEN_VMS && frame_pointer_needed))
5132 FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
5135 /* Cope with very large offsets to the register save area. */
5136 if (reg_offset + sa_size > 0x8000)
5138 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
5141 if (low + sa_size <= 0x8000)
5142 bias = reg_offset - low, reg_offset = low;
5144 bias = reg_offset, reg_offset = 0;
5146 sa_reg = gen_rtx_REG (DImode, 22);
5147 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
5149 FRP (emit_move_insn (sa_reg, sa_reg_exp));
5152 /* Restore registers in order, excepting a true frame pointer. */
5156 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
5157 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
5158 FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
5161 imask &= ~(1L << REG_RA);
5163 for (i = 0; i < 32; ++i)
5164 if (imask & (1L << i))
5166 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
5167 fp_offset = reg_offset;
5170 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
5171 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
5172 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
5177 for (i = 0; i < 32; ++i)
5178 if (fmask & (1L << i))
5180 mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
5181 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
5182 FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
5187 if (frame_size || eh_ofs)
5189 sp_adj1 = stack_pointer_rtx;
5193 sp_adj1 = gen_rtx_REG (DImode, 23);
5194 emit_move_insn (sp_adj1,
5195 gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
5198 /* If the stack size is large, begin computation into a temporary
5199 register so as not to interfere with a potential fp restore,
5200 which must be consecutive with an SP restore. */
5201 if (frame_size < 32768)
5202 sp_adj2 = GEN_INT (frame_size);
5203 else if (frame_size < 0x40007fffL)
5205 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
5207 sp_adj2 = plus_constant (sp_adj1, frame_size - low);
5208 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
5212 sp_adj1 = gen_rtx_REG (DImode, 23);
5213 FRP (emit_move_insn (sp_adj1, sp_adj2));
5215 sp_adj2 = GEN_INT (low);
5219 rtx tmp = gen_rtx_REG (DImode, 23);
5220 FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
5223 /* We can't drop new things to memory this late, afaik,
5224 so build it up by pieces. */
5225 FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
5226 -(frame_size < 0)));
5232 /* From now on, things must be in order. So emit blockages. */
5234 /* Restore the frame pointer. */
5235 if (fp_is_frame_pointer)
5237 emit_insn (gen_blockage ());
5238 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
5239 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
5240 FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
5242 else if (TARGET_OPEN_VMS)
5244 emit_insn (gen_blockage ());
5245 FRP (emit_move_insn (hard_frame_pointer_rtx,
5246 gen_rtx_REG (DImode, vms_save_fp_regno)));
5249 /* Restore the stack pointer. */
5250 emit_insn (gen_blockage ());
5251 FRP (emit_move_insn (stack_pointer_rtx,
5252 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
5256 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
5258 emit_insn (gen_blockage ());
5259 FRP (emit_move_insn (hard_frame_pointer_rtx,
5260 gen_rtx_REG (DImode, vms_save_fp_regno)));
5265 /* Output the rest of the textual info surrounding the epilogue. */
5268 alpha_end_function (file, fnname, decl)
5271 tree decl ATTRIBUTE_UNUSED;
5273 /* End the function. */
5274 if (!flag_inhibit_size_directive)
5276 fputs ("\t.end ", file);
5277 assemble_name (file, fnname);
5280 inside_function = FALSE;
5282 /* Show that we know this function if it is called again.
5284 Don't do this for global functions in object files destined for a
5285 shared library because the function may be overridden by the application
5286 or other libraries. Similarly, don't do this for weak functions. */
5288 if (!DECL_WEAK (current_function_decl)
5289 && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
5290 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
5293 /* Debugging support. */
5297 /* Count the number of sdb related labels are generated (to find block
5298 start and end boundaries). */
5300 int sdb_label_count = 0;
5302 /* Next label # for each statement. */
5304 static int sym_lineno = 0;
5306 /* Count the number of .file directives, so that .loc is up to date. */
5308 static int num_source_filenames = 0;
5310 /* Name of the file containing the current function. */
5312 static const char *current_function_file = "";
5314 /* Offsets to alpha virtual arg/local debugging pointers. */
5316 long alpha_arg_offset;
5317 long alpha_auto_offset;
5319 /* Emit a new filename to a stream. */
5322 alpha_output_filename (stream, name)
5326 static int first_time = TRUE;
5327 char ltext_label_name[100];
5332 ++num_source_filenames;
5333 current_function_file = name;
5334 fprintf (stream, "\t.file\t%d ", num_source_filenames);
5335 output_quoted_string (stream, name);
5336 fprintf (stream, "\n");
5337 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
5338 fprintf (stream, "\t#@stabs\n");
5341 else if (write_symbols == DBX_DEBUG)
5343 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
5344 fprintf (stream, "%s", ASM_STABS_OP);
5345 output_quoted_string (stream, name);
5346 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
5349 else if (name != current_function_file
5350 && strcmp (name, current_function_file) != 0)
5352 if (inside_function && ! TARGET_GAS)
5353 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
5356 ++num_source_filenames;
5357 current_function_file = name;
5358 fprintf (stream, "\t.file\t%d ", num_source_filenames);
5361 output_quoted_string (stream, name);
5362 fprintf (stream, "\n");
5366 /* Emit a linenumber to a stream. */
5369 alpha_output_lineno (stream, line)
5373 if (write_symbols == DBX_DEBUG)
5375 /* mips-tfile doesn't understand .stabd directives. */
5377 fprintf (stream, "$LM%d:\n%s%d,0,%d,$LM%d\n",
5378 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
5381 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
5384 /* Structure to show the current status of registers and memory. */
5386 struct shadow_summary
5389 unsigned int i : 31; /* Mask of int regs */
5390 unsigned int fp : 31; /* Mask of fp regs */
5391 unsigned int mem : 1; /* mem == imem | fpmem */
5395 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
5396 static void alpha_handle_trap_shadows PARAMS ((rtx));
5398 /* Summary the effects of expression X on the machine. Update SUM, a pointer
5399 to the summary structure. SET is nonzero if the insn is setting the
5400 object, otherwise zero. */
5403 summarize_insn (x, sum, set)
5405 struct shadow_summary *sum;
5408 const char *format_ptr;
5414 switch (GET_CODE (x))
5416 /* ??? Note that this case would be incorrect if the Alpha had a
5417 ZERO_EXTRACT in SET_DEST. */
5419 summarize_insn (SET_SRC (x), sum, 0);
5420 summarize_insn (SET_DEST (x), sum, 1);
5424 summarize_insn (XEXP (x, 0), sum, 1);
5428 summarize_insn (XEXP (x, 0), sum, 0);
5432 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
5433 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
5437 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
5438 summarize_insn (XVECEXP (x, 0, i), sum, 0);
5442 summarize_insn (SUBREG_REG (x), sum, 0);
5447 int regno = REGNO (x);
5448 unsigned long mask = ((unsigned long) 1) << (regno % 32);
5450 if (regno == 31 || regno == 63)
5456 sum->defd.i |= mask;
5458 sum->defd.fp |= mask;
5463 sum->used.i |= mask;
5465 sum->used.fp |= mask;
5476 /* Find the regs used in memory address computation: */
5477 summarize_insn (XEXP (x, 0), sum, 0);
5480 case CONST_INT: case CONST_DOUBLE:
5481 case SYMBOL_REF: case LABEL_REF: case CONST:
5485 /* Handle common unary and binary ops for efficiency. */
5486 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
5487 case MOD: case UDIV: case UMOD: case AND: case IOR:
5488 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
5489 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
5490 case NE: case EQ: case GE: case GT: case LE:
5491 case LT: case GEU: case GTU: case LEU: case LTU:
5492 summarize_insn (XEXP (x, 0), sum, 0);
5493 summarize_insn (XEXP (x, 1), sum, 0);
5496 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
5497 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
5498 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
5499 case SQRT: case FFS:
5500 summarize_insn (XEXP (x, 0), sum, 0);
5504 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
5505 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
5506 switch (format_ptr[i])
5509 summarize_insn (XEXP (x, i), sum, 0);
5513 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
5514 summarize_insn (XVECEXP (x, i, j), sum, 0);
5526 /* Ensure a sufficient number of `trapb' insns are in the code when
5527 the user requests code with a trap precision of functions or
5530 In naive mode, when the user requests a trap-precision of
5531 "instruction", a trapb is needed after every instruction that may
5532 generate a trap. This ensures that the code is resumption safe but
5535 When optimizations are turned on, we delay issuing a trapb as long
5536 as possible. In this context, a trap shadow is the sequence of
5537 instructions that starts with a (potentially) trap generating
5538 instruction and extends to the next trapb or call_pal instruction
5539 (but GCC never generates call_pal by itself). We can delay (and
5540 therefore sometimes omit) a trapb subject to the following
5543 (a) On entry to the trap shadow, if any Alpha register or memory
5544 location contains a value that is used as an operand value by some
5545 instruction in the trap shadow (live on entry), then no instruction
5546 in the trap shadow may modify the register or memory location.
5548 (b) Within the trap shadow, the computation of the base register
5549 for a memory load or store instruction may not involve using the
5550 result of an instruction that might generate an UNPREDICTABLE
5553 (c) Within the trap shadow, no register may be used more than once
5554 as a destination register. (This is to make life easier for the
5557 (d) The trap shadow may not include any branch instructions. */
5560 alpha_handle_trap_shadows (insns)
5563 struct shadow_summary shadow;
5564 int trap_pending, exception_nesting;
5568 exception_nesting = 0;
5571 shadow.used.mem = 0;
5572 shadow.defd = shadow.used;
5574 for (i = insns; i ; i = NEXT_INSN (i))
5576 if (GET_CODE (i) == NOTE)
5578 switch (NOTE_LINE_NUMBER (i))
5580 case NOTE_INSN_EH_REGION_BEG:
5581 exception_nesting++;
5586 case NOTE_INSN_EH_REGION_END:
5587 exception_nesting--;
5592 case NOTE_INSN_EPILOGUE_BEG:
5593 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
5598 else if (trap_pending)
5600 if (alpha_tp == ALPHA_TP_FUNC)
5602 if (GET_CODE (i) == JUMP_INSN
5603 && GET_CODE (PATTERN (i)) == RETURN)
5606 else if (alpha_tp == ALPHA_TP_INSN)
5610 struct shadow_summary sum;
5615 sum.defd = sum.used;
5617 switch (GET_CODE (i))
5620 /* Annoyingly, get_attr_trap will abort on these. */
5621 if (GET_CODE (PATTERN (i)) == USE
5622 || GET_CODE (PATTERN (i)) == CLOBBER)
5625 summarize_insn (PATTERN (i), &sum, 0);
5627 if ((sum.defd.i & shadow.defd.i)
5628 || (sum.defd.fp & shadow.defd.fp))
5630 /* (c) would be violated */
5634 /* Combine shadow with summary of current insn: */
5635 shadow.used.i |= sum.used.i;
5636 shadow.used.fp |= sum.used.fp;
5637 shadow.used.mem |= sum.used.mem;
5638 shadow.defd.i |= sum.defd.i;
5639 shadow.defd.fp |= sum.defd.fp;
5640 shadow.defd.mem |= sum.defd.mem;
5642 if ((sum.defd.i & shadow.used.i)
5643 || (sum.defd.fp & shadow.used.fp)
5644 || (sum.defd.mem & shadow.used.mem))
5646 /* (a) would be violated (also takes care of (b)) */
5647 if (get_attr_trap (i) == TRAP_YES
5648 && ((sum.defd.i & sum.used.i)
5649 || (sum.defd.fp & sum.used.fp)))
5668 n = emit_insn_before (gen_trapb (), i);
5669 PUT_MODE (n, TImode);
5670 PUT_MODE (i, TImode);
5674 shadow.used.mem = 0;
5675 shadow.defd = shadow.used;
5680 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
5681 && GET_CODE (i) == INSN
5682 && GET_CODE (PATTERN (i)) != USE
5683 && GET_CODE (PATTERN (i)) != CLOBBER
5684 && get_attr_trap (i) == TRAP_YES)
5686 if (optimize && !trap_pending)
5687 summarize_insn (PATTERN (i), &shadow, 0);
5693 /* Alpha can only issue instruction groups simultaneously if they are
5694 suitibly aligned. This is very processor-specific. */
5696 enum alphaev4_pipe {
5703 enum alphaev5_pipe {
5714 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
5715 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
5716 static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
5717 static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
5718 static rtx alphaev4_next_nop PARAMS ((int *));
5719 static rtx alphaev5_next_nop PARAMS ((int *));
5721 static void alpha_align_insns
5722 PARAMS ((rtx, unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
5724 static enum alphaev4_pipe
5725 alphaev4_insn_pipe (insn)
5728 if (recog_memoized (insn) < 0)
5730 if (get_attr_length (insn) != 4)
5733 switch (get_attr_type (insn))
5766 static enum alphaev5_pipe
5767 alphaev5_insn_pipe (insn)
5770 if (recog_memoized (insn) < 0)
5772 if (get_attr_length (insn) != 4)
5775 switch (get_attr_type (insn))
5815 /* IN_USE is a mask of the slots currently filled within the insn group.
5816 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
5817 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
5819 LEN is, of course, the length of the group in bytes. */
5822 alphaev4_next_group (insn, pin_use, plen)
5824 int *pin_use, *plen;
5831 || GET_CODE (PATTERN (insn)) == CLOBBER
5832 || GET_CODE (PATTERN (insn)) == USE)
5837 enum alphaev4_pipe pipe;
5839 pipe = alphaev4_insn_pipe (insn);
5843 /* Force complex instructions to start new groups. */
5847 /* If this is a completely unrecognized insn, its an asm.
5848 We don't know how long it is, so record length as -1 to
5849 signal a needed realignment. */
5850 if (recog_memoized (insn) < 0)
5853 len = get_attr_length (insn);
5857 if (in_use & EV4_IB0)
5859 if (in_use & EV4_IB1)
5864 in_use |= EV4_IB0 | EV4_IBX;
5868 if (in_use & EV4_IB0)
5870 if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
5878 if (in_use & EV4_IB1)
5888 /* Haifa doesn't do well scheduling branches. */
5889 if (GET_CODE (insn) == JUMP_INSN)
5893 insn = next_nonnote_insn (insn);
5895 if (!insn || ! INSN_P (insn))
5898 /* Let Haifa tell us where it thinks insn group boundaries are. */
5899 if (GET_MODE (insn) == TImode)
5902 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5907 insn = next_nonnote_insn (insn);
5915 /* IN_USE is a mask of the slots currently filled within the insn group.
5916 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
5917 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
5919 LEN is, of course, the length of the group in bytes. */
5922 alphaev5_next_group (insn, pin_use, plen)
5924 int *pin_use, *plen;
5931 || GET_CODE (PATTERN (insn)) == CLOBBER
5932 || GET_CODE (PATTERN (insn)) == USE)
5937 enum alphaev5_pipe pipe;
5939 pipe = alphaev5_insn_pipe (insn);
5943 /* Force complex instructions to start new groups. */
5947 /* If this is a completely unrecognized insn, its an asm.
5948 We don't know how long it is, so record length as -1 to
5949 signal a needed realignment. */
5950 if (recog_memoized (insn) < 0)
5953 len = get_attr_length (insn);
5956 /* ??? Most of the places below, we would like to abort, as
5957 it would indicate an error either in Haifa, or in the
5958 scheduling description. Unfortunately, Haifa never
5959 schedules the last instruction of the BB, so we don't
5960 have an accurate TI bit to go off. */
5962 if (in_use & EV5_E0)
5964 if (in_use & EV5_E1)
5969 in_use |= EV5_E0 | EV5_E01;
5973 if (in_use & EV5_E0)
5975 if (!(in_use & EV5_E01) || (in_use & EV5_E1))
5983 if (in_use & EV5_E1)
5989 if (in_use & EV5_FA)
5991 if (in_use & EV5_FM)
5996 in_use |= EV5_FA | EV5_FAM;
6000 if (in_use & EV5_FA)
6006 if (in_use & EV5_FM)
6019 /* Haifa doesn't do well scheduling branches. */
6020 /* ??? If this is predicted not-taken, slotting continues, except
6021 that no more IBR, FBR, or JSR insns may be slotted. */
6022 if (GET_CODE (insn) == JUMP_INSN)
6026 insn = next_nonnote_insn (insn);
6028 if (!insn || ! INSN_P (insn))
6031 /* Let Haifa tell us where it thinks insn group boundaries are. */
6032 if (GET_MODE (insn) == TImode)
6035 if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
6040 insn = next_nonnote_insn (insn);
6049 alphaev4_next_nop (pin_use)
6052 int in_use = *pin_use;
6055 if (!(in_use & EV4_IB0))
6060 else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
6065 else if (TARGET_FP && !(in_use & EV4_IB1))
6078 alphaev5_next_nop (pin_use)
6081 int in_use = *pin_use;
6084 if (!(in_use & EV5_E1))
6089 else if (TARGET_FP && !(in_use & EV5_FA))
6094 else if (TARGET_FP && !(in_use & EV5_FM))
6106 /* The instruction group alignment main loop. */
6109 alpha_align_insns (insns, max_align, next_group, next_nop)
6111 unsigned int max_align;
6112 rtx (*next_group) PARAMS ((rtx, int *, int *));
6113 rtx (*next_nop) PARAMS ((int *));
6115 /* ALIGN is the known alignment for the insn group. */
6117 /* OFS is the offset of the current insn in the insn group. */
6119 int prev_in_use, in_use, len;
6122 /* Let shorten branches care for assigning alignments to code labels. */
6123 shorten_branches (insns);
6125 align = (FUNCTION_BOUNDARY / BITS_PER_UNIT < max_align
6126 ? FUNCTION_BOUNDARY / BITS_PER_UNIT : max_align);
6128 ofs = prev_in_use = 0;
6130 if (GET_CODE (i) == NOTE)
6131 i = next_nonnote_insn (i);
6135 next = (*next_group) (i, &in_use, &len);
6137 /* When we see a label, resync alignment etc. */
6138 if (GET_CODE (i) == CODE_LABEL)
6140 unsigned int new_align = 1 << label_to_alignment (i);
6142 if (new_align >= align)
6144 align = new_align < max_align ? new_align : max_align;
6148 else if (ofs & (new_align-1))
6149 ofs = (ofs | (new_align-1)) + 1;
6154 /* Handle complex instructions special. */
6155 else if (in_use == 0)
6157 /* Asms will have length < 0. This is a signal that we have
6158 lost alignment knowledge. Assume, however, that the asm
6159 will not mis-align instructions. */
6168 /* If the known alignment is smaller than the recognized insn group,
6169 realign the output. */
6170 else if (align < len)
6172 unsigned int new_log_align = len > 8 ? 4 : 3;
6175 where = prev_nonnote_insn (i);
6176 if (!where || GET_CODE (where) != CODE_LABEL)
6179 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
6180 align = 1 << new_log_align;
6184 /* If the group won't fit in the same INT16 as the previous,
6185 we need to add padding to keep the group together. Rather
6186 than simply leaving the insn filling to the assembler, we
6187 can make use of the knowledge of what sorts of instructions
6188 were issued in the previous group to make sure that all of
6189 the added nops are really free. */
6190 else if (ofs + len > align)
6192 int nop_count = (align - ofs) / 4;
6195 /* Insert nops before labels and branches to truely merge the
6196 execution of the nops with the previous instruction group. */
6197 where = prev_nonnote_insn (i);
6200 if (GET_CODE (where) == CODE_LABEL)
6202 rtx where2 = prev_nonnote_insn (where);
6203 if (where2 && GET_CODE (where2) == JUMP_INSN)
6206 else if (GET_CODE (where) != JUMP_INSN)
6213 emit_insn_before ((*next_nop)(&prev_in_use), where);
6214 while (--nop_count);
6218 ofs = (ofs + len) & (align - 1);
6219 prev_in_use = in_use;
6224 /* Machine dependant reorg pass. */
6230 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
6231 alpha_handle_trap_shadows (insns);
6233 /* Due to the number of extra trapb insns, don't bother fixing up
6234 alignment when trap precision is instruction. Moreover, we can
6235 only do our job when sched2 is run. */
6236 if (optimize && !optimize_size
6237 && alpha_tp != ALPHA_TP_INSN
6238 && flag_schedule_insns_after_reload)
6240 if (alpha_cpu == PROCESSOR_EV4)
6241 alpha_align_insns (insns, 8, alphaev4_next_group, alphaev4_next_nop);
6242 else if (alpha_cpu == PROCESSOR_EV5)
6243 alpha_align_insns (insns, 16, alphaev5_next_group, alphaev5_next_nop);
6247 /* Check a floating-point value for validity for a particular machine mode. */
6249 static const char * const float_strings[] =
6251 /* These are for FLOAT_VAX. */
6252 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
6253 "-1.70141173319264430e+38",
6254 "2.93873587705571877e-39", /* 2^-128 */
6255 "-2.93873587705571877e-39",
6256 /* These are for the default broken IEEE mode, which traps
6257 on infinity or denormal numbers. */
6258 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
6259 "-3.402823466385288598117e+38",
6260 "1.1754943508222875079687e-38", /* 2^-126 */
6261 "-1.1754943508222875079687e-38",
6264 static REAL_VALUE_TYPE float_values[8];
6265 static int inited_float_values = 0;
6268 check_float_value (mode, d, overflow)
6269 enum machine_mode mode;
6271 int overflow ATTRIBUTE_UNUSED;
6274 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
6277 if (inited_float_values == 0)
6280 for (i = 0; i < 8; i++)
6281 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
6283 inited_float_values = 1;
6289 REAL_VALUE_TYPE *fvptr;
6291 if (TARGET_FLOAT_VAX)
6292 fvptr = &float_values[0];
6294 fvptr = &float_values[4];
6296 memcpy (&r, d, sizeof (REAL_VALUE_TYPE));
6297 if (REAL_VALUES_LESS (fvptr[0], r))
6299 bcopy ((char *) &fvptr[0], (char *) d,
6300 sizeof (REAL_VALUE_TYPE));
6303 else if (REAL_VALUES_LESS (r, fvptr[1]))
6305 bcopy ((char *) &fvptr[1], (char *) d,
6306 sizeof (REAL_VALUE_TYPE));
6309 else if (REAL_VALUES_LESS (dconst0, r)
6310 && REAL_VALUES_LESS (r, fvptr[2]))
6312 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
6315 else if (REAL_VALUES_LESS (r, dconst0)
6316 && REAL_VALUES_LESS (fvptr[3], r))
6318 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
6328 /* Return the VMS argument type corresponding to MODE. */
6331 alpha_arg_type (mode)
6332 enum machine_mode mode;
6337 return TARGET_FLOAT_VAX ? FF : FS;
6339 return TARGET_FLOAT_VAX ? FD : FT;
6345 /* Return an rtx for an integer representing the VMS Argument Information
6349 alpha_arg_info_reg_val (cum)
6350 CUMULATIVE_ARGS cum;
6352 unsigned HOST_WIDE_INT regval = cum.num_args;
6355 for (i = 0; i < 6; i++)
6356 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
6358 return GEN_INT (regval);
6361 #include <splay-tree.h>
6363 /* Structure to collect function names for final output
6366 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
6371 enum links_kind kind;
6374 static splay_tree alpha_links;
6376 static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
6377 static void mark_alpha_links PARAMS ((void *));
6378 static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
6380 /* Protect alpha_links from garbage collection. */
6383 mark_alpha_links_node (node, data)
6384 splay_tree_node node;
6385 void *data ATTRIBUTE_UNUSED;
6387 struct alpha_links *links = (struct alpha_links *) node->value;
6388 ggc_mark_rtx (links->linkage);
6393 mark_alpha_links (ptr)
6396 splay_tree tree = *(splay_tree *) ptr;
6397 splay_tree_foreach (tree, mark_alpha_links_node, NULL);
6400 /* Make (or fake) .linkage entry for function call.
6402 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
6404 Return an SYMBOL_REF rtx for the linkage. */
6407 alpha_need_linkage (name, is_local)
6411 splay_tree_node node;
6412 struct alpha_links *al;
6419 /* Is this name already defined? */
6421 node = splay_tree_lookup (alpha_links, (splay_tree_key) name);
6424 al = (struct alpha_links *) node->value;
6427 /* Defined here but external assumed. */
6428 if (al->kind == KIND_EXTERN)
6429 al->kind = KIND_LOCAL;
6433 /* Used here but unused assumed. */
6434 if (al->kind == KIND_UNUSED)
6435 al->kind = KIND_LOCAL;
6442 alpha_links = splay_tree_new ((splay_tree_compare_fn) strcmp,
6443 (splay_tree_delete_key_fn) free,
6444 (splay_tree_delete_key_fn) free);
6445 ggc_add_root (&alpha_links, 1, 1, mark_alpha_links);
6448 al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
6449 name = xstrdup (name);
6451 /* Assume external if no definition. */
6452 al->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
6454 /* Ensure we have an IDENTIFIER so assemble_name can mark it used. */
6455 get_identifier (name);
6457 /* Construct a SYMBOL_REF for us to call. */
6459 size_t name_len = strlen (name);
6460 char *linksym = alloca (name_len + 6);
6462 memcpy (linksym + 1, name, name_len);
6463 memcpy (linksym + 1 + name_len, "..lk", 5);
6464 al->linkage = gen_rtx_SYMBOL_REF (Pmode,
6465 ggc_alloc_string (linksym, name_len + 5));
6468 splay_tree_insert (alpha_links, (splay_tree_key) name,
6469 (splay_tree_value) al);
6475 alpha_write_one_linkage (node, data)
6476 splay_tree_node node;
6479 const char *name = (const char *) node->key;
6480 struct alpha_links *links = (struct alpha_links *) node->value;
6481 FILE *stream = (FILE *) data;
6483 if (links->kind == KIND_UNUSED
6484 || ! TREE_SYMBOL_REFERENCED (get_identifier (name)))
6487 fprintf (stream, "$%s..lk:\n", name);
6488 if (links->kind == KIND_LOCAL)
6490 /* Local and used, build linkage pair. */
6491 fprintf (stream, "\t.quad %s..en\n", name);
6492 fprintf (stream, "\t.quad %s\n", name);
6496 /* External and used, request linkage pair. */
6497 fprintf (stream, "\t.linkage %s\n", name);
6504 alpha_write_linkage (stream)
6507 readonly_section ();
6508 fprintf (stream, "\t.align 3\n");
6509 splay_tree_foreach (alpha_links, alpha_write_one_linkage, stream);
6515 alpha_need_linkage (name, is_local)
6516 const char *name ATTRIBUTE_UNUSED;
6517 int is_local ATTRIBUTE_UNUSED;
6522 #endif /* OPEN_VMS */