1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
33 #include "insn-attr.h"
45 extern char *version_string
;
46 extern int rtx_equal_function_value_matters
;
48 /* Specify which cpu to schedule for. */
50 enum processor_type alpha_cpu
;
51 static const 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 const char *alpha_cpu_string
; /* -mcpu= */
71 const char *alpha_tp_string
; /* -mtrap-precision=[p|s|i] */
72 const char *alpha_fprm_string
; /* -mfp-rounding-mode=[n|m|c|d] */
73 const char *alpha_fptm_string
; /* -mfp-trap-mode=[n|u|su|sui] */
74 const 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 /* Define the information needed to modify the epilogue for EH. */
84 rtx alpha_eh_epilogue_sp_ofs
;
86 /* Non-zero if inside of a function, because the Alpha asm can't
87 handle .files inside of functions. */
89 static int inside_function
= FALSE
;
91 /* If non-null, this rtx holds the return address for the function. */
93 static rtx alpha_return_addr_rtx
;
95 /* The number of cycles of latency we should assume on memory reads. */
97 int alpha_memory_latency
= 3;
99 /* Whether the function needs the GP. */
101 static int alpha_function_needs_gp
;
103 /* The alias set for prologue/epilogue register save/restore. */
105 static int alpha_sr_alias_set
;
107 /* Declarations of static functions. */
108 static void alpha_set_memflags_1
109 PROTO((rtx
, int, int, int));
110 static rtx alpha_emit_set_const_1
111 PROTO((rtx
, enum machine_mode
, HOST_WIDE_INT
, int));
112 static void alpha_expand_unaligned_load_words
113 PROTO((rtx
*out_regs
, rtx smem
, HOST_WIDE_INT words
, HOST_WIDE_INT ofs
));
114 static void alpha_expand_unaligned_store_words
115 PROTO((rtx
*out_regs
, rtx smem
, HOST_WIDE_INT words
, HOST_WIDE_INT ofs
));
116 static void alpha_sa_mask
117 PROTO((unsigned long *imaskP
, unsigned long *fmaskP
));
118 static int alpha_does_function_need_gp
122 /* Get the number of args of a function in one of two ways. */
124 #define NUM_ARGS current_function_args_info.num_args
126 #define NUM_ARGS current_function_args_info
132 /* Parse target option strings. */
137 alpha_tp
= ALPHA_TP_PROG
;
138 alpha_fprm
= ALPHA_FPRM_NORM
;
139 alpha_fptm
= ALPHA_FPTM_N
;
143 alpha_tp
= ALPHA_TP_INSN
;
144 alpha_fptm
= ALPHA_FPTM_SU
;
147 if (TARGET_IEEE_WITH_INEXACT
)
149 alpha_tp
= ALPHA_TP_INSN
;
150 alpha_fptm
= ALPHA_FPTM_SUI
;
155 if (! strcmp (alpha_tp_string
, "p"))
156 alpha_tp
= ALPHA_TP_PROG
;
157 else if (! strcmp (alpha_tp_string
, "f"))
158 alpha_tp
= ALPHA_TP_FUNC
;
159 else if (! strcmp (alpha_tp_string
, "i"))
160 alpha_tp
= ALPHA_TP_INSN
;
162 error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string
);
165 if (alpha_fprm_string
)
167 if (! strcmp (alpha_fprm_string
, "n"))
168 alpha_fprm
= ALPHA_FPRM_NORM
;
169 else if (! strcmp (alpha_fprm_string
, "m"))
170 alpha_fprm
= ALPHA_FPRM_MINF
;
171 else if (! strcmp (alpha_fprm_string
, "c"))
172 alpha_fprm
= ALPHA_FPRM_CHOP
;
173 else if (! strcmp (alpha_fprm_string
,"d"))
174 alpha_fprm
= ALPHA_FPRM_DYN
;
176 error ("bad value `%s' for -mfp-rounding-mode switch",
180 if (alpha_fptm_string
)
182 if (strcmp (alpha_fptm_string
, "n") == 0)
183 alpha_fptm
= ALPHA_FPTM_N
;
184 else if (strcmp (alpha_fptm_string
, "u") == 0)
185 alpha_fptm
= ALPHA_FPTM_U
;
186 else if (strcmp (alpha_fptm_string
, "su") == 0)
187 alpha_fptm
= ALPHA_FPTM_SU
;
188 else if (strcmp (alpha_fptm_string
, "sui") == 0)
189 alpha_fptm
= ALPHA_FPTM_SUI
;
191 error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string
);
195 = TARGET_CPU_DEFAULT
& MASK_CPU_EV6
? PROCESSOR_EV6
196 : (TARGET_CPU_DEFAULT
& MASK_CPU_EV5
? PROCESSOR_EV5
: PROCESSOR_EV4
);
198 if (alpha_cpu_string
)
200 if (! strcmp (alpha_cpu_string
, "ev4")
201 || ! strcmp (alpha_cpu_string
, "ev45")
202 || ! strcmp (alpha_cpu_string
, "21064"))
204 alpha_cpu
= PROCESSOR_EV4
;
205 target_flags
&= ~ (MASK_BWX
| MASK_MAX
| MASK_FIX
| MASK_CIX
);
207 else if (! strcmp (alpha_cpu_string
, "ev5")
208 || ! strcmp (alpha_cpu_string
, "21164"))
210 alpha_cpu
= PROCESSOR_EV5
;
211 target_flags
&= ~ (MASK_BWX
| MASK_MAX
| MASK_FIX
| MASK_CIX
);
213 else if (! strcmp (alpha_cpu_string
, "ev56")
214 || ! strcmp (alpha_cpu_string
, "21164a"))
216 alpha_cpu
= PROCESSOR_EV5
;
217 target_flags
|= MASK_BWX
;
218 target_flags
&= ~ (MASK_MAX
| MASK_FIX
| MASK_CIX
);
220 else if (! strcmp (alpha_cpu_string
, "pca56")
221 || ! strcmp (alpha_cpu_string
, "21164PC")
222 || ! strcmp (alpha_cpu_string
, "21164pc"))
224 alpha_cpu
= PROCESSOR_EV5
;
225 target_flags
|= MASK_BWX
| MASK_MAX
;
226 target_flags
&= ~ (MASK_FIX
| MASK_CIX
);
228 else if (! strcmp (alpha_cpu_string
, "ev6")
229 || ! strcmp (alpha_cpu_string
, "21264"))
231 alpha_cpu
= PROCESSOR_EV6
;
232 target_flags
|= MASK_BWX
| MASK_MAX
| MASK_FIX
;
233 target_flags
&= ~ (MASK_CIX
);
236 error ("bad value `%s' for -mcpu switch", alpha_cpu_string
);
239 /* Do some sanity checks on the above options. */
241 if ((alpha_fptm
== ALPHA_FPTM_SU
|| alpha_fptm
== ALPHA_FPTM_SUI
)
242 && alpha_tp
!= ALPHA_TP_INSN
&& alpha_cpu
!= PROCESSOR_EV6
)
244 warning ("fp software completion requires -mtrap-precision=i");
245 alpha_tp
= ALPHA_TP_INSN
;
248 if (alpha_cpu
== PROCESSOR_EV6
)
250 /* Except for EV6 pass 1 (not released), we always have precise
251 arithmetic traps. Which means we can do software completion
252 without minding trap shadows. */
253 alpha_tp
= ALPHA_TP_PROG
;
256 if (TARGET_FLOAT_VAX
)
258 if (alpha_fprm
== ALPHA_FPRM_MINF
|| alpha_fprm
== ALPHA_FPRM_DYN
)
260 warning ("rounding mode not supported for VAX floats");
261 alpha_fprm
= ALPHA_FPRM_NORM
;
263 if (alpha_fptm
== ALPHA_FPTM_SUI
)
265 warning ("trap mode not supported for VAX floats");
266 alpha_fptm
= ALPHA_FPTM_SU
;
274 if (!alpha_mlat_string
)
275 alpha_mlat_string
= "L1";
277 if (ISDIGIT ((unsigned char)alpha_mlat_string
[0])
278 && (lat
= strtol (alpha_mlat_string
, &end
, 10), *end
== '\0'))
280 else if ((alpha_mlat_string
[0] == 'L' || alpha_mlat_string
[0] == 'l')
281 && ISDIGIT ((unsigned char)alpha_mlat_string
[1])
282 && alpha_mlat_string
[2] == '\0')
284 static int const cache_latency
[][4] =
286 { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
287 { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
288 { 3, 13, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
291 lat
= alpha_mlat_string
[1] - '0';
292 if (lat
< 0 || lat
> 3 || cache_latency
[alpha_cpu
][lat
-1] == -1)
294 warning ("L%d cache latency unknown for %s",
295 lat
, alpha_cpu_name
[alpha_cpu
]);
299 lat
= cache_latency
[alpha_cpu
][lat
-1];
301 else if (! strcmp (alpha_mlat_string
, "main"))
303 /* Most current memories have about 370ns latency. This is
304 a reasonable guess for a fast cpu. */
309 warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string
);
313 alpha_memory_latency
= lat
;
316 /* Default the definition of "small data" to 8 bytes. */
320 /* Acquire a unique set number for our register saves and restores. */
321 alpha_sr_alias_set
= new_alias_set ();
324 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
332 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
334 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
340 /* Returns 1 if OP is either the constant zero or a register. If a
341 register, it must be in the proper mode unless MODE is VOIDmode. */
344 reg_or_0_operand (op
, mode
)
346 enum machine_mode mode
;
348 return op
== const0_rtx
|| register_operand (op
, mode
);
351 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
355 reg_or_6bit_operand (op
, mode
)
357 enum machine_mode mode
;
359 return ((GET_CODE (op
) == CONST_INT
360 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
361 || register_operand (op
, mode
));
365 /* Return 1 if OP is an 8-bit constant or any register. */
368 reg_or_8bit_operand (op
, mode
)
370 enum machine_mode mode
;
372 return ((GET_CODE (op
) == CONST_INT
373 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
374 || register_operand (op
, mode
));
377 /* Return 1 if OP is an 8-bit constant. */
380 cint8_operand (op
, mode
)
382 enum machine_mode mode ATTRIBUTE_UNUSED
;
384 return ((GET_CODE (op
) == CONST_INT
385 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100));
388 /* Return 1 if the operand is a valid second operand to an add insn. */
391 add_operand (op
, mode
)
393 enum machine_mode mode
;
395 if (GET_CODE (op
) == CONST_INT
)
396 /* Constraints I, J, O and P are covered by K. */
397 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'K')
398 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'L'));
400 return register_operand (op
, mode
);
403 /* Return 1 if the operand is a valid second operand to a sign-extending
407 sext_add_operand (op
, mode
)
409 enum machine_mode mode
;
411 if (GET_CODE (op
) == CONST_INT
)
412 return (CONST_OK_FOR_LETTER_P (INTVAL (op
), 'I')
413 || CONST_OK_FOR_LETTER_P (INTVAL (op
), 'O'));
415 return reg_not_elim_operand (op
, mode
);
418 /* Return 1 if OP is the constant 4 or 8. */
421 const48_operand (op
, mode
)
423 enum machine_mode mode ATTRIBUTE_UNUSED
;
425 return (GET_CODE (op
) == CONST_INT
426 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
429 /* Return 1 if OP is a valid first operand to an AND insn. */
432 and_operand (op
, mode
)
434 enum machine_mode mode
;
436 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
437 return (zap_mask (CONST_DOUBLE_LOW (op
))
438 && zap_mask (CONST_DOUBLE_HIGH (op
)));
440 if (GET_CODE (op
) == CONST_INT
)
441 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
442 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
443 || zap_mask (INTVAL (op
)));
445 return register_operand (op
, mode
);
448 /* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
451 or_operand (op
, mode
)
453 enum machine_mode mode
;
455 if (GET_CODE (op
) == CONST_INT
)
456 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
457 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
459 return register_operand (op
, mode
);
462 /* Return 1 if OP is a constant that is the width, in bits, of an integral
463 mode smaller than DImode. */
466 mode_width_operand (op
, mode
)
468 enum machine_mode mode ATTRIBUTE_UNUSED
;
470 return (GET_CODE (op
) == CONST_INT
471 && (INTVAL (op
) == 8 || INTVAL (op
) == 16
472 || INTVAL (op
) == 32 || INTVAL (op
) == 64));
475 /* Return 1 if OP is a constant that is the width of an integral machine mode
476 smaller than an integer. */
479 mode_mask_operand (op
, mode
)
481 enum machine_mode mode ATTRIBUTE_UNUSED
;
483 #if HOST_BITS_PER_WIDE_INT == 32
484 if (GET_CODE (op
) == CONST_DOUBLE
)
485 return (CONST_DOUBLE_LOW (op
) == -1
486 && (CONST_DOUBLE_HIGH (op
) == -1
487 || CONST_DOUBLE_HIGH (op
) == 0));
489 if (GET_CODE (op
) == CONST_DOUBLE
)
490 return (CONST_DOUBLE_LOW (op
) == -1 && CONST_DOUBLE_HIGH (op
) == 0);
493 return (GET_CODE (op
) == CONST_INT
494 && (INTVAL (op
) == 0xff
495 || INTVAL (op
) == 0xffff
496 || INTVAL (op
) == (HOST_WIDE_INT
)0xffffffff
497 #if HOST_BITS_PER_WIDE_INT == 64
503 /* Return 1 if OP is a multiple of 8 less than 64. */
506 mul8_operand (op
, mode
)
508 enum machine_mode mode ATTRIBUTE_UNUSED
;
510 return (GET_CODE (op
) == CONST_INT
511 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
512 && (INTVAL (op
) & 7) == 0);
515 /* Return 1 if OP is the constant zero in floating-point. */
518 fp0_operand (op
, mode
)
520 enum machine_mode mode
;
522 return (GET_MODE (op
) == mode
523 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
526 /* Return 1 if OP is the floating-point constant zero or a register. */
529 reg_or_fp0_operand (op
, mode
)
531 enum machine_mode mode
;
533 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
536 /* Return 1 if OP is a hard floating-point register. */
539 hard_fp_register_operand (op
, mode
)
541 enum machine_mode mode
;
543 return ((GET_CODE (op
) == REG
&& REGNO_REG_CLASS (REGNO (op
)) == FLOAT_REGS
)
544 || (GET_CODE (op
) == SUBREG
545 && hard_fp_register_operand (SUBREG_REG (op
), mode
)));
548 /* Return 1 if OP is a register or a constant integer. */
552 reg_or_cint_operand (op
, mode
)
554 enum machine_mode mode
;
556 return (GET_CODE (op
) == CONST_INT
557 || register_operand (op
, mode
));
560 /* Return 1 if OP is something that can be reloaded into a register;
561 if it is a MEM, it need not be valid. */
564 some_operand (op
, mode
)
566 enum machine_mode mode
;
568 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
571 switch (GET_CODE (op
))
573 case REG
: case MEM
: case CONST_DOUBLE
: case CONST_INT
: case LABEL_REF
:
574 case SYMBOL_REF
: case CONST
:
578 return some_operand (SUBREG_REG (op
), VOIDmode
);
587 /* Return 1 if OP is a valid operand for the source of a move insn. */
590 input_operand (op
, mode
)
592 enum machine_mode mode
;
594 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
597 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
600 switch (GET_CODE (op
))
605 /* This handles both the Windows/NT and OSF cases. */
606 return mode
== ptr_mode
|| mode
== DImode
;
612 if (register_operand (op
, mode
))
614 /* ... fall through ... */
616 return ((TARGET_BWX
|| (mode
!= HImode
&& mode
!= QImode
))
617 && general_operand (op
, mode
));
620 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
623 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
635 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
639 current_file_function_operand (op
, mode
)
641 enum machine_mode mode ATTRIBUTE_UNUSED
;
643 return (GET_CODE (op
) == SYMBOL_REF
644 && ! profile_flag
&& ! profile_block_flag
645 && (SYMBOL_REF_FLAG (op
)
646 || op
== XEXP (DECL_RTL (current_function_decl
), 0)));
649 /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
652 call_operand (op
, mode
)
654 enum machine_mode mode
;
659 return (GET_CODE (op
) == SYMBOL_REF
660 || (GET_CODE (op
) == REG
661 && (TARGET_OPEN_VMS
|| TARGET_WINDOWS_NT
|| REGNO (op
) == 27)));
664 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
665 comparisons are valid in which insn. */
668 alpha_comparison_operator (op
, mode
)
670 enum machine_mode mode
;
672 enum rtx_code code
= GET_CODE (op
);
674 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
677 return (code
== EQ
|| code
== LE
|| code
== LT
678 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
681 /* Return 1 if OP is a valid Alpha swapped comparison operator. */
684 alpha_swapped_comparison_operator (op
, mode
)
686 enum machine_mode mode
;
688 enum rtx_code code
= GET_CODE (op
);
690 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
693 code
= swap_condition (code
);
694 return (code
== EQ
|| code
== LE
|| code
== LT
695 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
698 /* Return 1 if OP is a signed comparison operation. */
701 signed_comparison_operator (op
, mode
)
703 enum machine_mode mode ATTRIBUTE_UNUSED
;
705 switch (GET_CODE (op
))
707 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
717 /* Return 1 if this is a divide or modulus operator. */
720 divmod_operator (op
, mode
)
722 enum machine_mode mode ATTRIBUTE_UNUSED
;
724 switch (GET_CODE (op
))
726 case DIV
: case MOD
: case UDIV
: case UMOD
:
736 /* Return 1 if this memory address is a known aligned register plus
737 a constant. It must be a valid address. This means that we can do
738 this as an aligned reference plus some offset.
740 Take into account what reload will do. */
743 aligned_memory_operand (op
, mode
)
745 enum machine_mode mode
;
749 if (reload_in_progress
)
752 if (GET_CODE (tmp
) == SUBREG
)
753 tmp
= SUBREG_REG (tmp
);
754 if (GET_CODE (tmp
) == REG
755 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
757 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
763 if (GET_CODE (op
) != MEM
764 || GET_MODE (op
) != mode
)
768 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
769 sorts of constructs. Dig for the real base register. */
770 if (reload_in_progress
771 && GET_CODE (op
) == PLUS
772 && GET_CODE (XEXP (op
, 0)) == PLUS
)
773 base
= XEXP (XEXP (op
, 0), 0);
776 if (! memory_address_p (mode
, op
))
778 base
= (GET_CODE (op
) == PLUS
? XEXP (op
, 0) : op
);
781 return (GET_CODE (base
) == REG
782 && REGNO_POINTER_ALIGN (REGNO (base
)) >= 4);
785 /* Similar, but return 1 if OP is a MEM which is not alignable. */
788 unaligned_memory_operand (op
, mode
)
790 enum machine_mode mode
;
794 if (reload_in_progress
)
797 if (GET_CODE (tmp
) == SUBREG
)
798 tmp
= SUBREG_REG (tmp
);
799 if (GET_CODE (tmp
) == REG
800 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
802 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
808 if (GET_CODE (op
) != MEM
809 || GET_MODE (op
) != mode
)
813 /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
814 sorts of constructs. Dig for the real base register. */
815 if (reload_in_progress
816 && GET_CODE (op
) == PLUS
817 && GET_CODE (XEXP (op
, 0)) == PLUS
)
818 base
= XEXP (XEXP (op
, 0), 0);
821 if (! memory_address_p (mode
, op
))
823 base
= (GET_CODE (op
) == PLUS
? XEXP (op
, 0) : op
);
826 return (GET_CODE (base
) == REG
827 && REGNO_POINTER_ALIGN (REGNO (base
)) < 4);
830 /* Return 1 if OP is either a register or an unaligned memory location. */
833 reg_or_unaligned_mem_operand (op
, mode
)
835 enum machine_mode mode
;
837 return register_operand (op
, mode
) || unaligned_memory_operand (op
, mode
);
840 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
843 any_memory_operand (op
, mode
)
845 enum machine_mode mode ATTRIBUTE_UNUSED
;
847 return (GET_CODE (op
) == MEM
848 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
849 || (reload_in_progress
&& GET_CODE (op
) == REG
850 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
851 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
852 && GET_CODE (SUBREG_REG (op
)) == REG
853 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
856 /* Returns 1 if OP is not an eliminable register.
858 This exists to cure a pathological abort in the s8addq (et al) patterns,
860 long foo () { long t; bar(); return (long) &t * 26107; }
862 which run afoul of a hack in reload to cure a (presumably) similar
863 problem with lea-type instructions on other targets. But there is
864 one of us and many of them, so work around the problem by selectively
865 preventing combine from making the optimization. */
868 reg_not_elim_operand (op
, mode
)
870 enum machine_mode mode
;
873 if (GET_CODE (op
) == SUBREG
)
874 inner
= SUBREG_REG (op
);
875 if (inner
== frame_pointer_rtx
|| inner
== arg_pointer_rtx
)
878 return register_operand (op
, mode
);
881 /* Return 1 is OP is a memory location that is not a reference (using
882 an AND) to an unaligned location. Take into account what reload
886 normal_memory_operand (op
, mode
)
888 enum machine_mode mode ATTRIBUTE_UNUSED
;
890 if (reload_in_progress
)
893 if (GET_CODE (tmp
) == SUBREG
)
894 tmp
= SUBREG_REG (tmp
);
895 if (GET_CODE (tmp
) == REG
896 && REGNO (tmp
) >= FIRST_PSEUDO_REGISTER
)
898 op
= reg_equiv_memory_loc
[REGNO (tmp
)];
900 /* This may not have been assigned an equivalent address if it will
901 be eliminated. In that case, it doesn't matter what we do. */
907 return GET_CODE (op
) == MEM
&& GET_CODE (XEXP (op
, 0)) != AND
;
910 /* Accept a register, but not a subreg of any kind. This allows us to
911 avoid pathological cases in reload wrt data movement common in
912 int->fp conversion. */
915 reg_no_subreg_operand (op
, mode
)
917 enum machine_mode mode
;
919 if (GET_CODE (op
) == SUBREG
)
921 return register_operand (op
, mode
);
924 /* Return 1 if this function can directly return via $26. */
929 return (! TARGET_OPEN_VMS
&& reload_completed
&& alpha_sa_size () == 0
930 && get_frame_size () == 0
931 && current_function_outgoing_args_size
== 0
932 && current_function_pretend_args_size
== 0);
935 /* REF is an alignable memory location. Place an aligned SImode
936 reference into *PALIGNED_MEM and the number of bits to shift into
937 *PBITNUM. SCRATCH is a free register for use in reloading out
938 of range stack slots. */
941 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
943 rtx
*paligned_mem
, *pbitnum
;
946 HOST_WIDE_INT offset
= 0;
948 if (GET_CODE (ref
) != MEM
)
951 if (reload_in_progress
952 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
954 base
= find_replacement (&XEXP (ref
, 0));
956 if (! memory_address_p (GET_MODE (ref
), base
))
961 base
= XEXP (ref
, 0);
964 if (GET_CODE (base
) == PLUS
)
965 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
967 *paligned_mem
= gen_rtx_MEM (SImode
, plus_constant (base
, offset
& ~3));
968 MEM_COPY_ATTRIBUTES (*paligned_mem
, ref
);
969 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
971 /* Sadly, we cannot use alias sets here because we may overlap other
972 data in a different alias set. */
973 /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
975 *pbitnum
= GEN_INT ((offset
& 3) * 8);
978 /* Similar, but just get the address. Handle the two reload cases.
979 Add EXTRA_OFFSET to the address we return. */
982 get_unaligned_address (ref
, extra_offset
)
987 HOST_WIDE_INT offset
= 0;
989 if (GET_CODE (ref
) != MEM
)
992 if (reload_in_progress
993 && ! memory_address_p (GET_MODE (ref
), XEXP (ref
, 0)))
995 base
= find_replacement (&XEXP (ref
, 0));
997 if (! memory_address_p (GET_MODE (ref
), base
))
1002 base
= XEXP (ref
, 0);
1005 if (GET_CODE (base
) == PLUS
)
1006 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
1008 return plus_constant (base
, offset
+ extra_offset
);
1011 /* Subfunction of the following function. Update the flags of any MEM
1012 found in part of X. */
1015 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
1017 int in_struct_p
, volatile_p
, unchanging_p
;
1021 switch (GET_CODE (x
))
1025 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
1026 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
1031 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
1036 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
1038 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
1043 MEM_IN_STRUCT_P (x
) = in_struct_p
;
1044 MEM_VOLATILE_P (x
) = volatile_p
;
1045 RTX_UNCHANGING_P (x
) = unchanging_p
;
1046 /* Sadly, we cannot use alias sets because the extra aliasing
1047 produced by the AND interferes. Given that two-byte quantities
1048 are the only thing we would be able to differentiate anyway,
1049 there does not seem to be any point in convoluting the early
1050 out of the alias check. */
1051 /* MEM_ALIAS_SET (x) = alias_set; */
1059 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1060 perform a memory operation, look for any MEMs in either a SET_DEST or
1061 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1062 REF into each of the MEMs found. If REF is not a MEM, don't do
1066 alpha_set_memflags (insn
, ref
)
1070 int in_struct_p
, volatile_p
, unchanging_p
;
1072 if (GET_CODE (ref
) != MEM
)
1075 in_struct_p
= MEM_IN_STRUCT_P (ref
);
1076 volatile_p
= MEM_VOLATILE_P (ref
);
1077 unchanging_p
= RTX_UNCHANGING_P (ref
);
1079 /* This is only called from alpha.md, after having had something
1080 generated from one of the insn patterns. So if everything is
1081 zero, the pattern is already up-to-date. */
1082 if (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
)
1085 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
1088 /* Try to output insns to set TARGET equal to the constant C if it can be
1089 done in less than N insns. Do all computations in MODE. Returns the place
1090 where the output has been placed if it can be done and the insns have been
1091 emitted. If it would take more than N insns, zero is returned and no
1092 insns and emitted. */
1095 alpha_emit_set_const (target
, mode
, c
, n
)
1097 enum machine_mode mode
;
1104 /* Try 1 insn, then 2, then up to N. */
1105 for (i
= 1; i
<= n
; i
++)
1106 if ((pat
= alpha_emit_set_const_1 (target
, mode
, c
, i
)) != 0)
1112 /* Internal routine for the above to check for N or below insns. */
1115 alpha_emit_set_const_1 (target
, mode
, c
, n
)
1117 enum machine_mode mode
;
1121 HOST_WIDE_INT
new = c
;
1123 /* Use a pseudo if highly optimizing and still generating RTL. */
1125 = (flag_expensive_optimizations
&& rtx_equal_function_value_matters
1129 #if HOST_BITS_PER_WIDE_INT == 64
1130 /* We are only called for SImode and DImode. If this is SImode, ensure that
1131 we are sign extended to a full word. This does not make any sense when
1132 cross-compiling on a narrow machine. */
1135 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
1138 /* If this is a sign-extended 32-bit constant, we can do this in at most
1139 three insns, so do it if we have enough insns left. We always have
1140 a sign-extended 32-bit constant when compiling on a narrow machine. */
1142 if (HOST_BITS_PER_WIDE_INT
!= 64
1143 || c
>> 31 == -1 || c
>> 31 == 0)
1145 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
1146 HOST_WIDE_INT tmp1
= c
- low
;
1148 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1149 HOST_WIDE_INT extra
= 0;
1151 /* If HIGH will be interpreted as negative but the constant is
1152 positive, we must adjust it to do two ldha insns. */
1154 if ((high
& 0x8000) != 0 && c
>= 0)
1158 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1161 if (c
== low
|| (low
== 0 && extra
== 0))
1163 /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1164 but that meant that we can't handle INT_MIN on 32-bit machines
1165 (like NT/Alpha), because we recurse indefinitely through
1166 emit_move_insn to gen_movdi. So instead, since we know exactly
1167 what we want, create it explicitly. */
1170 target
= gen_reg_rtx (mode
);
1171 emit_insn (gen_rtx_SET (VOIDmode
, target
, GEN_INT (c
)));
1174 else if (n
>= 2 + (extra
!= 0))
1176 temp
= copy_to_suggested_reg (GEN_INT (low
), subtarget
, mode
);
1179 temp
= expand_binop (mode
, add_optab
, temp
, GEN_INT (extra
<< 16),
1180 subtarget
, 0, OPTAB_WIDEN
);
1182 return expand_binop (mode
, add_optab
, temp
, GEN_INT (high
<< 16),
1183 target
, 0, OPTAB_WIDEN
);
1187 /* If we couldn't do it that way, try some other methods. But if we have
1188 no instructions left, don't bother. Likewise, if this is SImode and
1189 we can't make pseudos, we can't do anything since the expand_binop
1190 and expand_unop calls will widen and try to make pseudos. */
1193 || (mode
== SImode
&& ! rtx_equal_function_value_matters
))
1196 #if HOST_BITS_PER_WIDE_INT == 64
1197 /* First, see if can load a value into the target that is the same as the
1198 constant except that all bytes that are 0 are changed to be 0xff. If we
1199 can, then we can do a ZAPNOT to obtain the desired constant. */
1201 for (i
= 0; i
< 64; i
+= 8)
1202 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
1203 new |= (HOST_WIDE_INT
) 0xff << i
;
1205 /* We are only called for SImode and DImode. If this is SImode, ensure that
1206 we are sign extended to a full word. */
1209 new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1212 && (temp
= alpha_emit_set_const (subtarget
, mode
, new, n
- 1)) != 0)
1213 return expand_binop (mode
, and_optab
, temp
, GEN_INT (c
| ~ new),
1214 target
, 0, OPTAB_WIDEN
);
1217 /* Next, see if we can load a related constant and then shift and possibly
1218 negate it to get the constant we want. Try this once each increasing
1219 numbers of insns. */
1221 for (i
= 1; i
< n
; i
++)
1223 /* First try complementing. */
1224 if ((temp
= alpha_emit_set_const (subtarget
, mode
, ~ c
, i
)) != 0)
1225 return expand_unop (mode
, one_cmpl_optab
, temp
, target
, 0);
1227 /* Next try to form a constant and do a left shift. We can do this
1228 if some low-order bits are zero; the exact_log2 call below tells
1229 us that information. The bits we are shifting out could be any
1230 value, but here we'll just try the 0- and sign-extended forms of
1231 the constant. To try to increase the chance of having the same
1232 constant in more than one insn, start at the highest number of
1233 bits to shift, but try all possibilities in case a ZAPNOT will
1236 if ((bits
= exact_log2 (c
& - c
)) > 0)
1237 for (; bits
> 0; bits
--)
1238 if ((temp
= (alpha_emit_set_const
1240 (unsigned HOST_WIDE_INT
) (c
>> bits
), i
))) != 0
1241 || ((temp
= (alpha_emit_set_const
1243 ((unsigned HOST_WIDE_INT
) c
) >> bits
, i
)))
1245 return expand_binop (mode
, ashl_optab
, temp
, GEN_INT (bits
),
1246 target
, 0, OPTAB_WIDEN
);
1248 /* Now try high-order zero bits. Here we try the shifted-in bits as
1249 all zero and all ones. Be careful to avoid shifting outside the
1250 mode and to avoid shifting outside the host wide int size. */
1251 /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1252 confuse the recursive call and set all of the high 32 bits. */
1254 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1255 - floor_log2 (c
) - 1 - (HOST_BITS_PER_WIDE_INT
< 64))) > 0)
1256 for (; bits
> 0; bits
--)
1257 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1259 || ((temp
= (alpha_emit_set_const
1261 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1264 return expand_binop (mode
, lshr_optab
, temp
, GEN_INT (bits
),
1265 target
, 1, OPTAB_WIDEN
);
1267 /* Now try high-order 1 bits. We get that with a sign-extension.
1268 But one bit isn't enough here. Be careful to avoid shifting outside
1269 the mode and to avoid shifting outside the host wide int size. */
1271 if ((bits
= (MIN (HOST_BITS_PER_WIDE_INT
, GET_MODE_SIZE (mode
) * 8)
1272 - floor_log2 (~ c
) - 2)) > 0)
1273 for (; bits
> 0; bits
--)
1274 if ((temp
= alpha_emit_set_const (subtarget
, mode
,
1276 || ((temp
= (alpha_emit_set_const
1278 ((c
<< bits
) | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
1281 return expand_binop (mode
, ashr_optab
, temp
, GEN_INT (bits
),
1282 target
, 0, OPTAB_WIDEN
);
1288 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1289 fall back to a straight forward decomposition. We do this to avoid
1290 exponential run times encountered when looking for longer sequences
1291 with alpha_emit_set_const. */
1294 alpha_emit_set_long_const (target
, c1
, c2
)
1296 HOST_WIDE_INT c1
, c2
;
1298 HOST_WIDE_INT d1
, d2
, d3
, d4
;
1300 /* Decompose the entire word */
1301 #if HOST_BITS_PER_WIDE_INT >= 64
1302 if (c2
!= -(c1
< 0))
1304 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1306 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1307 c1
= (c1
- d2
) >> 32;
1308 d3
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1310 d4
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1314 d1
= ((c1
& 0xffff) ^ 0x8000) - 0x8000;
1316 d2
= ((c1
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1320 d3
= ((c2
& 0xffff) ^ 0x8000) - 0x8000;
1322 d4
= ((c2
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1327 /* Construct the high word */
1330 emit_move_insn (target
, GEN_INT (d4
));
1332 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d3
)));
1335 emit_move_insn (target
, GEN_INT (d3
));
1337 /* Shift it into place */
1338 emit_move_insn (target
, gen_rtx_ASHIFT (DImode
, target
, GEN_INT (32)));
1340 /* Add in the low bits. */
1342 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d2
)));
1344 emit_move_insn (target
, gen_rtx_PLUS (DImode
, target
, GEN_INT (d1
)));
1349 /* Generate the comparison for a conditional branch. */
1352 alpha_emit_conditional_branch (code
)
1355 enum rtx_code cmp_code
, branch_code
;
1356 enum machine_mode cmp_mode
, branch_mode
= VOIDmode
;
1357 rtx op0
= alpha_compare_op0
, op1
= alpha_compare_op1
;
1360 /* The general case: fold the comparison code to the types of compares
1361 that we have, choosing the branch as necessary. */
1364 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
1365 /* We have these compares: */
1366 cmp_code
= code
, branch_code
= NE
;
1370 /* This must be reversed. */
1371 cmp_code
= EQ
, branch_code
= EQ
;
1374 case GE
: case GT
: case GEU
: case GTU
:
1375 /* For FP, we swap them, for INT, we reverse them. */
1376 if (alpha_compare_fp_p
)
1378 cmp_code
= swap_condition (code
);
1380 tem
= op0
, op0
= op1
, op1
= tem
;
1384 cmp_code
= reverse_condition (code
);
1393 if (alpha_compare_fp_p
)
1398 /* When we are not as concerned about non-finite values, and we
1399 are comparing against zero, we can branch directly. */
1400 if (op1
== CONST0_RTX (DFmode
))
1401 cmp_code
= NIL
, branch_code
= code
;
1402 else if (op0
== CONST0_RTX (DFmode
))
1404 /* Undo the swap we probably did just above. */
1405 tem
= op0
, op0
= op1
, op1
= tem
;
1406 branch_code
= swap_condition (cmp_code
);
1412 /* ??? We mark the the branch mode to be CCmode to prevent the
1413 compare and branch from being combined, since the compare
1414 insn follows IEEE rules that the branch does not. */
1415 branch_mode
= CCmode
;
1422 /* The following optimizations are only for signed compares. */
1423 if (code
!= LEU
&& code
!= LTU
&& code
!= GEU
&& code
!= GTU
)
1425 /* Whee. Compare and branch against 0 directly. */
1426 if (op1
== const0_rtx
)
1427 cmp_code
= NIL
, branch_code
= code
;
1429 /* We want to use cmpcc/bcc when we can, since there is a zero delay
1430 bypass between logicals and br/cmov on EV5. But we don't want to
1431 force valid immediate constants into registers needlessly. */
1432 else if (GET_CODE (op1
) == CONST_INT
)
1434 HOST_WIDE_INT v
= INTVAL (op1
), n
= -v
;
1436 if (! CONST_OK_FOR_LETTER_P (v
, 'I')
1437 && (CONST_OK_FOR_LETTER_P (n
, 'K')
1438 || CONST_OK_FOR_LETTER_P (n
, 'L')))
1440 cmp_code
= PLUS
, branch_code
= code
;
1447 /* Force op0 into a register. */
1448 if (GET_CODE (op0
) != REG
)
1449 op0
= force_reg (cmp_mode
, op0
);
1451 /* Emit an initial compare instruction, if necessary. */
1453 if (cmp_code
!= NIL
)
1455 tem
= gen_reg_rtx (cmp_mode
);
1456 emit_move_insn (tem
, gen_rtx_fmt_ee (cmp_code
, cmp_mode
, op0
, op1
));
1459 /* Return the branch comparison. */
1460 return gen_rtx_fmt_ee (branch_code
, branch_mode
, tem
, CONST0_RTX (cmp_mode
));
1464 /* Rewrite a comparison against zero CMP of the form
1465 (CODE (cc0) (const_int 0)) so it can be written validly in
1466 a conditional move (if_then_else CMP ...).
1467 If both of the operands that set cc0 are non-zero we must emit
1468 an insn to perform the compare (it can't be done within
1469 the conditional move). */
1471 alpha_emit_conditional_move (cmp
, mode
)
1473 enum machine_mode mode
;
1475 enum rtx_code code
= GET_CODE (cmp
);
1476 enum rtx_code cmov_code
= NE
;
1477 rtx op0
= alpha_compare_op0
;
1478 rtx op1
= alpha_compare_op1
;
1479 enum machine_mode cmp_mode
1480 = (GET_MODE (op0
) == VOIDmode
? DImode
: GET_MODE (op0
));
1481 enum machine_mode cmp_op_mode
= alpha_compare_fp_p
? DFmode
: DImode
;
1482 enum machine_mode cmov_mode
= VOIDmode
;
1485 if (alpha_compare_fp_p
!= FLOAT_MODE_P (mode
))
1488 /* We may be able to use a conditional move directly.
1489 This avoids emitting spurious compares. */
1490 if (signed_comparison_operator (cmp
, cmp_op_mode
)
1491 && (!alpha_compare_fp_p
|| flag_fast_math
)
1492 && (op0
== CONST0_RTX (cmp_mode
) || op1
== CONST0_RTX (cmp_mode
)))
1493 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
1495 /* We can't put the comparison insides a conditional move;
1496 emit a compare instruction and put that inside the
1497 conditional move. Make sure we emit only comparisons we have;
1498 swap or reverse as necessary. */
1502 case EQ
: case LE
: case LT
: case LEU
: case LTU
:
1503 /* We have these compares: */
1507 /* This must be reversed. */
1508 code
= reverse_condition (code
);
1512 case GE
: case GT
: case GEU
: case GTU
:
1513 /* These must be swapped. Make sure the new first operand is in
1515 code
= swap_condition (code
);
1516 tem
= op0
, op0
= op1
, op1
= tem
;
1517 op0
= force_reg (cmp_mode
, op0
);
1524 /* ??? We mark the branch mode to be CCmode to prevent the compare
1525 and cmov from being combined, since the compare insn follows IEEE
1526 rules that the cmov does not. */
1527 if (alpha_compare_fp_p
&& !flag_fast_math
)
1530 tem
= gen_reg_rtx (cmp_op_mode
);
1531 emit_move_insn (tem
, gen_rtx_fmt_ee (code
, cmp_op_mode
, op0
, op1
));
1532 return gen_rtx_fmt_ee (cmov_code
, cmov_mode
, tem
, CONST0_RTX (cmp_op_mode
));
1535 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1539 word: ldq_u r1,X(r11) ldq_u r1,X(r11)
1540 ldq_u r2,X+1(r11) ldq_u r2,X+1(r11)
1541 lda r3,X(r11) lda r3,X+2(r11)
1542 extwl r1,r3,r1 extql r1,r3,r1
1543 extwh r2,r3,r2 extqh r2,r3,r2
1544 or r1.r2.r1 or r1,r2,r1
1547 long: ldq_u r1,X(r11) ldq_u r1,X(r11)
1548 ldq_u r2,X+3(r11) ldq_u r2,X+3(r11)
1549 lda r3,X(r11) lda r3,X(r11)
1550 extll r1,r3,r1 extll r1,r3,r1
1551 extlh r2,r3,r2 extlh r2,r3,r2
1552 or r1.r2.r1 addl r1,r2,r1
1554 quad: ldq_u r1,X(r11)
1563 alpha_expand_unaligned_load (tgt
, mem
, size
, ofs
, sign
)
1565 HOST_WIDE_INT size
, ofs
;
1568 rtx meml
, memh
, addr
, extl
, exth
;
1569 enum machine_mode mode
;
1571 meml
= gen_reg_rtx (DImode
);
1572 memh
= gen_reg_rtx (DImode
);
1573 addr
= gen_reg_rtx (DImode
);
1574 extl
= gen_reg_rtx (DImode
);
1575 exth
= gen_reg_rtx (DImode
);
1577 emit_move_insn (meml
,
1578 change_address (mem
, DImode
,
1579 gen_rtx_AND (DImode
,
1580 plus_constant (XEXP (mem
, 0),
1584 emit_move_insn (memh
,
1585 change_address (mem
, DImode
,
1586 gen_rtx_AND (DImode
,
1587 plus_constant (XEXP (mem
, 0),
1591 if (sign
&& size
== 2)
1593 emit_move_insn (addr
, plus_constant (XEXP (mem
, 0), ofs
+2));
1595 emit_insn (gen_extxl (extl
, meml
, GEN_INT (64), addr
));
1596 emit_insn (gen_extqh (exth
, memh
, addr
));
1598 /* We must use tgt here for the target. Alpha-vms port fails if we use
1599 addr for the target, because addr is marked as a pointer and combine
1600 knows that pointers are always sign-extended 32 bit values. */
1601 addr
= expand_binop (DImode
, ior_optab
, extl
, exth
, tgt
, 1, OPTAB_WIDEN
);
1602 addr
= expand_binop (DImode
, ashr_optab
, addr
, GEN_INT (48),
1603 addr
, 1, OPTAB_WIDEN
);
1607 emit_move_insn (addr
, plus_constant (XEXP (mem
, 0), ofs
));
1608 emit_insn (gen_extxl (extl
, meml
, GEN_INT (size
*8), addr
));
1612 emit_insn (gen_extwh (exth
, memh
, addr
));
1617 emit_insn (gen_extlh (exth
, memh
, addr
));
1622 emit_insn (gen_extqh (exth
, memh
, addr
));
1629 addr
= expand_binop (mode
, ior_optab
, gen_lowpart (mode
, extl
),
1630 gen_lowpart (mode
, exth
), gen_lowpart (mode
, tgt
),
1635 emit_move_insn (tgt
, gen_lowpart(GET_MODE (tgt
), addr
));
1638 /* Similarly, use ins and msk instructions to perform unaligned stores. */
1641 alpha_expand_unaligned_store (dst
, src
, size
, ofs
)
1643 HOST_WIDE_INT size
, ofs
;
1645 rtx dstl
, dsth
, addr
, insl
, insh
, meml
, memh
;
1647 dstl
= gen_reg_rtx (DImode
);
1648 dsth
= gen_reg_rtx (DImode
);
1649 insl
= gen_reg_rtx (DImode
);
1650 insh
= gen_reg_rtx (DImode
);
1652 meml
= change_address (dst
, DImode
,
1653 gen_rtx_AND (DImode
,
1654 plus_constant (XEXP (dst
, 0), ofs
),
1656 memh
= change_address (dst
, DImode
,
1657 gen_rtx_AND (DImode
,
1658 plus_constant (XEXP (dst
, 0),
1662 emit_move_insn (dsth
, memh
);
1663 emit_move_insn (dstl
, meml
);
1664 addr
= copy_addr_to_reg (plus_constant (XEXP (dst
, 0), ofs
));
1666 if (src
!= const0_rtx
)
1668 emit_insn (gen_insxh (insh
, gen_lowpart (DImode
, src
),
1669 GEN_INT (size
*8), addr
));
1674 emit_insn (gen_inswl (insl
, gen_lowpart (HImode
, src
), addr
));
1677 emit_insn (gen_insll (insl
, gen_lowpart (SImode
, src
), addr
));
1680 emit_insn (gen_insql (insl
, src
, addr
));
1685 emit_insn (gen_mskxh (dsth
, dsth
, GEN_INT (size
*8), addr
));
1690 emit_insn (gen_mskxl (dstl
, dstl
, GEN_INT (0xffff), addr
));
1693 emit_insn (gen_mskxl (dstl
, dstl
, GEN_INT (0xffffffff), addr
));
1697 #if HOST_BITS_PER_WIDE_INT == 32
1698 rtx msk
= immed_double_const (0xffffffff, 0xffffffff, DImode
);
1700 rtx msk
= immed_double_const (0xffffffffffffffff, 0, DImode
);
1702 emit_insn (gen_mskxl (dstl
, dstl
, msk
, addr
));
1707 if (src
!= const0_rtx
)
1709 dsth
= expand_binop (DImode
, ior_optab
, insh
, dsth
, dsth
, 0, OPTAB_WIDEN
);
1710 dstl
= expand_binop (DImode
, ior_optab
, insl
, dstl
, dstl
, 0, OPTAB_WIDEN
);
1713 /* Must store high before low for degenerate case of aligned. */
1714 emit_move_insn (memh
, dsth
);
1715 emit_move_insn (meml
, dstl
);
1718 /* The block move code tries to maximize speed by separating loads and
1719 stores at the expense of register pressure: we load all of the data
1720 before we store it back out. There are two secondary effects worth
1721 mentioning, that this speeds copying to/from aligned and unaligned
1722 buffers, and that it makes the code significantly easier to write. */
1724 #define MAX_MOVE_WORDS 8
1726 /* Load an integral number of consecutive unaligned quadwords. */
1729 alpha_expand_unaligned_load_words (out_regs
, smem
, words
, ofs
)
1732 HOST_WIDE_INT words
, ofs
;
1734 rtx
const im8
= GEN_INT (-8);
1735 rtx
const i64
= GEN_INT (64);
1736 rtx ext_tmps
[MAX_MOVE_WORDS
], data_regs
[MAX_MOVE_WORDS
+1];
1740 /* Generate all the tmp registers we need. */
1741 for (i
= 0; i
< words
; ++i
)
1743 data_regs
[i
] = out_regs
[i
];
1744 ext_tmps
[i
] = gen_reg_rtx (DImode
);
1746 data_regs
[words
] = gen_reg_rtx (DImode
);
1749 smem
= change_address (smem
, GET_MODE (smem
),
1750 plus_constant (XEXP (smem
, 0), ofs
));
1752 /* Load up all of the source data. */
1753 for (i
= 0; i
< words
; ++i
)
1755 emit_move_insn (data_regs
[i
],
1756 change_address (smem
, DImode
,
1757 gen_rtx_AND (DImode
,
1758 plus_constant (XEXP(smem
,0),
1762 emit_move_insn (data_regs
[words
],
1763 change_address (smem
, DImode
,
1764 gen_rtx_AND (DImode
,
1765 plus_constant (XEXP(smem
,0),
1769 /* Extract the half-word fragments. Unfortunately DEC decided to make
1770 extxh with offset zero a noop instead of zeroing the register, so
1771 we must take care of that edge condition ourselves with cmov. */
1773 sreg
= copy_addr_to_reg (XEXP (smem
, 0));
1774 areg
= expand_binop (DImode
, and_optab
, sreg
, GEN_INT (7), NULL
,
1776 for (i
= 0; i
< words
; ++i
)
1778 emit_insn (gen_extxl (data_regs
[i
], data_regs
[i
], i64
, sreg
));
1780 emit_insn (gen_extqh (ext_tmps
[i
], data_regs
[i
+1], sreg
));
1781 emit_insn (gen_rtx_SET (VOIDmode
, ext_tmps
[i
],
1782 gen_rtx_IF_THEN_ELSE (DImode
,
1783 gen_rtx_EQ (DImode
, areg
,
1785 const0_rtx
, ext_tmps
[i
])));
1788 /* Merge the half-words into whole words. */
1789 for (i
= 0; i
< words
; ++i
)
1791 out_regs
[i
] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
1792 ext_tmps
[i
], data_regs
[i
], 1, OPTAB_WIDEN
);
1796 /* Store an integral number of consecutive unaligned quadwords. DATA_REGS
1797 may be NULL to store zeros. */
1800 alpha_expand_unaligned_store_words (data_regs
, dmem
, words
, ofs
)
1803 HOST_WIDE_INT words
, ofs
;
1805 rtx
const im8
= GEN_INT (-8);
1806 rtx
const i64
= GEN_INT (64);
1807 #if HOST_BITS_PER_WIDE_INT == 32
1808 rtx
const im1
= immed_double_const (0xffffffff, 0xffffffff, DImode
);
1810 rtx
const im1
= immed_double_const (0xffffffffffffffff, 0, DImode
);
1812 rtx ins_tmps
[MAX_MOVE_WORDS
];
1813 rtx st_tmp_1
, st_tmp_2
, dreg
;
1814 rtx st_addr_1
, st_addr_2
;
1817 /* Generate all the tmp registers we need. */
1818 if (data_regs
!= NULL
)
1819 for (i
= 0; i
< words
; ++i
)
1820 ins_tmps
[i
] = gen_reg_rtx(DImode
);
1821 st_tmp_1
= gen_reg_rtx(DImode
);
1822 st_tmp_2
= gen_reg_rtx(DImode
);
1825 dmem
= change_address (dmem
, GET_MODE (dmem
),
1826 plus_constant (XEXP (dmem
, 0), ofs
));
1829 st_addr_2
= change_address (dmem
, DImode
,
1830 gen_rtx_AND (DImode
,
1831 plus_constant (XEXP(dmem
,0),
1834 st_addr_1
= change_address (dmem
, DImode
,
1835 gen_rtx_AND (DImode
,
1839 /* Load up the destination end bits. */
1840 emit_move_insn (st_tmp_2
, st_addr_2
);
1841 emit_move_insn (st_tmp_1
, st_addr_1
);
1843 /* Shift the input data into place. */
1844 dreg
= copy_addr_to_reg (XEXP (dmem
, 0));
1845 if (data_regs
!= NULL
)
1847 for (i
= words
-1; i
>= 0; --i
)
1849 emit_insn (gen_insxh (ins_tmps
[i
], data_regs
[i
], i64
, dreg
));
1850 emit_insn (gen_insql (data_regs
[i
], data_regs
[i
], dreg
));
1852 for (i
= words
-1; i
> 0; --i
)
1854 ins_tmps
[i
-1] = expand_binop (DImode
, ior_optab
, data_regs
[i
],
1855 ins_tmps
[i
-1], ins_tmps
[i
-1], 1,
1860 /* Split and merge the ends with the destination data. */
1861 emit_insn (gen_mskxh (st_tmp_2
, st_tmp_2
, i64
, dreg
));
1862 emit_insn (gen_mskxl (st_tmp_1
, st_tmp_1
, im1
, dreg
));
1864 if (data_regs
!= NULL
)
1866 st_tmp_2
= expand_binop (DImode
, ior_optab
, st_tmp_2
, ins_tmps
[words
-1],
1867 st_tmp_2
, 1, OPTAB_WIDEN
);
1868 st_tmp_1
= expand_binop (DImode
, ior_optab
, st_tmp_1
, data_regs
[0],
1869 st_tmp_1
, 1, OPTAB_WIDEN
);
1873 emit_move_insn (st_addr_2
, st_tmp_2
);
1874 for (i
= words
-1; i
> 0; --i
)
1876 emit_move_insn (change_address (dmem
, DImode
,
1877 gen_rtx_AND (DImode
,
1878 plus_constant(XEXP (dmem
,0),
1881 data_regs
? ins_tmps
[i
-1] : const0_rtx
);
1883 emit_move_insn (st_addr_1
, st_tmp_1
);
1887 /* Expand string/block move operations.
1889 operands[0] is the pointer to the destination.
1890 operands[1] is the pointer to the source.
1891 operands[2] is the number of bytes to move.
1892 operands[3] is the alignment. */
1895 alpha_expand_block_move (operands
)
1898 rtx bytes_rtx
= operands
[2];
1899 rtx align_rtx
= operands
[3];
1900 HOST_WIDE_INT orig_bytes
= INTVAL (bytes_rtx
);
1901 HOST_WIDE_INT bytes
= orig_bytes
;
1902 HOST_WIDE_INT src_align
= INTVAL (align_rtx
);
1903 HOST_WIDE_INT dst_align
= src_align
;
1904 rtx orig_src
= operands
[1];
1905 rtx orig_dst
= operands
[0];
1906 rtx data_regs
[2*MAX_MOVE_WORDS
+16];
1908 int i
, words
, ofs
, nregs
= 0;
1912 if (bytes
> MAX_MOVE_WORDS
*8)
1915 /* Look for additional alignment information from recorded register info. */
1917 tmp
= XEXP (orig_src
, 0);
1918 if (GET_CODE (tmp
) == REG
)
1920 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > src_align
)
1921 src_align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
1923 else if (GET_CODE (tmp
) == PLUS
1924 && GET_CODE (XEXP (tmp
, 0)) == REG
1925 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
1927 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
1928 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
1932 if (a
>= 8 && c
% 8 == 0)
1934 else if (a
>= 4 && c
% 4 == 0)
1936 else if (a
>= 2 && c
% 2 == 0)
1941 tmp
= XEXP (orig_dst
, 0);
1942 if (GET_CODE (tmp
) == REG
)
1944 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > dst_align
)
1945 dst_align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
1947 else if (GET_CODE (tmp
) == PLUS
1948 && GET_CODE (XEXP (tmp
, 0)) == REG
1949 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
1951 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
1952 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
1956 if (a
>= 8 && c
% 8 == 0)
1958 else if (a
>= 4 && c
% 4 == 0)
1960 else if (a
>= 2 && c
% 2 == 0)
1966 * Load the entire block into registers.
1969 if (GET_CODE (XEXP (orig_src
, 0)) == ADDRESSOF
)
1971 enum machine_mode mode
;
1972 tmp
= XEXP (XEXP (orig_src
, 0), 0);
1974 /* Don't use the existing register if we're reading more than
1975 is held in the register. Nor if there is not a mode that
1976 handles the exact size. */
1977 mode
= mode_for_size (bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
1979 && GET_MODE_SIZE (GET_MODE (tmp
)) >= bytes
)
1983 data_regs
[nregs
] = gen_lowpart (DImode
, tmp
);
1984 data_regs
[nregs
+1] = gen_highpart (DImode
, tmp
);
1988 data_regs
[nregs
++] = gen_lowpart (mode
, tmp
);
1992 /* No appropriate mode; fall back on memory. */
1993 orig_src
= change_address (orig_src
, GET_MODE (orig_src
),
1994 copy_addr_to_reg (XEXP (orig_src
, 0)));
1998 if (src_align
>= 8 && bytes
>= 8)
2002 for (i
= 0; i
< words
; ++i
)
2003 data_regs
[nregs
+i
] = gen_reg_rtx(DImode
);
2005 for (i
= 0; i
< words
; ++i
)
2007 emit_move_insn (data_regs
[nregs
+i
],
2008 change_address (orig_src
, DImode
,
2009 plus_constant (XEXP (orig_src
, 0),
2017 if (src_align
>= 4 && bytes
>= 4)
2021 for (i
= 0; i
< words
; ++i
)
2022 data_regs
[nregs
+i
] = gen_reg_rtx(SImode
);
2024 for (i
= 0; i
< words
; ++i
)
2026 emit_move_insn (data_regs
[nregs
+i
],
2027 change_address (orig_src
, SImode
,
2028 plus_constant (XEXP (orig_src
, 0),
2040 for (i
= 0; i
< words
+1; ++i
)
2041 data_regs
[nregs
+i
] = gen_reg_rtx(DImode
);
2043 alpha_expand_unaligned_load_words (data_regs
+ nregs
, orig_src
,
2050 if (!TARGET_BWX
&& bytes
>= 8)
2052 data_regs
[nregs
++] = tmp
= gen_reg_rtx (DImode
);
2053 alpha_expand_unaligned_load (tmp
, orig_src
, 8, ofs
, 0);
2057 if (!TARGET_BWX
&& bytes
>= 4)
2059 data_regs
[nregs
++] = tmp
= gen_reg_rtx (SImode
);
2060 alpha_expand_unaligned_load (tmp
, orig_src
, 4, ofs
, 0);
2069 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
2070 emit_move_insn (tmp
,
2071 change_address (orig_src
, HImode
,
2072 plus_constant (XEXP (orig_src
, 0),
2076 } while (bytes
>= 2);
2078 else if (!TARGET_BWX
)
2080 data_regs
[nregs
++] = tmp
= gen_reg_rtx (HImode
);
2081 alpha_expand_unaligned_load (tmp
, orig_src
, 2, ofs
, 0);
2088 data_regs
[nregs
++] = tmp
= gen_reg_rtx (QImode
);
2089 emit_move_insn (tmp
,
2090 change_address (orig_src
, QImode
,
2091 plus_constant (XEXP (orig_src
, 0),
2098 if (nregs
> (int)(sizeof(data_regs
)/sizeof(*data_regs
)))
2102 * Now save it back out again.
2107 if (GET_CODE (XEXP (orig_dst
, 0)) == ADDRESSOF
)
2109 enum machine_mode mode
;
2110 tmp
= XEXP (XEXP (orig_dst
, 0), 0);
2112 mode
= mode_for_size (orig_bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
2113 if (GET_MODE (tmp
) == mode
)
2117 emit_move_insn (tmp
, data_regs
[0]);
2121 else if (nregs
== 2 && mode
== TImode
)
2123 /* Undo the subregging done above when copying between
2124 two TImode registers. */
2125 if (GET_CODE (data_regs
[0]) == SUBREG
2126 && GET_MODE (SUBREG_REG (data_regs
[0])) == TImode
)
2128 emit_move_insn (tmp
, SUBREG_REG (data_regs
[0]));
2135 emit_move_insn (gen_lowpart (DImode
, tmp
), data_regs
[0]);
2136 emit_move_insn (gen_highpart (DImode
, tmp
), data_regs
[1]);
2140 emit_no_conflict_block (seq
, tmp
, data_regs
[0],
2141 data_regs
[1], NULL_RTX
);
2149 /* ??? If nregs > 1, consider reconstructing the word in regs. */
2150 /* ??? Optimize mode < dst_mode with strict_low_part. */
2152 /* No appropriate mode; fall back on memory. We can speed things
2153 up by recognizing extra alignment information. */
2154 orig_dst
= change_address (orig_dst
, GET_MODE (orig_dst
),
2155 copy_addr_to_reg (XEXP (orig_dst
, 0)));
2156 dst_align
= GET_MODE_SIZE (GET_MODE (tmp
));
2159 /* Write out the data in whatever chunks reading the source allowed. */
2162 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2164 emit_move_insn (change_address (orig_dst
, DImode
,
2165 plus_constant (XEXP (orig_dst
, 0),
2174 /* If the source has remaining DImode regs, write them out in
2176 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2178 tmp
= expand_binop (DImode
, lshr_optab
, data_regs
[i
], GEN_INT (32),
2179 NULL_RTX
, 1, OPTAB_WIDEN
);
2181 emit_move_insn (change_address (orig_dst
, SImode
,
2182 plus_constant (XEXP (orig_dst
, 0),
2184 gen_lowpart (SImode
, data_regs
[i
]));
2185 emit_move_insn (change_address (orig_dst
, SImode
,
2186 plus_constant (XEXP (orig_dst
, 0),
2188 gen_lowpart (SImode
, tmp
));
2193 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
2195 emit_move_insn (change_address(orig_dst
, SImode
,
2196 plus_constant (XEXP (orig_dst
, 0),
2203 if (i
< nregs
&& GET_MODE (data_regs
[i
]) == DImode
)
2205 /* Write out a remaining block of words using unaligned methods. */
2207 for (words
= 1; i
+words
< nregs
; ++words
)
2208 if (GET_MODE (data_regs
[i
+words
]) != DImode
)
2212 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 8, ofs
);
2214 alpha_expand_unaligned_store_words (data_regs
+i
, orig_dst
, words
, ofs
);
2220 /* Due to the above, this won't be aligned. */
2221 /* ??? If we have more than one of these, consider constructing full
2222 words in registers and using alpha_expand_unaligned_store_words. */
2223 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == SImode
)
2225 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 4, ofs
);
2231 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
2233 emit_move_insn (change_address (orig_dst
, HImode
,
2234 plus_constant (XEXP (orig_dst
, 0),
2241 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == HImode
)
2243 alpha_expand_unaligned_store (orig_dst
, data_regs
[i
], 2, ofs
);
2247 while (i
< nregs
&& GET_MODE (data_regs
[i
]) == QImode
)
2249 emit_move_insn (change_address (orig_dst
, QImode
,
2250 plus_constant (XEXP (orig_dst
, 0),
2265 alpha_expand_block_clear (operands
)
2268 rtx bytes_rtx
= operands
[1];
2269 rtx align_rtx
= operands
[2];
2270 HOST_WIDE_INT bytes
= INTVAL (bytes_rtx
);
2271 HOST_WIDE_INT align
= INTVAL (align_rtx
);
2272 rtx orig_dst
= operands
[0];
2274 HOST_WIDE_INT i
, words
, ofs
= 0;
2278 if (bytes
> MAX_MOVE_WORDS
*8)
2281 /* Look for stricter alignment. */
2283 tmp
= XEXP (orig_dst
, 0);
2284 if (GET_CODE (tmp
) == REG
)
2286 if (REGNO_POINTER_ALIGN (REGNO (tmp
)) > align
)
2287 align
= REGNO_POINTER_ALIGN (REGNO (tmp
));
2289 else if (GET_CODE (tmp
) == PLUS
2290 && GET_CODE (XEXP (tmp
, 0)) == REG
2291 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
2293 HOST_WIDE_INT c
= INTVAL (XEXP (tmp
, 1));
2294 int a
= REGNO_POINTER_ALIGN (REGNO (XEXP (tmp
, 0)));
2298 if (a
>= 8 && c
% 8 == 0)
2300 else if (a
>= 4 && c
% 4 == 0)
2302 else if (a
>= 2 && c
% 2 == 0)
2306 else if (GET_CODE (tmp
) == ADDRESSOF
)
2308 enum machine_mode mode
;
2310 mode
= mode_for_size (bytes
* BITS_PER_UNIT
, MODE_INT
, 1);
2311 if (GET_MODE (XEXP (tmp
, 0)) == mode
)
2313 emit_move_insn (XEXP (tmp
, 0), const0_rtx
);
2317 /* No appropriate mode; fall back on memory. */
2318 orig_dst
= change_address (orig_dst
, GET_MODE (orig_dst
),
2319 copy_addr_to_reg (tmp
));
2320 align
= GET_MODE_SIZE (GET_MODE (XEXP (tmp
, 0)));
2323 /* Handle a block of contiguous words first. */
2325 if (align
>= 8 && bytes
>= 8)
2329 for (i
= 0; i
< words
; ++i
)
2331 emit_move_insn (change_address(orig_dst
, DImode
,
2332 plus_constant (XEXP (orig_dst
, 0),
2340 if (align
>= 4 && bytes
>= 4)
2344 for (i
= 0; i
< words
; ++i
)
2346 emit_move_insn (change_address (orig_dst
, SImode
,
2347 plus_constant (XEXP (orig_dst
, 0),
2359 alpha_expand_unaligned_store_words (NULL
, orig_dst
, words
, ofs
);
2365 /* Next clean up any trailing pieces. We know from the contiguous
2366 block move that there are no aligned SImode or DImode hunks left. */
2368 if (!TARGET_BWX
&& bytes
>= 8)
2370 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 8, ofs
);
2374 if (!TARGET_BWX
&& bytes
>= 4)
2376 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 4, ofs
);
2385 emit_move_insn (change_address (orig_dst
, HImode
,
2386 plus_constant (XEXP (orig_dst
, 0),
2391 } while (bytes
>= 2);
2393 else if (!TARGET_BWX
)
2395 alpha_expand_unaligned_store (orig_dst
, const0_rtx
, 2, ofs
);
2402 emit_move_insn (change_address (orig_dst
, QImode
,
2403 plus_constant (XEXP (orig_dst
, 0),
2414 /* Adjust the cost of a scheduling dependency. Return the new cost of
2415 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
2418 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
2425 enum attr_type insn_type
, dep_insn_type
;
2427 /* If the dependence is an anti-dependence, there is no cost. For an
2428 output dependence, there is sometimes a cost, but it doesn't seem
2429 worth handling those few cases. */
2431 if (REG_NOTE_KIND (link
) != 0)
2434 /* If we can't recognize the insns, we can't really do anything. */
2435 if (recog_memoized (insn
) < 0 || recog_memoized (dep_insn
) < 0)
2438 insn_type
= get_attr_type (insn
);
2439 dep_insn_type
= get_attr_type (dep_insn
);
2441 /* Bring in the user-defined memory latency. */
2442 if (dep_insn_type
== TYPE_ILD
2443 || dep_insn_type
== TYPE_FLD
2444 || dep_insn_type
== TYPE_LDSYM
)
2445 cost
+= alpha_memory_latency
-1;
2450 /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2451 being stored, we can sometimes lower the cost. */
2453 if ((insn_type
== TYPE_IST
|| insn_type
== TYPE_FST
)
2454 && (set
= single_set (dep_insn
)) != 0
2455 && GET_CODE (PATTERN (insn
)) == SET
2456 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
2458 switch (dep_insn_type
)
2462 /* No savings here. */
2466 /* In these cases, we save one cycle. */
2470 /* In all other cases, we save two cycles. */
2471 return MAX (0, cost
- 2);
2475 /* Another case that needs adjustment is an arithmetic or logical
2476 operation. It's cost is usually one cycle, but we default it to
2477 two in the MD file. The only case that it is actually two is
2478 for the address in loads, stores, and jumps. */
2480 if (dep_insn_type
== TYPE_IADD
|| dep_insn_type
== TYPE_ILOG
)
2495 /* The final case is when a compare feeds into an integer branch;
2496 the cost is only one cycle in that case. */
2498 if (dep_insn_type
== TYPE_ICMP
&& insn_type
== TYPE_IBR
)
2503 /* And the lord DEC saith: "A special bypass provides an effective
2504 latency of 0 cycles for an ICMP or ILOG insn producing the test
2505 operand of an IBR or ICMOV insn." */
2507 if ((dep_insn_type
== TYPE_ICMP
|| dep_insn_type
== TYPE_ILOG
)
2508 && (set
= single_set (dep_insn
)) != 0)
2510 /* A branch only has one input. This must be it. */
2511 if (insn_type
== TYPE_IBR
)
2513 /* A conditional move has three, make sure it is the test. */
2514 if (insn_type
== TYPE_ICMOV
2515 && GET_CODE (set_src
= PATTERN (insn
)) == SET
2516 && GET_CODE (set_src
= SET_SRC (set_src
)) == IF_THEN_ELSE
2517 && rtx_equal_p (SET_DEST (set
), XEXP (set_src
, 0)))
2521 /* "The multiplier is unable to receive data from IEU bypass paths.
2522 The instruction issues at the expected time, but its latency is
2523 increased by the time it takes for the input data to become
2524 available to the multiplier" -- which happens in pipeline stage
2525 six, when results are comitted to the register file. */
2527 if (insn_type
== TYPE_IMUL
)
2529 switch (dep_insn_type
)
2531 /* These insns produce their results in pipeline stage five. */
2538 /* Other integer insns produce results in pipeline stage four. */
2546 /* There is additional latency to move the result of (most) FP
2547 operations anywhere but the FP register file. */
2549 if ((insn_type
== TYPE_FST
|| insn_type
== TYPE_FTOI
)
2550 && (dep_insn_type
== TYPE_FADD
||
2551 dep_insn_type
== TYPE_FMUL
||
2552 dep_insn_type
== TYPE_FCMOV
))
2558 /* Otherwise, return the default cost. */
2562 /* Functions to save and restore alpha_return_addr_rtx. */
2564 struct machine_function
2570 alpha_save_machine_status (p
)
2573 struct machine_function
*machine
=
2574 (struct machine_function
*) xmalloc (sizeof (struct machine_function
));
2576 p
->machine
= machine
;
2577 machine
->ra_rtx
= alpha_return_addr_rtx
;
2581 alpha_restore_machine_status (p
)
2584 struct machine_function
*machine
= p
->machine
;
2586 alpha_return_addr_rtx
= machine
->ra_rtx
;
2589 p
->machine
= (struct machine_function
*)0;
2592 /* Do anything needed before RTL is emitted for each function. */
2595 alpha_init_expanders ()
2597 alpha_return_addr_rtx
= NULL_RTX
;
2598 alpha_eh_epilogue_sp_ofs
= NULL_RTX
;
2600 /* Arrange to save and restore machine status around nested functions. */
2601 save_machine_status
= alpha_save_machine_status
;
2602 restore_machine_status
= alpha_restore_machine_status
;
2605 /* Start the ball rolling with RETURN_ADDR_RTX. */
2608 alpha_return_addr (count
, frame
)
2610 rtx frame ATTRIBUTE_UNUSED
;
2617 if (alpha_return_addr_rtx
)
2618 return alpha_return_addr_rtx
;
2620 /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */
2621 alpha_return_addr_rtx
= gen_reg_rtx (Pmode
);
2622 init
= gen_rtx_SET (VOIDmode
, alpha_return_addr_rtx
,
2623 gen_rtx_REG (Pmode
, REG_RA
));
2625 /* Emit the insn to the prologue with the other argument copies. */
2626 push_topmost_sequence ();
2627 emit_insn_after (init
, get_insns ());
2628 pop_topmost_sequence ();
2630 return alpha_return_addr_rtx
;
2634 alpha_ra_ever_killed ()
2638 #ifdef ASM_OUTPUT_MI_THUNK
2639 if (current_function_is_thunk
)
2642 if (!alpha_return_addr_rtx
)
2643 return regs_ever_live
[REG_RA
];
2645 push_topmost_sequence ();
2647 pop_topmost_sequence ();
2649 return reg_set_between_p (gen_rtx_REG (Pmode
, REG_RA
), top
, NULL_RTX
);
2653 /* Print an operand. Recognize special options, documented below. */
2656 print_operand (file
, x
, code
)
2666 /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2667 chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2668 mode. alpha_fprm controls which suffix is generated. */
2671 case ALPHA_FPRM_NORM
:
2673 case ALPHA_FPRM_MINF
:
2676 case ALPHA_FPRM_CHOP
:
2679 case ALPHA_FPRM_DYN
:
2686 /* Generates trap-mode suffix for instructions that accept the su
2687 suffix only (cmpt et al). */
2688 if (alpha_fptm
>= ALPHA_FPTM_SU
)
2693 /* Generates trap-mode suffix for instructions that accept the
2694 v and sv suffix. The only instruction that needs this is cvtql. */
2703 case ALPHA_FPTM_SUI
:
2710 /* Generates trap-mode suffix for instructions that accept the
2711 v, sv, and svi suffix. The only instruction that needs this
2723 case ALPHA_FPTM_SUI
:
2724 fputs ("svi", file
);
2730 /* Generates trap-mode suffix for instructions that accept the u, su,
2731 and sui suffix. This is the bulk of the IEEE floating point
2732 instructions (addt et al). */
2743 case ALPHA_FPTM_SUI
:
2744 fputs ("sui", file
);
2750 /* Generates trap-mode suffix for instructions that accept the sui
2751 suffix (cvtqt and cvtqs). */
2756 case ALPHA_FPTM_SU
: /* cvtqt/cvtqs can't cause underflow */
2758 case ALPHA_FPTM_SUI
:
2759 fputs ("sui", file
);
2765 /* Generates single precision instruction suffix. */
2766 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'f' : 's'));
2770 /* Generates double precision instruction suffix. */
2771 fprintf (file
, "%c", (TARGET_FLOAT_VAX
? 'g' : 't'));
2775 /* If this operand is the constant zero, write it as "$31". */
2776 if (GET_CODE (x
) == REG
)
2777 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2778 else if (x
== CONST0_RTX (GET_MODE (x
)))
2779 fprintf (file
, "$31");
2781 output_operand_lossage ("invalid %%r value");
2786 /* Similar, but for floating-point. */
2787 if (GET_CODE (x
) == REG
)
2788 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2789 else if (x
== CONST0_RTX (GET_MODE (x
)))
2790 fprintf (file
, "$f31");
2792 output_operand_lossage ("invalid %%R value");
2797 /* Write the 1's complement of a constant. */
2798 if (GET_CODE (x
) != CONST_INT
)
2799 output_operand_lossage ("invalid %%N value");
2801 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INTVAL (x
));
2805 /* Write 1 << C, for a constant C. */
2806 if (GET_CODE (x
) != CONST_INT
)
2807 output_operand_lossage ("invalid %%P value");
2809 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (HOST_WIDE_INT
) 1 << INTVAL (x
));
2813 /* Write the high-order 16 bits of a constant, sign-extended. */
2814 if (GET_CODE (x
) != CONST_INT
)
2815 output_operand_lossage ("invalid %%h value");
2817 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) >> 16);
2821 /* Write the low-order 16 bits of a constant, sign-extended. */
2822 if (GET_CODE (x
) != CONST_INT
)
2823 output_operand_lossage ("invalid %%L value");
2825 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
2826 (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
2830 /* Write mask for ZAP insn. */
2831 if (GET_CODE (x
) == CONST_DOUBLE
)
2833 HOST_WIDE_INT mask
= 0;
2834 HOST_WIDE_INT value
;
2836 value
= CONST_DOUBLE_LOW (x
);
2837 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
2842 value
= CONST_DOUBLE_HIGH (x
);
2843 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
2846 mask
|= (1 << (i
+ sizeof (int)));
2848 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
& 0xff);
2851 else if (GET_CODE (x
) == CONST_INT
)
2853 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
2855 for (i
= 0; i
< 8; i
++, value
>>= 8)
2859 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, mask
);
2862 output_operand_lossage ("invalid %%m value");
2866 /* 'b', 'w', 'l', or 'q' as the value of the constant. */
2867 if (GET_CODE (x
) != CONST_INT
2868 || (INTVAL (x
) != 8 && INTVAL (x
) != 16
2869 && INTVAL (x
) != 32 && INTVAL (x
) != 64))
2870 output_operand_lossage ("invalid %%M value");
2872 fprintf (file
, "%s",
2873 (INTVAL (x
) == 8 ? "b"
2874 : INTVAL (x
) == 16 ? "w"
2875 : INTVAL (x
) == 32 ? "l"
2880 /* Similar, except do it from the mask. */
2881 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
2882 fprintf (file
, "b");
2883 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
2884 fprintf (file
, "w");
2885 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
2886 fprintf (file
, "l");
2887 #if HOST_BITS_PER_WIDE_INT == 32
2888 else if (GET_CODE (x
) == CONST_DOUBLE
2889 && CONST_DOUBLE_HIGH (x
) == 0
2890 && CONST_DOUBLE_LOW (x
) == -1)
2891 fprintf (file
, "l");
2892 else if (GET_CODE (x
) == CONST_DOUBLE
2893 && CONST_DOUBLE_HIGH (x
) == -1
2894 && CONST_DOUBLE_LOW (x
) == -1)
2895 fprintf (file
, "q");
2897 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == -1)
2898 fprintf (file
, "q");
2899 else if (GET_CODE (x
) == CONST_DOUBLE
2900 && CONST_DOUBLE_HIGH (x
) == 0
2901 && CONST_DOUBLE_LOW (x
) == -1)
2902 fprintf (file
, "q");
2905 output_operand_lossage ("invalid %%U value");
2909 /* Write the constant value divided by 8. */
2910 if (GET_CODE (x
) != CONST_INT
2911 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
2912 && (INTVAL (x
) & 7) != 8)
2913 output_operand_lossage ("invalid %%s value");
2915 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) / 8);
2919 /* Same, except compute (64 - c) / 8 */
2921 if (GET_CODE (x
) != CONST_INT
2922 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
2923 && (INTVAL (x
) & 7) != 8)
2924 output_operand_lossage ("invalid %%s value");
2926 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (64 - INTVAL (x
)) / 8);
2929 case 'C': case 'D': case 'c': case 'd':
2930 /* Write out comparison name. */
2932 enum rtx_code c
= GET_CODE (x
);
2934 if (GET_RTX_CLASS (c
) != '<')
2935 output_operand_lossage ("invalid %%C value");
2938 c
= reverse_condition (c
);
2939 else if (code
== 'c')
2940 c
= swap_condition (c
);
2941 else if (code
== 'd')
2942 c
= swap_condition (reverse_condition (c
));
2945 fprintf (file
, "ule");
2947 fprintf (file
, "ult");
2949 fprintf (file
, "%s", GET_RTX_NAME (c
));
2954 /* Write the divide or modulus operator. */
2955 switch (GET_CODE (x
))
2958 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
2961 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
2964 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
2967 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
2970 output_operand_lossage ("invalid %%E value");
2976 /* Write "_u" for unaligned access. */
2977 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
2978 fprintf (file
, "_u");
2982 if (GET_CODE (x
) == REG
)
2983 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
2984 else if (GET_CODE (x
) == MEM
)
2985 output_address (XEXP (x
, 0));
2987 output_addr_const (file
, x
);
2991 output_operand_lossage ("invalid %%xn code");
2996 print_operand_address (file
, addr
)
3001 HOST_WIDE_INT offset
= 0;
3003 if (GET_CODE (addr
) == AND
)
3004 addr
= XEXP (addr
, 0);
3006 if (GET_CODE (addr
) == PLUS
3007 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3009 offset
= INTVAL (XEXP (addr
, 1));
3010 addr
= XEXP (addr
, 0);
3012 if (GET_CODE (addr
) == REG
)
3013 basereg
= REGNO (addr
);
3014 else if (GET_CODE (addr
) == SUBREG
3015 && GET_CODE (SUBREG_REG (addr
)) == REG
)
3016 basereg
= REGNO (SUBREG_REG (addr
)) + SUBREG_WORD (addr
);
3017 else if (GET_CODE (addr
) == CONST_INT
)
3018 offset
= INTVAL (addr
);
3022 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
3023 fprintf (file
, "($%d)", basereg
);
3026 /* Emit RTL insns to initialize the variable parts of a trampoline at
3027 TRAMP. FNADDR is an RTX for the address of the function's pure
3028 code. CXT is an RTX for the static chain value for the function.
3030 The three offset parameters are for the individual template's
3031 layout. A JMPOFS < 0 indicates that the trampoline does not
3032 contain instructions at all.
3034 We assume here that a function will be called many more times than
3035 its address is taken (e.g., it might be passed to qsort), so we
3036 take the trouble to initialize the "hint" field in the JMP insn.
3037 Note that the hint field is PC (new) + 4 * bits 13:0. */
3040 alpha_initialize_trampoline (tramp
, fnaddr
, cxt
, fnofs
, cxtofs
, jmpofs
)
3041 rtx tramp
, fnaddr
, cxt
;
3042 int fnofs
, cxtofs
, jmpofs
;
3044 rtx temp
, temp1
, addr
;
3045 /* VMS really uses DImode pointers in memory at this point. */
3046 enum machine_mode mode
= TARGET_OPEN_VMS
? Pmode
: ptr_mode
;
3048 #ifdef POINTERS_EXTEND_UNSIGNED
3049 fnaddr
= convert_memory_address (mode
, fnaddr
);
3050 cxt
= convert_memory_address (mode
, cxt
);
3053 /* Store function address and CXT. */
3054 addr
= memory_address (mode
, plus_constant (tramp
, fnofs
));
3055 emit_move_insn (gen_rtx_MEM (mode
, addr
), fnaddr
);
3056 addr
= memory_address (mode
, plus_constant (tramp
, cxtofs
));
3057 emit_move_insn (gen_rtx_MEM (mode
, addr
), cxt
);
3059 /* This has been disabled since the hint only has a 32k range, and in
3060 no existing OS is the stack within 32k of the text segment. */
3061 if (0 && jmpofs
>= 0)
3063 /* Compute hint value. */
3064 temp
= force_operand (plus_constant (tramp
, jmpofs
+4), NULL_RTX
);
3065 temp
= expand_binop (DImode
, sub_optab
, fnaddr
, temp
, temp
, 1,
3067 temp
= expand_shift (RSHIFT_EXPR
, Pmode
, temp
,
3068 build_int_2 (2, 0), NULL_RTX
, 1);
3069 temp
= expand_and (gen_lowpart (SImode
, temp
), GEN_INT (0x3fff), 0);
3071 /* Merge in the hint. */
3072 addr
= memory_address (SImode
, plus_constant (tramp
, jmpofs
));
3073 temp1
= force_reg (SImode
, gen_rtx_MEM (SImode
, addr
));
3074 temp1
= expand_and (temp1
, GEN_INT (0xffffc000), NULL_RTX
);
3075 temp1
= expand_binop (SImode
, ior_optab
, temp1
, temp
, temp1
, 1,
3077 emit_move_insn (gen_rtx_MEM (SImode
, addr
), temp1
);
3080 #ifdef TRANSFER_FROM_TRAMPOLINE
3081 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__enable_execute_stack"),
3082 0, VOIDmode
, 1, addr
, Pmode
);
3086 emit_insn (gen_imb ());
3090 alpha_build_va_list ()
3092 tree base
, ofs
, record
;
3094 if (TARGET_OPEN_VMS
)
3095 return ptr_type_node
;
3097 record
= make_node (RECORD_TYPE
);
3098 /* C++? SET_IS_AGGR_TYPE (record, 1); */
3100 ofs
= build_decl (FIELD_DECL
, get_identifier ("__offset"),
3102 DECL_FIELD_CONTEXT (ofs
) = record
;
3104 base
= build_decl (FIELD_DECL
, get_identifier ("__base"),
3106 DECL_FIELD_CONTEXT (base
) = record
;
3107 TREE_CHAIN (base
) = ofs
;
3109 TYPE_FIELDS (record
) = base
;
3110 layout_type (record
);
3116 alpha_va_start (stdarg_p
, valist
, nextarg
)
3119 rtx nextarg ATTRIBUTE_UNUSED
;
3121 HOST_WIDE_INT offset
;
3122 tree t
, offset_field
, base_field
;
3124 if (TARGET_OPEN_VMS
)
3125 std_expand_builtin_va_start (stdarg_p
, valist
, nextarg
);
3127 /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
3128 up by 48, storing fp arg registers in the first 48 bytes, and the
3129 integer arg registers in the next 48 bytes. This is only done,
3130 however, if any integer registers need to be stored.
3132 If no integer registers need be stored, then we must subtract 48
3133 in order to account for the integer arg registers which are counted
3134 in argsize above, but which are not actually stored on the stack. */
3136 if (NUM_ARGS
<= 5 + stdarg_p
)
3137 offset
= 6 * UNITS_PER_WORD
;
3139 offset
= -6 * UNITS_PER_WORD
;
3141 base_field
= TYPE_FIELDS (TREE_TYPE (valist
));
3142 offset_field
= TREE_CHAIN (base_field
);
3144 base_field
= build (COMPONENT_REF
, TREE_TYPE (base_field
),
3145 valist
, base_field
);
3146 offset_field
= build (COMPONENT_REF
, TREE_TYPE (offset_field
),
3147 valist
, offset_field
);
3149 t
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
3150 t
= build (PLUS_EXPR
, ptr_type_node
, t
, build_int_2 (offset
, 0));
3151 t
= build (MODIFY_EXPR
, TREE_TYPE (base_field
), base_field
, t
);
3152 TREE_SIDE_EFFECTS (t
) = 1;
3153 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3155 t
= build_int_2 (NUM_ARGS
*UNITS_PER_WORD
, 0);
3156 t
= build (MODIFY_EXPR
, TREE_TYPE (offset_field
), offset_field
, t
);
3157 TREE_SIDE_EFFECTS (t
) = 1;
3158 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3162 alpha_va_arg (valist
, type
)
3165 HOST_WIDE_INT tsize
;
3168 tree offset_field
, base_field
, addr_tree
, addend
;
3169 tree wide_type
, wide_ofs
;
3171 if (TARGET_OPEN_VMS
)
3172 return std_expand_builtin_va_arg (valist
, type
);
3174 tsize
= ((TREE_INT_CST_LOW (TYPE_SIZE (type
)) / BITS_PER_UNIT
+ 7) / 8) * 8;
3176 base_field
= TYPE_FIELDS (TREE_TYPE (valist
));
3177 offset_field
= TREE_CHAIN (base_field
);
3179 base_field
= build (COMPONENT_REF
, TREE_TYPE (base_field
),
3180 valist
, base_field
);
3181 offset_field
= build (COMPONENT_REF
, TREE_TYPE (offset_field
),
3182 valist
, offset_field
);
3184 wide_type
= make_signed_type (64);
3185 wide_ofs
= save_expr (build1 (CONVERT_EXPR
, wide_type
, offset_field
));
3188 if (FLOAT_TYPE_P (type
))
3190 tree fpaddend
, cond
;
3192 fpaddend
= fold (build (PLUS_EXPR
, TREE_TYPE (addend
),
3193 addend
, build_int_2 (-6*8, 0)));
3195 cond
= fold (build (LT_EXPR
, integer_type_node
,
3196 wide_ofs
, build_int_2 (6*8, 0)));
3198 addend
= fold (build (COND_EXPR
, TREE_TYPE (addend
), cond
,
3202 addr_tree
= build (PLUS_EXPR
, TREE_TYPE (base_field
),
3203 base_field
, addend
);
3205 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
3206 addr
= copy_to_reg (addr
);
3208 t
= build (MODIFY_EXPR
, TREE_TYPE (offset_field
), offset_field
,
3209 build (PLUS_EXPR
, TREE_TYPE (offset_field
),
3210 offset_field
, build_int_2 (tsize
, 0)));
3211 TREE_SIDE_EFFECTS (t
) = 1;
3212 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3217 /* This page contains routines that are used to determine what the function
3218 prologue and epilogue code will do and write them out. */
3220 /* Compute the size of the save area in the stack. */
3222 /* These variables are used for communication between the following functions.
3223 They indicate various things about the current function being compiled
3224 that are used to tell what kind of prologue, epilogue and procedure
3225 descriptior to generate. */
3227 /* Nonzero if we need a stack procedure. */
3228 static int vms_is_stack_procedure
;
3230 /* Register number (either FP or SP) that is used to unwind the frame. */
3231 static int vms_unwind_regno
;
3233 /* Register number used to save FP. We need not have one for RA since
3234 we don't modify it for register procedures. This is only defined
3235 for register frame procedures. */
3236 static int vms_save_fp_regno
;
3238 /* Register number used to reference objects off our PV. */
3239 static int vms_base_regno
;
3241 /* Compute register masks for saved registers. */
3244 alpha_sa_mask (imaskP
, fmaskP
)
3245 unsigned long *imaskP
;
3246 unsigned long *fmaskP
;
3248 unsigned long imask
= 0;
3249 unsigned long fmask
= 0;
3252 #ifdef ASM_OUTPUT_MI_THUNK
3253 if (!current_function_is_thunk
)
3256 if (TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3257 imask
|= (1L << HARD_FRAME_POINTER_REGNUM
);
3259 /* One for every register we have to save. */
3260 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3261 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
3262 && regs_ever_live
[i
] && i
!= REG_RA
)
3267 fmask
|= (1L << (i
- 32));
3270 if (imask
|| fmask
|| alpha_ra_ever_killed ())
3271 imask
|= (1L << REG_RA
);
3284 #ifdef ASM_OUTPUT_MI_THUNK
3285 if (current_function_is_thunk
)
3290 /* One for every register we have to save. */
3291 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3292 if (! fixed_regs
[i
] && ! call_used_regs
[i
]
3293 && regs_ever_live
[i
] && i
!= REG_RA
)
3297 if (TARGET_OPEN_VMS
)
3299 /* Start by assuming we can use a register procedure if we don't
3300 make any calls (REG_RA not used) or need to save any
3301 registers and a stack procedure if we do. */
3302 vms_is_stack_procedure
= sa_size
!= 0 || alpha_ra_ever_killed ();
3304 /* Decide whether to refer to objects off our PV via FP or PV.
3305 If we need FP for something else or if we receive a nonlocal
3306 goto (which expects PV to contain the value), we must use PV.
3307 Otherwise, start by assuming we can use FP. */
3308 vms_base_regno
= (frame_pointer_needed
3309 || current_function_has_nonlocal_label
3310 || vms_is_stack_procedure
3311 || current_function_outgoing_args_size
3312 ? REG_PV
: HARD_FRAME_POINTER_REGNUM
);
3314 /* If we want to copy PV into FP, we need to find some register
3315 in which to save FP. */
3317 vms_save_fp_regno
= -1;
3318 if (vms_base_regno
== HARD_FRAME_POINTER_REGNUM
)
3319 for (i
= 0; i
< 32; i
++)
3320 if (! fixed_regs
[i
] && call_used_regs
[i
] && ! regs_ever_live
[i
])
3321 vms_save_fp_regno
= i
;
3323 if (vms_save_fp_regno
== -1)
3324 vms_base_regno
= REG_PV
, vms_is_stack_procedure
= 1;
3326 /* Stack unwinding should be done via FP unless we use it for PV. */
3327 vms_unwind_regno
= (vms_base_regno
== REG_PV
3328 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
3330 /* If this is a stack procedure, allow space for saving FP and RA. */
3331 if (vms_is_stack_procedure
)
3336 /* If some registers were saved but not RA, RA must also be saved,
3337 so leave space for it. */
3338 if (sa_size
!= 0 || alpha_ra_ever_killed ())
3341 /* Our size must be even (multiple of 16 bytes). */
3350 alpha_pv_save_size ()
3353 return vms_is_stack_procedure
? 8 : 0;
3360 return vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
;
3364 vms_valid_decl_attribute_p (decl
, attributes
, identifier
, args
)
3365 tree decl ATTRIBUTE_UNUSED
;
3366 tree attributes ATTRIBUTE_UNUSED
;
3370 if (is_attribute_p ("overlaid", identifier
))
3371 return (args
== NULL_TREE
);
3376 alpha_does_function_need_gp ()
3380 /* We never need a GP for Windows/NT or VMS. */
3381 if (TARGET_WINDOWS_NT
|| TARGET_OPEN_VMS
)
3384 #ifdef TARGET_PROFILING_NEEDS_GP
3389 #ifdef ASM_OUTPUT_MI_THUNK
3390 if (current_function_is_thunk
)
3394 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
3395 Even if we are a static function, we still need to do this in case
3396 our address is taken and passed to something like qsort. */
3398 push_topmost_sequence ();
3399 insn
= get_insns ();
3400 pop_topmost_sequence ();
3402 for (; insn
; insn
= NEXT_INSN (insn
))
3403 if (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
3404 && GET_CODE (PATTERN (insn
)) != USE
3405 && GET_CODE (PATTERN (insn
)) != CLOBBER
)
3407 enum attr_type type
= get_attr_type (insn
);
3408 if (type
== TYPE_LDSYM
|| type
== TYPE_JSR
)
3415 /* Write a version stamp. Don't write anything if we are running as a
3416 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
3423 alpha_write_verstamp (file
)
3424 FILE *file ATTRIBUTE_UNUSED
;
3427 fprintf (file
, "\t.verstamp %d %d\n", MS_STAMP
, LS_STAMP
);
3431 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3435 set_frame_related_p ()
3437 rtx seq
= gen_sequence ();
3440 if (GET_CODE (seq
) == SEQUENCE
)
3442 int i
= XVECLEN (seq
, 0);
3444 RTX_FRAME_RELATED_P (XVECEXP (seq
, 0, i
)) = 1;
3445 return emit_insn (seq
);
3449 seq
= emit_insn (seq
);
3450 RTX_FRAME_RELATED_P (seq
) = 1;
3455 #define FRP(exp) (start_sequence (), exp, set_frame_related_p ())
3457 /* Write function prologue. */
3459 /* On vms we have two kinds of functions:
3461 - stack frame (PROC_STACK)
3462 these are 'normal' functions with local vars and which are
3463 calling other functions
3464 - register frame (PROC_REGISTER)
3465 keeps all data in registers, needs no stack
3467 We must pass this to the assembler so it can generate the
3468 proper pdsc (procedure descriptor)
3469 This is done with the '.pdesc' command.
3471 On not-vms, we don't really differentiate between the two, as we can
3472 simply allocate stack without saving registers. */
3475 alpha_expand_prologue ()
3477 /* Registers to save. */
3478 unsigned long imask
= 0;
3479 unsigned long fmask
= 0;
3480 /* Stack space needed for pushing registers clobbered by us. */
3481 HOST_WIDE_INT sa_size
;
3482 /* Complete stack size needed. */
3483 HOST_WIDE_INT frame_size
;
3484 /* Offset from base reg to register save area. */
3485 HOST_WIDE_INT reg_offset
;
3489 sa_size
= alpha_sa_size ();
3491 frame_size
= get_frame_size ();
3492 if (TARGET_OPEN_VMS
)
3493 frame_size
= ALPHA_ROUND (sa_size
3494 + (vms_is_stack_procedure
? 8 : 0)
3496 + current_function_pretend_args_size
);
3498 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3500 + ALPHA_ROUND (frame_size
3501 + current_function_pretend_args_size
));
3503 if (TARGET_OPEN_VMS
)
3506 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3508 alpha_sa_mask (&imask
, &fmask
);
3510 /* Adjust the stack by the frame size. If the frame size is > 4096
3511 bytes, we need to be sure we probe somewhere in the first and last
3512 4096 bytes (we can probably get away without the latter test) and
3513 every 8192 bytes in between. If the frame size is > 32768, we
3514 do this in a loop. Otherwise, we generate the explicit probe
3517 Note that we are only allowed to adjust sp once in the prologue. */
3519 if (frame_size
<= 32768)
3521 if (frame_size
> 4096)
3526 emit_insn (gen_probe_stack (GEN_INT (-probed
)));
3527 while ((probed
+= 8192) < frame_size
);
3529 /* We only have to do this probe if we aren't saving registers. */
3530 if (sa_size
== 0 && probed
+ 4096 < frame_size
)
3531 emit_insn (gen_probe_stack (GEN_INT (-frame_size
)));
3534 if (frame_size
!= 0)
3536 FRP (emit_insn (gen_adddi3 (stack_pointer_rtx
, stack_pointer_rtx
,
3537 GEN_INT (-frame_size
))));
3542 /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3543 number of 8192 byte blocks to probe. We then probe each block
3544 in the loop and then set SP to the proper location. If the
3545 amount remaining is > 4096, we have to do one more probe if we
3546 are not saving any registers. */
3548 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
3549 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
3550 rtx ptr
= gen_rtx_REG (DImode
, 22);
3551 rtx count
= gen_rtx_REG (DImode
, 23);
3554 emit_move_insn (count
, GEN_INT (blocks
));
3555 emit_insn (gen_adddi3 (ptr
, stack_pointer_rtx
, GEN_INT (4096)));
3557 /* Because of the difficulty in emitting a new basic block this
3558 late in the compilation, generate the loop as a single insn. */
3559 emit_insn (gen_prologue_stack_probe_loop (count
, ptr
));
3561 if (leftover
> 4096 && sa_size
== 0)
3563 rtx last
= gen_rtx_MEM (DImode
, plus_constant (ptr
, -leftover
));
3564 MEM_VOLATILE_P (last
) = 1;
3565 emit_move_insn (last
, const0_rtx
);
3568 if (TARGET_WINDOWS_NT
)
3570 /* For NT stack unwind (done by 'reverse execution'), it's
3571 not OK to take the result of a loop, even though the value
3572 is already in ptr, so we reload it via a single operation
3573 and subtract it to sp.
3575 Yes, that's correct -- we have to reload the whole constant
3576 into a temporary via ldah+lda then subtract from sp. To
3577 ensure we get ldah+lda, we use a special pattern. */
3579 HOST_WIDE_INT lo
, hi
;
3580 lo
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
3581 hi
= frame_size
- lo
;
3583 emit_move_insn (ptr
, GEN_INT (hi
));
3584 emit_insn (gen_nt_lda (ptr
, GEN_INT (lo
)));
3585 seq
= emit_insn (gen_subdi3 (stack_pointer_rtx
, stack_pointer_rtx
,
3590 seq
= emit_insn (gen_adddi3 (stack_pointer_rtx
, ptr
,
3591 GEN_INT (-leftover
)));
3594 /* This alternative is special, because the DWARF code cannot
3595 possibly intuit through the loop above. So we invent this
3596 note it looks at instead. */
3597 RTX_FRAME_RELATED_P (seq
) = 1;
3599 = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
3600 gen_rtx_SET (VOIDmode
, stack_pointer_rtx
,
3601 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3602 GEN_INT (-frame_size
))),
3606 /* Cope with very large offsets to the register save area. */
3607 sa_reg
= stack_pointer_rtx
;
3608 if (reg_offset
+ sa_size
> 0x8000)
3610 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
3613 if (low
+ sa_size
<= 0x8000)
3614 bias
= reg_offset
- low
, reg_offset
= low
;
3616 bias
= reg_offset
, reg_offset
= 0;
3618 sa_reg
= gen_rtx_REG (DImode
, 24);
3619 FRP (emit_insn (gen_adddi3 (sa_reg
, stack_pointer_rtx
, GEN_INT (bias
))));
3622 /* Save regs in stack order. Beginning with VMS PV. */
3623 if (TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3625 mem
= gen_rtx_MEM (DImode
, stack_pointer_rtx
);
3626 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3627 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_PV
)));
3630 /* Save register RA next. */
3631 if (imask
& (1L << REG_RA
))
3633 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
3634 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3635 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, REG_RA
)));
3636 imask
&= ~(1L << REG_RA
);
3640 /* Now save any other registers required to be saved. */
3641 for (i
= 0; i
< 32; i
++)
3642 if (imask
& (1L << i
))
3644 mem
= gen_rtx_MEM (DImode
, plus_constant (sa_reg
, reg_offset
));
3645 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3646 FRP (emit_move_insn (mem
, gen_rtx_REG (DImode
, i
)));
3650 for (i
= 0; i
< 32; i
++)
3651 if (fmask
& (1L << i
))
3653 mem
= gen_rtx_MEM (DFmode
, plus_constant (sa_reg
, reg_offset
));
3654 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3655 FRP (emit_move_insn (mem
, gen_rtx_REG (DFmode
, i
+32)));
3659 if (TARGET_OPEN_VMS
)
3661 if (!vms_is_stack_procedure
)
3663 /* Register frame procedures fave the fp. */
3664 FRP (emit_move_insn (gen_rtx_REG (DImode
, vms_save_fp_regno
),
3665 hard_frame_pointer_rtx
));
3668 if (vms_base_regno
!= REG_PV
)
3669 FRP (emit_move_insn (gen_rtx_REG (DImode
, vms_base_regno
),
3670 gen_rtx_REG (DImode
, REG_PV
)));
3672 if (vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
3674 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
3677 /* If we have to allocate space for outgoing args, do it now. */
3678 if (current_function_outgoing_args_size
!= 0)
3680 FRP (emit_move_insn (stack_pointer_rtx
,
3681 plus_constant (hard_frame_pointer_rtx
,
3682 - ALPHA_ROUND (current_function_outgoing_args_size
))));
3687 /* If we need a frame pointer, set it from the stack pointer. */
3688 if (frame_pointer_needed
)
3690 if (TARGET_CAN_FAULT_IN_PROLOGUE
)
3691 FRP (emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
));
3694 /* This must always be the last instruction in the
3695 prologue, thus we emit a special move + clobber. */
3696 FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx
,
3697 stack_pointer_rtx
, sa_reg
)));
3702 /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3703 the prologue, for exception handling reasons, we cannot do this for
3704 any insn that might fault. We could prevent this for mems with a
3705 (clobber:BLK (scratch)), but this doesn't work for fp insns. So we
3706 have to prevent all such scheduling with a blockage.
3708 Linux, on the other hand, never bothered to implement OSF/1's
3709 exception handling, and so doesn't care about such things. Anyone
3710 planning to use dwarf2 frame-unwind info can also omit the blockage. */
3712 if (! TARGET_CAN_FAULT_IN_PROLOGUE
)
3713 emit_insn (gen_blockage ());
3716 /* Output the textual info surrounding the prologue. */
3719 alpha_start_function (file
, fnname
, decl
)
3722 tree decl ATTRIBUTE_UNUSED
;
3724 unsigned long imask
= 0;
3725 unsigned long fmask
= 0;
3726 /* Stack space needed for pushing registers clobbered by us. */
3727 HOST_WIDE_INT sa_size
;
3728 /* Complete stack size needed. */
3729 HOST_WIDE_INT frame_size
;
3730 /* Offset from base reg to register save area. */
3731 HOST_WIDE_INT reg_offset
;
3732 char *entry_label
= (char *) alloca (strlen (fnname
) + 6);
3735 sa_size
= alpha_sa_size ();
3737 frame_size
= get_frame_size ();
3738 if (TARGET_OPEN_VMS
)
3739 frame_size
= ALPHA_ROUND (sa_size
3740 + (vms_is_stack_procedure
? 8 : 0)
3742 + current_function_pretend_args_size
);
3744 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3746 + ALPHA_ROUND (frame_size
3747 + current_function_pretend_args_size
));
3749 if (TARGET_OPEN_VMS
)
3752 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3754 alpha_sa_mask (&imask
, &fmask
);
3756 /* Ecoff can handle multiple .file directives, so put out file and lineno.
3757 We have to do that before the .ent directive as we cannot switch
3758 files within procedures with native ecoff because line numbers are
3759 linked to procedure descriptors.
3760 Outputting the lineno helps debugging of one line functions as they
3761 would otherwise get no line number at all. Please note that we would
3762 like to put out last_linenum from final.c, but it is not accessible. */
3764 if (write_symbols
== SDB_DEBUG
)
3766 ASM_OUTPUT_SOURCE_FILENAME (file
,
3767 DECL_SOURCE_FILE (current_function_decl
));
3768 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
3769 ASM_OUTPUT_SOURCE_LINE (file
,
3770 DECL_SOURCE_LINE (current_function_decl
));
3773 /* Issue function start and label. */
3774 if (TARGET_OPEN_VMS
|| !flag_inhibit_size_directive
)
3776 fputs ("\t.ent ", file
);
3777 assemble_name (file
, fnname
);
3781 strcpy (entry_label
, fnname
);
3782 if (TARGET_OPEN_VMS
)
3783 strcat (entry_label
, "..en");
3784 ASM_OUTPUT_LABEL (file
, entry_label
);
3785 inside_function
= TRUE
;
3787 if (TARGET_OPEN_VMS
)
3788 fprintf (file
, "\t.base $%d\n", vms_base_regno
);
3790 if (!TARGET_OPEN_VMS
&& TARGET_IEEE_CONFORMANT
3791 && !flag_inhibit_size_directive
)
3793 /* Set flags in procedure descriptor to request IEEE-conformant
3794 math-library routines. The value we set it to is PDSC_EXC_IEEE
3795 (/usr/include/pdsc.h). */
3796 fputs ("\t.eflag 48\n", file
);
3799 /* Set up offsets to alpha virtual arg/local debugging pointer. */
3800 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
3801 alpha_arg_offset
= -frame_size
+ 48;
3803 /* Describe our frame. If the frame size is larger than an integer,
3804 print it as zero to avoid an assembler error. We won't be
3805 properly describing such a frame, but that's the best we can do. */
3806 if (TARGET_OPEN_VMS
)
3808 fprintf (file
, "\t.frame $%d,", vms_unwind_regno
);
3809 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3810 frame_size
>= (1l << 31) ? 0 : frame_size
);
3811 fputs (",$26,", file
);
3812 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, reg_offset
);
3815 else if (!flag_inhibit_size_directive
)
3817 fprintf (file
, "\t.frame $%d,",
3818 (frame_pointer_needed
3819 ? HARD_FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
));
3820 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3821 frame_size
>= (1l << 31) ? 0 : frame_size
);
3822 fprintf (file
, ",$26,%d\n", current_function_pretend_args_size
);
3825 /* Describe which registers were spilled. */
3826 if (TARGET_OPEN_VMS
)
3829 /* ??? Does VMS care if mask contains ra? The old code did'nt
3830 set it, so I don't here. */
3831 fprintf (file
, "\t.mask 0x%lx,0\n", imask
& ~(1L << REG_RA
));
3833 fprintf (file
, "\t.fmask 0x%lx,0\n", fmask
);
3834 if (!vms_is_stack_procedure
)
3835 fprintf (file
, "\t.fp_save $%d\n", vms_save_fp_regno
);
3837 else if (!flag_inhibit_size_directive
)
3841 fprintf (file
, "\t.mask 0x%lx,", imask
);
3842 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3843 frame_size
>= (1l << 31) ? 0 : reg_offset
- frame_size
);
3846 for (i
= 0; i
< 32; ++i
)
3847 if (imask
& (1L << i
))
3853 fprintf (file
, "\t.fmask 0x%lx,", fmask
);
3854 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
3855 frame_size
>= (1l << 31) ? 0 : reg_offset
- frame_size
);
3860 /* Emit GP related things. It is rather unfortunate about the alignment
3861 issues surrounding a CODE_LABEL that forces us to do the label in
3863 if (!TARGET_OPEN_VMS
&& !TARGET_WINDOWS_NT
)
3865 alpha_function_needs_gp
= alpha_does_function_need_gp ();
3866 if (alpha_function_needs_gp
)
3867 fputs ("\tldgp $29,0($27)\n", file
);
3870 assemble_name (file
, fnname
);
3871 fputs ("..ng:\n", file
);
3875 /* Ifdef'ed cause readonly_section and link_section are only
3877 readonly_section ();
3878 fprintf (file
, "\t.align 3\n");
3879 assemble_name (file
, fnname
); fputs ("..na:\n", file
);
3880 fputs ("\t.ascii \"", file
);
3881 assemble_name (file
, fnname
);
3882 fputs ("\\0\"\n", file
);
3885 fprintf (file
, "\t.align 3\n");
3886 fputs ("\t.name ", file
);
3887 assemble_name (file
, fnname
);
3888 fputs ("..na\n", file
);
3889 ASM_OUTPUT_LABEL (file
, fnname
);
3890 fprintf (file
, "\t.pdesc ");
3891 assemble_name (file
, fnname
);
3892 fprintf (file
, "..en,%s\n", vms_is_stack_procedure
? "stack" : "reg");
3893 alpha_need_linkage (fnname
, 1);
3898 /* Emit the .prologue note at the scheduled end of the prologue. */
3901 output_end_prologue (file
)
3904 if (TARGET_OPEN_VMS
)
3905 fputs ("\t.prologue\n", file
);
3906 else if (TARGET_WINDOWS_NT
)
3907 fputs ("\t.prologue 0\n", file
);
3908 else if (!flag_inhibit_size_directive
)
3909 fprintf (file
, "\t.prologue %d\n", alpha_function_needs_gp
);
3912 /* Write function epilogue. */
3914 /* ??? At some point we will want to support full unwind, and so will
3915 need to mark the epilogue as well. At the moment, we just confuse
3918 #define FRP(exp) exp
3921 alpha_expand_epilogue ()
3923 /* Registers to save. */
3924 unsigned long imask
= 0;
3925 unsigned long fmask
= 0;
3926 /* Stack space needed for pushing registers clobbered by us. */
3927 HOST_WIDE_INT sa_size
;
3928 /* Complete stack size needed. */
3929 HOST_WIDE_INT frame_size
;
3930 /* Offset from base reg to register save area. */
3931 HOST_WIDE_INT reg_offset
;
3932 int fp_is_frame_pointer
, fp_offset
;
3933 rtx sa_reg
, sa_reg_exp
= NULL
;
3934 rtx sp_adj1
, sp_adj2
, mem
;
3937 sa_size
= alpha_sa_size ();
3939 frame_size
= get_frame_size ();
3940 if (TARGET_OPEN_VMS
)
3941 frame_size
= ALPHA_ROUND (sa_size
3942 + (vms_is_stack_procedure
? 8 : 0)
3944 + current_function_pretend_args_size
);
3946 frame_size
= (ALPHA_ROUND (current_function_outgoing_args_size
)
3948 + ALPHA_ROUND (frame_size
3949 + current_function_pretend_args_size
));
3951 if (TARGET_OPEN_VMS
)
3954 reg_offset
= ALPHA_ROUND (current_function_outgoing_args_size
);
3956 alpha_sa_mask (&imask
, &fmask
);
3958 fp_is_frame_pointer
= ((TARGET_OPEN_VMS
&& vms_is_stack_procedure
)
3959 || (!TARGET_OPEN_VMS
&& frame_pointer_needed
));
3963 /* If we have a frame pointer, restore SP from it. */
3964 if ((TARGET_OPEN_VMS
3965 && vms_unwind_regno
== HARD_FRAME_POINTER_REGNUM
)
3966 || (!TARGET_OPEN_VMS
&& frame_pointer_needed
))
3968 FRP (emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
));
3971 /* Cope with very large offsets to the register save area. */
3972 sa_reg
= stack_pointer_rtx
;
3973 if (reg_offset
+ sa_size
> 0x8000)
3975 int low
= ((reg_offset
& 0xffff) ^ 0x8000) - 0x8000;
3978 if (low
+ sa_size
<= 0x8000)
3979 bias
= reg_offset
- low
, reg_offset
= low
;
3981 bias
= reg_offset
, reg_offset
= 0;
3983 sa_reg
= gen_rtx_REG (DImode
, 22);
3984 sa_reg_exp
= plus_constant (stack_pointer_rtx
, bias
);
3986 FRP (emit_move_insn (sa_reg
, sa_reg_exp
));
3989 /* Restore registers in order, excepting a true frame pointer. */
3991 if (! alpha_eh_epilogue_sp_ofs
)
3993 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, reg_offset
));
3994 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
3995 FRP (emit_move_insn (gen_rtx_REG (DImode
, REG_RA
), mem
));
3998 imask
&= ~(1L << REG_RA
);
4000 for (i
= 0; i
< 32; ++i
)
4001 if (imask
& (1L << i
))
4003 if (i
== HARD_FRAME_POINTER_REGNUM
&& fp_is_frame_pointer
)
4004 fp_offset
= reg_offset
;
4007 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, reg_offset
));
4008 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
4009 FRP (emit_move_insn (gen_rtx_REG (DImode
, i
), mem
));
4014 for (i
= 0; i
< 32; ++i
)
4015 if (fmask
& (1L << i
))
4017 mem
= gen_rtx_MEM (DFmode
, plus_constant(sa_reg
, reg_offset
));
4018 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
4019 FRP (emit_move_insn (gen_rtx_REG (DFmode
, i
+32), mem
));
4024 if (frame_size
|| alpha_eh_epilogue_sp_ofs
)
4026 sp_adj1
= stack_pointer_rtx
;
4028 if (alpha_eh_epilogue_sp_ofs
)
4030 sp_adj1
= gen_rtx_REG (DImode
, 23);
4031 emit_move_insn (sp_adj1
,
4032 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
4033 alpha_eh_epilogue_sp_ofs
));
4036 /* If the stack size is large, begin computation into a temporary
4037 register so as not to interfere with a potential fp restore,
4038 which must be consecutive with an SP restore. */
4039 if (frame_size
< 32768)
4040 sp_adj2
= GEN_INT (frame_size
);
4041 else if (frame_size
< 0x40007fffL
)
4043 int low
= ((frame_size
& 0xffff) ^ 0x8000) - 0x8000;
4045 sp_adj2
= plus_constant (sp_adj1
, frame_size
- low
);
4046 if (sa_reg_exp
&& rtx_equal_p (sa_reg_exp
, sp_adj2
))
4050 sp_adj1
= gen_rtx_REG (DImode
, 23);
4051 FRP (emit_move_insn (sp_adj1
, sp_adj2
));
4053 sp_adj2
= GEN_INT (low
);
4057 rtx tmp
= gen_rtx_REG (DImode
, 23);
4058 FRP (sp_adj2
= alpha_emit_set_const (tmp
, DImode
, frame_size
, 3));
4061 /* We can't drop new things to memory this late, afaik,
4062 so build it up by pieces. */
4063 FRP (sp_adj2
= alpha_emit_set_long_const (tmp
, frame_size
,
4064 -(frame_size
< 0)));
4070 /* From now on, things must be in order. So emit blockages. */
4072 /* Restore the frame pointer. */
4073 if (fp_is_frame_pointer
)
4075 emit_insn (gen_blockage ());
4076 mem
= gen_rtx_MEM (DImode
, plus_constant(sa_reg
, fp_offset
));
4077 MEM_ALIAS_SET (mem
) = alpha_sr_alias_set
;
4078 FRP (emit_move_insn (hard_frame_pointer_rtx
, mem
));
4080 else if (TARGET_OPEN_VMS
)
4082 emit_insn (gen_blockage ());
4083 FRP (emit_move_insn (hard_frame_pointer_rtx
,
4084 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
4087 /* Restore the stack pointer. */
4088 emit_insn (gen_blockage ());
4089 FRP (emit_move_insn (stack_pointer_rtx
,
4090 gen_rtx_PLUS (DImode
, sp_adj1
, sp_adj2
)));
4094 if (TARGET_OPEN_VMS
&& !vms_is_stack_procedure
)
4096 emit_insn (gen_blockage ());
4097 FRP (emit_move_insn (hard_frame_pointer_rtx
,
4098 gen_rtx_REG (DImode
, vms_save_fp_regno
)));
4103 emit_jump_insn (gen_return_internal ());
4106 /* Output the rest of the textual info surrounding the epilogue. */
4109 alpha_end_function (file
, fnname
, decl
)
4112 tree decl ATTRIBUTE_UNUSED
;
4114 /* End the function. */
4115 if (!flag_inhibit_size_directive
)
4117 fputs ("\t.end ", file
);
4118 assemble_name (file
, fnname
);
4121 inside_function
= FALSE
;
4123 /* Show that we know this function if it is called again.
4125 Don't do this for global functions in object files destined for a
4126 shared library because the function may be overridden by the application
4127 or other libraries. Similarly, don't do this for weak functions. */
4129 if (!DECL_WEAK (current_function_decl
)
4130 && (!flag_pic
|| !TREE_PUBLIC (current_function_decl
)))
4131 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
4134 /* Debugging support. */
4138 /* Count the number of sdb related labels are generated (to find block
4139 start and end boundaries). */
4141 int sdb_label_count
= 0;
4143 /* Next label # for each statement. */
4145 static int sym_lineno
= 0;
4147 /* Count the number of .file directives, so that .loc is up to date. */
4149 static int num_source_filenames
= 0;
4151 /* Name of the file containing the current function. */
4153 static const char *current_function_file
= "";
4155 /* Offsets to alpha virtual arg/local debugging pointers. */
4157 long alpha_arg_offset
;
4158 long alpha_auto_offset
;
4160 /* Emit a new filename to a stream. */
4163 alpha_output_filename (stream
, name
)
4167 static int first_time
= TRUE
;
4168 char ltext_label_name
[100];
4173 ++num_source_filenames
;
4174 current_function_file
= name
;
4175 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
4176 output_quoted_string (stream
, name
);
4177 fprintf (stream
, "\n");
4178 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
4179 fprintf (stream
, "\t#@stabs\n");
4182 else if (write_symbols
== DBX_DEBUG
)
4184 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
4185 fprintf (stream
, "%s ", ASM_STABS_OP
);
4186 output_quoted_string (stream
, name
);
4187 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
4190 else if (name
!= current_function_file
4191 && strcmp (name
, current_function_file
) != 0)
4193 if (inside_function
&& ! TARGET_GAS
)
4194 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
4197 ++num_source_filenames
;
4198 current_function_file
= name
;
4199 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
4202 output_quoted_string (stream
, name
);
4203 fprintf (stream
, "\n");
4207 /* Emit a linenumber to a stream. */
4210 alpha_output_lineno (stream
, line
)
4214 if (write_symbols
== DBX_DEBUG
)
4216 /* mips-tfile doesn't understand .stabd directives. */
4218 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4219 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
4222 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);
4225 /* Structure to show the current status of registers and memory. */
4227 struct shadow_summary
4230 unsigned long i
: 31; /* Mask of int regs */
4231 unsigned long fp
: 31; /* Mask of fp regs */
4232 unsigned long mem
: 1; /* mem == imem | fpmem */
4236 static void summarize_insn
PROTO((rtx
, struct shadow_summary
*, int));
4237 static void alpha_handle_trap_shadows
PROTO((rtx
));
4239 /* Summary the effects of expression X on the machine. Update SUM, a pointer
4240 to the summary structure. SET is nonzero if the insn is setting the
4241 object, otherwise zero. */
4244 summarize_insn (x
, sum
, set
)
4246 struct shadow_summary
*sum
;
4249 const char *format_ptr
;
4255 switch (GET_CODE (x
))
4257 /* ??? Note that this case would be incorrect if the Alpha had a
4258 ZERO_EXTRACT in SET_DEST. */
4260 summarize_insn (SET_SRC (x
), sum
, 0);
4261 summarize_insn (SET_DEST (x
), sum
, 1);
4265 summarize_insn (XEXP (x
, 0), sum
, 1);
4269 summarize_insn (XEXP (x
, 0), sum
, 0);
4273 for (i
= ASM_OPERANDS_INPUT_LENGTH (x
) - 1; i
>= 0; i
--)
4274 summarize_insn (ASM_OPERANDS_INPUT (x
, i
), sum
, 0);
4278 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
4279 summarize_insn (XVECEXP (x
, 0, i
), sum
, 0);
4283 summarize_insn (SUBREG_REG (x
), sum
, 0);
4288 int regno
= REGNO (x
);
4289 unsigned long mask
= 1UL << (regno
% 32);
4291 if (regno
== 31 || regno
== 63)
4297 sum
->defd
.i
|= mask
;
4299 sum
->defd
.fp
|= mask
;
4304 sum
->used
.i
|= mask
;
4306 sum
->used
.fp
|= mask
;
4317 /* Find the regs used in memory address computation: */
4318 summarize_insn (XEXP (x
, 0), sum
, 0);
4321 case CONST_INT
: case CONST_DOUBLE
:
4322 case SYMBOL_REF
: case LABEL_REF
: case CONST
:
4325 /* Handle common unary and binary ops for efficiency. */
4326 case COMPARE
: case PLUS
: case MINUS
: case MULT
: case DIV
:
4327 case MOD
: case UDIV
: case UMOD
: case AND
: case IOR
:
4328 case XOR
: case ASHIFT
: case ROTATE
: case ASHIFTRT
: case LSHIFTRT
:
4329 case ROTATERT
: case SMIN
: case SMAX
: case UMIN
: case UMAX
:
4330 case NE
: case EQ
: case GE
: case GT
: case LE
:
4331 case LT
: case GEU
: case GTU
: case LEU
: case LTU
:
4332 summarize_insn (XEXP (x
, 0), sum
, 0);
4333 summarize_insn (XEXP (x
, 1), sum
, 0);
4336 case NEG
: case NOT
: case SIGN_EXTEND
: case ZERO_EXTEND
:
4337 case TRUNCATE
: case FLOAT_EXTEND
: case FLOAT_TRUNCATE
: case FLOAT
:
4338 case FIX
: case UNSIGNED_FLOAT
: case UNSIGNED_FIX
: case ABS
:
4339 case SQRT
: case FFS
:
4340 summarize_insn (XEXP (x
, 0), sum
, 0);
4344 format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
4345 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4346 switch (format_ptr
[i
])
4349 summarize_insn (XEXP (x
, i
), sum
, 0);
4353 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
4354 summarize_insn (XVECEXP (x
, i
, j
), sum
, 0);
4366 /* Ensure a sufficient number of `trapb' insns are in the code when
4367 the user requests code with a trap precision of functions or
4370 In naive mode, when the user requests a trap-precision of
4371 "instruction", a trapb is needed after every instruction that may
4372 generate a trap. This ensures that the code is resumption safe but
4375 When optimizations are turned on, we delay issuing a trapb as long
4376 as possible. In this context, a trap shadow is the sequence of
4377 instructions that starts with a (potentially) trap generating
4378 instruction and extends to the next trapb or call_pal instruction
4379 (but GCC never generates call_pal by itself). We can delay (and
4380 therefore sometimes omit) a trapb subject to the following
4383 (a) On entry to the trap shadow, if any Alpha register or memory
4384 location contains a value that is used as an operand value by some
4385 instruction in the trap shadow (live on entry), then no instruction
4386 in the trap shadow may modify the register or memory location.
4388 (b) Within the trap shadow, the computation of the base register
4389 for a memory load or store instruction may not involve using the
4390 result of an instruction that might generate an UNPREDICTABLE
4393 (c) Within the trap shadow, no register may be used more than once
4394 as a destination register. (This is to make life easier for the
4397 (d) The trap shadow may not include any branch instructions. */
4400 alpha_handle_trap_shadows (insns
)
4403 struct shadow_summary shadow
;
4404 int trap_pending
, exception_nesting
;
4408 exception_nesting
= 0;
4411 shadow
.used
.mem
= 0;
4412 shadow
.defd
= shadow
.used
;
4414 for (i
= insns
; i
; i
= NEXT_INSN (i
))
4416 if (GET_CODE (i
) == NOTE
)
4418 switch (NOTE_LINE_NUMBER (i
))
4420 case NOTE_INSN_EH_REGION_BEG
:
4421 exception_nesting
++;
4426 case NOTE_INSN_EH_REGION_END
:
4427 exception_nesting
--;
4432 case NOTE_INSN_EPILOGUE_BEG
:
4433 if (trap_pending
&& alpha_tp
>= ALPHA_TP_FUNC
)
4438 else if (trap_pending
)
4440 if (alpha_tp
== ALPHA_TP_FUNC
)
4442 if (GET_CODE (i
) == JUMP_INSN
4443 && GET_CODE (PATTERN (i
)) == RETURN
)
4446 else if (alpha_tp
== ALPHA_TP_INSN
)
4450 struct shadow_summary sum
;
4455 sum
.defd
= sum
.used
;
4457 switch (GET_CODE (i
))
4460 /* Annoyingly, get_attr_trap will abort on these. */
4461 if (GET_CODE (PATTERN (i
)) == USE
4462 || GET_CODE (PATTERN (i
)) == CLOBBER
)
4465 summarize_insn (PATTERN (i
), &sum
, 0);
4467 if ((sum
.defd
.i
& shadow
.defd
.i
)
4468 || (sum
.defd
.fp
& shadow
.defd
.fp
))
4470 /* (c) would be violated */
4474 /* Combine shadow with summary of current insn: */
4475 shadow
.used
.i
|= sum
.used
.i
;
4476 shadow
.used
.fp
|= sum
.used
.fp
;
4477 shadow
.used
.mem
|= sum
.used
.mem
;
4478 shadow
.defd
.i
|= sum
.defd
.i
;
4479 shadow
.defd
.fp
|= sum
.defd
.fp
;
4480 shadow
.defd
.mem
|= sum
.defd
.mem
;
4482 if ((sum
.defd
.i
& shadow
.used
.i
)
4483 || (sum
.defd
.fp
& shadow
.used
.fp
)
4484 || (sum
.defd
.mem
& shadow
.used
.mem
))
4486 /* (a) would be violated (also takes care of (b)) */
4487 if (get_attr_trap (i
) == TRAP_YES
4488 && ((sum
.defd
.i
& sum
.used
.i
)
4489 || (sum
.defd
.fp
& sum
.used
.fp
)))
4508 n
= emit_insn_before (gen_trapb (), i
);
4509 PUT_MODE (n
, TImode
);
4510 PUT_MODE (i
, TImode
);
4514 shadow
.used
.mem
= 0;
4515 shadow
.defd
= shadow
.used
;
4520 if ((exception_nesting
> 0 || alpha_tp
>= ALPHA_TP_FUNC
)
4521 && GET_CODE (i
) == INSN
4522 && GET_CODE (PATTERN (i
)) != USE
4523 && GET_CODE (PATTERN (i
)) != CLOBBER
4524 && get_attr_trap (i
) == TRAP_YES
)
4526 if (optimize
&& !trap_pending
)
4527 summarize_insn (PATTERN (i
), &shadow
, 0);
4534 /* Alpha can only issue instruction groups simultaneously if they are
4535 suitibly aligned. This is very processor-specific. */
4537 enum alphaev4_pipe
{
4544 enum alphaev5_pipe
{
4555 static enum alphaev4_pipe alphaev4_insn_pipe
PROTO((rtx
));
4556 static enum alphaev5_pipe alphaev5_insn_pipe
PROTO((rtx
));
4557 static rtx alphaev4_next_group
PROTO((rtx
, int*, int*));
4558 static rtx alphaev5_next_group
PROTO((rtx
, int*, int*));
4559 static rtx alphaev4_next_nop
PROTO((int*));
4560 static rtx alphaev5_next_nop
PROTO((int*));
4562 static void alpha_align_insns
4563 PROTO((rtx
, int, rtx (*)(rtx
, int*, int*), rtx (*)(int*), int));
4565 static enum alphaev4_pipe
4566 alphaev4_insn_pipe (insn
)
4569 if (recog_memoized (insn
) < 0)
4571 if (get_attr_length (insn
) != 4)
4574 switch (get_attr_type (insn
))
4607 static enum alphaev5_pipe
4608 alphaev5_insn_pipe (insn
)
4611 if (recog_memoized (insn
) < 0)
4613 if (get_attr_length (insn
) != 4)
4616 switch (get_attr_type (insn
))
4656 /* IN_USE is a mask of the slots currently filled within the insn group.
4657 The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then
4658 the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
4660 LEN is, of course, the length of the group in bytes. */
4663 alphaev4_next_group (insn
, pin_use
, plen
)
4665 int *pin_use
, *plen
;
4671 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i'
4672 || GET_CODE (PATTERN (insn
)) == CLOBBER
4673 || GET_CODE (PATTERN (insn
)) == USE
)
4678 enum alphaev4_pipe pipe
;
4680 pipe
= alphaev4_insn_pipe (insn
);
4684 /* Force complex instructions to start new groups. */
4688 /* If this is a completely unrecognized insn, its an asm.
4689 We don't know how long it is, so record length as -1 to
4690 signal a needed realignment. */
4691 if (recog_memoized (insn
) < 0)
4694 len
= get_attr_length (insn
);
4698 if (in_use
& EV4_IB0
)
4700 if (in_use
& EV4_IB1
)
4705 in_use
|= EV4_IB0
| EV4_IBX
;
4709 if (in_use
& EV4_IB0
)
4711 if (!(in_use
& EV4_IBX
) || (in_use
& EV4_IB1
))
4719 if (in_use
& EV4_IB1
)
4729 /* Haifa doesn't do well scheduling branches. */
4730 if (GET_CODE (insn
) == JUMP_INSN
)
4734 insn
= next_nonnote_insn (insn
);
4736 if (!insn
|| GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
4739 /* Let Haifa tell us where it thinks insn group boundaries are. */
4740 if (GET_MODE (insn
) == TImode
)
4743 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
4748 insn
= next_nonnote_insn (insn
);
4756 /* IN_USE is a mask of the slots currently filled within the insn group.
4757 The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then
4758 the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
4760 LEN is, of course, the length of the group in bytes. */
4763 alphaev5_next_group (insn
, pin_use
, plen
)
4765 int *pin_use
, *plen
;
4771 if (GET_RTX_CLASS (GET_CODE (insn
)) != 'i'
4772 || GET_CODE (PATTERN (insn
)) == CLOBBER
4773 || GET_CODE (PATTERN (insn
)) == USE
)
4778 enum alphaev5_pipe pipe
;
4780 pipe
= alphaev5_insn_pipe (insn
);
4784 /* Force complex instructions to start new groups. */
4788 /* If this is a completely unrecognized insn, its an asm.
4789 We don't know how long it is, so record length as -1 to
4790 signal a needed realignment. */
4791 if (recog_memoized (insn
) < 0)
4794 len
= get_attr_length (insn
);
4797 /* ??? Most of the places below, we would like to abort, as
4798 it would indicate an error either in Haifa, or in the
4799 scheduling description. Unfortunately, Haifa never
4800 schedules the last instruction of the BB, so we don't
4801 have an accurate TI bit to go off. */
4803 if (in_use
& EV5_E0
)
4805 if (in_use
& EV5_E1
)
4810 in_use
|= EV5_E0
| EV5_E01
;
4814 if (in_use
& EV5_E0
)
4816 if (!(in_use
& EV5_E01
) || (in_use
& EV5_E1
))
4824 if (in_use
& EV5_E1
)
4830 if (in_use
& EV5_FA
)
4832 if (in_use
& EV5_FM
)
4837 in_use
|= EV5_FA
| EV5_FAM
;
4841 if (in_use
& EV5_FA
)
4847 if (in_use
& EV5_FM
)
4860 /* Haifa doesn't do well scheduling branches. */
4861 /* ??? If this is predicted not-taken, slotting continues, except
4862 that no more IBR, FBR, or JSR insns may be slotted. */
4863 if (GET_CODE (insn
) == JUMP_INSN
)
4867 insn
= next_nonnote_insn (insn
);
4869 if (!insn
|| GET_RTX_CLASS (GET_CODE (insn
)) != 'i')
4872 /* Let Haifa tell us where it thinks insn group boundaries are. */
4873 if (GET_MODE (insn
) == TImode
)
4876 if (GET_CODE (insn
) == CLOBBER
|| GET_CODE (insn
) == USE
)
4881 insn
= next_nonnote_insn (insn
);
4890 alphaev4_next_nop (pin_use
)
4893 int in_use
= *pin_use
;
4896 if (!(in_use
& EV4_IB0
))
4901 else if ((in_use
& (EV4_IBX
|EV4_IB1
)) == EV4_IBX
)
4906 else if (TARGET_FP
&& !(in_use
& EV4_IB1
))
4919 alphaev5_next_nop (pin_use
)
4922 int in_use
= *pin_use
;
4925 if (!(in_use
& EV5_E1
))
4930 else if (TARGET_FP
&& !(in_use
& EV5_FA
))
4935 else if (TARGET_FP
&& !(in_use
& EV5_FM
))
4947 /* The instruction group alignment main loop. */
4950 alpha_align_insns (insns
, max_align
, next_group
, next_nop
, gp_in_use
)
4953 rtx (*next_group
) PROTO((rtx
, int*, int*));
4954 rtx (*next_nop
) PROTO((int*));
4957 /* ALIGN is the known alignment for the insn group. */
4959 /* OFS is the offset of the current insn in the insn group. */
4961 int prev_in_use
, in_use
, len
;
4964 /* Let shorten branches care for assigning alignments to code labels. */
4965 shorten_branches (insns
);
4967 align
= (FUNCTION_BOUNDARY
/BITS_PER_UNIT
< max_align
4968 ? FUNCTION_BOUNDARY
/BITS_PER_UNIT
: max_align
);
4970 /* Account for the initial GP load, which happens before the scheduled
4971 prologue we emitted as RTL. */
4972 ofs
= prev_in_use
= 0;
4973 if (alpha_does_function_need_gp())
4975 ofs
= 8 & (align
- 1);
4976 prev_in_use
= gp_in_use
;
4980 if (GET_CODE (i
) == NOTE
)
4981 i
= next_nonnote_insn (i
);
4985 next
= (*next_group
)(i
, &in_use
, &len
);
4987 /* When we see a label, resync alignment etc. */
4988 if (GET_CODE (i
) == CODE_LABEL
)
4990 int new_align
= 1 << label_to_alignment (i
);
4991 if (new_align
>= align
)
4993 align
= new_align
< max_align
? new_align
: max_align
;
4996 else if (ofs
& (new_align
-1))
4997 ofs
= (ofs
| (new_align
-1)) + 1;
5002 /* Handle complex instructions special. */
5003 else if (in_use
== 0)
5005 /* Asms will have length < 0. This is a signal that we have
5006 lost alignment knowledge. Assume, however, that the asm
5007 will not mis-align instructions. */
5016 /* If the known alignment is smaller than the recognized insn group,
5017 realign the output. */
5018 else if (align
< len
)
5020 int new_log_align
= len
> 8 ? 4 : 3;
5023 where
= prev_nonnote_insn (i
);
5024 if (!where
|| GET_CODE (where
) != CODE_LABEL
)
5027 emit_insn_before (gen_realign (GEN_INT (new_log_align
)), where
);
5028 align
= 1 << new_log_align
;
5032 /* If the group won't fit in the same INT16 as the previous,
5033 we need to add padding to keep the group together. Rather
5034 than simply leaving the insn filling to the assembler, we
5035 can make use of the knowledge of what sorts of instructions
5036 were issued in the previous group to make sure that all of
5037 the added nops are really free. */
5038 else if (ofs
+ len
> align
)
5040 int nop_count
= (align
- ofs
) / 4;
5043 /* Insert nops before labels and branches to truely merge the
5044 execution of the nops with the previous instruction group. */
5045 where
= prev_nonnote_insn (i
);
5048 if (GET_CODE (where
) == CODE_LABEL
)
5050 rtx where2
= prev_nonnote_insn (where
);
5051 if (where2
&& GET_CODE (where2
) == JUMP_INSN
)
5054 else if (GET_CODE (where
) != JUMP_INSN
)
5061 emit_insn_before ((*next_nop
)(&prev_in_use
), where
);
5062 while (--nop_count
);
5066 ofs
= (ofs
+ len
) & (align
- 1);
5067 prev_in_use
= in_use
;
5073 /* Machine dependant reorg pass. */
5079 if (alpha_tp
!= ALPHA_TP_PROG
|| flag_exceptions
)
5080 alpha_handle_trap_shadows (insns
);
5083 /* Due to the number of extra trapb insns, don't bother fixing up
5084 alignment when trap precision is instruction. Moreover, we can
5085 only do our job when sched2 is run and Haifa is our scheduler. */
5086 if (optimize
&& !optimize_size
5087 && alpha_tp
!= ALPHA_TP_INSN
5088 && flag_schedule_insns_after_reload
)
5090 if (alpha_cpu
== PROCESSOR_EV4
)
5091 alpha_align_insns (insns
, 8, alphaev4_next_group
,
5092 alphaev4_next_nop
, EV4_IB0
);
5093 else if (alpha_cpu
== PROCESSOR_EV5
)
5094 alpha_align_insns (insns
, 16, alphaev5_next_group
,
5095 alphaev5_next_nop
, EV5_E01
| EV5_E0
);
5101 /* Check a floating-point value for validity for a particular machine mode. */
5103 static char * const float_strings
[] =
5105 /* These are for FLOAT_VAX. */
5106 "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5107 "-1.70141173319264430e+38",
5108 "2.93873587705571877e-39", /* 2^-128 */
5109 "-2.93873587705571877e-39",
5110 /* These are for the default broken IEEE mode, which traps
5111 on infinity or denormal numbers. */
5112 "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5113 "-3.402823466385288598117e+38",
5114 "1.1754943508222875079687e-38", /* 2^-126 */
5115 "-1.1754943508222875079687e-38",
5118 static REAL_VALUE_TYPE float_values
[8];
5119 static int inited_float_values
= 0;
5122 check_float_value (mode
, d
, overflow
)
5123 enum machine_mode mode
;
5125 int overflow ATTRIBUTE_UNUSED
;
5128 if (TARGET_IEEE
|| TARGET_IEEE_CONFORMANT
|| TARGET_IEEE_WITH_INEXACT
)
5131 if (inited_float_values
== 0)
5134 for (i
= 0; i
< 8; i
++)
5135 float_values
[i
] = REAL_VALUE_ATOF (float_strings
[i
], DFmode
);
5137 inited_float_values
= 1;
5143 REAL_VALUE_TYPE
*fvptr
;
5145 if (TARGET_FLOAT_VAX
)
5146 fvptr
= &float_values
[0];
5148 fvptr
= &float_values
[4];
5150 bcopy ((char *) d
, (char *) &r
, sizeof (REAL_VALUE_TYPE
));
5151 if (REAL_VALUES_LESS (fvptr
[0], r
))
5153 bcopy ((char *) &fvptr
[0], (char *) d
,
5154 sizeof (REAL_VALUE_TYPE
));
5157 else if (REAL_VALUES_LESS (r
, fvptr
[1]))
5159 bcopy ((char *) &fvptr
[1], (char *) d
,
5160 sizeof (REAL_VALUE_TYPE
));
5163 else if (REAL_VALUES_LESS (dconst0
, r
)
5164 && REAL_VALUES_LESS (r
, fvptr
[2]))
5166 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
5169 else if (REAL_VALUES_LESS (r
, dconst0
)
5170 && REAL_VALUES_LESS (fvptr
[3], r
))
5172 bcopy ((char *) &dconst0
, (char *) d
, sizeof (REAL_VALUE_TYPE
));
5182 /* Return the VMS argument type corresponding to MODE. */
5185 alpha_arg_type (mode
)
5186 enum machine_mode mode
;
5191 return TARGET_FLOAT_VAX
? FF
: FS
;
5193 return TARGET_FLOAT_VAX
? FD
: FT
;
5199 /* Return an rtx for an integer representing the VMS Argument Information
5203 alpha_arg_info_reg_val (cum
)
5204 CUMULATIVE_ARGS cum
;
5206 unsigned HOST_WIDE_INT regval
= cum
.num_args
;
5209 for (i
= 0; i
< 6; i
++)
5210 regval
|= ((int) cum
.atypes
[i
]) << (i
* 3 + 8);
5212 return GEN_INT (regval
);
5215 /* Structure to collect function names for final output
5218 enum links_kind
{KIND_UNUSED
, KIND_LOCAL
, KIND_EXTERN
};
5221 struct alpha_links
{
5222 struct alpha_links
*next
;
5224 enum links_kind kind
;
5227 static struct alpha_links
*alpha_links_base
= 0;
5229 /* Make (or fake) .linkage entry for function call.
5231 IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
5234 alpha_need_linkage (name
, is_local
)
5239 struct alpha_links
*lptr
, *nptr
;
5244 /* Is this name already defined ? */
5246 for (lptr
= alpha_links_base
; lptr
; lptr
= lptr
->next
)
5247 if (strcmp (lptr
->name
, name
) == 0)
5251 /* Defined here but external assumed. */
5252 if (lptr
->kind
== KIND_EXTERN
)
5253 lptr
->kind
= KIND_LOCAL
;
5257 /* Used here but unused assumed. */
5258 if (lptr
->kind
== KIND_UNUSED
)
5259 lptr
->kind
= KIND_LOCAL
;
5264 nptr
= (struct alpha_links
*) xmalloc (sizeof (struct alpha_links
));
5265 nptr
->next
= alpha_links_base
;
5266 nptr
->name
= xstrdup (name
);
5268 /* Assume external if no definition. */
5269 nptr
->kind
= (is_local
? KIND_UNUSED
: KIND_EXTERN
);
5271 /* Ensure we have an IDENTIFIER so assemble_name can mark is used. */
5272 get_identifier (name
);
5274 alpha_links_base
= nptr
;
5281 alpha_write_linkage (stream
)
5284 struct alpha_links
*lptr
, *nptr
;
5286 readonly_section ();
5288 fprintf (stream
, "\t.align 3\n");
5290 for (lptr
= alpha_links_base
; lptr
; lptr
= nptr
)
5294 if (lptr
->kind
== KIND_UNUSED
5295 || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr
->name
)))
5298 fprintf (stream
, "$%s..lk:\n", lptr
->name
);
5299 if (lptr
->kind
== KIND_LOCAL
)
5301 /* Local and used, build linkage pair. */
5302 fprintf (stream
, "\t.quad %s..en\n", lptr
->name
);
5303 fprintf (stream
, "\t.quad %s\n", lptr
->name
);
5306 /* External and used, request linkage pair. */
5307 fprintf (stream
, "\t.linkage %s\n", lptr
->name
);
5314 alpha_need_linkage (name
, is_local
)
5315 char *name ATTRIBUTE_UNUSED
;
5316 int is_local ATTRIBUTE_UNUSED
;
5320 #endif /* OPEN_VMS */