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. */
28 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
34 #include "insn-attr.h"
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 || register_operand (op, mode));
344 /* Return 1 if OP is an 8-bit constant or any register. */
347 reg_or_8bit_operand (op, mode)
349 enum machine_mode mode;
351 return ((GET_CODE (op) == CONST_INT
352 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
353 || register_operand (op, mode));
356 /* Return 1 if OP is an 8-bit constant. */
359 cint8_operand (op, mode)
361 enum machine_mode mode;
363 return (GET_CODE (op) == CONST_INT
364 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
367 /* Return 1 if the operand is a valid second operand to an add insn. */
370 add_operand (op, mode)
372 enum machine_mode mode;
374 if (GET_CODE (op) == CONST_INT)
375 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
376 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
377 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
379 return register_operand (op, mode);
382 /* Return 1 if the operand is a valid second operand to a sign-extending
386 sext_add_operand (op, mode)
388 enum machine_mode mode;
390 if (GET_CODE (op) == CONST_INT)
391 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
392 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
394 return register_operand (op, mode);
397 /* Return 1 if OP is the constant 4 or 8. */
400 const48_operand (op, mode)
402 enum machine_mode mode;
404 return (GET_CODE (op) == CONST_INT
405 && (INTVAL (op) == 4 || INTVAL (op) == 8));
408 /* Return 1 if OP is a valid first operand to an AND insn. */
411 and_operand (op, mode)
413 enum machine_mode mode;
415 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
416 return (zap_mask (CONST_DOUBLE_LOW (op))
417 && zap_mask (CONST_DOUBLE_HIGH (op)));
419 if (GET_CODE (op) == CONST_INT)
420 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
421 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
422 || zap_mask (INTVAL (op)));
424 return register_operand (op, mode);
427 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
430 or_operand (op, mode)
432 enum machine_mode mode;
434 if (GET_CODE (op) == CONST_INT)
435 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
436 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
438 return register_operand (op, mode);
441 /* Return 1 if OP is a constant that is the width, in bits, of an integral
442 mode smaller than DImode. */
445 mode_width_operand (op, mode)
447 enum machine_mode mode;
449 return (GET_CODE (op) == CONST_INT
450 && (INTVAL (op) == 8 || INTVAL (op) == 16
451 || INTVAL (op) == 32 || INTVAL (op) == 64));
454 /* Return 1 if OP is a constant that is the width of an integral machine mode
455 smaller than an integer. */
458 mode_mask_operand (op, mode)
460 enum machine_mode mode;
462 #if HOST_BITS_PER_WIDE_INT == 32
463 if (GET_CODE (op) == CONST_DOUBLE)
464 return (CONST_DOUBLE_LOW (op) == -1
465 && (CONST_DOUBLE_HIGH (op) == -1
466 || CONST_DOUBLE_HIGH (op) == 0));
468 if (GET_CODE (op) == CONST_DOUBLE)
469 return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
472 return (GET_CODE (op) == CONST_INT
473 && (INTVAL (op) == 0xff
474 || INTVAL (op) == 0xffff
475 || INTVAL (op) == 0xffffffff
476 #if HOST_BITS_PER_WIDE_INT == 64
477 || INTVAL (op) == 0xffffffffffffffff
482 /* Return 1 if OP is a multiple of 8 less than 64. */
485 mul8_operand (op, mode)
487 enum machine_mode mode;
489 return (GET_CODE (op) == CONST_INT
490 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
491 && (INTVAL (op) & 7) == 0);
494 /* Return 1 if OP is the constant zero in floating-point. */
497 fp0_operand (op, mode)
499 enum machine_mode mode;
501 return (GET_MODE (op) == mode
502 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
505 /* Return 1 if OP is the floating-point constant zero or a register. */
508 reg_or_fp0_operand (op, mode)
510 enum machine_mode mode;
512 return fp0_operand (op, mode) || register_operand (op, mode);
515 /* Return 1 if OP is a hard floating-point register. */
518 hard_fp_register_operand (op, mode)
520 enum machine_mode mode;
522 return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
523 || (GET_CODE (op) == SUBREG
524 && hard_fp_register_operand (SUBREG_REG (op), mode)));
527 /* Return 1 if OP is a register or a constant integer. */
531 reg_or_cint_operand (op, mode)
533 enum machine_mode mode;
535 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
538 /* Return 1 if OP is something that can be reloaded into a register;
539 if it is a MEM, it need not be valid. */
542 some_operand (op, mode)
544 enum machine_mode mode;
546 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
549 switch (GET_CODE (op))
551 case REG: case MEM: case CONST_DOUBLE:
552 case CONST_INT: case LABEL_REF: case SYMBOL_REF: case CONST:
556 return some_operand (SUBREG_REG (op), VOIDmode);
565 /* Return 1 if OP is a valid operand for the source of a move insn. */
568 input_operand (op, mode)
570 enum machine_mode mode;
572 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
575 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
578 switch (GET_CODE (op))
583 /* This handles both the Windows/NT and OSF cases. */
584 return mode == ptr_mode || mode == DImode;
590 if (register_operand (op, mode))
592 /* ... fall through ... */
594 return ((TARGET_BWX || (mode != HImode && mode != QImode))
595 && general_operand (op, mode));
598 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
601 return mode == QImode || mode == HImode || add_operand (op, mode);
610 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
614 current_file_function_operand (op, mode)
616 enum machine_mode mode;
618 return (GET_CODE (op) == SYMBOL_REF
619 && ! profile_flag && ! profile_block_flag
620 && (SYMBOL_REF_FLAG (op)
621 || op == XEXP (DECL_RTL (current_function_decl), 0)));
624 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
627 call_operand (op, mode)
629 enum machine_mode mode;
634 return (GET_CODE (op) == SYMBOL_REF
635 || (GET_CODE (op) == REG
636 && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
639 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
640 comparisons are valid in which insn. */
643 alpha_comparison_operator (op, mode)
645 enum machine_mode mode;
647 enum rtx_code code = GET_CODE (op);
649 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
652 return (code == EQ || code == LE || code == LT
653 || (mode == DImode && (code == LEU || code == LTU)));
656 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
659 alpha_swapped_comparison_operator (op, mode)
661 enum machine_mode mode;
663 enum rtx_code code = GET_CODE (op);
665 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
668 code = swap_condition (code);
669 return (code == EQ || code == LE || code == LT
670 || (mode == DImode && (code == LEU || code == LTU)));
673 /* Return 1 if OP is a signed comparison operation. */
676 signed_comparison_operator (op, mode)
678 enum machine_mode mode;
680 switch (GET_CODE (op))
682 case EQ: case NE: case LE: case LT: case GE: case GT:
692 /* Return 1 if this is a divide or modulus operator. */
695 divmod_operator (op, mode)
697 enum machine_mode mode;
699 switch (GET_CODE (op))
701 case DIV: case MOD: case UDIV: case UMOD:
711 /* Return 1 if this memory address is a known aligned register plus
712 a constant. It must be a valid address. This means that we can do
713 this as an aligned reference plus some offset.
715 Take into account what reload will do.
717 We could say that out-of-range stack slots are alignable, but that would
718 complicate get_aligned_mem and it isn't worth the trouble since few
719 functions have large stack space. */
722 aligned_memory_operand (op, mode)
724 enum machine_mode mode;
726 if (GET_CODE (op) == SUBREG)
728 if (GET_MODE (op) != mode)
730 op = SUBREG_REG (op);
731 mode = GET_MODE (op);
734 if (reload_in_progress && GET_CODE (op) == REG
735 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
736 op = reg_equiv_mem[REGNO (op)];
738 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
739 || ! memory_address_p (mode, XEXP (op, 0)))
744 if (GET_CODE (op) == PLUS)
747 return (GET_CODE (op) == REG
748 && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
751 /* Similar, but return 1 if OP is a MEM which is not alignable. */
754 unaligned_memory_operand (op, mode)
756 enum machine_mode mode;
758 if (GET_CODE (op) == SUBREG)
760 if (GET_MODE (op) != mode)
762 op = SUBREG_REG (op);
763 mode = GET_MODE (op);
766 if (reload_in_progress && GET_CODE (op) == REG
767 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
768 op = reg_equiv_mem[REGNO (op)];
770 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
775 if (! memory_address_p (mode, op))
778 if (GET_CODE (op) == PLUS)
781 return (GET_CODE (op) != REG
782 || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
785 /* Return 1 if OP is either a register or an unaligned memory location. */
788 reg_or_unaligned_mem_operand (op, mode)
790 enum machine_mode mode;
792 return register_operand (op, mode) || unaligned_memory_operand (op, mode);
795 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
798 any_memory_operand (op, mode)
800 enum machine_mode mode;
802 return (GET_CODE (op) == MEM
803 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
804 || (reload_in_progress && GET_CODE (op) == REG
805 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
806 || (reload_in_progress && GET_CODE (op) == SUBREG
807 && GET_CODE (SUBREG_REG (op)) == REG
808 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
811 /* Return 1 if this function can directly return via $26. */
816 return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
817 && get_frame_size () == 0
818 && current_function_outgoing_args_size == 0
819 && current_function_pretend_args_size == 0);
822 /* REF is an alignable memory location. Place an aligned SImode
823 reference into *PALIGNED_MEM and the number of bits to shift into
827 get_aligned_mem (ref, paligned_mem, pbitnum)
829 rtx *paligned_mem, *pbitnum;
832 HOST_WIDE_INT offset = 0;
834 if (GET_CODE (ref) == SUBREG)
836 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
837 if (BYTES_BIG_ENDIAN)
838 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
839 - MIN (UNITS_PER_WORD,
840 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
841 ref = SUBREG_REG (ref);
844 if (GET_CODE (ref) == REG)
845 ref = reg_equiv_mem[REGNO (ref)];
847 if (reload_in_progress)
848 base = find_replacement (&XEXP (ref, 0));
850 base = XEXP (ref, 0);
852 if (GET_CODE (base) == PLUS)
853 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
855 *paligned_mem = gen_rtx_MEM (SImode,
856 plus_constant (base, offset & ~3));
857 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
858 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
859 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
861 *pbitnum = GEN_INT ((offset & 3) * 8);
864 /* Similar, but just get the address. Handle the two reload cases.
865 Add EXTRA_OFFSET to the address we return. */
868 get_unaligned_address (ref, extra_offset)
873 HOST_WIDE_INT offset = 0;
875 if (GET_CODE (ref) == SUBREG)
877 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
878 if (BYTES_BIG_ENDIAN)
879 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
880 - MIN (UNITS_PER_WORD,
881 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
882 ref = SUBREG_REG (ref);
885 if (GET_CODE (ref) == REG)
886 ref = reg_equiv_mem[REGNO (ref)];
888 if (reload_in_progress)
889 base = find_replacement (&XEXP (ref, 0));
891 base = XEXP (ref, 0);
893 if (GET_CODE (base) == PLUS)
894 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
896 return plus_constant (base, offset + extra_offset);
899 /* Subfunction of the following function. Update the flags of any MEM
900 found in part of X. */
903 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
905 int in_struct_p, volatile_p, unchanging_p;
909 switch (GET_CODE (x))
913 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
914 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
919 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
924 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
926 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
931 MEM_IN_STRUCT_P (x) = in_struct_p;
932 MEM_VOLATILE_P (x) = volatile_p;
933 RTX_UNCHANGING_P (x) = unchanging_p;
941 /* Given INSN, which is either an INSN or a SEQUENCE generated to
942 perform a memory operation, look for any MEMs in either a SET_DEST or
943 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
944 REF into each of the MEMs found. If REF is not a MEM, don't do
948 alpha_set_memflags (insn, ref)
952 /* Note that it is always safe to get these flags, though they won't
953 be what we think if REF is not a MEM. */
954 int in_struct_p = MEM_IN_STRUCT_P (ref);
955 int volatile_p = MEM_VOLATILE_P (ref);
956 int unchanging_p = RTX_UNCHANGING_P (ref);
958 if (GET_CODE (ref) != MEM
959 || (! in_struct_p && ! volatile_p && ! unchanging_p))
962 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
965 /* Try to output insns to set TARGET equal to the constant C if it can be
966 done in less than N insns. Do all computations in MODE. Returns the place
967 where the output has been placed if it can be done and the insns have been
968 emitted. If it would take more than N insns, zero is returned and no
969 insns and emitted. */
972 alpha_emit_set_const (target, mode, c, n)
974 enum machine_mode mode;
981 /* Try 1 insn, then 2, then up to N. */
982 for (i = 1; i <= n; i++)
983 if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
989 /* Internal routine for the above to check for N or below insns. */
992 alpha_emit_set_const_1 (target, mode, c, n)
994 enum machine_mode mode;
998 HOST_WIDE_INT new = c;
1000 /* Use a pseudo if highly optimizing and still generating RTL. */
1002 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1006 #if HOST_BITS_PER_WIDE_INT == 64
1007 /* We are only called for SImode and DImode. If this is SImode, ensure that
1008 we are sign extended to a full word. This does not make any sense when
1009 cross-compiling on a narrow machine. */
1012 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1015 /* If this is a sign-extended 32-bit constant, we can do this in at most
1016 three insns, so do it if we have enough insns left. We always have
1017 a sign-extended 32-bit constant when compiling on a narrow machine. */
1019 if (HOST_BITS_PER_WIDE_INT != 64
1020 || c >> 31 == -1 || c >> 31 == 0)
1022 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1023 HOST_WIDE_INT tmp1 = c - low;
1025 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1026 HOST_WIDE_INT extra = 0;
1028 /* If HIGH will be interpreted as negative but the constant is
1029 positive, we must adjust it to do two ldha insns. */
1031 if ((high & 0x8000) != 0 && c >= 0)
1035 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1038 if (c == low || (low == 0 && extra == 0))
1040 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1041 but that meant that we can't handle INT_MIN on 32-bit machines
1042 (like NT/Alpha), because we recurse indefinitely through
1043 emit_move_insn to gen_movdi. So instead, since we know exactly
1044 what we want, create it explicitly. */
1047 target = gen_reg_rtx (mode);
1048 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1051 else if (n >= 2 + (extra != 0))
1053 temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1056 temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1057 subtarget, 0, OPTAB_WIDEN);
1059 return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1060 target, 0, OPTAB_WIDEN);
1064 /* If we couldn't do it that way, try some other methods. But if we have
1065 no instructions left, don't bother. Likewise, if this is SImode and
1066 we can't make pseudos, we can't do anything since the expand_binop
1067 and expand_unop calls will widen and try to make pseudos. */
1070 || (mode == SImode && ! rtx_equal_function_value_matters))
1073 #if HOST_BITS_PER_WIDE_INT == 64
1074 /* First, see if can load a value into the target that is the same as the
1075 constant except that all bytes that are 0 are changed to be 0xff. If we
1076 can, then we can do a ZAPNOT to obtain the desired constant. */
1078 for (i = 0; i < 64; i += 8)
1079 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1080 new |= (HOST_WIDE_INT) 0xff << i;
1082 /* We are only called for SImode and DImode. If this is SImode, ensure that
1083 we are sign extended to a full word. */
1086 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1089 && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1090 return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1091 target, 0, OPTAB_WIDEN);
1094 /* Next, see if we can load a related constant and then shift and possibly
1095 negate it to get the constant we want. Try this once each increasing
1096 numbers of insns. */
1098 for (i = 1; i < n; i++)
1100 /* First try complementing. */
1101 if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1102 return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1104 /* Next try to form a constant and do a left shift. We can do this
1105 if some low-order bits are zero; the exact_log2 call below tells
1106 us that information. The bits we are shifting out could be any
1107 value, but here we'll just try the 0- and sign-extended forms of
1108 the constant. To try to increase the chance of having the same
1109 constant in more than one insn, start at the highest number of
1110 bits to shift, but try all possibilities in case a ZAPNOT will
1113 if ((bits = exact_log2 (c & - c)) > 0)
1114 for (; bits > 0; bits--)
1115 if ((temp = (alpha_emit_set_const
1117 (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
1118 || ((temp = (alpha_emit_set_const
1120 ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1122 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1123 target, 0, OPTAB_WIDEN);
1125 /* Now try high-order zero bits. Here we try the shifted-in bits as
1126 all zero and all ones. Be careful to avoid shifting outside the
1127 mode and to avoid shifting outside the host wide int size. */
1128 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1129 confuse the recursive call and set all of the high 32 bits. */
1131 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1132 - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1133 for (; bits > 0; bits--)
1134 if ((temp = alpha_emit_set_const (subtarget, mode,
1136 || ((temp = (alpha_emit_set_const
1138 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1141 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1142 target, 1, OPTAB_WIDEN);
1144 /* Now try high-order 1 bits. We get that with a sign-extension.
1145 But one bit isn't enough here. Be careful to avoid shifting outside
1146 the mode and to avoid shifting outside the host wide int size. */
1148 if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1149 - floor_log2 (~ c) - 2)) > 0)
1150 for (; bits > 0; bits--)
1151 if ((temp = alpha_emit_set_const (subtarget, mode,
1153 || ((temp = (alpha_emit_set_const
1155 ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1158 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1159 target, 0, OPTAB_WIDEN);
1165 #if HOST_BITS_PER_WIDE_INT == 64
1166 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1167 fall back to a straight forward decomposition. We do this to avoid
1168 exponential run times encountered when looking for longer sequences
1169 with alpha_emit_set_const. */
1172 alpha_emit_set_long_const (target, c)
1176 /* Use a pseudo if highly optimizing and still generating RTL. */
1178 = (flag_expensive_optimizations && rtx_equal_function_value_matters
1180 HOST_WIDE_INT d1, d2, d3, d4;
1183 /* Decompose the entire word */
1184 d1 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1186 d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1188 d3 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1190 d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000;
1195 /* Construct the high word */
1197 r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode);
1199 r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode);
1201 r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4),
1202 subtarget, 0, OPTAB_WIDEN);
1204 /* Shift it into place */
1205 r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32),
1206 subtarget, 0, OPTAB_WIDEN);
1208 if (subtarget == 0 && d1 == d3 && d2 == d4)
1209 r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN);
1214 /* Add in the low word */
1216 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2),
1217 subtarget, 0, OPTAB_WIDEN);
1219 r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1),
1220 subtarget, 0, OPTAB_WIDEN);
1224 r1 = copy_to_suggested_reg(r1, target, DImode);
1228 #endif /* HOST_BITS_PER_WIDE_INT == 64 */
1230 /* Generate the comparison for a conditional branch. */
1233 alpha_emit_conditional_branch (code)
1236 enum rtx_code cmp_code, branch_code;
1237 enum machine_mode cmp_mode, branch_mode = VOIDmode;
1238 rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1241 /* The general case: fold the comparison code to the types of compares
1242 that we have, choosing the branch as necessary. */
1245 case EQ: case LE: case LT: case LEU: case LTU:
1246 /* We have these compares: */
1247 cmp_code = code, branch_code = NE;
1251 /* This must be reversed. */
1252 cmp_code = EQ, branch_code = EQ;
1255 case GE: case GT: case GEU: case GTU:
1256 /* For FP, we swap them, for INT, we reverse them. */
1257 if (alpha_compare_fp_p)
1259 cmp_code = swap_condition (code);
1261 tem = op0, op0 = op1, op1 = tem;
1265 cmp_code = reverse_condition (code);
1274 if (alpha_compare_fp_p)
1279 /* When we are not as concerned about non-finite values, and we
1280 are comparing against zero, we can branch directly. */
1281 if (op1 == CONST0_RTX (DFmode))
1282 cmp_code = NIL, branch_code = code;
1283 else if (op0 == CONST0_RTX (DFmode))
1285 /* Undo the swap we probably did just above. */
1286 tem = op0, op0 = op1, op1 = tem;
1287 branch_code = swap_condition (cmp_code);
1293 /* ??? We mark the the branch mode to be CCmode to prevent the
1294 compare and branch from being combined, since the compare
1295 insn follows IEEE rules that the branch does not. */
1296 branch_mode = CCmode;
1303 /* The following optimizations are only for signed compares. */
1304 if (code != LEU && code != LTU && code != GEU && code != GTU)
1306 /* Whee. Compare and branch against 0 directly. */
1307 if (op1 == const0_rtx)
1308 cmp_code = NIL, branch_code = code;
1310 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1311 bypass between logicals and br/cmov on EV5. But we don't want to
1312 force valid immediate constants into registers needlessly. */
1313 else if (GET_CODE (op1) == CONST_INT)
1315 HOST_WIDE_INT v = INTVAL (op1), n = -v;
1317 if (! CONST_OK_FOR_LETTER_P (v, 'I')
1318 && (CONST_OK_FOR_LETTER_P (n, 'K')
1319 || CONST_OK_FOR_LETTER_P (n, 'L')))
1321 cmp_code = PLUS, branch_code = code;
1328 /* Force op0 into a register. */
1329 if (GET_CODE (op0) != REG)
1330 op0 = force_reg (cmp_mode, op0);
1332 /* Emit an initial compare instruction, if necessary. */
1334 if (cmp_code != NIL)
1336 tem = gen_reg_rtx (cmp_mode);
1337 emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1340 /* Return the branch comparison. */
1341 return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1345 /* Rewrite a comparison against zero CMP of the form
1346 (CODE (cc0) (const_int 0)) so it can be written validly in
1347 a conditional move (if_then_else CMP ...).
1348 If both of the operands that set cc0 are non-zero we must emit
1349 an insn to perform the compare (it can't be done within
1350 the conditional move). */
1352 alpha_emit_conditional_move (cmp, mode)
1354 enum machine_mode mode;
1356 enum rtx_code code = GET_CODE (cmp);
1357 enum rtx_code cmov_code = NE;
1358 rtx op0 = alpha_compare_op0;
1359 rtx op1 = alpha_compare_op1;
1360 enum machine_mode cmp_mode
1361 = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1362 enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1363 enum machine_mode cmov_mode = VOIDmode;
1366 if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1369 /* We may be able to use a conditional move directly.
1370 This avoids emitting spurious compares. */
1371 if (signed_comparison_operator (cmp, cmp_op_mode)
1372 && (!alpha_compare_fp_p || flag_fast_math)
1373 && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1374 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1376 /* We can't put the comparison insides a conditional move;
1377 emit a compare instruction and put that inside the
1378 conditional move. Make sure we emit only comparisons we have;
1379 swap or reverse as necessary. */
1383 case EQ: case LE: case LT: case LEU: case LTU:
1384 /* We have these compares: */
1388 /* This must be reversed. */
1389 code = reverse_condition (code);
1393 case GE: case GT: case GEU: case GTU:
1394 /* These must be swapped. Make sure the new first operand is in
1396 code = swap_condition (code);
1397 tem = op0, op0 = op1, op1 = tem;
1398 op0 = force_reg (cmp_mode, op0);
1405 /* ??? We mark the the branch mode to be CCmode to prevent the compare
1406 and cmov from being combined, since the compare insn follows IEEE
1407 rules that the cmov does not. */
1408 if (alpha_compare_fp_p && !flag_fast_math)
1411 tem = gen_reg_rtx (cmp_op_mode);
1412 emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1413 return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1416 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1420 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1421 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1422 lda r3,X(r11) lda r3,X+2(r11)
1423 extwl r1,r3,r1 extql r1,r3,r1
1424 extwh r2,r3,r2 extqh r2,r3,r2
1425 or r1.r2.r1 or r1,r2,r1
1428 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1429 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1430 lda r3,X(r11) lda r3,X(r11)
1431 extll r1,r3,r1 extll r1,r3,r1
1432 extlh r2,r3,r2 extlh r2,r3,r2
1433 or r1.r2.r1 addl r1,r2,r1
1435 quad: ldq_u r1,X(r11)
1444 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1446 HOST_WIDE_INT size, ofs;
1449 rtx meml, memh, addr, extl, exth;
1450 enum machine_mode mode;
1452 meml = gen_reg_rtx (DImode);
1453 memh = gen_reg_rtx (DImode);
1454 addr = gen_reg_rtx (DImode);
1455 extl = gen_reg_rtx (DImode);
1456 exth = gen_reg_rtx (DImode);
1458 emit_move_insn (meml,
1459 change_address (mem, DImode,
1460 gen_rtx_AND (DImode,
1461 plus_constant (XEXP (mem, 0),
1465 emit_move_insn (memh,
1466 change_address (mem, DImode,
1467 gen_rtx_AND (DImode,
1468 plus_constant (XEXP (mem, 0),
1472 if (sign && size == 2)
1474 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1476 emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1477 emit_insn (gen_extqh (exth, memh, addr));
1479 /* We must use tgt here for the target. Alpha-vms port fails if we use
1480 addr for the target, because addr is marked as a pointer and combine
1481 knows that pointers are always sign-extended 32 bit values. */
1482 addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1483 addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
1484 addr, 1, OPTAB_WIDEN);
1488 emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1489 emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1493 emit_insn (gen_extwh (exth, memh, addr));
1498 emit_insn (gen_extlh (exth, memh, addr));
1503 emit_insn (gen_extqh (exth, memh, addr));
1508 addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1509 gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1514 emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1517 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1520 alpha_expand_unaligned_store (dst, src, size, ofs)
1522 HOST_WIDE_INT size, ofs;
1524 rtx dstl, dsth, addr, insl, insh, meml, memh;
1526 dstl = gen_reg_rtx (DImode);
1527 dsth = gen_reg_rtx (DImode);
1528 insl = gen_reg_rtx (DImode);
1529 insh = gen_reg_rtx (DImode);
1531 meml = change_address (dst, DImode,
1532 gen_rtx_AND (DImode,
1533 plus_constant (XEXP (dst, 0), ofs),
1535 memh = change_address (dst, DImode,
1536 gen_rtx_AND (DImode,
1537 plus_constant (XEXP (dst, 0),
1541 emit_move_insn (dsth, memh);
1542 emit_move_insn (dstl, meml);
1543 addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1545 if (src != const0_rtx)
1547 emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1548 GEN_INT (size*8), addr));
1553 emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1556 emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1559 emit_insn (gen_insql (insl, src, addr));
1564 emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1569 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1572 emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1576 #if HOST_BITS_PER_WIDE_INT == 32
1577 rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1579 rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1581 emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1586 if (src != const0_rtx)
1588 dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1589 dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1592 /* Must store high before low for degenerate case of aligned. */
1593 emit_move_insn (memh, dsth);
1594 emit_move_insn (meml, dstl);
1597 /* The block move code tries to maximize speed by separating loads and
1598 stores at the expense of register pressure: we load all of the data
1599 before we store it back out. There are two secondary effects worth
1600 mentioning, that this speeds copying to/from aligned and unaligned
1601 buffers, and that it makes the code significantly easier to write. */
1603 #define MAX_MOVE_WORDS 8
1605 /* Load an integral number of consecutive unaligned quadwords. */
1608 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1611 HOST_WIDE_INT words, ofs;
1613 rtx const im8 = GEN_INT (-8);
1614 rtx const i64 = GEN_INT (64);
1615 rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1619 /* Generate all the tmp registers we need. */
1620 for (i = 0; i < words; ++i)
1622 data_regs[i] = out_regs[i];
1623 ext_tmps[i] = gen_reg_rtx (DImode);
1625 data_regs[words] = gen_reg_rtx (DImode);
1628 smem = change_address (smem, GET_MODE (smem),
1629 plus_constant (XEXP (smem, 0), ofs));
1631 /* Load up all of the source data. */
1632 for (i = 0; i < words; ++i)
1634 emit_move_insn (data_regs[i],
1635 change_address (smem, DImode,
1636 gen_rtx_AND (DImode,
1637 plus_constant (XEXP(smem,0),
1641 emit_move_insn (data_regs[words],
1642 change_address (smem, DImode,
1643 gen_rtx_AND (DImode,
1644 plus_constant (XEXP(smem,0),
1648 /* Extract the half-word fragments. Unfortunately DEC decided to make
1649 extxh with offset zero a noop instead of zeroing the register, so
1650 we must take care of that edge condition ourselves with cmov. */
1652 sreg = copy_addr_to_reg (XEXP (smem, 0));
1653 areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
1655 for (i = 0; i < words; ++i)
1657 emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1659 emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1660 emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1661 gen_rtx_IF_THEN_ELSE (DImode,
1662 gen_rtx_EQ (DImode, areg,
1664 const0_rtx, ext_tmps[i])));
1667 /* Merge the half-words into whole words. */
1668 for (i = 0; i < words; ++i)
1670 out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1671 ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1675 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1676 may be NULL to store zeros. */
1679 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1682 HOST_WIDE_INT words, ofs;
1684 rtx const im8 = GEN_INT (-8);
1685 rtx const i64 = GEN_INT (64);
1686 #if HOST_BITS_PER_WIDE_INT == 32
1687 rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1689 rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1691 rtx ins_tmps[MAX_MOVE_WORDS];
1692 rtx st_tmp_1, st_tmp_2, dreg;
1693 rtx st_addr_1, st_addr_2;
1696 /* Generate all the tmp registers we need. */
1697 if (data_regs != NULL)
1698 for (i = 0; i < words; ++i)
1699 ins_tmps[i] = gen_reg_rtx(DImode);
1700 st_tmp_1 = gen_reg_rtx(DImode);
1701 st_tmp_2 = gen_reg_rtx(DImode);
1704 dmem = change_address (dmem, GET_MODE (dmem),
1705 plus_constant (XEXP (dmem, 0), ofs));
1708 st_addr_2 = change_address (dmem, DImode,
1709 gen_rtx_AND (DImode,
1710 plus_constant (XEXP(dmem,0),
1713 st_addr_1 = change_address (dmem, DImode,
1714 gen_rtx_AND (DImode,
1718 /* Load up the destination end bits. */
1719 emit_move_insn (st_tmp_2, st_addr_2);
1720 emit_move_insn (st_tmp_1, st_addr_1);
1722 /* Shift the input data into place. */
1723 dreg = copy_addr_to_reg (XEXP (dmem, 0));
1724 if (data_regs != NULL)
1726 for (i = words-1; i >= 0; --i)
1728 emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1729 emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1731 for (i = words-1; i > 0; --i)
1733 ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1734 ins_tmps[i-1], ins_tmps[i-1], 1,
1739 /* Split and merge the ends with the destination data. */
1740 emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1741 emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1743 if (data_regs != NULL)
1745 st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1746 st_tmp_2, 1, OPTAB_WIDEN);
1747 st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1748 st_tmp_1, 1, OPTAB_WIDEN);
1752 emit_move_insn (st_addr_2, st_tmp_2);
1753 for (i = words-1; i > 0; --i)
1755 emit_move_insn (change_address (dmem, DImode,
1756 gen_rtx_AND (DImode,
1757 plus_constant(XEXP (dmem,0),
1760 data_regs ? ins_tmps[i-1] : const0_rtx);
1762 emit_move_insn (st_addr_1, st_tmp_1);
1766 /* Expand string/block move operations.
1768 operands[0] is the pointer to the destination.
1769 operands[1] is the pointer to the source.
1770 operands[2] is the number of bytes to move.
1771 operands[3] is the alignment. */
1774 alpha_expand_block_move (operands)
1777 rtx bytes_rtx = operands[2];
1778 rtx align_rtx = operands[3];
1779 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1780 HOST_WIDE_INT src_align = INTVAL (align_rtx);
1781 HOST_WIDE_INT dst_align = src_align;
1782 rtx orig_src = operands[1];
1783 rtx orig_dst = operands[0];
1784 rtx data_regs[2*MAX_MOVE_WORDS+16];
1786 int i, words, ofs, nregs = 0;
1790 if (bytes > MAX_MOVE_WORDS*8)
1793 /* Look for additional alignment information from recorded register info. */
1795 tmp = XEXP (orig_src, 0);
1796 if (GET_CODE (tmp) == REG)
1798 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1799 src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1801 else if (GET_CODE (tmp) == PLUS
1802 && GET_CODE (XEXP (tmp, 0)) == REG
1803 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1805 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1806 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1810 if (a >= 8 && c % 8 == 0)
1812 else if (a >= 4 && c % 4 == 0)
1814 else if (a >= 2 && c % 2 == 0)
1819 tmp = XEXP (orig_dst, 0);
1820 if (GET_CODE (tmp) == REG)
1822 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1823 dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1825 else if (GET_CODE (tmp) == PLUS
1826 && GET_CODE (XEXP (tmp, 0)) == REG
1827 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1829 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1830 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1834 if (a >= 8 && c % 8 == 0)
1836 else if (a >= 4 && c % 4 == 0)
1838 else if (a >= 2 && c % 2 == 0)
1844 * Load the entire block into registers.
1847 if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1849 enum machine_mode mode;
1850 tmp = XEXP (XEXP (orig_src, 0), 0);
1852 mode = mode_for_size (bytes, MODE_INT, 1);
1854 && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1856 /* Whee! Optimize the load to use the existing register. */
1857 data_regs[nregs++] = gen_lowpart (mode, tmp);
1861 /* ??? We could potentially be copying 3 bytes or whatnot from
1862 a wider reg. Probably not worth worrying about. */
1863 /* No appropriate mode; fall back on memory. */
1864 orig_src = change_address (orig_src, GET_MODE (orig_src),
1865 copy_addr_to_reg (XEXP (orig_src, 0)));
1869 if (src_align >= 8 && bytes >= 8)
1873 for (i = 0; i < words; ++i)
1874 data_regs[nregs+i] = gen_reg_rtx(DImode);
1876 for (i = 0; i < words; ++i)
1878 emit_move_insn (data_regs[nregs+i],
1879 change_address(orig_src, DImode,
1880 plus_constant (XEXP (orig_src, 0),
1888 if (src_align >= 4 && bytes >= 4)
1892 for (i = 0; i < words; ++i)
1893 data_regs[nregs+i] = gen_reg_rtx(SImode);
1895 for (i = 0; i < words; ++i)
1897 emit_move_insn (data_regs[nregs+i],
1898 change_address(orig_src, SImode,
1899 plus_constant (XEXP (orig_src, 0),
1911 for (i = 0; i < words+1; ++i)
1912 data_regs[nregs+i] = gen_reg_rtx(DImode);
1914 alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1920 if (!TARGET_BWX && bytes >= 8)
1922 data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1923 alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1927 if (!TARGET_BWX && bytes >= 4)
1929 data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1930 alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1939 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1940 emit_move_insn (tmp,
1941 change_address (orig_src, HImode,
1942 plus_constant (XEXP (orig_src, 0),
1946 } while (bytes >= 2);
1948 else if (!TARGET_BWX)
1950 data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1951 alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1958 data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1959 emit_move_insn (tmp,
1960 change_address (orig_src, QImode,
1961 plus_constant (XEXP (orig_src, 0),
1968 if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1972 * Now save it back out again.
1977 if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1979 enum machine_mode mode;
1980 tmp = XEXP (XEXP (orig_dst, 0), 0);
1982 mode = mode_for_size (bytes, MODE_INT, 1);
1983 if (GET_MODE (tmp) == mode && nregs == 1)
1985 emit_move_insn (tmp, data_regs[0]);
1990 /* ??? If nregs > 1, consider reconstructing the word in regs. */
1991 /* ??? Optimize mode < dst_mode with strict_low_part. */
1992 /* No appropriate mode; fall back on memory. */
1993 orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
1994 copy_addr_to_reg (XEXP (orig_dst, 0)));
1997 /* Write out the data in whatever chunks reading the source allowed. */
2000 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2002 emit_move_insn (change_address(orig_dst, DImode,
2003 plus_constant (XEXP (orig_dst, 0),
2012 /* If the source has remaining DImode regs, write them out in
2014 while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2016 tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2017 NULL_RTX, 1, OPTAB_WIDEN);
2019 emit_move_insn (change_address(orig_dst, SImode,
2020 plus_constant (XEXP (orig_dst, 0),
2022 gen_lowpart (SImode, data_regs[i]));
2023 emit_move_insn (change_address(orig_dst, SImode,
2024 plus_constant (XEXP (orig_dst, 0),
2026 gen_lowpart (SImode, tmp));
2031 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2033 emit_move_insn (change_address(orig_dst, SImode,
2034 plus_constant (XEXP (orig_dst, 0),
2041 if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2043 /* Write out a remaining block of words using unaligned methods. */
2045 for (words = 1; i+words < nregs ; ++words)
2046 if (GET_MODE (data_regs[i+words]) != DImode)
2050 alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2052 alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2058 /* Due to the above, this won't be aligned. */
2059 /* ??? If we have more than one of these, consider constructing full
2060 words in registers and using alpha_expand_unaligned_store_words. */
2061 while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2063 alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2069 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2071 emit_move_insn (change_address (orig_dst, HImode,
2072 plus_constant (XEXP (orig_dst, 0),
2079 while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2081 alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2085 while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2087 emit_move_insn (change_address (orig_dst, QImode,
2088 plus_constant (XEXP (orig_dst, 0),
2103 alpha_expand_block_clear (operands)
2106 rtx bytes_rtx = operands[1];
2107 rtx align_rtx = operands[2];
2108 HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2109 HOST_WIDE_INT align = INTVAL (align_rtx);
2110 rtx orig_dst = operands[0];
2112 HOST_WIDE_INT i, words, ofs = 0;
2116 if (bytes > MAX_MOVE_WORDS*8)
2119 /* Look for stricter alignment. */
2121 tmp = XEXP (orig_dst, 0);
2122 if (GET_CODE (tmp) == REG)
2124 if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2125 align = REGNO_POINTER_ALIGN (REGNO (tmp));
2127 else if (GET_CODE (tmp) == PLUS
2128 && GET_CODE (XEXP (tmp, 0)) == REG
2129 && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2131 HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2132 int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2136 if (a >= 8 && c % 8 == 0)
2138 else if (a >= 4 && c % 4 == 0)
2140 else if (a >= 2 && c % 2 == 0)
2145 /* Handle a block of contiguous words first. */
2147 if (align >= 8 && bytes >= 8)
2151 for (i = 0; i < words; ++i)
2153 emit_move_insn (change_address(orig_dst, DImode,
2154 plus_constant (XEXP (orig_dst, 0),
2162 if (align >= 4 && bytes >= 4)
2166 for (i = 0; i < words; ++i)
2168 emit_move_insn (change_address(orig_dst, SImode,
2169 plus_constant (XEXP (orig_dst, 0),
2181 alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2187 /* Next clean up any trailing pieces. We know from the contiguous
2188 block move that there are no aligned SImode or DImode hunks left. */
2190 if (!TARGET_BWX && bytes >= 8)
2192 alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2196 if (!TARGET_BWX && bytes >= 4)
2198 alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2207 emit_move_insn (change_address (orig_dst, HImode,
2208 plus_constant (XEXP (orig_dst, 0),
2213 } while (bytes >= 2);
2215 else if (!TARGET_BWX)
2217 alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2224 emit_move_insn (change_address (orig_dst, QImode,
2225 plus_constant (XEXP (orig_dst, 0),
2236 /* Adjust the cost of a scheduling dependency. Return the new cost of
2237 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2240 alpha_adjust_cost (insn, link, dep_insn, cost)
2247 enum attr_type insn_type, dep_insn_type;
2249 /* If the dependence is an anti-dependence, there is no cost. For an
2250 output dependence, there is sometimes a cost, but it doesn't seem
2251 worth handling those few cases. */
2253 if (REG_NOTE_KIND (link) != 0)
2256 /* If we can't recognize the insns, we can't really do anything. */
2257 if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2260 insn_type = get_attr_type (insn);
2261 dep_insn_type = get_attr_type (dep_insn);
2263 /* Bring in the user-defined memory latency. */
2264 if (dep_insn_type == TYPE_ILD
2265 || dep_insn_type == TYPE_FLD
2266 || dep_insn_type == TYPE_LDSYM)
2267 cost += alpha_memory_latency-1;
2272 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2273 being stored, we can sometimes lower the cost. */
2275 if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2276 && (set = single_set (dep_insn)) != 0
2277 && GET_CODE (PATTERN (insn)) == SET
2278 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2280 switch (dep_insn_type)
2284 /* No savings here. */
2288 /* In these cases, we save one cycle. */
2292 /* In all other cases, we save two cycles. */
2293 return MAX (0, cost - 2);
2297 /* Another case that needs adjustment is an arithmetic or logical
2298 operation. It's cost is usually one cycle, but we default it to
2299 two in the MD file. The only case that it is actually two is
2300 for the address in loads, stores, and jumps. */
2302 if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2317 /* The final case is when a compare feeds into an integer branch;
2318 the cost is only one cycle in that case. */
2320 if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2325 /* And the lord DEC saith: "A special bypass provides an effective
2326 latency of 0 cycles for an ICMP or ILOG insn producing the test
2327 operand of an IBR or ICMOV insn." */
2329 if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2330 && (set = single_set (dep_insn)) != 0)
2332 /* A branch only has one input. This must be it. */
2333 if (insn_type == TYPE_IBR)
2335 /* A conditional move has three, make sure it is the test. */
2336 if (insn_type == TYPE_ICMOV
2337 && GET_CODE (set_src = PATTERN (insn)) == SET
2338 && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2339 && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2343 /* "The multiplier is unable to receive data from IEU bypass paths.
2344 The instruction issues at the expected time, but its latency is
2345 increased by the time it takes for the input data to become
2346 available to the multiplier" -- which happens in pipeline stage
2347 six, when results are comitted to the register file. */
2349 if (insn_type == TYPE_IMUL)
2351 switch (dep_insn_type)
2353 /* These insns produce their results in pipeline stage five. */
2360 /* Other integer insns produce results in pipeline stage four. */
2368 /* There is additional latency to move the result of (most) FP
2369 operations anywhere but the FP register file. */
2371 if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2372 && (dep_insn_type == TYPE_FADD ||
2373 dep_insn_type == TYPE_FMUL ||
2374 dep_insn_type == TYPE_FCMOV))
2380 /* Otherwise, return the default cost. */
2384 /* Functions to save and restore alpha_return_addr_rtx. */
2386 struct machine_function
2392 alpha_save_machine_status (p)
2395 struct machine_function *machine =
2396 (struct machine_function *) xmalloc (sizeof (struct machine_function));
2398 p->machine = machine;
2399 machine->ra_rtx = alpha_return_addr_rtx;
2403 alpha_restore_machine_status (p)
2406 struct machine_function *machine = p->machine;
2408 alpha_return_addr_rtx = machine->ra_rtx;
2411 p->machine = (struct machine_function *)0;
2414 /* Do anything needed before RTL is emitted for each function. */
2417 alpha_init_expanders ()
2419 alpha_return_addr_rtx = NULL_RTX;
2421 /* Arrange to save and restore machine status around nested functions. */
2422 save_machine_status = alpha_save_machine_status;
2423 restore_machine_status = alpha_restore_machine_status;
2426 /* Start the ball rolling with RETURN_ADDR_RTX. */
2429 alpha_return_addr (count, frame)
2438 if (alpha_return_addr_rtx)
2439 return alpha_return_addr_rtx;
2441 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2442 alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2443 init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2444 gen_rtx_REG (Pmode, REG_RA));
2446 /* Emit the insn to the prologue with the other argument copies. */
2447 push_topmost_sequence ();
2448 emit_insn_after (init, get_insns ());
2449 pop_topmost_sequence ();
2451 return alpha_return_addr_rtx;
2455 alpha_ra_ever_killed ()
2457 #ifdef ASM_OUTPUT_MI_THUNK
2458 if (current_function_is_thunk)
2461 if (!alpha_return_addr_rtx)
2462 return regs_ever_live[REG_RA];
2464 return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2465 get_insns(), NULL_RTX);
2469 /* Print an operand. Recognize special options, documented below. */
2472 print_operand (file, x, code)
2482 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2483 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2484 mode. alpha_fprm controls which suffix is generated. */
2487 case ALPHA_FPRM_NORM:
2489 case ALPHA_FPRM_MINF:
2492 case ALPHA_FPRM_CHOP:
2495 case ALPHA_FPRM_DYN:
2502 /* Generates trap-mode suffix for instructions that accept the su
2503 suffix only (cmpt et al). */
2504 if (alpha_tp == ALPHA_TP_INSN)
2509 /* Generates trap-mode suffix for instructions that accept the
2510 v and sv suffix. The only instruction that needs this is cvtql. */
2519 case ALPHA_FPTM_SUI:
2526 /* Generates trap-mode suffix for instructions that accept the
2527 v, sv, and svi suffix. The only instruction that needs this
2539 case ALPHA_FPTM_SUI:
2540 fputs ("svi", file);
2546 /* Generates trap-mode suffix for instructions that accept the u, su,
2547 and sui suffix. This is the bulk of the IEEE floating point
2548 instructions (addt et al). */
2559 case ALPHA_FPTM_SUI:
2560 fputs ("sui", file);
2566 /* Generates trap-mode suffix for instructions that accept the sui
2567 suffix (cvtqt and cvtqs). */
2572 case ALPHA_FPTM_SU: /* cvtqt/cvtqs can't cause underflow */
2574 case ALPHA_FPTM_SUI:
2575 fputs ("sui", file);
2581 /* Generates single precision instruction suffix. */
2582 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2586 /* Generates double precision instruction suffix. */
2587 fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2591 /* If this operand is the constant zero, write it as "$31". */
2592 if (GET_CODE (x) == REG)
2593 fprintf (file, "%s", reg_names[REGNO (x)]);
2594 else if (x == CONST0_RTX (GET_MODE (x)))
2595 fprintf (file, "$31");
2597 output_operand_lossage ("invalid %%r value");
2602 /* Similar, but for floating-point. */
2603 if (GET_CODE (x) == REG)
2604 fprintf (file, "%s", reg_names[REGNO (x)]);
2605 else if (x == CONST0_RTX (GET_MODE (x)))
2606 fprintf (file, "$f31");
2608 output_operand_lossage ("invalid %%R value");
2613 /* Write the 1's complement of a constant. */
2614 if (GET_CODE (x) != CONST_INT)
2615 output_operand_lossage ("invalid %%N value");
2617 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2621 /* Write 1 << C, for a constant C. */
2622 if (GET_CODE (x) != CONST_INT)
2623 output_operand_lossage ("invalid %%P value");
2625 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2629 /* Write the high-order 16 bits of a constant, sign-extended. */
2630 if (GET_CODE (x) != CONST_INT)
2631 output_operand_lossage ("invalid %%h value");
2633 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2637 /* Write the low-order 16 bits of a constant, sign-extended. */
2638 if (GET_CODE (x) != CONST_INT)
2639 output_operand_lossage ("invalid %%L value");
2641 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2642 (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2646 /* Write mask for ZAP insn. */
2647 if (GET_CODE (x) == CONST_DOUBLE)
2649 HOST_WIDE_INT mask = 0;
2650 HOST_WIDE_INT value;
2652 value = CONST_DOUBLE_LOW (x);
2653 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2658 value = CONST_DOUBLE_HIGH (x);
2659 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2662 mask |= (1 << (i + sizeof (int)));
2664 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2667 else if (GET_CODE (x) == CONST_INT)
2669 HOST_WIDE_INT mask = 0, value = INTVAL (x);
2671 for (i = 0; i < 8; i++, value >>= 8)
2675 fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2678 output_operand_lossage ("invalid %%m value");
2682 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2683 if (GET_CODE (x) != CONST_INT
2684 || (INTVAL (x) != 8 && INTVAL (x) != 16
2685 && INTVAL (x) != 32 && INTVAL (x) != 64))
2686 output_operand_lossage ("invalid %%M value");
2688 fprintf (file, "%s",
2689 (INTVAL (x) == 8 ? "b"
2690 : INTVAL (x) == 16 ? "w"
2691 : INTVAL (x) == 32 ? "l"
2696 /* Similar, except do it from the mask. */
2697 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2698 fprintf (file, "b");
2699 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2700 fprintf (file, "w");
2701 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2702 fprintf (file, "l");
2703 #if HOST_BITS_PER_WIDE_INT == 32
2704 else if (GET_CODE (x) == CONST_DOUBLE
2705 && CONST_DOUBLE_HIGH (x) == 0
2706 && CONST_DOUBLE_LOW (x) == -1)
2707 fprintf (file, "l");
2708 else if (GET_CODE (x) == CONST_DOUBLE
2709 && CONST_DOUBLE_HIGH (x) == -1
2710 && CONST_DOUBLE_LOW (x) == -1)
2711 fprintf (file, "q");
2713 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2714 fprintf (file, "q");
2715 else if (GET_CODE (x) == CONST_DOUBLE
2716 && CONST_DOUBLE_HIGH (x) == 0
2717 && CONST_DOUBLE_LOW (x) == -1)
2718 fprintf (file, "q");
2721 output_operand_lossage ("invalid %%U value");
2725 /* Write the constant value divided by 8. */
2726 if (GET_CODE (x) != CONST_INT
2727 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2728 && (INTVAL (x) & 7) != 8)
2729 output_operand_lossage ("invalid %%s value");
2731 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2735 /* Same, except compute (64 - c) / 8 */
2737 if (GET_CODE (x) != CONST_INT
2738 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2739 && (INTVAL (x) & 7) != 8)
2740 output_operand_lossage ("invalid %%s value");
2742 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2745 case 'C': case 'D': case 'c': case 'd':
2746 /* Write out comparison name. */
2748 enum rtx_code c = GET_CODE (x);
2750 if (GET_RTX_CLASS (c) != '<')
2751 output_operand_lossage ("invalid %%C value");
2754 c = reverse_condition (c);
2755 else if (code == 'c')
2756 c = swap_condition (c);
2757 else if (code == 'd')
2758 c = swap_condition (reverse_condition (c));
2761 fprintf (file, "ule");
2763 fprintf (file, "ult");
2765 fprintf (file, "%s", GET_RTX_NAME (c));
2770 /* Write the divide or modulus operator. */
2771 switch (GET_CODE (x))
2774 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2777 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2780 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2783 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2786 output_operand_lossage ("invalid %%E value");
2792 /* Write "_u" for unaligned access. */
2793 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2794 fprintf (file, "_u");
2798 if (GET_CODE (x) == REG)
2799 fprintf (file, "%s", reg_names[REGNO (x)]);
2800 else if (GET_CODE (x) == MEM)
2801 output_address (XEXP (x, 0));
2803 output_addr_const (file, x);
2807 output_operand_lossage ("invalid %%xn code");
2811 /* Do what is necessary for `va_start'. The argument is ignored;
2812 We look at the current function to determine if stdarg or varargs
2813 is used and fill in an initial va_list. A pointer to this constructor
2817 alpha_builtin_saveregs (arglist)
2820 rtx block, addr, dest, argsize;
2821 tree fntype = TREE_TYPE (current_function_decl);
2822 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2823 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2824 != void_type_node));
2826 /* Compute the current position into the args, taking into account
2827 both registers and memory. Both of these are already included in
2830 argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2832 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2833 storing fp arg registers in the first 48 bytes, and the integer arg
2834 registers in the next 48 bytes. This is only done, however, if any
2835 integer registers need to be stored.
2837 If no integer registers need be stored, then we must subtract 48 in
2838 order to account for the integer arg registers which are counted in
2839 argsize above, but which are not actually stored on the stack. */
2841 if (TARGET_OPEN_VMS)
2842 addr = plus_constant (virtual_incoming_args_rtx,
2843 NUM_ARGS <= 5 + stdarg
2844 ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2846 addr = (NUM_ARGS <= 5 + stdarg
2847 ? plus_constant (virtual_incoming_args_rtx,
2849 : plus_constant (virtual_incoming_args_rtx,
2850 - (6 * UNITS_PER_WORD)));
2852 /* For VMS, we include the argsize, while on Unix, it's handled as
2853 a separate field. */
2854 if (TARGET_OPEN_VMS)
2855 addr = plus_constant (addr, INTVAL (argsize));
2857 addr = force_operand (addr, NULL_RTX);
2859 #ifdef POINTERS_EXTEND_UNSIGNED
2860 addr = convert_memory_address (ptr_mode, addr);
2863 if (TARGET_OPEN_VMS)
2867 /* Allocate the va_list constructor */
2868 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2869 RTX_UNCHANGING_P (block) = 1;
2870 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2872 /* Store the address of the first integer register in the __base
2875 dest = change_address (block, ptr_mode, XEXP (block, 0));
2876 emit_move_insn (dest, addr);
2878 if (flag_check_memory_usage)
2879 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2881 GEN_INT (GET_MODE_SIZE (ptr_mode)),
2882 TYPE_MODE (sizetype),
2883 GEN_INT (MEMORY_USE_RW),
2884 TYPE_MODE (integer_type_node));
2886 /* Store the argsize as the __va_offset member. */
2887 dest = change_address (block, TYPE_MODE (integer_type_node),
2888 plus_constant (XEXP (block, 0),
2889 POINTER_SIZE/BITS_PER_UNIT));
2890 emit_move_insn (dest, argsize);
2892 if (flag_check_memory_usage)
2893 emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2895 GEN_INT (GET_MODE_SIZE
2896 (TYPE_MODE (integer_type_node))),
2897 TYPE_MODE (sizetype),
2898 GEN_INT (MEMORY_USE_RW),
2899 TYPE_MODE (integer_type_node));
2901 /* Return the address of the va_list constructor, but don't put it in a
2902 register. Doing so would fail when not optimizing and produce worse
2903 code when optimizing. */
2904 return XEXP (block, 0);
2908 /* This page contains routines that are used to determine what the function
2909 prologue and epilogue code will do and write them out. */
2911 /* Compute the size of the save area in the stack. */
2913 /* These variables are used for communication between the following functions.
2914 They indicate various things about the current function being compiled
2915 that are used to tell what kind of prologue, epilogue and procedure
2916 descriptior to generate. */
2918 /* Nonzero if we need a stack procedure. */
2919 static int vms_is_stack_procedure;
2921 /* Register number (either FP or SP) that is used to unwind the frame. */
2922 static int vms_unwind_regno;
2924 /* Register number used to save FP. We need not have one for RA since
2925 we don't modify it for register procedures. This is only defined
2926 for register frame procedures. */
2927 static int vms_save_fp_regno;
2929 /* Register number used to reference objects off our PV. */
2930 static int vms_base_regno;
2932 /* Compute register masks for saved registers. */
2935 alpha_sa_mask (imaskP, fmaskP)
2936 unsigned long *imaskP;
2937 unsigned long *fmaskP;
2939 unsigned long imask = 0;
2940 unsigned long fmask = 0;
2943 #ifdef ASM_OUTPUT_MI_THUNK
2944 if (!current_function_is_thunk)
2947 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
2948 imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2950 /* One for every register we have to save. */
2951 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2952 if (! fixed_regs[i] && ! call_used_regs[i]
2953 && regs_ever_live[i] && i != REG_RA)
2958 fmask |= (1L << (i - 32));
2961 if (imask || fmask || alpha_ra_ever_killed ())
2962 imask |= (1L << REG_RA);
2975 #ifdef ASM_OUTPUT_MI_THUNK
2976 if (current_function_is_thunk)
2981 /* One for every register we have to save. */
2982 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2983 if (! fixed_regs[i] && ! call_used_regs[i]
2984 && regs_ever_live[i] && i != REG_RA)
2988 if (TARGET_OPEN_VMS)
2990 /* Start by assuming we can use a register procedure if we don't
2991 make any calls (REG_RA not used) or need to save any
2992 registers and a stack procedure if we do. */
2993 vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2995 /* Decide whether to refer to objects off our PV via FP or PV.
2996 If we need FP for something else or if we receive a nonlocal
2997 goto (which expects PV to contain the value), we must use PV.
2998 Otherwise, start by assuming we can use FP. */
2999 vms_base_regno = (frame_pointer_needed
3000 || current_function_has_nonlocal_label
3001 || vms_is_stack_procedure
3002 || current_function_outgoing_args_size
3003 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3005 /* If we want to copy PV into FP, we need to find some register
3006 in which to save FP. */
3008 vms_save_fp_regno = -1;
3009 if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3010 for (i = 0; i < 32; i++)
3011 if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3012 vms_save_fp_regno = i;
3014 if (vms_save_fp_regno == -1)
3015 vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3017 /* Stack unwinding should be done via FP unless we use it for PV. */
3018 vms_unwind_regno = (vms_base_regno == REG_PV
3019 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3021 /* If this is a stack procedure, allow space for saving FP and RA. */
3022 if (vms_is_stack_procedure)
3027 /* If some registers were saved but not RA, RA must also be saved,
3028 so leave space for it. */
3029 if (sa_size != 0 || alpha_ra_ever_killed ())
3032 /* Our size must be even (multiple of 16 bytes). */
3041 alpha_pv_save_size ()
3044 return vms_is_stack_procedure ? 8 : 0;
3051 return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3055 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3061 if (is_attribute_p ("overlaid", identifier))
3062 return (args == NULL_TREE);
3067 alpha_does_function_need_gp ()
3071 /* We never need a GP for Windows/NT or VMS. */
3072 if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3075 #ifdef TARGET_PROFILING_NEEDS_GP
3080 #ifdef ASM_OUTPUT_MI_THUNK
3081 if (current_function_is_thunk)
3085 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3086 Even if we are a static function, we still need to do this in case
3087 our address is taken and passed to something like qsort. */
3089 push_topmost_sequence ();
3090 insn = get_insns ();
3091 pop_topmost_sequence ();
3093 for (; insn; insn = NEXT_INSN (insn))
3094 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3095 && GET_CODE (PATTERN (insn)) != USE
3096 && GET_CODE (PATTERN (insn)) != CLOBBER)
3098 enum attr_type type = get_attr_type (insn);
3099 if (type == TYPE_LDSYM || type == TYPE_JSR)
3106 /* Write a version stamp. Don't write anything if we are running as a
3107 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3114 alpha_write_verstamp (file)
3118 fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3122 /* Write function prologue. */
3124 /* On vms we have two kinds of functions:
3126 - stack frame (PROC_STACK)
3127 these are 'normal' functions with local vars and which are
3128 calling other functions
3129 - register frame (PROC_REGISTER)
3130 keeps all data in registers, needs no stack
3132 We must pass this to the assembler so it can generate the
3133 proper pdsc (procedure descriptor)
3134 This is done with the '.pdesc' command.
3136 On not-vms, we don't really differentiate between the two, as we can
3137 simply allocate stack without saving registers. */
3140 alpha_expand_prologue ()
3142 /* Registers to save. */
3143 unsigned long imask = 0;
3144 unsigned long fmask = 0;
3145 /* Stack space needed for pushing registers clobbered by us. */
3146 HOST_WIDE_INT sa_size;
3147 /* Complete stack size needed. */
3148 HOST_WIDE_INT frame_size;
3149 /* Offset from base reg to register save area. */
3150 HOST_WIDE_INT reg_offset;
3154 sa_size = alpha_sa_size ();
3156 frame_size = get_frame_size ();
3157 if (TARGET_OPEN_VMS)
3158 frame_size = ALPHA_ROUND (sa_size
3159 + (vms_is_stack_procedure ? 8 : 0)
3161 + current_function_pretend_args_size);
3163 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3165 + ALPHA_ROUND (frame_size
3166 + current_function_pretend_args_size));
3168 if (TARGET_OPEN_VMS)
3171 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3173 alpha_sa_mask (&imask, &fmask);
3175 /* Adjust the stack by the frame size. If the frame size is > 4096
3176 bytes, we need to be sure we probe somewhere in the first and last
3177 4096 bytes (we can probably get away without the latter test) and
3178 every 8192 bytes in between. If the frame size is > 32768, we
3179 do this in a loop. Otherwise, we generate the explicit probe
3182 Note that we are only allowed to adjust sp once in the prologue. */
3184 if (frame_size <= 32768)
3186 if (frame_size > 4096)
3191 emit_insn (gen_probe_stack (GEN_INT (-probed)));
3192 while ((probed += 8192) < frame_size);
3194 /* We only have to do this probe if we aren't saving registers. */
3195 if (sa_size == 0 && probed + 4096 < frame_size)
3196 emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3199 if (frame_size != 0)
3201 emit_move_insn (stack_pointer_rtx,
3202 plus_constant (stack_pointer_rtx, -frame_size));
3207 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3208 number of 8192 byte blocks to probe. We then probe each block
3209 in the loop and then set SP to the proper location. If the
3210 amount remaining is > 4096, we have to do one more probe if we
3211 are not saving any registers. */
3213 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3214 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3215 rtx ptr = gen_rtx_REG (DImode, 22);
3216 rtx count = gen_rtx_REG (DImode, 23);
3218 emit_move_insn (count, GEN_INT (blocks));
3219 emit_move_insn (ptr, plus_constant (stack_pointer_rtx, 4096));
3221 /* Because of the difficulty in emitting a new basic block this
3222 late in the compilation, generate the loop as a single insn. */
3223 emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3225 if (leftover > 4096 && sa_size == 0)
3227 rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3228 MEM_VOLATILE_P (last) = 1;
3229 emit_move_insn (last, const0_rtx);
3232 emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
3235 /* Cope with very large offsets to the register save area. */
3236 sa_reg = stack_pointer_rtx;
3237 if (reg_offset + sa_size > 0x8000)
3239 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3242 if (low + sa_size <= 0x8000)
3243 bias = reg_offset - low, reg_offset = low;
3245 bias = reg_offset, reg_offset = 0;
3247 sa_reg = gen_rtx_REG (DImode, 24);
3248 emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias));
3251 /* Save regs in stack order. Beginning with VMS PV. */
3252 if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3254 emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx),
3255 gen_rtx_REG (DImode, REG_PV));
3258 /* Save register RA next. */
3259 if (imask & (1L << REG_RA))
3261 emit_move_insn (gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)),
3262 gen_rtx_REG (DImode, REG_RA));
3263 imask &= ~(1L << REG_RA);
3267 /* Now save any other registers required to be saved. */
3268 for (i = 0; i < 32; i++)
3269 if (imask & (1L << i))
3271 emit_move_insn (gen_rtx_MEM (DImode,
3272 plus_constant (sa_reg, reg_offset)),
3273 gen_rtx_REG (DImode, i));
3277 for (i = 0; i < 32; i++)
3278 if (fmask & (1L << i))
3280 emit_move_insn (gen_rtx_MEM (DFmode,
3281 plus_constant (sa_reg, reg_offset)),
3282 gen_rtx_REG (DFmode, i+32));
3286 if (TARGET_OPEN_VMS)
3288 if (!vms_is_stack_procedure)
3290 /* Register frame procedures fave the fp. */
3291 emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3292 hard_frame_pointer_rtx);
3295 if (vms_base_regno != REG_PV)
3296 emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3297 gen_rtx_REG (DImode, REG_PV));
3299 if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3301 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
3304 /* If we have to allocate space for outgoing args, do it now. */
3305 if (current_function_outgoing_args_size != 0)
3307 emit_move_insn (stack_pointer_rtx,
3308 plus_constant (hard_frame_pointer_rtx,
3309 - ALPHA_ROUND (current_function_outgoing_args_size)));
3314 /* If we need a frame pointer, set it from the stack pointer. */
3315 if (frame_pointer_needed)
3317 if (TARGET_CAN_FAULT_IN_PROLOGUE)
3318 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
3321 /* This must always be the last instruction in the
3322 prologue, thus we emit a special move + clobber. */
3323 emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3324 stack_pointer_rtx, sa_reg));
3329 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3330 the prologue, for exception handling reasons, we cannot do this for
3331 any insn that might fault. We could prevent this for mems with a
3332 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3333 have to prevent all such scheduling with a blockage.
3335 Linux, on the other hand, never bothered to implement OSF/1's
3336 exception handling, and so doesn't care about such things. Anyone
3337 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3339 if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3340 emit_insn (gen_blockage ());
3343 /* Output the textual info surrounding the prologue. */
3346 alpha_start_function (file, fnname, decl)
3351 unsigned long imask = 0;
3352 unsigned long fmask = 0;
3353 /* Stack space needed for pushing registers clobbered by us. */
3354 HOST_WIDE_INT sa_size;
3355 /* Complete stack size needed. */
3356 HOST_WIDE_INT frame_size;
3357 /* Offset from base reg to register save area. */
3358 HOST_WIDE_INT reg_offset;
3359 char *entry_label = (char *) alloca (strlen (fnname) + 6);
3362 sa_size = alpha_sa_size ();
3364 frame_size = get_frame_size ();
3365 if (TARGET_OPEN_VMS)
3366 frame_size = ALPHA_ROUND (sa_size
3367 + (vms_is_stack_procedure ? 8 : 0)
3369 + current_function_pretend_args_size);
3371 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3373 + ALPHA_ROUND (frame_size
3374 + current_function_pretend_args_size));
3376 if (TARGET_OPEN_VMS)
3379 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3381 alpha_sa_mask (&imask, &fmask);
3383 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3384 We have to do that before the .ent directive as we cannot switch
3385 files within procedures with native ecoff because line numbers are
3386 linked to procedure descriptors.
3387 Outputting the lineno helps debugging of one line functions as they
3388 would otherwise get no line number at all. Please note that we would
3389 like to put out last_linenum from final.c, but it is not accessible. */
3391 if (write_symbols == SDB_DEBUG)
3393 ASM_OUTPUT_SOURCE_FILENAME (file,
3394 DECL_SOURCE_FILE (current_function_decl));
3395 if (debug_info_level != DINFO_LEVEL_TERSE)
3396 ASM_OUTPUT_SOURCE_LINE (file,
3397 DECL_SOURCE_LINE (current_function_decl));
3400 /* Issue function start and label. */
3401 if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3403 fputs ("\t.ent ", file);
3404 assemble_name (file, fnname);
3408 strcpy (entry_label, fnname);
3409 if (TARGET_OPEN_VMS)
3410 strcat (entry_label, "..en");
3411 ASM_OUTPUT_LABEL (file, entry_label);
3412 inside_function = TRUE;
3414 if (TARGET_OPEN_VMS)
3415 fprintf (file, "\t.base $%d\n", vms_base_regno);
3417 if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3418 && !flag_inhibit_size_directive)
3420 /* Set flags in procedure descriptor to request IEEE-conformant
3421 math-library routines. The value we set it to is PDSC_EXC_IEEE
3422 (/usr/include/pdsc.h). */
3423 fputs ("\t.eflag 48\n", file);
3426 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3427 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3428 alpha_arg_offset = -frame_size + 48;
3430 /* Describe our frame. If the frame size is larger than an integer,
3431 print it as zero to avoid an assembler error. We won't be
3432 properly describing such a frame, but that's the best we can do. */
3433 if (TARGET_OPEN_VMS)
3435 fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3436 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3437 frame_size >= (1l << 31) ? 0 : frame_size);
3438 fprintf (file, ",$26,%d\n", reg_offset);
3440 else if (!flag_inhibit_size_directive)
3442 fprintf (file, "\t.frame $%d,",
3443 (frame_pointer_needed
3444 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3445 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3446 frame_size >= (1l << 31) ? 0 : frame_size);
3447 fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3450 /* Describe which registers were spilled. */
3451 if (TARGET_OPEN_VMS)
3454 /* ??? Does VMS care if mask contains ra? The old code did'nt
3455 set it, so I don't here. */
3456 fprintf (file, "\t.mask 0x%x,0\n", imask & ~(1L << REG_RA));
3458 fprintf (file, "\t.fmask 0x%x,0\n", fmask);
3459 if (!vms_is_stack_procedure)
3460 fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3462 else if (!flag_inhibit_size_directive)
3466 fprintf (file, "\t.mask 0x%x,", imask);
3467 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3468 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3471 for (i = 0; i < 32; ++i)
3472 if (imask & (1L << i))
3478 fprintf (file, "\t.fmask 0x%x,", fmask);
3479 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3480 frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3485 /* Emit GP related things. It is rather unfortunate about the alignment
3486 issues surrounding a CODE_LABEL that forces us to do the label in
3488 if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3493 alpha_function_needs_gp = alpha_does_function_need_gp ();
3494 if (alpha_function_needs_gp)
3495 fputs ("\tldgp $29,0($27)\n", file);
3498 assemble_name (file, fnname);
3499 fputs ("..ng:\n", file);
3503 /* Ifdef'ed cause readonly_section and link_section are only
3505 readonly_section ();
3506 fprintf (file, "\t.align 3\n");
3507 assemble_name (file, fnname); fputs ("..na:\n", file);
3508 fputs ("\t.ascii \"", file);
3509 assemble_name (file, fnname);
3510 fputs ("\\0\"\n", file);
3513 fprintf (file, "\t.align 3\n");
3514 fputs ("\t.name ", file);
3515 assemble_name (file, fnname);
3516 fputs ("..na\n", file);
3517 ASM_OUTPUT_LABEL (file, fnname);
3518 fprintf (file, "\t.pdesc ");
3519 assemble_name (file, fnname);
3520 fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3521 alpha_need_linkage (fnname, 1);
3526 /* Emit the .prologue note at the scheduled end of the prologue. */
3529 output_end_prologue (file)
3532 if (TARGET_OPEN_VMS)
3533 fputs ("\t.prologue\n", file);
3534 else if (TARGET_WINDOWS_NT)
3535 fputs ("\t.prologue 0\n", file);
3536 else if (!flag_inhibit_size_directive)
3537 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3540 /* Write function epilogue. */
3543 alpha_expand_epilogue ()
3545 /* Registers to save. */
3546 unsigned long imask = 0;
3547 unsigned long fmask = 0;
3548 /* Stack space needed for pushing registers clobbered by us. */
3549 HOST_WIDE_INT sa_size;
3550 /* Complete stack size needed. */
3551 HOST_WIDE_INT frame_size;
3552 /* Offset from base reg to register save area. */
3553 HOST_WIDE_INT reg_offset;
3554 int fp_is_frame_pointer, fp_offset;
3555 rtx sa_reg, sa_reg_exp = NULL;
3556 rtx sp_adj1, sp_adj2;
3559 sa_size = alpha_sa_size ();
3561 frame_size = get_frame_size ();
3562 if (TARGET_OPEN_VMS)
3563 frame_size = ALPHA_ROUND (sa_size
3564 + (vms_is_stack_procedure ? 8 : 0)
3566 + current_function_pretend_args_size);
3568 frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3570 + ALPHA_ROUND (frame_size
3571 + current_function_pretend_args_size));
3573 if (TARGET_OPEN_VMS)
3576 reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3578 alpha_sa_mask (&imask, &fmask);
3580 fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3581 || (!TARGET_OPEN_VMS && frame_pointer_needed));
3585 /* If we have a frame pointer, restore SP from it. */
3586 if ((TARGET_OPEN_VMS
3587 && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3588 || (!TARGET_OPEN_VMS && frame_pointer_needed))
3590 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
3593 /* Cope with very large offsets to the register save area. */
3594 sa_reg = stack_pointer_rtx;
3595 if (reg_offset + sa_size > 0x8000)
3597 int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3600 if (low + sa_size <= 0x8000)
3601 bias = reg_offset - low, reg_offset = low;
3603 bias = reg_offset, reg_offset = 0;
3605 sa_reg = gen_rtx_REG (DImode, 22);
3606 sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3608 emit_move_insn (sa_reg, sa_reg_exp);
3611 /* Restore registers in order, excepting a true frame pointer. */
3613 emit_move_insn (gen_rtx_REG (DImode, REG_RA),
3614 gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)));
3616 imask &= ~(1L << REG_RA);
3618 for (i = 0; i < 32; ++i)
3619 if (imask & (1L << i))
3621 if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3622 fp_offset = reg_offset;
3625 emit_move_insn (gen_rtx_REG (DImode, i),
3626 gen_rtx_MEM (DImode,
3627 plus_constant(sa_reg,
3633 for (i = 0; i < 32; ++i)
3634 if (fmask & (1L << i))
3636 emit_move_insn (gen_rtx_REG (DFmode, i+32),
3637 gen_rtx_MEM (DFmode,
3638 plus_constant(sa_reg, reg_offset)));
3645 /* If the stack size is large, begin computation into a temporary
3646 register so as not to interfere with a potential fp restore,
3647 which must be consecutive with an SP restore. */
3648 if (frame_size < 32768)
3650 sp_adj1 = stack_pointer_rtx;
3651 sp_adj2 = GEN_INT (frame_size);
3653 else if (frame_size < 0x40007fffL)
3655 int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3657 sp_adj2 = plus_constant (stack_pointer_rtx, frame_size - low);
3658 if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3662 sp_adj1 = gen_rtx_REG (DImode, 23);
3663 emit_move_insn (sp_adj1, sp_adj2);
3665 sp_adj2 = GEN_INT (low);
3669 sp_adj2 = gen_rtx_REG (DImode, 23);
3670 sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3);
3673 /* We can't drop new things to memory this late, afaik,
3674 so build it up by pieces. */
3675 #if HOST_BITS_PER_WIDE_INT == 64
3676 sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size);
3683 sp_adj2 = stack_pointer_rtx;
3686 /* From now on, things must be in order. So emit blockages. */
3688 /* Restore the frame pointer. */
3689 if (fp_is_frame_pointer)
3691 emit_insn (gen_blockage ());
3692 emit_move_insn (hard_frame_pointer_rtx,
3693 gen_rtx_MEM (DImode,
3694 plus_constant(sa_reg, fp_offset)));
3696 else if (TARGET_OPEN_VMS)
3698 emit_insn (gen_blockage ());
3699 emit_move_insn (hard_frame_pointer_rtx,
3700 gen_rtx_REG (DImode, vms_save_fp_regno));
3703 /* Restore the stack pointer. */
3704 emit_insn (gen_blockage ());
3705 emit_move_insn (stack_pointer_rtx,
3706 gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
3710 if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
3712 emit_insn (gen_blockage ());
3713 emit_move_insn (hard_frame_pointer_rtx,
3714 gen_rtx_REG (DImode, vms_save_fp_regno));
3719 emit_jump_insn (gen_return_internal ());
3722 /* Output the rest of the textual info surrounding the epilogue. */
3725 alpha_end_function (file, fnname, decl)
3730 /* End the function. */
3731 if (!flag_inhibit_size_directive)
3733 fputs ("\t.end ", file);
3734 assemble_name (file, fnname);
3737 inside_function = FALSE;
3739 /* Show that we know this function if it is called again.
3741 Don't do this for global functions in object files destined for a
3742 shared library because the function may be overridden by the application
3744 ??? Is this just ELF? */
3746 if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3747 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3750 /* Debugging support. */
3754 /* Count the number of sdb related labels are generated (to find block
3755 start and end boundaries). */
3757 int sdb_label_count = 0;
3759 /* Next label # for each statement. */
3761 static int sym_lineno = 0;
3763 /* Count the number of .file directives, so that .loc is up to date. */
3765 static int num_source_filenames = 0;
3767 /* Name of the file containing the current function. */
3769 static char *current_function_file = "";
3771 /* Offsets to alpha virtual arg/local debugging pointers. */
3773 long alpha_arg_offset;
3774 long alpha_auto_offset;
3776 /* Emit a new filename to a stream. */
3779 alpha_output_filename (stream, name)
3783 static int first_time = TRUE;
3784 char ltext_label_name[100];
3789 ++num_source_filenames;
3790 current_function_file = name;
3791 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3792 output_quoted_string (stream, name);
3793 fprintf (stream, "\n");
3794 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3795 fprintf (stream, "\t#@stabs\n");
3798 else if (write_symbols == DBX_DEBUG)
3800 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3801 fprintf (stream, "%s ", ASM_STABS_OP);
3802 output_quoted_string (stream, name);
3803 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
3806 else if (name != current_function_file
3807 && strcmp (name, current_function_file) != 0)
3809 if (inside_function && ! TARGET_GAS)
3810 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3813 ++num_source_filenames;
3814 current_function_file = name;
3815 fprintf (stream, "\t.file\t%d ", num_source_filenames);
3818 output_quoted_string (stream, name);
3819 fprintf (stream, "\n");
3823 /* Emit a linenumber to a stream. */
3826 alpha_output_lineno (stream, line)
3830 if (write_symbols == DBX_DEBUG)
3832 /* mips-tfile doesn't understand .stabd directives. */
3834 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3835 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3838 fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3841 /* Structure to show the current status of registers and memory. */
3843 struct shadow_summary
3846 unsigned long i : 31; /* Mask of int regs */
3847 unsigned long fp : 31; /* Mask of fp regs */
3848 unsigned long mem : 1; /* mem == imem | fpmem */
3852 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
3853 static void alpha_handle_trap_shadows PROTO((rtx));
3855 /* Summary the effects of expression X on the machine. Update SUM, a pointer
3856 to the summary structure. SET is nonzero if the insn is setting the
3857 object, otherwise zero. */
3860 summarize_insn (x, sum, set)
3862 struct shadow_summary *sum;
3871 switch (GET_CODE (x))
3873 /* ??? Note that this case would be incorrect if the Alpha had a
3874 ZERO_EXTRACT in SET_DEST. */
3876 summarize_insn (SET_SRC (x), sum, 0);
3877 summarize_insn (SET_DEST (x), sum, 1);
3881 summarize_insn (XEXP (x, 0), sum, 1);
3885 summarize_insn (XEXP (x, 0), sum, 0);
3889 for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3890 summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3894 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3895 summarize_insn (XVECEXP (x, 0, i), sum, 0);
3899 summarize_insn (SUBREG_REG (x), sum, 0);
3904 int regno = REGNO (x);
3905 unsigned long mask = 1UL << (regno % 32);
3907 if (regno == 31 || regno == 63)
3913 sum->defd.i |= mask;
3915 sum->defd.fp |= mask;
3920 sum->used.i |= mask;
3922 sum->used.fp |= mask;
3933 /* Find the regs used in memory address computation: */
3934 summarize_insn (XEXP (x, 0), sum, 0);
3937 case CONST_INT: case CONST_DOUBLE:
3938 case SYMBOL_REF: case LABEL_REF: case CONST:
3941 /* Handle common unary and binary ops for efficiency. */
3942 case COMPARE: case PLUS: case MINUS: case MULT: case DIV:
3943 case MOD: case UDIV: case UMOD: case AND: case IOR:
3944 case XOR: case ASHIFT: case ROTATE: case ASHIFTRT: case LSHIFTRT:
3945 case ROTATERT: case SMIN: case SMAX: case UMIN: case UMAX:
3946 case NE: case EQ: case GE: case GT: case LE:
3947 case LT: case GEU: case GTU: case LEU: case LTU:
3948 summarize_insn (XEXP (x, 0), sum, 0);
3949 summarize_insn (XEXP (x, 1), sum, 0);
3952 case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
3953 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
3954 case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
3955 case SQRT: case FFS:
3956 summarize_insn (XEXP (x, 0), sum, 0);
3960 format_ptr = GET_RTX_FORMAT (GET_CODE (x));
3961 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3962 switch (format_ptr[i])
3965 summarize_insn (XEXP (x, i), sum, 0);
3969 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3970 summarize_insn (XVECEXP (x, i, j), sum, 0);
3982 /* Ensure a sufficient number of `trapb' insns are in the code when
3983 the user requests code with a trap precision of functions or
3986 In naive mode, when the user requests a trap-precision of
3987 "instruction", a trapb is needed after every instruction that may
3988 generate a trap. This ensures that the code is resumption safe but
3991 When optimizations are turned on, we delay issuing a trapb as long
3992 as possible. In this context, a trap shadow is the sequence of
3993 instructions that starts with a (potentially) trap generating
3994 instruction and extends to the next trapb or call_pal instruction
3995 (but GCC never generates call_pal by itself). We can delay (and
3996 therefore sometimes omit) a trapb subject to the following
3999 (a) On entry to the trap shadow, if any Alpha register or memory
4000 location contains a value that is used as an operand value by some
4001 instruction in the trap shadow (live on entry), then no instruction
4002 in the trap shadow may modify the register or memory location.
4004 (b) Within the trap shadow, the computation of the base register
4005 for a memory load or store instruction may not involve using the
4006 result of an instruction that might generate an UNPREDICTABLE
4009 (c) Within the trap shadow, no register may be used more than once
4010 as a destination register. (This is to make life easier for the
4013 (d) The trap shadow may not include any branch instructions. */
4016 alpha_handle_trap_shadows (insns)
4019 struct shadow_summary shadow;
4020 int trap_pending, exception_nesting;
4023 if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
4027 exception_nesting = 0;
4030 shadow.used.mem = 0;
4031 shadow.defd = shadow.used;
4033 for (i = insns; i ; i = NEXT_INSN (i))
4035 if (GET_CODE (i) == NOTE)
4037 switch (NOTE_LINE_NUMBER (i))
4039 case NOTE_INSN_EH_REGION_BEG:
4040 exception_nesting++;
4045 case NOTE_INSN_EH_REGION_END:
4046 exception_nesting--;
4051 case NOTE_INSN_EPILOGUE_BEG:
4052 if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4057 else if (trap_pending)
4059 if (alpha_tp == ALPHA_TP_FUNC)
4061 if (GET_CODE (i) == JUMP_INSN
4062 && GET_CODE (PATTERN (i)) == RETURN)
4065 else if (alpha_tp == ALPHA_TP_INSN)
4069 struct shadow_summary sum;
4074 sum.defd = sum.used;
4076 switch (GET_CODE (i))
4079 /* Annoyingly, get_attr_trap will abort on these. */
4080 if (GET_CODE (PATTERN (i)) == USE
4081 || GET_CODE (PATTERN (i)) == CLOBBER)
4084 summarize_insn (PATTERN (i), &sum, 0);
4086 if ((sum.defd.i & shadow.defd.i)
4087 || (sum.defd.fp & shadow.defd.fp))
4089 /* (c) would be violated */
4093 /* Combine shadow with summary of current insn: */
4094 shadow.used.i |= sum.used.i;
4095 shadow.used.fp |= sum.used.fp;
4096 shadow.used.mem |= sum.used.mem;
4097 shadow.defd.i |= sum.defd.i;
4098 shadow.defd.fp |= sum.defd.fp;
4099 shadow.defd.mem |= sum.defd.mem;
4101 if ((sum.defd.i & shadow.used.i)
4102 || (sum.defd.fp & shadow.used.fp)
4103 || (sum.defd.mem & shadow.used.mem))
4105 /* (a) would be violated (also takes care of (b)) */
4106 if (get_attr_trap (i) == TRAP_YES
4107 && ((sum.defd.i & sum.used.i)
4108 || (sum.defd.fp & sum.used.fp)))
4127 emit_insn_before (gen_trapb (), i);
4131 shadow.used.mem = 0;
4132 shadow.defd = shadow.used;
4137 if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4138 && GET_CODE (i) == INSN
4139 && GET_CODE (PATTERN (i)) != USE
4140 && GET_CODE (PATTERN (i)) != CLOBBER
4141 && get_attr_trap (i) == TRAP_YES)
4143 if (optimize && !trap_pending)
4144 summarize_insn (PATTERN (i), &shadow, 0);
4150 /* Machine dependant reorg pass. */
4156 alpha_handle_trap_shadows (insns);
4160 /* Check a floating-point value for validity for a particular machine mode. */
4162 static char * const float_strings[] =
4164 /* These are for FLOAT_VAX. */
4165 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4166 "-1.70141173319264430e+38",
4167 "2.93873587705571877e-39", /* 2^-128 */
4168 "-2.93873587705571877e-39",
4169 /* These are for the default broken IEEE mode, which traps
4170 on infinity or denormal numbers. */
4171 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4172 "-3.402823466385288598117e+38",
4173 "1.1754943508222875079687e-38", /* 2^-126 */
4174 "-1.1754943508222875079687e-38",
4177 static REAL_VALUE_TYPE float_values[8];
4178 static int inited_float_values = 0;
4181 check_float_value (mode, d, overflow)
4182 enum machine_mode mode;
4187 if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4190 if (inited_float_values == 0)
4193 for (i = 0; i < 8; i++)
4194 float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4196 inited_float_values = 1;
4202 REAL_VALUE_TYPE *fvptr;
4204 if (TARGET_FLOAT_VAX)
4205 fvptr = &float_values[0];
4207 fvptr = &float_values[4];
4209 bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4210 if (REAL_VALUES_LESS (fvptr[0], r))
4212 bcopy ((char *) &fvptr[0], (char *) d,
4213 sizeof (REAL_VALUE_TYPE));
4216 else if (REAL_VALUES_LESS (r, fvptr[1]))
4218 bcopy ((char *) &fvptr[1], (char *) d,
4219 sizeof (REAL_VALUE_TYPE));
4222 else if (REAL_VALUES_LESS (dconst0, r)
4223 && REAL_VALUES_LESS (r, fvptr[2]))
4225 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4228 else if (REAL_VALUES_LESS (r, dconst0)
4229 && REAL_VALUES_LESS (fvptr[3], r))
4231 bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4241 /* Return the VMS argument type corresponding to MODE. */
4244 alpha_arg_type (mode)
4245 enum machine_mode mode;
4250 return TARGET_FLOAT_VAX ? FF : FS;
4252 return TARGET_FLOAT_VAX ? FD : FT;
4258 /* Return an rtx for an integer representing the VMS Argument Information
4262 alpha_arg_info_reg_val (cum)
4263 CUMULATIVE_ARGS cum;
4265 unsigned HOST_WIDE_INT regval = cum.num_args;
4268 for (i = 0; i < 6; i++)
4269 regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4271 return GEN_INT (regval);
4274 /* Structure to collect function names for final output
4277 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4280 struct alpha_links {
4281 struct alpha_links *next;
4283 enum links_kind kind;
4286 static struct alpha_links *alpha_links_base = 0;
4288 /* Make (or fake) .linkage entry for function call.
4290 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
4293 alpha_need_linkage (name, is_local)
4298 struct alpha_links *lptr, *nptr;
4303 /* Is this name already defined ? */
4305 for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4306 if (strcmp (lptr->name, name) == 0)
4310 /* Defined here but external assumed. */
4311 if (lptr->kind == KIND_EXTERN)
4312 lptr->kind = KIND_LOCAL;
4316 /* Used here but unused assumed. */
4317 if (lptr->kind == KIND_UNUSED)
4318 lptr->kind = KIND_LOCAL;
4323 nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4324 nptr->next = alpha_links_base;
4325 nptr->name = xstrdup (name);
4327 /* Assume external if no definition. */
4328 nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4330 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
4331 get_identifier (name);
4333 alpha_links_base = nptr;
4340 alpha_write_linkage (stream)
4343 struct alpha_links *lptr, *nptr;
4345 readonly_section ();
4347 fprintf (stream, "\t.align 3\n");
4349 for (lptr = alpha_links_base; lptr; lptr = nptr)
4353 if (lptr->kind == KIND_UNUSED
4354 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4357 fprintf (stream, "$%s..lk:\n", lptr->name);
4358 if (lptr->kind == KIND_LOCAL)
4360 /* Local and used, build linkage pair. */
4361 fprintf (stream, "\t.quad %s..en\n", lptr->name);
4362 fprintf (stream, "\t.quad %s\n", lptr->name);
4365 /* External and used, request linkage pair. */
4366 fprintf (stream, "\t.linkage %s\n", lptr->name);
4373 alpha_need_linkage (name, is_local)
4379 #endif /* OPEN_VMS */