1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
45 extern char *version_string;
46 extern int rtx_equal_function_value_matters;
48 /* Specify which cpu to schedule for. */
50 enum processor_type alpha_cpu;
51 static char* const alpha_cpu_name[] =
56 /* Specify how accurate floating-point traps need to be. */
58 enum alpha_trap_precision alpha_tp;
60 /* Specify the floating-point rounding mode. */
62 enum alpha_fp_rounding_mode alpha_fprm;
64 /* Specify which things cause traps. */
66 enum alpha_fp_trap_mode alpha_fptm;
68 /* Strings decoded into the above options. */
70 char *alpha_cpu_string; /* -mcpu= */
71 char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
72 char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
73 char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
74 char *alpha_mlat_string; /* -mmemory-latency= */
76 /* Save information from a "cmpxx" operation until the branch or scc is
79 rtx alpha_compare_op0, alpha_compare_op1;
80 int alpha_compare_fp_p;
82 /* Non-zero if inside of a function, because the Alpha asm can't
83 handle .files inside of functions. */
85 static int inside_function = FALSE;
87 /* If non-null, this rtx holds the return address for the function. */
89 static rtx alpha_return_addr_rtx;
91 /* The number of cycles of latency we should assume on memory reads. */
93 int alpha_memory_latency = 3;
95 /* Whether the function needs the GP. */
97 static int alpha_function_needs_gp;
99 /* Declarations of static functions. */
100 static void alpha_set_memflags_1
101 PROTO((rtx, int, int, int));
102 static rtx alpha_emit_set_const_1
103 PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int));
104 static void alpha_expand_unaligned_load_words
105 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
106 static void alpha_expand_unaligned_store_words
107 PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
108 static void alpha_sa_mask
109 PROTO((unsigned long *imaskP, unsigned long *fmaskP));
110 static int alpha_does_function_need_gp
114 /* Get the number of args of a function in one of two ways. */
116 #define NUM_ARGS current_function_args_info.num_args
118 #define NUM_ARGS current_function_args_info
124 /* Parse target option strings. */
130 = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
131 : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
133 if (alpha_cpu_string)
135 if (! strcmp (alpha_cpu_string, "ev4")
136 || ! strcmp (alpha_cpu_string, "21064"))
138 alpha_cpu = PROCESSOR_EV4;
139 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
141 else if (! strcmp (alpha_cpu_string, "ev5")
142 || ! strcmp (alpha_cpu_string, "21164"))
144 alpha_cpu = PROCESSOR_EV5;
145 target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
147 else if (! strcmp (alpha_cpu_string, "ev56")
148 || ! strcmp (alpha_cpu_string, "21164a"))
150 alpha_cpu = PROCESSOR_EV5;
151 target_flags |= MASK_BWX;
152 target_flags &= ~ (MASK_CIX | MASK_MAX);
154 else if (! strcmp (alpha_cpu_string, "pca56")
155 || ! strcmp (alpha_cpu_string, "21164PC")
156 || ! strcmp (alpha_cpu_string, "21164pc"))
158 alpha_cpu = PROCESSOR_EV5;
159 target_flags |= MASK_BWX | MASK_MAX;
160 target_flags &= ~ MASK_CIX;
162 else if (! strcmp (alpha_cpu_string, "ev6")
163 || ! strcmp (alpha_cpu_string, "21264"))
165 alpha_cpu = PROCESSOR_EV6;
166 target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
169 error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
172 alpha_tp = ALPHA_TP_PROG;
173 alpha_fprm = ALPHA_FPRM_NORM;
174 alpha_fptm = ALPHA_FPTM_N;
178 alpha_tp = ALPHA_TP_INSN;
179 alpha_fptm = ALPHA_FPTM_SU;
182 if (TARGET_IEEE_WITH_INEXACT)
184 alpha_tp = ALPHA_TP_INSN;
185 alpha_fptm = ALPHA_FPTM_SUI;
190 if (! strcmp (alpha_tp_string, "p"))
191 alpha_tp = ALPHA_TP_PROG;
192 else if (! strcmp (alpha_tp_string, "f"))
193 alpha_tp = ALPHA_TP_FUNC;
194 else if (! strcmp (alpha_tp_string, "i"))
195 alpha_tp = ALPHA_TP_INSN;
197 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
200 if (alpha_fprm_string)
202 if (! strcmp (alpha_fprm_string, "n"))
203 alpha_fprm = ALPHA_FPRM_NORM;
204 else if (! strcmp (alpha_fprm_string, "m"))
205 alpha_fprm = ALPHA_FPRM_MINF;
206 else if (! strcmp (alpha_fprm_string, "c"))
207 alpha_fprm = ALPHA_FPRM_CHOP;
208 else if (! strcmp (alpha_fprm_string,"d"))
209 alpha_fprm = ALPHA_FPRM_DYN;
211 error ("bad value `%s' for -mfp-rounding-mode switch",
215 if (alpha_fptm_string)
217 if (strcmp (alpha_fptm_string, "n") == 0)
218 alpha_fptm = ALPHA_FPTM_N;
219 else if (strcmp (alpha_fptm_string, "u") == 0)
220 alpha_fptm = ALPHA_FPTM_U;
221 else if (strcmp (alpha_fptm_string, "su") == 0)
222 alpha_fptm = ALPHA_FPTM_SU;
223 else if (strcmp (alpha_fptm_string, "sui") == 0)
224 alpha_fptm = ALPHA_FPTM_SUI;
226 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
229 /* Do some sanity checks on the above option. */
231 if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
232 && alpha_tp != ALPHA_TP_INSN)
234 warning ("fp software completion requires -mtrap-precision=i");
235 alpha_tp = ALPHA_TP_INSN;
238 if (TARGET_FLOAT_VAX)
240 if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
242 warning ("rounding mode not supported for VAX floats");
243 alpha_fprm = ALPHA_FPRM_NORM;
245 if (alpha_fptm == ALPHA_FPTM_SUI)
247 warning ("trap mode not supported for VAX floats");
248 alpha_fptm = ALPHA_FPTM_SU;
256 if (!alpha_mlat_string)
257 alpha_mlat_string = "L1";
259 if (isdigit (alpha_mlat_string[0])
260 && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
262 else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
263 && isdigit (alpha_mlat_string[1])
264 && alpha_mlat_string[2] == '\0')
266 static int const cache_latency[][4] =
268 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
269 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
270 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
273 lat = alpha_mlat_string[1] - '0';
274 if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
276 warning ("L%d cache latency unknown for %s",
277 lat, alpha_cpu_name[alpha_cpu]);
281 lat = cache_latency[alpha_cpu][lat-1];
283 else if (! strcmp (alpha_mlat_string, "main"))
285 /* Most current memories have about 370ns latency. This is
286 a reasonable guess for a fast cpu. */
291 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
295 alpha_memory_latency = lat;
298 /* Default the definition of "small data" to 8 bytes. */
303 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
311 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
313 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
319 /* Returns 1 if OP is either the constant zero or a register. If a
320 register, it must be in the proper mode unless MODE is VOIDmode. */
323 reg_or_0_operand (op, mode)
325 enum machine_mode mode;
327 return op == const0_rtx || register_operand (op, mode);
330 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
334 reg_or_6bit_operand (op, mode)
336 enum machine_mode mode;
338 return ((GET_CODE (op) == CONST_INT
339 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
340 || GET_CODE (op) == CONSTANT_P_RTX
341 || register_operand (op, mode));
345 /* Return 1 if OP is an 8-bit constant or any register. */
348 reg_or_8bit_operand (op, mode)
350 enum machine_mode mode;
352 return ((GET_CODE (op) == CONST_INT
353 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
354 || GET_CODE (op) == CONSTANT_P_RTX
355 || register_operand (op, mode));
358 /* Return 1 if OP is an 8-bit constant. */
361 cint8_operand (op, mode)
363 enum machine_mode mode ATTRIBUTE_UNUSED;
365 return ((GET_CODE (op) == CONST_INT
366 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
367 || GET_CODE (op) == CONSTANT_P_RTX);
370 /* Return 1 if the operand is a valid second operand to an add insn. */
373 add_operand (op, mode)
375 enum machine_mode mode;
377 if (GET_CODE (op) == CONST_INT)
378 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
379 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
380 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
381 else if (GET_CODE (op) == CONSTANT_P_RTX)
384 return register_operand (op, mode);
387 /* Return 1 if the operand is a valid second operand to a sign-extending
391 sext_add_operand (op, mode)
393 enum machine_mode mode;
395 if (GET_CODE (op) == CONST_INT)
396 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
397 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
398 else if (GET_CODE (op) == CONSTANT_P_RTX)
401 return register_operand (op, mode);
404 /* Return 1 if OP is the constant 4 or 8. */
407 const48_operand (op, mode)
409 enum machine_mode mode ATTRIBUTE_UNUSED;
411 return (GET_CODE (op) == CONST_INT
412 && (INTVAL (op) == 4 || INTVAL (op) == 8));
415 /* Return 1 if OP is a valid first operand to an AND insn. */
418 and_operand (op, mode)
420 enum machine_mode mode;
422 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
423 return (zap_mask (CONST_DOUBLE_LOW (op))
424 && zap_mask (CONST_DOUBLE_HIGH (op)));
426 if (GET_CODE (op) == CONST_INT)
427 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
428 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
429 || zap_mask (INTVAL (op)));
430 else if (GET_CODE (op) == CONSTANT_P_RTX)
433 return register_operand (op, mode);
436 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
439 or_operand (op, mode)
441 enum machine_mode mode;
443 if (GET_CODE (op) == CONST_INT)
444 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
445 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
446 else if (GET_CODE (op) == CONSTANT_P_RTX)
449 return register_operand (op, mode);
452 /* Return 1 if OP is a constant that is the width, in bits, of an integral
453 mode smaller than DImode. */
456 mode_width_operand (op, mode)
458 enum machine_mode mode ATTRIBUTE_UNUSED;
460 return (GET_CODE (op) == CONST_INT
461 && (INTVAL (op) == 8 || INTVAL (op) == 16
462 || INTVAL (op) == 32 || INTVAL (op) == 64));
465 /* Return 1 if OP is a constant that is the width of an integral machine mode
466 smaller than an integer. */
469 mode_mask_operand (op, mode)
471 enum machine_mode mode ATTRIBUTE_UNUSED;
473 #if HOST_BITS_PER_WIDE_INT == 32
474 if (GET_CODE (op) == CONST_DOUBLE)
475 return (CONST_DOUBLE_LOW (op) == -1
476 && (CONST_DOUBLE_HIGH (op) == -1
477 || CONST_DOUBLE_HIGH (op) == 0));
479 if (GET_CODE (op) == CONST_DOUBLE)
480 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
483 return (GET_CODE (op) == CONST_INT
484 && (INTVAL (op) == 0xff
485 || INTVAL (op) == 0xffff
486 || INTVAL (op) == 0xffffffff
487 #if HOST_BITS_PER_WIDE_INT == 64
488 || INTVAL (op) == 0xffffffffffffffff
493 /* Return 1 if OP is a multiple of 8 less than 64. */
496 mul8_operand (op, mode)
498 enum machine_mode mode ATTRIBUTE_UNUSED;
500 return (GET_CODE (op) == CONST_INT
501 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
502 && (INTVAL (op) & 7) == 0);
505 /* Return 1 if OP is the constant zero in floating-point. */
508 fp0_operand (op, mode)
510 enum machine_mode mode;
512 return (GET_MODE (op) == mode
513 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
516 /* Return 1 if OP is the floating-point constant zero or a register. */
519 reg_or_fp0_operand (op, mode)
521 enum machine_mode mode;
523 return fp0_operand (op, mode) || register_operand (op, mode);
526 /* Return 1 if OP is a hard floating-point register. */
529 hard_fp_register_operand (op, mode)
531 enum machine_mode mode;
533 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
534 || (GET_CODE (op) == SUBREG
535 && hard_fp_register_operand (SUBREG_REG (op), mode)));
538 /* Return 1 if OP is a register or a constant integer. */
542 reg_or_cint_operand (op, mode)
544 enum machine_mode mode;
546 return (GET_CODE (op) == CONST_INT
547 || GET_CODE (op) == CONSTANT_P_RTX
548 || register_operand (op, mode));
551 /* Return 1 if OP is something that can be reloaded into a register;
552 if it is a MEM, it need not be valid. */
555 some_operand (op, mode)
557 enum machine_mode mode;
559 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
562 switch (GET_CODE (op))
564 case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF:
565 case SYMBOL_REF: case CONST: case CONSTANT_P_RTX:
569 return some_operand (SUBREG_REG (op), VOIDmode);
578 /* Return 1 if OP is a valid operand for the source of a move insn. */
581 input_operand (op, mode)
583 enum machine_mode mode;
585 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
588 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
591 switch (GET_CODE (op))
596 /* This handles both the Windows/NT and OSF cases. */
597 return mode == ptr_mode || mode == DImode;
603 if (register_operand (op, mode))
605 /* ... fall through ... */
607 return ((TARGET_BWX || (mode != HImode && mode != QImode))
608 && general_operand (op, mode));
611 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
615 return mode == QImode || mode == HImode || add_operand (op, mode);
624 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
628 current_file_function_operand (op, mode)
630 enum machine_mode mode ATTRIBUTE_UNUSED;
632 return (GET_CODE (op) == SYMBOL_REF
633 && ! profile_flag && ! profile_block_flag
634 && (SYMBOL_REF_FLAG (op)
635 || op == XEXP (DECL_RTL (current_function_decl), 0)));
638 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
641 call_operand (op, mode)
643 enum machine_mode mode;
648 return (GET_CODE (op) == SYMBOL_REF
649 || (GET_CODE (op) == REG
650 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
653 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
654 comparisons are valid in which insn. */
657 alpha_comparison_operator (op, mode)
659 enum machine_mode mode;
661 enum rtx_code code = GET_CODE (op);
663 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
666 return (code == EQ || code == LE || code == LT
667 || (mode == DImode && (code == LEU || code == LTU)));
670 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
673 alpha_swapped_comparison_operator (op, mode)
675 enum machine_mode mode;
677 enum rtx_code code = GET_CODE (op);
679 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
682 code = swap_condition (code);
683 return (code == EQ || code == LE || code == LT
684 || (mode == DImode && (code == LEU || code == LTU)));
687 /* Return 1 if OP is a signed comparison operation. */
690 signed_comparison_operator (op, mode)
692 enum machine_mode mode ATTRIBUTE_UNUSED;
694 switch (GET_CODE (op))
696 case EQ: case NE: case LE: case LT: case GE: case GT:
706 /* Return 1 if this is a divide or modulus operator. */
709 divmod_operator (op, mode)
711 enum machine_mode mode ATTRIBUTE_UNUSED;
713 switch (GET_CODE (op))
715 case DIV: case MOD: case UDIV: case UMOD:
725 /* Return 1 if this memory address is a known aligned register plus
726 a constant. It must be a valid address. This means that we can do
727 this as an aligned reference plus some offset.
729 Take into account what reload will do.
731 We could say that out-of-range stack slots are alignable, but that would
732 complicate get_aligned_mem and it isn't worth the trouble since few
733 functions have large stack space. */
736 aligned_memory_operand (op, mode)
738 enum machine_mode mode;
740 if (GET_CODE (op) == SUBREG)
742 if (GET_MODE (op) != mode)
744 op = SUBREG_REG (op);
745 mode = GET_MODE (op);
748 if (reload_in_progress && GET_CODE (op) == REG
749 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
750 op = reg_equiv_mem[REGNO (op)];
752 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
753 || ! memory_address_p (mode, XEXP (op, 0)))
758 if (GET_CODE (op) == PLUS)
761 return (GET_CODE (op) == REG
762 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
765 /* Similar, but return 1 if OP is a MEM which is not alignable. */
768 unaligned_memory_operand (op, mode)
770 enum machine_mode mode;
772 if (GET_CODE (op) == SUBREG)
774 if (GET_MODE (op) != mode)
776 op = SUBREG_REG (op);
777 mode = GET_MODE (op);
780 if (reload_in_progress && GET_CODE (op) == REG
781 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
782 op = reg_equiv_mem[REGNO (op)];
784 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
789 if (! memory_address_p (mode, op))
792 if (GET_CODE (op) == PLUS)
795 return (GET_CODE (op) != REG
796 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
799 /* Return 1 if OP is either a register or an unaligned memory location. */
802 reg_or_unaligned_mem_operand (op, mode)
804 enum machine_mode mode;
806 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
809 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
812 any_memory_operand (op, mode)
814 enum machine_mode mode ATTRIBUTE_UNUSED;
816 return (GET_CODE (op) == MEM
817 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
818 || (reload_in_progress && GET_CODE (op) == REG
819 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
820 || (reload_in_progress && GET_CODE (op) == SUBREG
821 && GET_CODE (SUBREG_REG (op)) == REG
822 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
825 /* Return 1 if this function can directly return via $26. */
830 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
831 && get_frame_size () == 0
832 && current_function_outgoing_args_size == 0
833 && current_function_pretend_args_size == 0);
836 /* REF is an alignable memory location. Place an aligned SImode
837 reference into *PALIGNED_MEM and the number of bits to shift into
841 get_aligned_mem (ref, paligned_mem, pbitnum)
843 rtx *paligned_mem, *pbitnum;
846 HOST_WIDE_INT offset = 0;
848 if (GET_CODE (ref) == SUBREG)
850 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
851 if (BYTES_BIG_ENDIAN)
852 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
853 - MIN (UNITS_PER_WORD,
854 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
855 ref = SUBREG_REG (ref);
858 if (GET_CODE (ref) == REG)
859 ref = reg_equiv_mem[REGNO (ref)];
861 if (reload_in_progress)
862 base = find_replacement (&XEXP (ref, 0));
864 base = XEXP (ref, 0);
866 if (GET_CODE (base) == PLUS)
867 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
869 *paligned_mem = gen_rtx_MEM (SImode,
870 plus_constant (base, offset & ~3));
871 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
872 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
873 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
875 *pbitnum = GEN_INT ((offset & 3) * 8);
878 /* Similar, but just get the address. Handle the two reload cases.
879 Add EXTRA_OFFSET to the address we return. */
882 get_unaligned_address (ref, extra_offset)
887 HOST_WIDE_INT offset = 0;
889 if (GET_CODE (ref) == SUBREG)
891 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
892 if (BYTES_BIG_ENDIAN)
893 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
894 - MIN (UNITS_PER_WORD,
895 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
896 ref = SUBREG_REG (ref);
899 if (GET_CODE (ref) == REG)
900 ref = reg_equiv_mem[REGNO (ref)];
902 if (reload_in_progress)
903 base = find_replacement (&XEXP (ref, 0));
905 base = XEXP (ref, 0);
907 if (GET_CODE (base) == PLUS)
908 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
910 return plus_constant (base, offset + extra_offset);
913 /* Subfunction of the following function. Update the flags of any MEM
914 found in part of X. */
917 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
919 int in_struct_p, volatile_p, unchanging_p;
923 switch (GET_CODE (x))
927 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
928 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
933 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
938 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
940 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
945 MEM_IN_STRUCT_P (x) = in_struct_p;
946 MEM_VOLATILE_P (x) = volatile_p;
947 RTX_UNCHANGING_P (x) = unchanging_p;
955 /* Given INSN, which is either an INSN or a SEQUENCE generated to
956 perform a memory operation, look for any MEMs in either a SET_DEST or
957 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
958 REF into each of the MEMs found. If REF is not a MEM, don't do
962 alpha_set_memflags (insn, ref)
966 /* Note that it is always safe to get these flags, though they won't
967 be what we think if REF is not a MEM. */
968 int in_struct_p = MEM_IN_STRUCT_P (ref);
969 int volatile_p = MEM_VOLATILE_P (ref);
970 int unchanging_p = RTX_UNCHANGING_P (ref);
972 if (GET_CODE (ref) != MEM
973 || (! in_struct_p && ! volatile_p && ! unchanging_p))
976 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
979 /* Try to output insns to set TARGET equal to the constant C if it can be
980 done in less than N insns. Do all computations in MODE. Returns the place
981 where the output has been placed if it can be done and the insns have been
982 emitted. If it would take more than N insns, zero is returned and no
983 insns and emitted. */
986 alpha_emit_set_const (target, mode, c, n)
988 enum machine_mode mode;
995 /* Try 1 insn, then 2, then up to N. */
996 for (i = 1; i <= n; i++)
997 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1003 /* Internal routine for the above to check for N or below insns. */
1006 alpha_emit_set_const_1 (target, mode, c, n)
1008 enum machine_mode mode;
1012 HOST_WIDE_INT new = c;
1014 /* Use a pseudo if highly optimizing and still generating RTL. */
1016 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1020 #if HOST_BITS_PER_WIDE_INT == 64
1021 /* We are only called for SImode and DImode. If this is SImode, ensure that
1022 we are sign extended to a full word. This does not make any sense when
1023 cross-compiling on a narrow machine. */
1026 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1029 /* If this is a sign-extended 32-bit constant, we can do this in at most
1030 three insns, so do it if we have enough insns left. We always have
1031 a sign-extended 32-bit constant when compiling on a narrow machine. */
1033 if (HOST_BITS_PER_WIDE_INT != 64
1034 || c >> 31 == -1 || c >> 31 == 0)
1036 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1037 HOST_WIDE_INT tmp1 = c - low;
1039 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1040 HOST_WIDE_INT extra = 0;
1042 /* If HIGH will be interpreted as negative but the constant is
1043 positive, we must adjust it to do two ldha insns. */
1045 if ((high & 0x8000) != 0 && c >= 0)
1049 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1052 if (c == low || (low == 0 && extra == 0))
1054 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1055 but that meant that we can't handle INT_MIN on 32-bit machines
1056 (like NT/Alpha), because we recurse indefinitely through
1057 emit_move_insn to gen_movdi. So instead, since we know exactly
1058 what we want, create it explicitly. */
1061 target = gen_reg_rtx (mode);
1062 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1065 else if (n >= 2 + (extra != 0))
1067 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1070 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1071 subtarget, 0, OPTAB_WIDEN);
1073 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1074 target, 0, OPTAB_WIDEN);
1078 /* If we couldn't do it that way, try some other methods. But if we have
1079 no instructions left, don't bother. Likewise, if this is SImode and
1080 we can't make pseudos, we can't do anything since the expand_binop
1081 and expand_unop calls will widen and try to make pseudos. */
1084 || (mode == SImode && ! rtx_equal_function_value_matters))
1087 #if HOST_BITS_PER_WIDE_INT == 64
1088 /* First, see if can load a value into the target that is the same as the
1089 constant except that all bytes that are 0 are changed to be 0xff. If we
1090 can, then we can do a ZAPNOT to obtain the desired constant. */
1092 for (i = 0; i < 64; i += 8)
1093 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1094 new |= (HOST_WIDE_INT) 0xff << i;
1096 /* We are only called for SImode and DImode. If this is SImode, ensure that
1097 we are sign extended to a full word. */
1100 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1103 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1104 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1105 target, 0, OPTAB_WIDEN);
1108 /* Next, see if we can load a related constant and then shift and possibly
1109 negate it to get the constant we want. Try this once each increasing
1110 numbers of insns. */
1112 for (i = 1; i < n; i++)
1114 /* First try complementing. */
1115 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1116 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1118 /* Next try to form a constant and do a left shift. We can do this
1119 if some low-order bits are zero; the exact_log2 call below tells
1120 us that information. The bits we are shifting out could be any
1121 value, but here we'll just try the 0- and sign-extended forms of
1122 the constant. To try to increase the chance of having the same
1123 constant in more than one insn, start at the highest number of
1124 bits to shift, but try all possibilities in case a ZAPNOT will
1127 if ((bits = exact_log2 (c & - c)) > 0)
1128 for (; bits > 0; bits--)
1129 if ((temp = (alpha_emit_set_const
1131 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
1132 || ((temp = (alpha_emit_set_const
1134 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1136 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1137 target, 0, OPTAB_WIDEN);
1139 /* Now try high-order zero bits. Here we try the shifted-in bits as
1140 all zero and all ones. Be careful to avoid shifting outside the
1141 mode and to avoid shifting outside the host wide int size. */
1142 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1143 confuse the recursive call and set all of the high 32 bits. */
1145 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1146 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1147 for (; bits > 0; bits--)
1148 if ((temp = alpha_emit_set_const (subtarget, mode,
1150 || ((temp = (alpha_emit_set_const
1152 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1155 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1156 target, 1, OPTAB_WIDEN);
1158 /* Now try high-order 1 bits. We get that with a sign-extension.
1159 But one bit isn't enough here. Be careful to avoid shifting outside
1160 the mode and to avoid shifting outside the host wide int size. */
1162 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1163 - floor_log2 (~ c) - 2)) > 0)
1164 for (; bits > 0; bits--)
1165 if ((temp = alpha_emit_set_const (subtarget, mode,
1167 || ((temp = (alpha_emit_set_const
1169 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1172 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1173 target, 0, OPTAB_WIDEN);
1179 #if HOST_BITS_PER_WIDE_INT == 64
1180 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1181 fall back to a straight forward decomposition. We do this to avoid
1182 exponential run times encountered when looking for longer sequences
1183 with alpha_emit_set_const. */
1186 alpha_emit_set_long_const (target, c)
1190 /* Use a pseudo if highly optimizing and still generating RTL. */
1192 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1194 HOST_WIDE_INT d1, d2, d3, d4;
1197 /* Decompose the entire word */
1198 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1200 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1202 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1204 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1209 /* Construct the high word */
1211 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
1213 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
1215 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1216 subtarget, 0, OPTAB_WIDEN);
1218 /* Shift it into place */
1219 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1220 subtarget, 0, OPTAB_WIDEN);
1222 if (subtarget == 0 && d1 == d3 && d2 == d4)
1223 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1228 /* Add in the low word */
1230 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1231 subtarget, 0, OPTAB_WIDEN);
1233 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1234 subtarget, 0, OPTAB_WIDEN);
1238 r1 = copy_to_suggested_reg(r1, target, DImode);
1242 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1244 /* Generate the comparison for a conditional branch. */
1247 alpha_emit_conditional_branch (code)
1250 enum rtx_code cmp_code, branch_code;
1251 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1252 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1255 /* The general case: fold the comparison code to the types of compares
1256 that we have, choosing the branch as necessary. */
1259 case EQ: case LE: case LT: case LEU: case LTU:
1260 /* We have these compares: */
1261 cmp_code = code, branch_code = NE;
1265 /* This must be reversed. */
1266 cmp_code = EQ, branch_code = EQ;
1269 case GE: case GT: case GEU: case GTU:
1270 /* For FP, we swap them, for INT, we reverse them. */
1271 if (alpha_compare_fp_p)
1273 cmp_code = swap_condition (code);
1275 tem = op0, op0 = op1, op1 = tem;
1279 cmp_code = reverse_condition (code);
1288 if (alpha_compare_fp_p)
1293 /* When we are not as concerned about non-finite values, and we
1294 are comparing against zero, we can branch directly. */
1295 if (op1 == CONST0_RTX (DFmode))
1296 cmp_code = NIL, branch_code = code;
1297 else if (op0 == CONST0_RTX (DFmode))
1299 /* Undo the swap we probably did just above. */
1300 tem = op0, op0 = op1, op1 = tem;
1301 branch_code = swap_condition (cmp_code);
1307 /* ??? We mark the the branch mode to be CCmode to prevent the
1308 compare and branch from being combined, since the compare
1309 insn follows IEEE rules that the branch does not. */
1310 branch_mode = CCmode;
1317 /* The following optimizations are only for signed compares. */
1318 if (code != LEU && code != LTU && code != GEU && code != GTU)
1320 /* Whee. Compare and branch against 0 directly. */
1321 if (op1 == const0_rtx)
1322 cmp_code = NIL, branch_code = code;
1324 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1325 bypass between logicals and br/cmov on EV5. But we don't want to
1326 force valid immediate constants into registers needlessly. */
1327 else if (GET_CODE (op1) == CONST_INT)
1329 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1331 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1332 && (CONST_OK_FOR_LETTER_P (n, 'K')
1333 || CONST_OK_FOR_LETTER_P (n, 'L')))
1335 cmp_code = PLUS, branch_code = code;
1342 /* Force op0 into a register. */
1343 if (GET_CODE (op0) != REG)
1344 op0 = force_reg (cmp_mode, op0);
1346 /* Emit an initial compare instruction, if necessary. */
1348 if (cmp_code != NIL)
1350 tem = gen_reg_rtx (cmp_mode);
1351 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1354 /* Return the branch comparison. */
1355 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1359 /* Rewrite a comparison against zero CMP of the form
1360 (CODE (cc0) (const_int 0)) so it can be written validly in
1361 a conditional move (if_then_else CMP ...).
1362 If both of the operands that set cc0 are non-zero we must emit
1363 an insn to perform the compare (it can't be done within
1364 the conditional move). */
1366 alpha_emit_conditional_move (cmp, mode)
1368 enum machine_mode mode;
1370 enum rtx_code code = GET_CODE (cmp);
1371 enum rtx_code cmov_code = NE;
1372 rtx op0 = alpha_compare_op0;
1373 rtx op1 = alpha_compare_op1;
1374 enum machine_mode cmp_mode
1375 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1376 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1377 enum machine_mode cmov_mode = VOIDmode;
1380 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1383 /* We may be able to use a conditional move directly.
1384 This avoids emitting spurious compares. */
1385 if (signed_comparison_operator (cmp, cmp_op_mode)
1386 && (!alpha_compare_fp_p || flag_fast_math)
1387 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1388 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1390 /* We can't put the comparison insides a conditional move;
1391 emit a compare instruction and put that inside the
1392 conditional move. Make sure we emit only comparisons we have;
1393 swap or reverse as necessary. */
1397 case EQ: case LE: case LT: case LEU: case LTU:
1398 /* We have these compares: */
1402 /* This must be reversed. */
1403 code = reverse_condition (code);
1407 case GE: case GT: case GEU: case GTU:
1408 /* These must be swapped. Make sure the new first operand is in
1410 code = swap_condition (code);
1411 tem = op0, op0 = op1, op1 = tem;
1412 op0 = force_reg (cmp_mode, op0);
1419 /* ??? We mark the branch mode to be CCmode to prevent the compare
1420 and cmov from being combined, since the compare insn follows IEEE
1421 rules that the cmov does not. */
1422 if (alpha_compare_fp_p && !flag_fast_math)
1425 tem = gen_reg_rtx (cmp_op_mode);
1426 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1427 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1430 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1434 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1435 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1436 lda r3,X(r11) lda r3,X+2(r11)
1437 extwl r1,r3,r1 extql r1,r3,r1
1438 extwh r2,r3,r2 extqh r2,r3,r2
1439 or r1.r2.r1 or r1,r2,r1
1442 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1443 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1444 lda r3,X(r11) lda r3,X(r11)
1445 extll r1,r3,r1 extll r1,r3,r1
1446 extlh r2,r3,r2 extlh r2,r3,r2
1447 or r1.r2.r1 addl r1,r2,r1
1449 quad: ldq_u r1,X(r11)
1458 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1460 HOST_WIDE_INT size, ofs;
1463 rtx meml, memh, addr, extl, exth;
1464 enum machine_mode mode;
1466 meml = gen_reg_rtx (DImode);
1467 memh = gen_reg_rtx (DImode);
1468 addr = gen_reg_rtx (DImode);
1469 extl = gen_reg_rtx (DImode);
1470 exth = gen_reg_rtx (DImode);
1472 emit_move_insn (meml,
1473 change_address (mem, DImode,
1474 gen_rtx_AND (DImode,
1475 plus_constant (XEXP (mem, 0),
1479 emit_move_insn (memh,
1480 change_address (mem, DImode,
1481 gen_rtx_AND (DImode,
1482 plus_constant (XEXP (mem, 0),
1486 if (sign && size == 2)
1488 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1490 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1491 emit_insn (gen_extqh (exth, memh, addr));
1493 /* We must use tgt here for the target. Alpha-vms port fails if we use
1494 addr for the target, because addr is marked as a pointer and combine
1495 knows that pointers are always sign-extended 32 bit values. */
1496 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1497 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1498 addr, 1, OPTAB_WIDEN);
1502 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1503 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1507 emit_insn (gen_extwh (exth, memh, addr));
1512 emit_insn (gen_extlh (exth, memh, addr));
1517 emit_insn (gen_extqh (exth, memh, addr));
1522 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1523 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1528 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1531 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1534 alpha_expand_unaligned_store (dst, src, size, ofs)
1536 HOST_WIDE_INT size, ofs;
1538 rtx dstl, dsth, addr, insl, insh, meml, memh;
1540 dstl = gen_reg_rtx (DImode);
1541 dsth = gen_reg_rtx (DImode);
1542 insl = gen_reg_rtx (DImode);
1543 insh = gen_reg_rtx (DImode);
1545 meml = change_address (dst, DImode,
1546 gen_rtx_AND (DImode,
1547 plus_constant (XEXP (dst, 0), ofs),
1549 memh = change_address (dst, DImode,
1550 gen_rtx_AND (DImode,
1551 plus_constant (XEXP (dst, 0),
1555 emit_move_insn (dsth, memh);
1556 emit_move_insn (dstl, meml);
1557 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1559 if (src != const0_rtx)
1561 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1562 GEN_INT (size*8), addr));
1567 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1570 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1573 emit_insn (gen_insql (insl, src, addr));
1578 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1583 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1586 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1590 #if HOST_BITS_PER_WIDE_INT == 32
1591 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1593 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1595 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1600 if (src != const0_rtx)
1602 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1603 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1606 /* Must store high before low for degenerate case of aligned. */
1607 emit_move_insn (memh, dsth);
1608 emit_move_insn (meml, dstl);
1611 /* The block move code tries to maximize speed by separating loads and
1612 stores at the expense of register pressure: we load all of the data
1613 before we store it back out. There are two secondary effects worth
1614 mentioning, that this speeds copying to/from aligned and unaligned
1615 buffers, and that it makes the code significantly easier to write. */
1617 #define MAX_MOVE_WORDS 8
1619 /* Load an integral number of consecutive unaligned quadwords. */
1622 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1625 HOST_WIDE_INT words, ofs;
1627 rtx const im8 = GEN_INT (-8);
1628 rtx const i64 = GEN_INT (64);
1629 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1633 /* Generate all the tmp registers we need. */
1634 for (i = 0; i < words; ++i)
1636 data_regs[i] = out_regs[i];
1637 ext_tmps[i] = gen_reg_rtx (DImode);
1639 data_regs[words] = gen_reg_rtx (DImode);
1642 smem = change_address (smem, GET_MODE (smem),
1643 plus_constant (XEXP (smem, 0), ofs));
1645 /* Load up all of the source data. */
1646 for (i = 0; i < words; ++i)
1648 emit_move_insn (data_regs[i],
1649 change_address (smem, DImode,
1650 gen_rtx_AND (DImode,
1651 plus_constant (XEXP(smem,0),
1655 emit_move_insn (data_regs[words],
1656 change_address (smem, DImode,
1657 gen_rtx_AND (DImode,
1658 plus_constant (XEXP(smem,0),
1662 /* Extract the half-word fragments. Unfortunately DEC decided to make
1663 extxh with offset zero a noop instead of zeroing the register, so
1664 we must take care of that edge condition ourselves with cmov. */
1666 sreg = copy_addr_to_reg (XEXP (smem, 0));
1667 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1669 for (i = 0; i < words; ++i)
1671 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1673 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1674 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1675 gen_rtx_IF_THEN_ELSE (DImode,
1676 gen_rtx_EQ (DImode, areg,
1678 const0_rtx, ext_tmps[i])));
1681 /* Merge the half-words into whole words. */
1682 for (i = 0; i < words; ++i)
1684 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1685 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1689 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1690 may be NULL to store zeros. */
1693 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1696 HOST_WIDE_INT words, ofs;
1698 rtx const im8 = GEN_INT (-8);
1699 rtx const i64 = GEN_INT (64);
1700 #if HOST_BITS_PER_WIDE_INT == 32
1701 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1703 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1705 rtx ins_tmps[MAX_MOVE_WORDS];
1706 rtx st_tmp_1, st_tmp_2, dreg;
1707 rtx st_addr_1, st_addr_2;
1710 /* Generate all the tmp registers we need. */
1711 if (data_regs != NULL)
1712 for (i = 0; i < words; ++i)
1713 ins_tmps[i] = gen_reg_rtx(DImode);
1714 st_tmp_1 = gen_reg_rtx(DImode);
1715 st_tmp_2 = gen_reg_rtx(DImode);
1718 dmem = change_address (dmem, GET_MODE (dmem),
1719 plus_constant (XEXP (dmem, 0), ofs));
1722 st_addr_2 = change_address (dmem, DImode,
1723 gen_rtx_AND (DImode,
1724 plus_constant (XEXP(dmem,0),
1727 st_addr_1 = change_address (dmem, DImode,
1728 gen_rtx_AND (DImode,
1732 /* Load up the destination end bits. */
1733 emit_move_insn (st_tmp_2, st_addr_2);
1734 emit_move_insn (st_tmp_1, st_addr_1);
1736 /* Shift the input data into place. */
1737 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1738 if (data_regs != NULL)
1740 for (i = words-1; i >= 0; --i)
1742 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1743 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1745 for (i = words-1; i > 0; --i)
1747 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1748 ins_tmps[i-1], ins_tmps[i-1], 1,
1753 /* Split and merge the ends with the destination data. */
1754 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1755 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1757 if (data_regs != NULL)
1759 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1760 st_tmp_2, 1, OPTAB_WIDEN);
1761 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1762 st_tmp_1, 1, OPTAB_WIDEN);
1766 emit_move_insn (st_addr_2, st_tmp_2);
1767 for (i = words-1; i > 0; --i)
1769 emit_move_insn (change_address (dmem, DImode,
1770 gen_rtx_AND (DImode,
1771 plus_constant(XEXP (dmem,0),
1774 data_regs ? ins_tmps[i-1] : const0_rtx);
1776 emit_move_insn (st_addr_1, st_tmp_1);
1780 /* Expand string/block move operations.
1782 operands[0] is the pointer to the destination.
1783 operands[1] is the pointer to the source.
1784 operands[2] is the number of bytes to move.
1785 operands[3] is the alignment. */
1788 alpha_expand_block_move (operands)
1791 rtx bytes_rtx = operands[2];
1792 rtx align_rtx = operands[3];
1793 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1794 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1795 HOST_WIDE_INT dst_align = src_align;
1796 rtx orig_src = operands[1];
1797 rtx orig_dst = operands[0];
1798 rtx data_regs[2*MAX_MOVE_WORDS+16];
1800 int i, words, ofs, nregs = 0;
1804 if (bytes > MAX_MOVE_WORDS*8)
1807 /* Look for additional alignment information from recorded register info. */
1809 tmp = XEXP (orig_src, 0);
1810 if (GET_CODE (tmp) == REG)
1812 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1813 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1815 else if (GET_CODE (tmp) == PLUS
1816 && GET_CODE (XEXP (tmp, 0)) == REG
1817 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1819 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1820 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1824 if (a >= 8 && c % 8 == 0)
1826 else if (a >= 4 && c % 4 == 0)
1828 else if (a >= 2 && c % 2 == 0)
1833 tmp = XEXP (orig_dst, 0);
1834 if (GET_CODE (tmp) == REG)
1836 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1837 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1839 else if (GET_CODE (tmp) == PLUS
1840 && GET_CODE (XEXP (tmp, 0)) == REG
1841 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1843 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1844 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1848 if (a >= 8 && c % 8 == 0)
1850 else if (a >= 4 && c % 4 == 0)
1852 else if (a >= 2 && c % 2 == 0)
1858 * Load the entire block into registers.
1861 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1863 enum machine_mode mode;
1864 tmp = XEXP (XEXP (orig_src, 0), 0);
1866 mode = mode_for_size (bytes, MODE_INT, 1);
1868 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1870 /* Whee! Optimize the load to use the existing register. */
1871 data_regs[nregs++] = gen_lowpart (mode, tmp);
1875 /* ??? We could potentially be copying 3 bytes or whatnot from
1876 a wider reg. Probably not worth worrying about. */
1877 /* No appropriate mode; fall back on memory. */
1878 orig_src = change_address (orig_src, GET_MODE (orig_src),
1879 copy_addr_to_reg (XEXP (orig_src, 0)));
1883 if (src_align >= 8 && bytes >= 8)
1887 for (i = 0; i < words; ++i)
1888 data_regs[nregs+i] = gen_reg_rtx(DImode);
1890 for (i = 0; i < words; ++i)
1892 emit_move_insn (data_regs[nregs+i],
1893 change_address(orig_src, DImode,
1894 plus_constant (XEXP (orig_src, 0),
1902 if (src_align >= 4 && bytes >= 4)
1906 for (i = 0; i < words; ++i)
1907 data_regs[nregs+i] = gen_reg_rtx(SImode);
1909 for (i = 0; i < words; ++i)
1911 emit_move_insn (data_regs[nregs+i],
1912 change_address(orig_src, SImode,
1913 plus_constant (XEXP (orig_src, 0),
1925 for (i = 0; i < words+1; ++i)
1926 data_regs[nregs+i] = gen_reg_rtx(DImode);
1928 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1934 if (!TARGET_BWX && bytes >= 8)
1936 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1937 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1941 if (!TARGET_BWX && bytes >= 4)
1943 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1944 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1953 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1954 emit_move_insn (tmp,
1955 change_address (orig_src, HImode,
1956 plus_constant (XEXP (orig_src, 0),
1960 } while (bytes >= 2);
1962 else if (!TARGET_BWX)
1964 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1965 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1972 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1973 emit_move_insn (tmp,
1974 change_address (orig_src, QImode,
1975 plus_constant (XEXP (orig_src, 0),
1982 if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1986 * Now save it back out again.
1991 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1993 enum machine_mode mode;
1994 tmp = XEXP (XEXP (orig_dst, 0), 0);
1996 mode = mode_for_size (bytes, MODE_INT, 1);
1997 if (GET_MODE (tmp) == mode && nregs == 1)
1999 emit_move_insn (tmp, data_regs[0]);
2004 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2005 /* ??? Optimize mode < dst_mode with strict_low_part. */
2006 /* No appropriate mode; fall back on memory. */
2007 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2008 copy_addr_to_reg (XEXP (orig_dst, 0)));
2011 /* Write out the data in whatever chunks reading the source allowed. */
2014 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2016 emit_move_insn (change_address(orig_dst, DImode,
2017 plus_constant (XEXP (orig_dst, 0),
2026 /* If the source has remaining DImode regs, write them out in
2028 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2030 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2031 NULL_RTX, 1, OPTAB_WIDEN);
2033 emit_move_insn (change_address(orig_dst, SImode,
2034 plus_constant (XEXP (orig_dst, 0),
2036 gen_lowpart (SImode, data_regs[i]));
2037 emit_move_insn (change_address(orig_dst, SImode,
2038 plus_constant (XEXP (orig_dst, 0),
2040 gen_lowpart (SImode, tmp));
2045 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2047 emit_move_insn (change_address(orig_dst, SImode,
2048 plus_constant (XEXP (orig_dst, 0),
2055 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2057 /* Write out a remaining block of words using unaligned methods. */
2059 for (words = 1; i+words < nregs ; ++words)
2060 if (GET_MODE (data_regs[i+words]) != DImode)
2064 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2066 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2072 /* Due to the above, this won't be aligned. */
2073 /* ??? If we have more than one of these, consider constructing full
2074 words in registers and using alpha_expand_unaligned_store_words. */
2075 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2077 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2083 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2085 emit_move_insn (change_address (orig_dst, HImode,
2086 plus_constant (XEXP (orig_dst, 0),
2093 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2095 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2099 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2101 emit_move_insn (change_address (orig_dst, QImode,
2102 plus_constant (XEXP (orig_dst, 0),
2117 alpha_expand_block_clear (operands)
2120 rtx bytes_rtx = operands[1];
2121 rtx align_rtx = operands[2];
2122 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2123 HOST_WIDE_INT align = INTVAL (align_rtx);
2124 rtx orig_dst = operands[0];
2126 HOST_WIDE_INT i, words, ofs = 0;
2130 if (bytes > MAX_MOVE_WORDS*8)
2133 /* Look for stricter alignment. */
2135 tmp = XEXP (orig_dst, 0);
2136 if (GET_CODE (tmp) == REG)
2138 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2139 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2141 else if (GET_CODE (tmp) == PLUS
2142 && GET_CODE (XEXP (tmp, 0)) == REG
2143 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2145 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2146 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2150 if (a >= 8 && c % 8 == 0)
2152 else if (a >= 4 && c % 4 == 0)
2154 else if (a >= 2 && c % 2 == 0)
2159 /* Handle a block of contiguous words first. */
2161 if (align >= 8 && bytes >= 8)
2165 for (i = 0; i < words; ++i)
2167 emit_move_insn (change_address(orig_dst, DImode,
2168 plus_constant (XEXP (orig_dst, 0),
2176 if (align >= 4 && bytes >= 4)
2180 for (i = 0; i < words; ++i)
2182 emit_move_insn (change_address(orig_dst, SImode,
2183 plus_constant (XEXP (orig_dst, 0),
2195 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2201 /* Next clean up any trailing pieces. We know from the contiguous
2202 block move that there are no aligned SImode or DImode hunks left. */
2204 if (!TARGET_BWX && bytes >= 8)
2206 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2210 if (!TARGET_BWX && bytes >= 4)
2212 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2221 emit_move_insn (change_address (orig_dst, HImode,
2222 plus_constant (XEXP (orig_dst, 0),
2227 } while (bytes >= 2);
2229 else if (!TARGET_BWX)
2231 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2238 emit_move_insn (change_address (orig_dst, QImode,
2239 plus_constant (XEXP (orig_dst, 0),
2250 /* Adjust the cost of a scheduling dependency. Return the new cost of
2251 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2254 alpha_adjust_cost (insn, link, dep_insn, cost)
2261 enum attr_type insn_type, dep_insn_type;
2263 /* If the dependence is an anti-dependence, there is no cost. For an
2264 output dependence, there is sometimes a cost, but it doesn't seem
2265 worth handling those few cases. */
2267 if (REG_NOTE_KIND (link) != 0)
2270 /* If we can't recognize the insns, we can't really do anything. */
2271 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2274 insn_type = get_attr_type (insn);
2275 dep_insn_type = get_attr_type (dep_insn);
2277 /* Bring in the user-defined memory latency. */
2278 if (dep_insn_type == TYPE_ILD
2279 || dep_insn_type == TYPE_FLD
2280 || dep_insn_type == TYPE_LDSYM)
2281 cost += alpha_memory_latency-1;
2286 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2287 being stored, we can sometimes lower the cost. */
2289 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2290 && (set = single_set (dep_insn)) != 0
2291 && GET_CODE (PATTERN (insn)) == SET
2292 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2294 switch (dep_insn_type)
2298 /* No savings here. */
2302 /* In these cases, we save one cycle. */
2306 /* In all other cases, we save two cycles. */
2307 return MAX (0, cost - 2);
2311 /* Another case that needs adjustment is an arithmetic or logical
2312 operation. It's cost is usually one cycle, but we default it to
2313 two in the MD file. The only case that it is actually two is
2314 for the address in loads, stores, and jumps. */
2316 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2331 /* The final case is when a compare feeds into an integer branch;
2332 the cost is only one cycle in that case. */
2334 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2339 /* And the lord DEC saith: "A special bypass provides an effective
2340 latency of 0 cycles for an ICMP or ILOG insn producing the test
2341 operand of an IBR or ICMOV insn." */
2343 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2344 && (set = single_set (dep_insn)) != 0)
2346 /* A branch only has one input. This must be it. */
2347 if (insn_type == TYPE_IBR)
2349 /* A conditional move has three, make sure it is the test. */
2350 if (insn_type == TYPE_ICMOV
2351 && GET_CODE (set_src = PATTERN (insn)) == SET
2352 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2353 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2357 /* "The multiplier is unable to receive data from IEU bypass paths.
2358 The instruction issues at the expected time, but its latency is
2359 increased by the time it takes for the input data to become
2360 available to the multiplier" -- which happens in pipeline stage
2361 six, when results are comitted to the register file. */
2363 if (insn_type == TYPE_IMUL)
2365 switch (dep_insn_type)
2367 /* These insns produce their results in pipeline stage five. */
2374 /* Other integer insns produce results in pipeline stage four. */
2382 /* There is additional latency to move the result of (most) FP
2383 operations anywhere but the FP register file. */
2385 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2386 && (dep_insn_type == TYPE_FADD ||
2387 dep_insn_type == TYPE_FMUL ||
2388 dep_insn_type == TYPE_FCMOV))
2394 /* Otherwise, return the default cost. */
2398 /* Functions to save and restore alpha_return_addr_rtx. */
2400 struct machine_function
2406 alpha_save_machine_status (p)
2409 struct machine_function *machine =
2410 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2412 p->machine = machine;
2413 machine->ra_rtx = alpha_return_addr_rtx;
2417 alpha_restore_machine_status (p)
2420 struct machine_function *machine = p->machine;
2422 alpha_return_addr_rtx = machine->ra_rtx;
2425 p->machine = (struct machine_function *)0;
2428 /* Do anything needed before RTL is emitted for each function. */
2431 alpha_init_expanders ()
2433 alpha_return_addr_rtx = NULL_RTX;
2435 /* Arrange to save and restore machine status around nested functions. */
2436 save_machine_status = alpha_save_machine_status;
2437 restore_machine_status = alpha_restore_machine_status;
2440 /* Start the ball rolling with RETURN_ADDR_RTX. */
2443 alpha_return_addr (count, frame)
2445 rtx frame ATTRIBUTE_UNUSED;
2452 if (alpha_return_addr_rtx)
2453 return alpha_return_addr_rtx;
2455 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2456 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2457 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2458 gen_rtx_REG (Pmode, REG_RA));
2460 /* Emit the insn to the prologue with the other argument copies. */
2461 push_topmost_sequence ();
2462 emit_insn_after (init, get_insns ());
2463 pop_topmost_sequence ();
2465 return alpha_return_addr_rtx;
2469 alpha_ra_ever_killed ()
2471 #ifdef ASM_OUTPUT_MI_THUNK
2472 if (current_function_is_thunk)
2475 if (!alpha_return_addr_rtx)
2476 return regs_ever_live[REG_RA];
2478 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2479 get_insns(), NULL_RTX);
2483 /* Print an operand. Recognize special options, documented below. */
2486 print_operand (file, x, code)
2496 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2497 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2498 mode. alpha_fprm controls which suffix is generated. */
2501 case ALPHA_FPRM_NORM:
2503 case ALPHA_FPRM_MINF:
2506 case ALPHA_FPRM_CHOP:
2509 case ALPHA_FPRM_DYN:
2516 /* Generates trap-mode suffix for instructions that accept the su
2517 suffix only (cmpt et al). */
2518 if (alpha_tp == ALPHA_TP_INSN)
2523 /* Generates trap-mode suffix for instructions that accept the
2524 v and sv suffix. The only instruction that needs this is cvtql. */
2533 case ALPHA_FPTM_SUI:
2540 /* Generates trap-mode suffix for instructions that accept the
2541 v, sv, and svi suffix. The only instruction that needs this
2553 case ALPHA_FPTM_SUI:
2554 fputs ("svi", file);
2560 /* Generates trap-mode suffix for instructions that accept the u, su,
2561 and sui suffix. This is the bulk of the IEEE floating point
2562 instructions (addt et al). */
2573 case ALPHA_FPTM_SUI:
2574 fputs ("sui", file);
2580 /* Generates trap-mode suffix for instructions that accept the sui
2581 suffix (cvtqt and cvtqs). */
2586 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2588 case ALPHA_FPTM_SUI:
2589 fputs ("sui", file);
2595 /* Generates single precision instruction suffix. */
2596 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2600 /* Generates double precision instruction suffix. */
2601 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2605 /* If this operand is the constant zero, write it as "$31". */
2606 if (GET_CODE (x) == REG)
2607 fprintf (file, "%s", reg_names[REGNO (x)]);
2608 else if (x == CONST0_RTX (GET_MODE (x)))
2609 fprintf (file, "$31");
2611 output_operand_lossage ("invalid %%r value");
2616 /* Similar, but for floating-point. */
2617 if (GET_CODE (x) == REG)
2618 fprintf (file, "%s", reg_names[REGNO (x)]);
2619 else if (x == CONST0_RTX (GET_MODE (x)))
2620 fprintf (file, "$f31");
2622 output_operand_lossage ("invalid %%R value");
2627 /* Write the 1's complement of a constant. */
2628 if (GET_CODE (x) != CONST_INT)
2629 output_operand_lossage ("invalid %%N value");
2631 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2635 /* Write 1 << C, for a constant C. */
2636 if (GET_CODE (x) != CONST_INT)
2637 output_operand_lossage ("invalid %%P value");
2639 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2643 /* Write the high-order 16 bits of a constant, sign-extended. */
2644 if (GET_CODE (x) != CONST_INT)
2645 output_operand_lossage ("invalid %%h value");
2647 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2651 /* Write the low-order 16 bits of a constant, sign-extended. */
2652 if (GET_CODE (x) != CONST_INT)
2653 output_operand_lossage ("invalid %%L value");
2655 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2656 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2660 /* Write mask for ZAP insn. */
2661 if (GET_CODE (x) == CONST_DOUBLE)
2663 HOST_WIDE_INT mask = 0;
2664 HOST_WIDE_INT value;
2666 value = CONST_DOUBLE_LOW (x);
2667 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2672 value = CONST_DOUBLE_HIGH (x);
2673 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2676 mask |= (1 << (i + sizeof (int)));
2678 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2681 else if (GET_CODE (x) == CONST_INT)
2683 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2685 for (i = 0; i < 8; i++, value >>= 8)
2689 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2692 output_operand_lossage ("invalid %%m value");
2696 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2697 if (GET_CODE (x) != CONST_INT
2698 || (INTVAL (x) != 8 && INTVAL (x) != 16
2699 && INTVAL (x) != 32 && INTVAL (x) != 64))
2700 output_operand_lossage ("invalid %%M value");
2702 fprintf (file, "%s",
2703 (INTVAL (x) == 8 ? "b"
2704 : INTVAL (x) == 16 ? "w"
2705 : INTVAL (x) == 32 ? "l"
2710 /* Similar, except do it from the mask. */
2711 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2712 fprintf (file, "b");
2713 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2714 fprintf (file, "w");
2715 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2716 fprintf (file, "l");
2717 #if HOST_BITS_PER_WIDE_INT == 32
2718 else if (GET_CODE (x) == CONST_DOUBLE
2719 && CONST_DOUBLE_HIGH (x) == 0
2720 && CONST_DOUBLE_LOW (x) == -1)
2721 fprintf (file, "l");
2722 else if (GET_CODE (x) == CONST_DOUBLE
2723 && CONST_DOUBLE_HIGH (x) == -1
2724 && CONST_DOUBLE_LOW (x) == -1)
2725 fprintf (file, "q");
2727 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2728 fprintf (file, "q");
2729 else if (GET_CODE (x) == CONST_DOUBLE
2730 && CONST_DOUBLE_HIGH (x) == 0
2731 && CONST_DOUBLE_LOW (x) == -1)
2732 fprintf (file, "q");
2735 output_operand_lossage ("invalid %%U value");
2739 /* Write the constant value divided by 8. */
2740 if (GET_CODE (x) != CONST_INT
2741 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2742 && (INTVAL (x) & 7) != 8)
2743 output_operand_lossage ("invalid %%s value");
2745 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2749 /* Same, except compute (64 - c) / 8 */
2751 if (GET_CODE (x) != CONST_INT
2752 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2753 && (INTVAL (x) & 7) != 8)
2754 output_operand_lossage ("invalid %%s value");
2756 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2759 case 'C': case 'D': case 'c': case 'd':
2760 /* Write out comparison name. */
2762 enum rtx_code c = GET_CODE (x);
2764 if (GET_RTX_CLASS (c) != '<')
2765 output_operand_lossage ("invalid %%C value");
2768 c = reverse_condition (c);
2769 else if (code == 'c')
2770 c = swap_condition (c);
2771 else if (code == 'd')
2772 c = swap_condition (reverse_condition (c));
2775 fprintf (file, "ule");
2777 fprintf (file, "ult");
2779 fprintf (file, "%s", GET_RTX_NAME (c));
2784 /* Write the divide or modulus operator. */
2785 switch (GET_CODE (x))
2788 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2791 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2794 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2797 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2800 output_operand_lossage ("invalid %%E value");
2806 /* Write "_u" for unaligned access. */
2807 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2808 fprintf (file, "_u");
2812 if (GET_CODE (x) == REG)
2813 fprintf (file, "%s", reg_names[REGNO (x)]);
2814 else if (GET_CODE (x) == MEM)
2815 output_address (XEXP (x, 0));
2817 output_addr_const (file, x);
2821 output_operand_lossage ("invalid %%xn code");
2825 /* Emit RTL insns to initialize the variable parts of a trampoline at
2826 TRAMP. FNADDR is an RTX for the address of the function's pure
2827 code. CXT is an RTX for the static chain value for the function.
2829 The three offset parameters are for the individual template's
2830 layout. A JMPOFS < 0 indicates that the trampoline does not
2831 contain instructions at all.
2833 We assume here that a function will be called many more times than
2834 its address is taken (e.g., it might be passed to qsort), so we
2835 take the trouble to initialize the "hint" field in the JMP insn.
2836 Note that the hint field is PC (new) + 4 * bits 13:0. */
2839 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2840 rtx tramp, fnaddr, cxt;
2841 int fnofs, cxtofs, jmpofs;
2843 rtx temp, temp1, addr;
2844 /* ??? Something is wrong with VMS codegen in that we get aborts when
2845 using ptr_mode. Hack around it for now. */
2846 enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2848 /* Store function address and CXT. */
2849 addr = memory_address (mode, plus_constant (tramp, fnofs));
2850 emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2851 addr = memory_address (mode, plus_constant (tramp, cxtofs));
2852 emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2854 /* This has been disabled since the hint only has a 32k range, and in
2855 no existing OS is the stack within 32k of the text segment. */
2856 if (0 && jmpofs >= 0)
2858 /* Compute hint value. */
2859 temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
2860 temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
2862 temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
2863 build_int_2 (2, 0), NULL_RTX, 1);
2864 temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
2866 /* Merge in the hint. */
2867 addr = memory_address (SImode, plus_constant (tramp, jmpofs));
2868 temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
2869 temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
2870 temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
2872 emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
2875 #ifdef TRANSFER_FROM_TRAMPOLINE
2876 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
2877 0, VOIDmode, 1, addr, Pmode);
2881 emit_insn (gen_imb ());
2884 /* Do what is necessary for `va_start'. The argument is ignored;
2885 We look at the current function to determine if stdarg or varargs
2886 is used and fill in an initial va_list. A pointer to this constructor
2890 alpha_builtin_saveregs (arglist)
2891 tree arglist ATTRIBUTE_UNUSED;
2893 rtx block, addr, dest, argsize;
2894 tree fntype = TREE_TYPE (current_function_decl);
2895 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2896 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2897 != void_type_node));
2899 /* Compute the current position into the args, taking into account
2900 both registers and memory. Both of these are already included in
2903 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2905 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2906 storing fp arg registers in the first 48 bytes, and the integer arg
2907 registers in the next 48 bytes. This is only done, however, if any
2908 integer registers need to be stored.
2910 If no integer registers need be stored, then we must subtract 48 in
2911 order to account for the integer arg registers which are counted in
2912 argsize above, but which are not actually stored on the stack. */
2914 if (TARGET_OPEN_VMS)
2915 addr = plus_constant (virtual_incoming_args_rtx,
2916 NUM_ARGS <= 5 + stdarg
2917 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2919 addr = (NUM_ARGS <= 5 + stdarg
2920 ? plus_constant (virtual_incoming_args_rtx,
2922 : plus_constant (virtual_incoming_args_rtx,
2923 - (6 * UNITS_PER_WORD)));
2925 /* For VMS, we include the argsize, while on Unix, it's handled as
2926 a separate field. */
2927 if (TARGET_OPEN_VMS)
2928 addr = plus_constant (addr, INTVAL (argsize));
2930 addr = force_operand (addr, NULL_RTX);
2932 #ifdef POINTERS_EXTEND_UNSIGNED
2933 addr = convert_memory_address (ptr_mode, addr);
2936 if (TARGET_OPEN_VMS)
2940 /* Allocate the va_list constructor */
2941 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2942 RTX_UNCHANGING_P (block) = 1;
2943 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2945 /* Store the address of the first integer register in the __base
2948 dest = change_address (block, ptr_mode, XEXP (block, 0));
2949 emit_move_insn (dest, addr);
2951 if (flag_check_memory_usage)
2952 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2954 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2955 TYPE_MODE (sizetype),
2956 GEN_INT (MEMORY_USE_RW),
2957 TYPE_MODE (integer_type_node));
2959 /* Store the argsize as the __va_offset member. */
2960 dest = change_address (block, TYPE_MODE (integer_type_node),
2961 plus_constant (XEXP (block, 0),
2962 POINTER_SIZE/BITS_PER_UNIT));
2963 emit_move_insn (dest, argsize);
2965 if (flag_check_memory_usage)
2966 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2968 GEN_INT (GET_MODE_SIZE
2969 (TYPE_MODE (integer_type_node))),
2970 TYPE_MODE (sizetype),
2971 GEN_INT (MEMORY_USE_RW),
2972 TYPE_MODE (integer_type_node));
2974 /* Return the address of the va_list constructor, but don't put it in a
2975 register. Doing so would fail when not optimizing and produce worse
2976 code when optimizing. */
2977 return XEXP (block, 0);
2981 /* This page contains routines that are used to determine what the function
2982 prologue and epilogue code will do and write them out. */
2984 /* Compute the size of the save area in the stack. */
2986 /* These variables are used for communication between the following functions.
2987 They indicate various things about the current function being compiled
2988 that are used to tell what kind of prologue, epilogue and procedure
2989 descriptior to generate. */
2991 /* Nonzero if we need a stack procedure. */
2992 static int vms_is_stack_procedure;
2994 /* Register number (either FP or SP) that is used to unwind the frame. */
2995 static int vms_unwind_regno;
2997 /* Register number used to save FP. We need not have one for RA since
2998 we don't modify it for register procedures. This is only defined
2999 for register frame procedures. */
3000 static int vms_save_fp_regno;
3002 /* Register number used to reference objects off our PV. */
3003 static int vms_base_regno;
3005 /* Compute register masks for saved registers. */
3008 alpha_sa_mask (imaskP, fmaskP)
3009 unsigned long *imaskP;
3010 unsigned long *fmaskP;
3012 unsigned long imask = 0;
3013 unsigned long fmask = 0;
3016 #ifdef ASM_OUTPUT_MI_THUNK
3017 if (!current_function_is_thunk)
3020 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3021 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3023 /* One for every register we have to save. */
3024 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3025 if (! fixed_regs[i] && ! call_used_regs[i]
3026 && regs_ever_live[i] && i != REG_RA)
3031 fmask |= (1L << (i - 32));
3034 if (imask || fmask || alpha_ra_ever_killed ())
3035 imask |= (1L << REG_RA);
3048 #ifdef ASM_OUTPUT_MI_THUNK
3049 if (current_function_is_thunk)
3054 /* One for every register we have to save. */
3055 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3056 if (! fixed_regs[i] && ! call_used_regs[i]
3057 && regs_ever_live[i] && i != REG_RA)
3061 if (TARGET_OPEN_VMS)
3063 /* Start by assuming we can use a register procedure if we don't
3064 make any calls (REG_RA not used) or need to save any
3065 registers and a stack procedure if we do. */
3066 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3068 /* Decide whether to refer to objects off our PV via FP or PV.
3069 If we need FP for something else or if we receive a nonlocal
3070 goto (which expects PV to contain the value), we must use PV.
3071 Otherwise, start by assuming we can use FP. */
3072 vms_base_regno = (frame_pointer_needed
3073 || current_function_has_nonlocal_label
3074 || vms_is_stack_procedure
3075 || current_function_outgoing_args_size
3076 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3078 /* If we want to copy PV into FP, we need to find some register
3079 in which to save FP. */
3081 vms_save_fp_regno = -1;
3082 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3083 for (i = 0; i < 32; i++)
3084 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3085 vms_save_fp_regno = i;
3087 if (vms_save_fp_regno == -1)
3088 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3090 /* Stack unwinding should be done via FP unless we use it for PV. */
3091 vms_unwind_regno = (vms_base_regno == REG_PV
3092 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3094 /* If this is a stack procedure, allow space for saving FP and RA. */
3095 if (vms_is_stack_procedure)
3100 /* If some registers were saved but not RA, RA must also be saved,
3101 so leave space for it. */
3102 if (sa_size != 0 || alpha_ra_ever_killed ())
3105 /* Our size must be even (multiple of 16 bytes). */
3114 alpha_pv_save_size ()
3117 return vms_is_stack_procedure ? 8 : 0;
3124 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3128 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3129 tree decl ATTRIBUTE_UNUSED;
3130 tree attributes ATTRIBUTE_UNUSED;
3134 if (is_attribute_p ("overlaid", identifier))
3135 return (args == NULL_TREE);
3140 alpha_does_function_need_gp ()
3144 /* We never need a GP for Windows/NT or VMS. */
3145 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3148 #ifdef TARGET_PROFILING_NEEDS_GP
3153 #ifdef ASM_OUTPUT_MI_THUNK
3154 if (current_function_is_thunk)
3158 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3159 Even if we are a static function, we still need to do this in case
3160 our address is taken and passed to something like qsort. */
3162 push_topmost_sequence ();
3163 insn = get_insns ();
3164 pop_topmost_sequence ();
3166 for (; insn; insn = NEXT_INSN (insn))
3167 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3168 && GET_CODE (PATTERN (insn)) != USE
3169 && GET_CODE (PATTERN (insn)) != CLOBBER)
3171 enum attr_type type = get_attr_type (insn);
3172 if (type == TYPE_LDSYM || type == TYPE_JSR)
3179 /* Write a version stamp. Don't write anything if we are running as a
3180 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3187 alpha_write_verstamp (file)
3191 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3195 /* Write function prologue. */
3197 /* On vms we have two kinds of functions:
3199 - stack frame (PROC_STACK)
3200 these are 'normal' functions with local vars and which are
3201 calling other functions
3202 - register frame (PROC_REGISTER)
3203 keeps all data in registers, needs no stack
3205 We must pass this to the assembler so it can generate the
3206 proper pdsc (procedure descriptor)
3207 This is done with the '.pdesc' command.
3209 On not-vms, we don't really differentiate between the two, as we can
3210 simply allocate stack without saving registers. */
3213 alpha_expand_prologue ()
3215 /* Registers to save. */
3216 unsigned long imask = 0;
3217 unsigned long fmask = 0;
3218 /* Stack space needed for pushing registers clobbered by us. */
3219 HOST_WIDE_INT sa_size;
3220 /* Complete stack size needed. */
3221 HOST_WIDE_INT frame_size;
3222 /* Offset from base reg to register save area. */
3223 HOST_WIDE_INT reg_offset;
3227 sa_size = alpha_sa_size ();
3229 frame_size = get_frame_size ();
3230 if (TARGET_OPEN_VMS)
3231 frame_size = ALPHA_ROUND (sa_size
3232 + (vms_is_stack_procedure ? 8 : 0)
3234 + current_function_pretend_args_size);
3236 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3238 + ALPHA_ROUND (frame_size
3239 + current_function_pretend_args_size));
3241 if (TARGET_OPEN_VMS)
3244 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3246 alpha_sa_mask (&imask, &fmask);
3248 /* Adjust the stack by the frame size. If the frame size is > 4096
3249 bytes, we need to be sure we probe somewhere in the first and last
3250 4096 bytes (we can probably get away without the latter test) and
3251 every 8192 bytes in between. If the frame size is > 32768, we
3252 do this in a loop. Otherwise, we generate the explicit probe
3255 Note that we are only allowed to adjust sp once in the prologue. */
3257 if (frame_size <= 32768)
3259 if (frame_size > 4096)
3264 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3265 while ((probed += 8192) < frame_size);
3267 /* We only have to do this probe if we aren't saving registers. */
3268 if (sa_size == 0 && probed + 4096 < frame_size)
3269 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3272 if (frame_size != 0)
3274 emit_move_insn (stack_pointer_rtx,
3275 plus_constant (stack_pointer_rtx, -frame_size));
3280 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3281 number of 8192 byte blocks to probe. We then probe each block
3282 in the loop and then set SP to the proper location. If the
3283 amount remaining is > 4096, we have to do one more probe if we
3284 are not saving any registers. */
3286 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3287 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3288 rtx ptr = gen_rtx_REG (DImode, 22);
3289 rtx count = gen_rtx_REG (DImode, 23);
3291 emit_move_insn (count, GEN_INT (blocks));
3292 emit_move_insn (ptr, plus_constant (stack_pointer_rtx, 4096));
3294 /* Because of the difficulty in emitting a new basic block this
3295 late in the compilation, generate the loop as a single insn. */
3296 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3298 if (leftover > 4096 && sa_size == 0)
3300 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3301 MEM_VOLATILE_P (last) = 1;
3302 emit_move_insn (last, const0_rtx);
3305 emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
3308 /* Cope with very large offsets to the register save area. */
3309 sa_reg = stack_pointer_rtx;
3310 if (reg_offset + sa_size > 0x8000)
3312 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3315 if (low + sa_size <= 0x8000)
3316 bias = reg_offset - low, reg_offset = low;
3318 bias = reg_offset, reg_offset = 0;
3320 sa_reg = gen_rtx_REG (DImode, 24);
3321 emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias));
3324 /* Save regs in stack order. Beginning with VMS PV. */
3325 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3327 emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx),
3328 gen_rtx_REG (DImode, REG_PV));
3331 /* Save register RA next. */
3332 if (imask & (1L << REG_RA))
3334 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)),
3335 gen_rtx_REG (DImode, REG_RA));
3336 imask &= ~(1L << REG_RA);
3340 /* Now save any other registers required to be saved. */
3341 for (i = 0; i < 32; i++)
3342 if (imask & (1L << i))
3344 emit_move_insn (gen_rtx_MEM (DImode,
3345 plus_constant (sa_reg, reg_offset)),
3346 gen_rtx_REG (DImode, i));
3350 for (i = 0; i < 32; i++)
3351 if (fmask & (1L << i))
3353 emit_move_insn (gen_rtx_MEM (DFmode,
3354 plus_constant (sa_reg, reg_offset)),
3355 gen_rtx_REG (DFmode, i+32));
3359 if (TARGET_OPEN_VMS)
3361 if (!vms_is_stack_procedure)
3363 /* Register frame procedures fave the fp. */
3364 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3365 hard_frame_pointer_rtx);
3368 if (vms_base_regno != REG_PV)
3369 emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3370 gen_rtx_REG (DImode, REG_PV));
3372 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3374 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
3377 /* If we have to allocate space for outgoing args, do it now. */
3378 if (current_function_outgoing_args_size != 0)
3380 emit_move_insn (stack_pointer_rtx,
3381 plus_constant (hard_frame_pointer_rtx,
3382 - ALPHA_ROUND (current_function_outgoing_args_size)));
3387 /* If we need a frame pointer, set it from the stack pointer. */
3388 if (frame_pointer_needed)
3390 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3391 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
3394 /* This must always be the last instruction in the
3395 prologue, thus we emit a special move + clobber. */
3396 emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3397 stack_pointer_rtx, sa_reg));
3402 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3403 the prologue, for exception handling reasons, we cannot do this for
3404 any insn that might fault. We could prevent this for mems with a
3405 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3406 have to prevent all such scheduling with a blockage.
3408 Linux, on the other hand, never bothered to implement OSF/1's
3409 exception handling, and so doesn't care about such things. Anyone
3410 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3412 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3413 emit_insn (gen_blockage ());
3416 /* Output the textual info surrounding the prologue. */
3419 alpha_start_function (file, fnname, decl)
3422 tree decl ATTRIBUTE_UNUSED;
3424 unsigned long imask = 0;
3425 unsigned long fmask = 0;
3426 /* Stack space needed for pushing registers clobbered by us. */
3427 HOST_WIDE_INT sa_size;
3428 /* Complete stack size needed. */
3429 HOST_WIDE_INT frame_size;
3430 /* Offset from base reg to register save area. */
3431 HOST_WIDE_INT reg_offset;
3432 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3435 sa_size = alpha_sa_size ();
3437 frame_size = get_frame_size ();
3438 if (TARGET_OPEN_VMS)
3439 frame_size = ALPHA_ROUND (sa_size
3440 + (vms_is_stack_procedure ? 8 : 0)
3442 + current_function_pretend_args_size);
3444 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3446 + ALPHA_ROUND (frame_size
3447 + current_function_pretend_args_size));
3449 if (TARGET_OPEN_VMS)
3452 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3454 alpha_sa_mask (&imask, &fmask);
3456 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3457 We have to do that before the .ent directive as we cannot switch
3458 files within procedures with native ecoff because line numbers are
3459 linked to procedure descriptors.
3460 Outputting the lineno helps debugging of one line functions as they
3461 would otherwise get no line number at all. Please note that we would
3462 like to put out last_linenum from final.c, but it is not accessible. */
3464 if (write_symbols == SDB_DEBUG)
3466 ASM_OUTPUT_SOURCE_FILENAME (file,
3467 DECL_SOURCE_FILE (current_function_decl));
3468 if (debug_info_level != DINFO_LEVEL_TERSE)
3469 ASM_OUTPUT_SOURCE_LINE (file,
3470 DECL_SOURCE_LINE (current_function_decl));
3473 /* Issue function start and label. */
3474 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3476 fputs ("\t.ent ", file);
3477 assemble_name (file, fnname);
3481 strcpy (entry_label, fnname);
3482 if (TARGET_OPEN_VMS)
3483 strcat (entry_label, "..en");
3484 ASM_OUTPUT_LABEL (file, entry_label);
3485 inside_function = TRUE;
3487 if (TARGET_OPEN_VMS)
3488 fprintf (file, "\t.base $%d\n", vms_base_regno);
3490 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3491 && !flag_inhibit_size_directive)
3493 /* Set flags in procedure descriptor to request IEEE-conformant
3494 math-library routines. The value we set it to is PDSC_EXC_IEEE
3495 (/usr/include/pdsc.h). */
3496 fputs ("\t.eflag 48\n", file);
3499 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3500 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3501 alpha_arg_offset = -frame_size + 48;
3503 /* Describe our frame. If the frame size is larger than an integer,
3504 print it as zero to avoid an assembler error. We won't be
3505 properly describing such a frame, but that's the best we can do. */
3506 if (TARGET_OPEN_VMS)
3508 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3509 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3510 frame_size >= (1l << 31) ? 0 : frame_size);
3511 fputs (",$26,", file);
3512 fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3515 else if (!flag_inhibit_size_directive)
3517 fprintf (file, "\t.frame $%d,",
3518 (frame_pointer_needed
3519 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3520 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3521 frame_size >= (1l << 31) ? 0 : frame_size);
3522 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3525 /* Describe which registers were spilled. */
3526 if (TARGET_OPEN_VMS)
3529 /* ??? Does VMS care if mask contains ra? The old code did'nt
3530 set it, so I don't here. */
3531 fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3533 fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3534 if (!vms_is_stack_procedure)
3535 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3537 else if (!flag_inhibit_size_directive)
3541 fprintf (file, "\t.mask 0x%lx,", imask);
3542 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3543 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3546 for (i = 0; i < 32; ++i)
3547 if (imask & (1L << i))
3553 fprintf (file, "\t.fmask 0x%lx,", fmask);
3554 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3555 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3560 /* Emit GP related things. It is rather unfortunate about the alignment
3561 issues surrounding a CODE_LABEL that forces us to do the label in
3563 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3565 alpha_function_needs_gp = alpha_does_function_need_gp ();
3566 if (alpha_function_needs_gp)
3567 fputs ("\tldgp $29,0($27)\n", file);
3570 assemble_name (file, fnname);
3571 fputs ("..ng:\n", file);
3575 /* Ifdef'ed cause readonly_section and link_section are only
3577 readonly_section ();
3578 fprintf (file, "\t.align 3\n");
3579 assemble_name (file, fnname); fputs ("..na:\n", file);
3580 fputs ("\t.ascii \"", file);
3581 assemble_name (file, fnname);
3582 fputs ("\\0\"\n", file);
3585 fprintf (file, "\t.align 3\n");
3586 fputs ("\t.name ", file);
3587 assemble_name (file, fnname);
3588 fputs ("..na\n", file);
3589 ASM_OUTPUT_LABEL (file, fnname);
3590 fprintf (file, "\t.pdesc ");
3591 assemble_name (file, fnname);
3592 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3593 alpha_need_linkage (fnname, 1);
3598 /* Emit the .prologue note at the scheduled end of the prologue. */
3601 output_end_prologue (file)
3604 if (TARGET_OPEN_VMS)
3605 fputs ("\t.prologue\n", file);
3606 else if (TARGET_WINDOWS_NT)
3607 fputs ("\t.prologue 0\n", file);
3608 else if (!flag_inhibit_size_directive)
3609 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3612 /* Write function epilogue. */
3615 alpha_expand_epilogue ()
3617 /* Registers to save. */
3618 unsigned long imask = 0;
3619 unsigned long fmask = 0;
3620 /* Stack space needed for pushing registers clobbered by us. */
3621 HOST_WIDE_INT sa_size;
3622 /* Complete stack size needed. */
3623 HOST_WIDE_INT frame_size;
3624 /* Offset from base reg to register save area. */
3625 HOST_WIDE_INT reg_offset;
3626 int fp_is_frame_pointer, fp_offset;
3627 rtx sa_reg, sa_reg_exp = NULL;
3628 rtx sp_adj1, sp_adj2;
3631 sa_size = alpha_sa_size ();
3633 frame_size = get_frame_size ();
3634 if (TARGET_OPEN_VMS)
3635 frame_size = ALPHA_ROUND (sa_size
3636 + (vms_is_stack_procedure ? 8 : 0)
3638 + current_function_pretend_args_size);
3640 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3642 + ALPHA_ROUND (frame_size
3643 + current_function_pretend_args_size));
3645 if (TARGET_OPEN_VMS)
3648 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3650 alpha_sa_mask (&imask, &fmask);
3652 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3653 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3657 /* If we have a frame pointer, restore SP from it. */
3658 if ((TARGET_OPEN_VMS
3659 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3660 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3662 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
3665 /* Cope with very large offsets to the register save area. */
3666 sa_reg = stack_pointer_rtx;
3667 if (reg_offset + sa_size > 0x8000)
3669 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3672 if (low + sa_size <= 0x8000)
3673 bias = reg_offset - low, reg_offset = low;
3675 bias = reg_offset, reg_offset = 0;
3677 sa_reg = gen_rtx_REG (DImode, 22);
3678 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3680 emit_move_insn (sa_reg, sa_reg_exp);
3683 /* Restore registers in order, excepting a true frame pointer. */
3685 emit_move_insn (gen_rtx_REG (DImode, REG_RA),
3686 gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)));
3688 imask &= ~(1L << REG_RA);
3690 for (i = 0; i < 32; ++i)
3691 if (imask & (1L << i))
3693 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3694 fp_offset = reg_offset;
3697 emit_move_insn (gen_rtx_REG (DImode, i),
3698 gen_rtx_MEM (DImode,
3699 plus_constant(sa_reg,
3705 for (i = 0; i < 32; ++i)
3706 if (fmask & (1L << i))
3708 emit_move_insn (gen_rtx_REG (DFmode, i+32),
3709 gen_rtx_MEM (DFmode,
3710 plus_constant(sa_reg, reg_offset)));
3717 /* If the stack size is large, begin computation into a temporary
3718 register so as not to interfere with a potential fp restore,
3719 which must be consecutive with an SP restore. */
3720 if (frame_size < 32768)
3722 sp_adj1 = stack_pointer_rtx;
3723 sp_adj2 = GEN_INT (frame_size);
3725 else if (frame_size < 0x40007fffL)
3727 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3729 sp_adj2 = plus_constant (stack_pointer_rtx, frame_size - low);
3730 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3734 sp_adj1 = gen_rtx_REG (DImode, 23);
3735 emit_move_insn (sp_adj1, sp_adj2);
3737 sp_adj2 = GEN_INT (low);
3741 sp_adj2 = gen_rtx_REG (DImode, 23);
3742 sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3);
3745 /* We can't drop new things to memory this late, afaik,
3746 so build it up by pieces. */
3747 #if HOST_BITS_PER_WIDE_INT == 64
3748 sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size);
3755 sp_adj2 = stack_pointer_rtx;
3758 /* From now on, things must be in order. So emit blockages. */
3760 /* Restore the frame pointer. */
3761 if (fp_is_frame_pointer)
3763 emit_insn (gen_blockage ());
3764 emit_move_insn (hard_frame_pointer_rtx,
3765 gen_rtx_MEM (DImode,
3766 plus_constant(sa_reg, fp_offset)));
3768 else if (TARGET_OPEN_VMS)
3770 emit_insn (gen_blockage ());
3771 emit_move_insn (hard_frame_pointer_rtx,
3772 gen_rtx_REG (DImode, vms_save_fp_regno));
3775 /* Restore the stack pointer. */
3776 emit_insn (gen_blockage ());
3777 emit_move_insn (stack_pointer_rtx,
3778 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
3782 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
3784 emit_insn (gen_blockage ());
3785 emit_move_insn (hard_frame_pointer_rtx,
3786 gen_rtx_REG (DImode, vms_save_fp_regno));
3791 emit_jump_insn (gen_return_internal ());
3794 /* Output the rest of the textual info surrounding the epilogue. */
3797 alpha_end_function (file, fnname, decl)
3800 tree decl ATTRIBUTE_UNUSED;
3802 /* End the function. */
3803 if (!flag_inhibit_size_directive)
3805 fputs ("\t.end ", file);
3806 assemble_name (file, fnname);
3809 inside_function = FALSE;
3811 /* Show that we know this function if it is called again.
3813 Don't do this for global functions in object files destined for a
3814 shared library because the function may be overridden by the application
3816 ??? Is this just ELF? */
3818 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3819 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3822 /* Debugging support. */
3826 /* Count the number of sdb related labels are generated (to find block
3827 start and end boundaries). */
3829 int sdb_label_count = 0;
3831 /* Next label # for each statement. */
3833 static int sym_lineno = 0;
3835 /* Count the number of .file directives, so that .loc is up to date. */
3837 static int num_source_filenames = 0;
3839 /* Name of the file containing the current function. */
3841 static char *current_function_file = "";
3843 /* Offsets to alpha virtual arg/local debugging pointers. */
3845 long alpha_arg_offset;
3846 long alpha_auto_offset;
3848 /* Emit a new filename to a stream. */
3851 alpha_output_filename (stream, name)
3855 static int first_time = TRUE;
3856 char ltext_label_name[100];
3861 ++num_source_filenames;
3862 current_function_file = name;
3863 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3864 output_quoted_string (stream, name);
3865 fprintf (stream, "\n");
3866 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3867 fprintf (stream, "\t#@stabs\n");
3870 else if (write_symbols == DBX_DEBUG)
3872 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3873 fprintf (stream, "%s ", ASM_STABS_OP);
3874 output_quoted_string (stream, name);
3875 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3878 else if (name != current_function_file
3879 && strcmp (name, current_function_file) != 0)
3881 if (inside_function && ! TARGET_GAS)
3882 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3885 ++num_source_filenames;
3886 current_function_file = name;
3887 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3890 output_quoted_string (stream, name);
3891 fprintf (stream, "\n");
3895 /* Emit a linenumber to a stream. */
3898 alpha_output_lineno (stream, line)
3902 if (write_symbols == DBX_DEBUG)
3904 /* mips-tfile doesn't understand .stabd directives. */
3906 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3907 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3910 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3913 /* Structure to show the current status of registers and memory. */
3915 struct shadow_summary
3918 unsigned long i : 31; /* Mask of int regs */
3919 unsigned long fp : 31; /* Mask of fp regs */
3920 unsigned long mem : 1; /* mem == imem | fpmem */
3924 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
3925 static void alpha_handle_trap_shadows PROTO((rtx));
3927 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3928 to the summary structure. SET is nonzero if the insn is setting the
3929 object, otherwise zero. */
3932 summarize_insn (x, sum, set)
3934 struct shadow_summary *sum;
3943 switch (GET_CODE (x))
3945 /* ??? Note that this case would be incorrect if the Alpha had a
3946 ZERO_EXTRACT in SET_DEST. */
3948 summarize_insn (SET_SRC (x), sum, 0);
3949 summarize_insn (SET_DEST (x), sum, 1);
3953 summarize_insn (XEXP (x, 0), sum, 1);
3957 summarize_insn (XEXP (x, 0), sum, 0);
3961 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3962 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3966 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3967 summarize_insn (XVECEXP (x, 0, i), sum, 0);
3971 summarize_insn (SUBREG_REG (x), sum, 0);
3976 int regno = REGNO (x);
3977 unsigned long mask = 1UL << (regno % 32);
3979 if (regno == 31 || regno == 63)
3985 sum->defd.i |= mask;
3987 sum->defd.fp |= mask;
3992 sum->used.i |= mask;
3994 sum->used.fp |= mask;
4005 /* Find the regs used in memory address computation: */
4006 summarize_insn (XEXP (x, 0), sum, 0);
4009 case CONST_INT: case CONST_DOUBLE:
4010 case SYMBOL_REF: case LABEL_REF: case CONST:
4013 /* Handle common unary and binary ops for efficiency. */
4014 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
4015 case MOD: case UDIV: case UMOD: case AND: case IOR:
4016 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
4017 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
4018 case NE: case EQ: case GE: case GT: case LE:
4019 case LT: case GEU: case GTU: case LEU: case LTU:
4020 summarize_insn (XEXP (x, 0), sum, 0);
4021 summarize_insn (XEXP (x, 1), sum, 0);
4024 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
4025 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
4026 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
4027 case SQRT: case FFS:
4028 summarize_insn (XEXP (x, 0), sum, 0);
4032 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4033 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4034 switch (format_ptr[i])
4037 summarize_insn (XEXP (x, i), sum, 0);
4041 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4042 summarize_insn (XVECEXP (x, i, j), sum, 0);
4054 /* Ensure a sufficient number of `trapb' insns are in the code when
4055 the user requests code with a trap precision of functions or
4058 In naive mode, when the user requests a trap-precision of
4059 "instruction", a trapb is needed after every instruction that may
4060 generate a trap. This ensures that the code is resumption safe but
4063 When optimizations are turned on, we delay issuing a trapb as long
4064 as possible. In this context, a trap shadow is the sequence of
4065 instructions that starts with a (potentially) trap generating
4066 instruction and extends to the next trapb or call_pal instruction
4067 (but GCC never generates call_pal by itself). We can delay (and
4068 therefore sometimes omit) a trapb subject to the following
4071 (a) On entry to the trap shadow, if any Alpha register or memory
4072 location contains a value that is used as an operand value by some
4073 instruction in the trap shadow (live on entry), then no instruction
4074 in the trap shadow may modify the register or memory location.
4076 (b) Within the trap shadow, the computation of the base register
4077 for a memory load or store instruction may not involve using the
4078 result of an instruction that might generate an UNPREDICTABLE
4081 (c) Within the trap shadow, no register may be used more than once
4082 as a destination register. (This is to make life easier for the
4085 (d) The trap shadow may not include any branch instructions. */
4088 alpha_handle_trap_shadows (insns)
4091 struct shadow_summary shadow;
4092 int trap_pending, exception_nesting;
4096 exception_nesting = 0;
4099 shadow.used.mem = 0;
4100 shadow.defd = shadow.used;
4102 for (i = insns; i ; i = NEXT_INSN (i))
4104 if (GET_CODE (i) == NOTE)
4106 switch (NOTE_LINE_NUMBER (i))
4108 case NOTE_INSN_EH_REGION_BEG:
4109 exception_nesting++;
4114 case NOTE_INSN_EH_REGION_END:
4115 exception_nesting--;
4120 case NOTE_INSN_EPILOGUE_BEG:
4121 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4126 else if (trap_pending)
4128 if (alpha_tp == ALPHA_TP_FUNC)
4130 if (GET_CODE (i) == JUMP_INSN
4131 && GET_CODE (PATTERN (i)) == RETURN)
4134 else if (alpha_tp == ALPHA_TP_INSN)
4138 struct shadow_summary sum;
4143 sum.defd = sum.used;
4145 switch (GET_CODE (i))
4148 /* Annoyingly, get_attr_trap will abort on these. */
4149 if (GET_CODE (PATTERN (i)) == USE
4150 || GET_CODE (PATTERN (i)) == CLOBBER)
4153 summarize_insn (PATTERN (i), &sum, 0);
4155 if ((sum.defd.i & shadow.defd.i)
4156 || (sum.defd.fp & shadow.defd.fp))
4158 /* (c) would be violated */
4162 /* Combine shadow with summary of current insn: */
4163 shadow.used.i |= sum.used.i;
4164 shadow.used.fp |= sum.used.fp;
4165 shadow.used.mem |= sum.used.mem;
4166 shadow.defd.i |= sum.defd.i;
4167 shadow.defd.fp |= sum.defd.fp;
4168 shadow.defd.mem |= sum.defd.mem;
4170 if ((sum.defd.i & shadow.used.i)
4171 || (sum.defd.fp & shadow.used.fp)
4172 || (sum.defd.mem & shadow.used.mem))
4174 /* (a) would be violated (also takes care of (b)) */
4175 if (get_attr_trap (i) == TRAP_YES
4176 && ((sum.defd.i & sum.used.i)
4177 || (sum.defd.fp & sum.used.fp)))
4196 n = emit_insn_before (gen_trapb (), i);
4197 PUT_MODE (n, TImode);
4198 PUT_MODE (i, TImode);
4202 shadow.used.mem = 0;
4203 shadow.defd = shadow.used;
4208 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4209 && GET_CODE (i) == INSN
4210 && GET_CODE (PATTERN (i)) != USE
4211 && GET_CODE (PATTERN (i)) != CLOBBER
4212 && get_attr_trap (i) == TRAP_YES)
4214 if (optimize && !trap_pending)
4215 summarize_insn (PATTERN (i), &shadow, 0);
4222 /* Alpha can only issue instruction groups simultaneously if they are
4223 suitibly aligned. This is very processor-specific. */
4225 enum alphaev5_pipe {
4236 static enum alphaev5_pipe
4237 alphaev5_insn_pipe (insn)
4240 if (recog_memoized (insn) < 0)
4242 if (get_attr_length (insn) != 4)
4245 switch (get_attr_type (insn))
4283 /* IN_USE is a mask of the slots currently filled within the
4284 insn group. The mask bits come from alphaev5_pipe above.
4285 If EV5_E01 is set, then the insn in EV5_E0 can be swapp
4286 by the hardware into EV5_E1.
4288 LEN is, of course, the length of the group in bytes. */
4291 alphaev5_next_group (insn, pin_use, plen)
4293 int *pin_use, *plen;
4299 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4304 enum alphaev5_pipe pipe;
4307 pipe = alphaev5_insn_pipe (insn);
4311 /* Force complex instructions to start new groups. */
4315 /* If this is a completely unrecognized insn, its an asm.
4316 We don't know how long it is, so record length as -1 to
4317 signal a needed realignment. */
4318 if (recog_memoized (insn) < 0)
4321 len = get_attr_length (insn);
4324 /* ??? Most of the places below, we would like to abort, as
4325 it would indicate an error either in Haifa, or in the
4326 scheduling description. Unfortunately, Haifa never
4327 schedules the last instruction of the BB, so we don't
4328 have an accurate TI bit to go off. */
4330 if (in_use & EV5_E0)
4332 if (in_use & EV5_E1)
4337 in_use |= EV5_E0 | EV5_E01;
4341 if (in_use & EV5_E0)
4343 if (!(in_use & EV5_E01) || in_use & EV5_E1)
4351 if (in_use & EV5_E1)
4357 if (in_use & EV5_FA)
4359 if (in_use & EV5_FM)
4364 in_use |= EV5_FA | EV5_FAM;
4368 if (in_use & EV5_FA)
4374 if (in_use & EV5_FM)
4387 /* Haifa doesn't do well scheduling branches. */
4388 /* ??? If this is predicted not-taken, slotting continues, except
4389 that no more IBR, FBR, or JSR insns may be slotted. */
4390 if (GET_CODE (insn) == JUMP_INSN)
4393 insn = next_nonnote_insn (insn);
4395 if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4398 /* Let Haifa tell us where it thinks insn group boundaries are. */
4399 if (GET_MODE (insn) == TImode)
4411 insn = next_nonnote_insn (insn);
4416 alphaev5_align_insns (insns)
4419 /* ALIGN is the known alignment for the insn group. */
4421 /* OFS is the offset of the current insn in the insn group. */
4423 int prev_in_use, in_use, len;
4426 /* Let shorten branches care for assigning alignments to code labels. */
4427 shorten_branches (insns);
4429 ofs = prev_in_use = 0;
4430 if (alpha_does_function_need_gp())
4433 prev_in_use = EV5_E01 | EV5_E0;
4435 align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < 16
4436 ? FUNCTION_BOUNDARY/BITS_PER_UNIT : 16);
4439 if (GET_CODE (i) == NOTE)
4440 i = next_nonnote_insn (i);
4444 next = alphaev5_next_group (i, &in_use, &len);
4446 /* When we see a label, resync alignment etc. */
4447 if (GET_CODE (i) == CODE_LABEL)
4449 int new_align = 1 << label_to_alignment (i);
4450 if (new_align >= align)
4452 align = new_align < 16 ? new_align : 16;
4455 else if (ofs & (new_align-1))
4456 ofs = (ofs | (new_align-1)) + 1;
4461 /* Handle complex instructions special. */
4462 else if (in_use == 0)
4464 /* Asms will have length < 0. This is a signal that we have
4465 lost alignment knowledge. Assume, however, that the asm
4466 will not mis-align instructions. */
4475 /* If the known alignment is smaller than the recognized insn group,
4476 realign the output. */
4477 else if (align < len)
4479 int new_log_align = len > 8 ? 4 : 3;
4482 where = prev_nonnote_insn (i);
4483 if (!where || GET_CODE (where) != CODE_LABEL)
4486 emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4487 align = 1 << new_log_align;
4491 /* If the group won't fit in the same INT16 as the previous,
4492 we need to add padding to keep the group together. Rather
4493 than simply leaving the insn filling to the assembler, we
4494 can make use of the knowledge of what sorts of instructions
4495 were issued in the previous group to make sure that all of
4496 the added nops are really free. */
4497 else if (ofs + len > align)
4499 int nop_count = (align - ofs) / 4;
4502 where = prev_nonnote_insn (i);
4503 if (!where || GET_CODE (where) != CODE_LABEL)
4508 if (!(prev_in_use & EV5_E1))
4510 prev_in_use |= EV5_E1;
4511 emit_insn_before (gen_nop(), where);
4513 else if (TARGET_FP && !(prev_in_use & EV5_FA))
4515 prev_in_use |= EV5_FA;
4516 emit_insn_before (gen_fnop(), where);
4518 else if (TARGET_FP && !(prev_in_use & EV5_FM))
4520 prev_in_use |= EV5_FM;
4521 emit_insn_before (gen_fnop(), where);
4524 emit_insn_before (gen_unop(), where);
4526 while (--nop_count);
4530 ofs = (ofs + len) & (align - 1);
4531 prev_in_use = in_use;
4537 /* Machine dependant reorg pass. */
4543 if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4544 alpha_handle_trap_shadows (insns);
4547 /* Due to the number of extra trapb insns, don't bother fixing up
4548 alignment when trap precision is instruction. Moreover, we can
4549 only do our job when sched2 is run and Haifa is our scheduler. */
4550 if (optimize && !optimize_size
4551 && alpha_tp != ALPHA_TP_INSN
4552 && flag_schedule_insns_after_reload)
4554 if (alpha_cpu == PROCESSOR_EV5)
4555 alphaev5_align_insns (insns);
4561 /* Check a floating-point value for validity for a particular machine mode. */
4563 static char * const float_strings[] =
4565 /* These are for FLOAT_VAX. */
4566 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4567 "-1.70141173319264430e+38",
4568 "2.93873587705571877e-39", /* 2^-128 */
4569 "-2.93873587705571877e-39",
4570 /* These are for the default broken IEEE mode, which traps
4571 on infinity or denormal numbers. */
4572 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4573 "-3.402823466385288598117e+38",
4574 "1.1754943508222875079687e-38", /* 2^-126 */
4575 "-1.1754943508222875079687e-38",
4578 static REAL_VALUE_TYPE float_values[8];
4579 static int inited_float_values = 0;
4582 check_float_value (mode, d, overflow)
4583 enum machine_mode mode;
4585 int overflow ATTRIBUTE_UNUSED;
4588 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4591 if (inited_float_values == 0)
4594 for (i = 0; i < 8; i++)
4595 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4597 inited_float_values = 1;
4603 REAL_VALUE_TYPE *fvptr;
4605 if (TARGET_FLOAT_VAX)
4606 fvptr = &float_values[0];
4608 fvptr = &float_values[4];
4610 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4611 if (REAL_VALUES_LESS (fvptr[0], r))
4613 bcopy ((char *) &fvptr[0], (char *) d,
4614 sizeof (REAL_VALUE_TYPE));
4617 else if (REAL_VALUES_LESS (r, fvptr[1]))
4619 bcopy ((char *) &fvptr[1], (char *) d,
4620 sizeof (REAL_VALUE_TYPE));
4623 else if (REAL_VALUES_LESS (dconst0, r)
4624 && REAL_VALUES_LESS (r, fvptr[2]))
4626 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4629 else if (REAL_VALUES_LESS (r, dconst0)
4630 && REAL_VALUES_LESS (fvptr[3], r))
4632 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4642 /* Return the VMS argument type corresponding to MODE. */
4645 alpha_arg_type (mode)
4646 enum machine_mode mode;
4651 return TARGET_FLOAT_VAX ? FF : FS;
4653 return TARGET_FLOAT_VAX ? FD : FT;
4659 /* Return an rtx for an integer representing the VMS Argument Information
4663 alpha_arg_info_reg_val (cum)
4664 CUMULATIVE_ARGS cum;
4666 unsigned HOST_WIDE_INT regval = cum.num_args;
4669 for (i = 0; i < 6; i++)
4670 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4672 return GEN_INT (regval);
4675 /* Structure to collect function names for final output
4678 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4681 struct alpha_links {
4682 struct alpha_links *next;
4684 enum links_kind kind;
4687 static struct alpha_links *alpha_links_base = 0;
4689 /* Make (or fake) .linkage entry for function call.
4691 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
4694 alpha_need_linkage (name, is_local)
4699 struct alpha_links *lptr, *nptr;
4704 /* Is this name already defined ? */
4706 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4707 if (strcmp (lptr->name, name) == 0)
4711 /* Defined here but external assumed. */
4712 if (lptr->kind == KIND_EXTERN)
4713 lptr->kind = KIND_LOCAL;
4717 /* Used here but unused assumed. */
4718 if (lptr->kind == KIND_UNUSED)
4719 lptr->kind = KIND_LOCAL;
4724 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4725 nptr->next = alpha_links_base;
4726 nptr->name = xstrdup (name);
4728 /* Assume external if no definition. */
4729 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4731 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
4732 get_identifier (name);
4734 alpha_links_base = nptr;
4741 alpha_write_linkage (stream)
4744 struct alpha_links *lptr, *nptr;
4746 readonly_section ();
4748 fprintf (stream, "\t.align 3\n");
4750 for (lptr = alpha_links_base; lptr; lptr = nptr)
4754 if (lptr->kind == KIND_UNUSED
4755 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4758 fprintf (stream, "$%s..lk:\n", lptr->name);
4759 if (lptr->kind == KIND_LOCAL)
4761 /* Local and used, build linkage pair. */
4762 fprintf (stream, "\t.quad %s..en\n", lptr->name);
4763 fprintf (stream, "\t.quad %s\n", lptr->name);
4766 /* External and used, request linkage pair. */
4767 fprintf (stream, "\t.linkage %s\n", lptr->name);
4774 alpha_need_linkage (name, is_local)
4775 char *name ATTRIBUTE_UNUSED;
4776 int is_local ATTRIBUTE_UNUSED;
4780 #endif /* OPEN_VMS */