1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@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, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
32 #include "insn-attr.h"
40 /* Save information from a "cmpxx" operation until the branch or scc is
43 rtx alpha_compare_op0
, alpha_compare_op1
;
44 int alpha_compare_fp_p
;
46 /* Save the name of the current function as used by the assembler. This
47 is used by the epilogue. */
49 char *alpha_function_name
;
51 /* Nonzero if the current function needs gp. */
53 int alpha_function_needs_gp
;
55 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
63 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
65 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
71 /* Returns 1 if OP is either the constant zero or a register. If a
72 register, it must be in the proper mode unless MODE is VOIDmode. */
75 reg_or_0_operand (op
, mode
)
77 enum machine_mode mode
;
79 return op
== const0_rtx
|| register_operand (op
, mode
);
82 /* Return 1 if OP is an 8-bit constant or any register. */
85 reg_or_8bit_operand (op
, mode
)
87 enum machine_mode mode
;
89 return ((GET_CODE (op
) == CONST_INT
90 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
91 || register_operand (op
, mode
));
94 /* Return 1 if the operand is a valid second operand to an add insn. */
97 add_operand (op
, mode
)
99 enum machine_mode mode
;
101 if (GET_CODE (op
) == CONST_INT
)
102 return ((unsigned HOST_WIDE_INT
) (INTVAL (op
) + 0x8000) < 0x10000
103 || ((INTVAL (op
) & 0xffff) == 0
104 && (INTVAL (op
) >> 31 == -1
105 || INTVAL (op
) >> 31 == 0)));
107 return register_operand (op
, mode
);
110 /* Return 1 if the operand is a valid second operand to a sign-extending
114 sext_add_operand (op
, mode
)
116 enum machine_mode mode
;
118 if (GET_CODE (op
) == CONST_INT
)
119 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 255
120 || (unsigned HOST_WIDE_INT
) (- INTVAL (op
)) < 255);
122 return register_operand (op
, mode
);
125 /* Return 1 if OP is the constant 4 or 8. */
128 const48_operand (op
, mode
)
130 enum machine_mode mode
;
132 return (GET_CODE (op
) == CONST_INT
133 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
136 /* Return 1 if OP is a valid first operand to an AND insn. */
139 and_operand (op
, mode
)
141 enum machine_mode mode
;
143 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
144 return (zap_mask (CONST_DOUBLE_LOW (op
))
145 && zap_mask (CONST_DOUBLE_HIGH (op
)));
147 if (GET_CODE (op
) == CONST_INT
)
148 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
149 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
150 || zap_mask (INTVAL (op
)));
152 return register_operand (op
, mode
);
155 /* Return 1 if OP is a constant that is the width, in bits, of an integral
156 mode smaller than DImode. */
159 mode_width_operand (op
, mode
)
161 enum machine_mode mode
;
163 return (GET_CODE (op
) == CONST_INT
164 && (INTVAL (op
) == 8 || INTVAL (op
) == 16 || INTVAL (op
) == 32));
167 /* Return 1 if OP is a constant that is the width of an integral machine mode
168 smaller than an integer. */
171 mode_mask_operand (op
, mode
)
173 enum machine_mode mode
;
175 #if HOST_BITS_PER_WIDE_INT == 32
176 if (GET_CODE (op
) == CONST_DOUBLE
)
177 return CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == -1;
180 if (GET_CODE (op
) == CONST_INT
)
181 return (INTVAL (op
) == 0xff
182 || INTVAL (op
) == 0xffff
183 #if HOST_BITS_PER_WIDE_INT == 64
184 || INTVAL (op
) == 0xffffffff
189 /* Return 1 if OP is a multiple of 8 less than 64. */
192 mul8_operand (op
, mode
)
194 enum machine_mode mode
;
196 return (GET_CODE (op
) == CONST_INT
197 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
198 && (INTVAL (op
) & 7) == 0);
201 /* Return 1 if OP is the constant zero in floating-point. */
204 fp0_operand (op
, mode
)
206 enum machine_mode mode
;
208 return (GET_MODE (op
) == mode
209 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
212 /* Return 1 if OP is the floating-point constant zero or a register. */
215 reg_or_fp0_operand (op
, mode
)
217 enum machine_mode mode
;
219 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
222 /* Return 1 if OP is a register or a constant integer. */
226 reg_or_cint_operand (op
, mode
)
228 enum machine_mode mode
;
230 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
233 /* Return 1 if OP is a valid operand for the source of a move insn. */
236 input_operand (op
, mode
)
238 enum machine_mode mode
;
240 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
243 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
246 switch (GET_CODE (op
))
251 return mode
== DImode
;
257 if (register_operand (op
, mode
))
259 /* ... fall through ... */
261 return mode
!= HImode
&& mode
!= QImode
&& general_operand (op
, mode
);
264 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
267 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
273 /* Return 1 if OP is a SYMBOL_REF for the current function. */
276 current_function_operand (op
, mode
)
278 enum machine_mode mode
;
280 return (GET_CODE (op
) == SYMBOL_REF
281 && ! strcmp (XSTR (op
, 0), current_function_name
));
284 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
285 comparisons are valid in which insn. */
288 alpha_comparison_operator (op
, mode
)
290 enum machine_mode mode
;
292 enum rtx_code code
= GET_CODE (op
);
294 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
297 return (code
== EQ
|| code
== LE
|| code
== LT
298 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
301 /* Return 1 if OP is a signed comparison operation. */
304 signed_comparison_operator (op
, mode
)
306 enum machine_mode mode
;
308 switch (GET_CODE (op
))
310 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
317 /* Return 1 if this is a divide or modulus operator. */
320 divmod_operator (op
, mode
)
322 enum machine_mode mode
;
324 switch (GET_CODE (op
))
326 case DIV
: case MOD
: case UDIV
: case UMOD
:
333 /* Return 1 if this memory address is a known aligned register plus
334 a constant. It must be a valid address. This means that we can do
335 this as an aligned reference plus some offset.
337 Take into account what reload will do.
339 We could say that out-of-range stack slots are alignable, but that would
340 complicate get_aligned_mem and it isn't worth the trouble since few
341 functions have large stack space. */
344 aligned_memory_operand (op
, mode
)
346 enum machine_mode mode
;
348 if (GET_CODE (op
) == SUBREG
)
350 if (GET_MODE (op
) != mode
)
352 op
= SUBREG_REG (op
);
353 mode
= GET_MODE (op
);
356 if (reload_in_progress
&& GET_CODE (op
) == REG
357 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
358 op
= reg_equiv_mem
[REGNO (op
)];
360 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
361 || ! memory_address_p (mode
, XEXP (op
, 0)))
366 if (GET_CODE (op
) == PLUS
)
369 return (GET_CODE (op
) == REG
370 && (REGNO (op
) == STACK_POINTER_REGNUM
|| op
== frame_pointer_rtx
371 || (REGNO (op
) >= FIRST_VIRTUAL_REGISTER
372 && REGNO (op
) <= LAST_VIRTUAL_REGISTER
)));
375 /* Similar, but return 1 if OP is a MEM which is not alignable. */
378 unaligned_memory_operand (op
, mode
)
380 enum machine_mode mode
;
382 if (GET_CODE (op
) == SUBREG
)
384 if (GET_MODE (op
) != mode
)
386 op
= SUBREG_REG (op
);
387 mode
= GET_MODE (op
);
390 if (reload_in_progress
&& GET_CODE (op
) == REG
391 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
392 op
= reg_equiv_mem
[REGNO (op
)];
394 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
)
399 if (! memory_address_p (mode
, op
))
402 if (GET_CODE (op
) == PLUS
)
405 return (GET_CODE (op
) != REG
406 || (REGNO (op
) != STACK_POINTER_REGNUM
&& op
!= frame_pointer_rtx
407 && (REGNO (op
) < FIRST_VIRTUAL_REGISTER
408 || REGNO (op
) > LAST_VIRTUAL_REGISTER
)));
411 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
414 any_memory_operand (op
, mode
)
416 enum machine_mode mode
;
418 return (GET_CODE (op
) == MEM
419 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
420 || (reload_in_progress
&& GET_CODE (op
) == REG
421 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
422 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
423 && GET_CODE (SUBREG_REG (op
)) == REG
424 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
427 /* REF is an alignable memory location. Place an aligned SImode
428 reference into *PALIGNED_MEM and the number of bits to shift into
432 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
434 rtx
*paligned_mem
, *pbitnum
;
437 HOST_WIDE_INT offset
= 0;
439 if (GET_CODE (ref
) == SUBREG
)
441 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
442 if (BYTES_BIG_ENDIAN
)
443 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
444 - MIN (UNITS_PER_WORD
,
445 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
446 ref
= SUBREG_REG (ref
);
449 if (GET_CODE (ref
) == REG
)
450 ref
= reg_equiv_mem
[REGNO (ref
)];
452 if (reload_in_progress
)
453 base
= find_replacement (&XEXP (ref
, 0));
455 base
= XEXP (ref
, 0);
457 if (GET_CODE (base
) == PLUS
)
458 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
460 *paligned_mem
= gen_rtx (MEM
, SImode
,
461 plus_constant (base
, offset
& ~3));
462 MEM_IN_STRUCT_P (*paligned_mem
) = MEM_IN_STRUCT_P (ref
);
463 MEM_VOLATILE_P (*paligned_mem
) = MEM_VOLATILE_P (ref
);
464 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
466 *pbitnum
= GEN_INT ((offset
& 3) * 8);
469 /* Similar, but just get the address. Handle the two reload cases. */
472 get_unaligned_address (ref
)
476 HOST_WIDE_INT offset
= 0;
478 if (GET_CODE (ref
) == SUBREG
)
480 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
481 if (BYTES_BIG_ENDIAN
)
482 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
483 - MIN (UNITS_PER_WORD
,
484 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
485 ref
= SUBREG_REG (ref
);
488 if (GET_CODE (ref
) == REG
)
489 ref
= reg_equiv_mem
[REGNO (ref
)];
491 if (reload_in_progress
)
492 base
= find_replacement (&XEXP (ref
, 0));
494 base
= XEXP (ref
, 0);
496 if (GET_CODE (base
) == PLUS
)
497 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
499 return plus_constant (base
, offset
);
502 /* Subfunction of the following function. Update the flags of any MEM
503 found in part of X. */
506 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
508 int in_struct_p
, volatile_p
, unchanging_p
;
512 switch (GET_CODE (x
))
516 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
517 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
522 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
527 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
529 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
534 MEM_IN_STRUCT_P (x
) = in_struct_p
;
535 MEM_VOLATILE_P (x
) = volatile_p
;
536 RTX_UNCHANGING_P (x
) = unchanging_p
;
541 /* Given INSN, which is either an INSN or a SEQUENCE generated to
542 perform a memory operation, look for any MEMs in either a SET_DEST or
543 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
544 REF into each of the MEMs found. If REF is not a MEM, don't do
548 alpha_set_memflags (insn
, ref
)
552 /* Note that it is always safe to get these flags, though they won't
553 be what we think if REF is not a MEM. */
554 int in_struct_p
= MEM_IN_STRUCT_P (ref
);
555 int volatile_p
= MEM_VOLATILE_P (ref
);
556 int unchanging_p
= RTX_UNCHANGING_P (ref
);
558 if (GET_CODE (ref
) != MEM
559 || (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
))
562 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
565 /* Try to output insns to set TARGET equal to the constant C if it can be
566 done in less than N insns. Returns 1 if it can be done and the
567 insns have been emitted. If it would take more than N insns, zero is
568 returned and no insns and emitted. */
571 alpha_emit_set_const (target
, c
, n
)
576 HOST_WIDE_INT
new = c
;
579 #if HOST_BITS_PER_WIDE_INT == 64
580 /* We are only called for SImode and DImode. If this is SImode, ensure that
581 we are sign extended to a full word. This does not make any sense when
582 cross-compiling on a narrow machine. */
584 if (GET_MODE (target
) == SImode
)
585 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
588 /* If this is a sign-extended 32-bit constant, we can do this in at most
589 three insns, so do it if we have enough insns left. We always have
590 a sign-extended 32-bit constant when compiling on a narrow machine. */
592 if (HOST_BITS_PER_WIDE_INT
!= 64
593 || c
>> 31 == -1 || c
>> 31 == 0)
595 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
596 HOST_WIDE_INT tmp1
= c
- low
;
598 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
599 HOST_WIDE_INT tmp2
= c
- (high
<< 16) - low
;
600 HOST_WIDE_INT extra
= 0;
606 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
609 if (c
== low
|| (low
== 0 && extra
== 0))
611 emit_move_insn (target
, GEN_INT (c
));
614 else if (n
>= 2 + (extra
!= 0))
616 emit_move_insn (target
, GEN_INT (low
));
618 emit_insn (gen_add2_insn (target
, GEN_INT (extra
<< 16)));
620 emit_insn (gen_add2_insn (target
, GEN_INT (high
<< 16)));
625 /* If we couldn't do it that way, try some other methods (that depend on
626 being able to compute in the target's word size). But if we have no
627 instructions left, don't bother. Also, don't even try if this is
628 SImode (in which case we should have already done something, but
629 do a sanity check here). */
631 if (n
== 1 || HOST_BITS_PER_WIDE_INT
< 64 || GET_MODE (target
) != DImode
)
634 /* First, see if can load a value into the target that is the same as the
635 constant except that all bytes that are 0 are changed to be 0xff. If we
636 can, then we can do a ZAPNOT to obtain the desired constant. */
638 for (i
= 0; i
< 64; i
+= 8)
639 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
640 new |= (HOST_WIDE_INT
) 0xff << i
;
642 if (alpha_emit_set_const (target
, new, n
- 1))
644 emit_insn (gen_anddi3 (target
, target
, GEN_INT (c
| ~ new)));
648 /* Find, see if we can load a related constant and then shift and possibly
649 negate it to get the constant we want. Try this once each increasing
652 for (i
= 1; i
< n
; i
++)
654 /* First try complementing. */
655 if (alpha_emit_set_const (target
, ~ c
, i
))
657 emit_insn (gen_one_cmpldi2 (target
, target
));
661 /* First try to form a constant and do a left shift. We can do this
662 if some low-order bits are zero; the exact_log2 call below tells
663 us that information. The bits we are shifting out could be any
664 value, but here we'll just try the 0- and sign-extended forms of
665 the constant. To try to increase the chance of having the same
666 constant in more than one insn, start at the highest number of
667 bits to shift, but try all possibilities in case a ZAPNOT will
670 if ((bits
= exact_log2 (c
& - c
)) > 0)
671 for (; bits
> 0; bits
--)
672 if (alpha_emit_set_const (target
, c
>> bits
, i
)
673 || alpha_emit_set_const (target
,
674 ((unsigned HOST_WIDE_INT
) c
) >> bits
,
677 emit_insn (gen_ashldi3 (target
, target
, GEN_INT (bits
)));
681 /* Now try high-order zero bits. Here we try the shifted-in bits as
682 all zero and all ones. */
684 if ((bits
= HOST_BITS_PER_WIDE_INT
- floor_log2 (c
) - 1) > 0)
685 for (; bits
> 0; bits
--)
686 if (alpha_emit_set_const (target
, c
<< bits
, i
)
687 || alpha_emit_set_const (target
,
689 | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
692 emit_insn (gen_lshrdi3 (target
, target
, GEN_INT (bits
)));
696 /* Now try high-order 1 bits. We get that with a sign-extension.
697 But one bit isn't enough here. */
699 if ((bits
= HOST_BITS_PER_WIDE_INT
- floor_log2 (~ c
) - 2) > 0)
700 for (; bits
> 0; bits
--)
701 if (alpha_emit_set_const (target
, c
<< bits
, i
)
702 || alpha_emit_set_const (target
,
704 | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
707 emit_insn (gen_ashrdi3 (target
, target
, GEN_INT (bits
)));
715 /* Adjust the cost of a scheduling dependency. Return the new cost of
716 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
719 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
727 /* If the dependence is an anti-dependence, there is no cost. For an
728 output dependence, there is sometimes a cost, but it doesn't seem
729 worth handling those few cases. */
731 if (REG_NOTE_KIND (link
) != 0)
734 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
735 we can sometimes lower the cost. */
737 if (recog_memoized (insn
) >= 0 && get_attr_type (insn
) == TYPE_ST
738 && (set
= single_set (dep_insn
)) != 0
739 && GET_CODE (PATTERN (insn
)) == SET
740 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
741 switch (get_attr_type (dep_insn
))
744 /* No savings here. */
749 /* In these cases, we save one cycle. */
753 /* In all other cases, we save two cycles. */
754 return MAX (0, cost
- 4);
757 /* Another case that needs adjustment is an arithmetic or logical
758 operation. It's cost is usually one cycle, but we default it to
759 two in the MD file. The only case that it is actually two is
760 for the address in loads and stores. */
762 if (recog_memoized (dep_insn
) >= 0
763 && get_attr_type (dep_insn
) == TYPE_IADDLOG
)
764 switch (get_attr_type (insn
))
774 /* The final case is when a compare feeds into an integer branch. The cost
775 is only one cycle in that case. */
777 if (recog_memoized (dep_insn
) >= 0
778 && get_attr_type (dep_insn
) == TYPE_ICMP
779 && recog_memoized (insn
) >= 0
780 && get_attr_type (insn
) == TYPE_IBR
)
783 /* Otherwise, return the default cost. */
788 /* Print an operand. Recognize special options, documented below. */
791 print_operand (file
, x
, code
)
801 /* If this operand is the constant zero, write it as "$31". */
802 if (GET_CODE (x
) == REG
)
803 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
804 else if (x
== CONST0_RTX (GET_MODE (x
)))
805 fprintf (file
, "$31");
807 output_operand_lossage ("invalid %%r value");
812 /* Similar, but for floating-point. */
813 if (GET_CODE (x
) == REG
)
814 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
815 else if (x
== CONST0_RTX (GET_MODE (x
)))
816 fprintf (file
, "$f31");
818 output_operand_lossage ("invalid %%R value");
823 /* Write the 1's complement of a constant. */
824 if (GET_CODE (x
) != CONST_INT
)
825 output_operand_lossage ("invalid %%N value");
827 fprintf (file
, "%ld", ~ INTVAL (x
));
831 /* Write 1 << C, for a constant C. */
832 if (GET_CODE (x
) != CONST_INT
)
833 output_operand_lossage ("invalid %%P value");
835 fprintf (file
, "%ld", (HOST_WIDE_INT
) 1 << INTVAL (x
));
839 /* Write the high-order 16 bits of a constant, sign-extended. */
840 if (GET_CODE (x
) != CONST_INT
)
841 output_operand_lossage ("invalid %%h value");
843 fprintf (file
, "%ld", INTVAL (x
) >> 16);
847 /* Write the low-order 16 bits of a constant, sign-extended. */
848 if (GET_CODE (x
) != CONST_INT
)
849 output_operand_lossage ("invalid %%L value");
851 fprintf (file
, "%ld", (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
855 /* Write mask for ZAP insn. */
856 if (GET_CODE (x
) == CONST_DOUBLE
)
858 HOST_WIDE_INT mask
= 0;
861 value
= CONST_DOUBLE_LOW (x
);
862 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
867 value
= CONST_DOUBLE_HIGH (x
);
868 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
871 mask
|= (1 << (i
+ sizeof (int)));
873 fprintf (file
, "%ld", mask
& 0xff);
876 else if (GET_CODE (x
) == CONST_INT
)
878 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
880 for (i
= 0; i
< 8; i
++, value
>>= 8)
884 fprintf (file
, "%ld", mask
);
887 output_operand_lossage ("invalid %%m value");
891 /* 'b', 'w', or 'l' as the value of the constant. */
892 if (GET_CODE (x
) != CONST_INT
893 || (INTVAL (x
) != 8 && INTVAL (x
) != 16 && INTVAL (x
) != 32))
894 output_operand_lossage ("invalid %%M value");
897 INTVAL (x
) == 8 ? "b" : INTVAL (x
) == 16 ? "w" : "l");
901 /* Similar, except do it from the mask. */
902 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
904 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
906 #if HOST_BITS_PER_WIDE_INT == 32
907 else if (GET_CODE (x
) == CONST_DOUBLE
908 && CONST_DOUBLE_HIGH (x
) == 0
909 && CONST_DOUBLE_LOW (x
) == -1)
912 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
916 output_operand_lossage ("invalid %%U value");
920 /* Write the constant value divided by 8. */
921 if (GET_CODE (x
) != CONST_INT
922 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
923 && (INTVAL (x
) & 7) != 8)
924 output_operand_lossage ("invalid %%s value");
926 fprintf (file
, "%ld", INTVAL (x
) / 8);
930 /* Same, except compute (64 - c) / 8 */
932 if (GET_CODE (x
) != CONST_INT
933 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
934 && (INTVAL (x
) & 7) != 8)
935 output_operand_lossage ("invalid %%s value");
937 fprintf (file
, "%ld", (64 - INTVAL (x
)) / 8);
941 /* Write out comparison name. */
942 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
943 output_operand_lossage ("invalid %%C value");
945 if (GET_CODE (x
) == LEU
)
946 fprintf (file
, "ule");
947 else if (GET_CODE (x
) == LTU
)
948 fprintf (file
, "ult");
950 fprintf (file
, "%s", GET_RTX_NAME (GET_CODE (x
)));
954 /* Similar, but write reversed code. We can't get an unsigned code
956 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
957 output_operand_lossage ("invalid %%D value");
959 fprintf (file
, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x
))));
963 /* Write the divide or modulus operator. */
964 switch (GET_CODE (x
))
967 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
970 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
973 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
976 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
979 output_operand_lossage ("invalid %%E value");
985 /* Write the symbol; if the current function uses GP, write a
987 if (GET_CODE (x
) != SYMBOL_REF
)
988 output_operand_lossage ("invalid %%F value");
990 output_addr_const (file
, x
);
991 if (alpha_function_needs_gp
)
992 fprintf (file
, "..ng");
996 /* Write "_u" for unaligned access. */
997 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
998 fprintf (file
, "_u");
1002 if (GET_CODE (x
) == REG
)
1003 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1004 else if (GET_CODE (x
) == MEM
)
1005 output_address (XEXP (x
, 0));
1007 output_addr_const (file
, x
);
1011 output_operand_lossage ("invalid %%xn code");
1015 /* Do what is necessary for `va_start'. The argument is ignored;
1016 We look at the current function to determine if stdargs or varargs
1017 is used and fill in an initial va_list. A pointer to this constructor
1021 alpha_builtin_saveregs (arglist
)
1024 rtx block
, addr
, argsize
;
1025 tree fntype
= TREE_TYPE (current_function_decl
);
1026 int stdargs
= (TYPE_ARG_TYPES (fntype
) != 0
1027 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
1028 != void_type_node
));
1029 int nregs
= current_function_args_info
;
1031 /* If we have a variable-sized argument already, we will have used all
1032 the registers, so set up to indicate that. */
1034 if (GET_CODE (current_function_arg_offset_rtx
) != CONST_INT
)
1036 argsize
= plus_constant (current_function_arg_offset_rtx
,
1037 ((6 - stdargs
) * UNITS_PER_WORD
1038 + UNITS_PER_WORD
- 1));
1039 argsize
= expand_shift (RSHIFT_EXPR
, Pmode
, argsize
,
1040 build_int_2 (3, 0), argsize
, 0);
1044 /* If we are using memory, deduct the stdarg adjustment from it,
1045 otherwise from the number of registers. Then compute the current
1048 int memargs
= ((INTVAL (current_function_arg_offset_rtx
)
1049 + UNITS_PER_WORD
- 1)
1057 argsize
= GEN_INT (MIN (nregs
, 6) + memargs
);
1060 /* Allocate the va_list constructor */
1061 block
= assign_stack_local (BLKmode
, 4 * UNITS_PER_WORD
, BITS_PER_WORD
);
1062 RTX_UNCHANGING_P (block
) = 1;
1063 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
1065 /* Store the argsize as the __va_arg member. */
1066 emit_move_insn (change_address (block
, DImode
, XEXP (block
, 0)),
1069 /* Store the arg pointer in the __va_stack member. */
1070 emit_move_insn (change_address (block
, Pmode
,
1071 plus_constant (XEXP (block
, 0),
1073 virtual_incoming_args_rtx
);
1075 /* Allocate the integer register space, and store it as the
1076 __va_ireg member. */
1077 addr
= assign_stack_local (BLKmode
, 6 * UNITS_PER_WORD
, -1);
1078 MEM_IN_STRUCT_P (addr
) = 1;
1079 RTX_UNCHANGING_P (addr
) = 1;
1080 RTX_UNCHANGING_P (XEXP (addr
, 0)) = 1;
1082 emit_move_insn (change_address (block
, Pmode
,
1083 plus_constant (XEXP (block
, 0),
1084 2 * UNITS_PER_WORD
)),
1085 copy_to_reg (XEXP (addr
, 0)));
1087 /* Now store the incoming integer registers. */
1091 change_address (addr
, Pmode
,
1092 plus_constant (XEXP (addr
, 0),
1093 nregs
* UNITS_PER_WORD
)),
1096 /* Allocate the FP register space, and store it as the
1097 __va_freg member. */
1098 addr
= assign_stack_local (BLKmode
, 6 * UNITS_PER_WORD
, -1);
1099 MEM_IN_STRUCT_P (addr
) = 1;
1100 RTX_UNCHANGING_P (addr
) = 1;
1101 RTX_UNCHANGING_P (XEXP (addr
, 0)) = 1;
1103 emit_move_insn (change_address (block
, Pmode
,
1104 plus_constant (XEXP (block
, 0),
1105 3 * UNITS_PER_WORD
)),
1106 copy_to_reg (XEXP (addr
, 0)));
1108 /* Now store the incoming floating-point registers. If we are not
1109 to use the floating-point registers, store the integer registers
1110 in those locations too. */
1113 (16 + 32 * (TARGET_FPREGS
!= 0) + nregs
,
1114 change_address (addr
, Pmode
,
1115 plus_constant (XEXP (addr
, 0),
1116 nregs
* UNITS_PER_WORD
)),
1119 /* Return the address of the va_list constructor, but don't put it in a
1120 register. This fails when not optimizing and produces worse code when
1122 return XEXP (block
, 0);
1125 /* This page contains routines that are used to determine what the function
1126 prologue and epilogue code will do and write them out. */
1128 /* Compute the size of the save area in the stack. */
1136 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1137 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
])
1143 /* Return non-zero if this function needs gp. It does if it has
1151 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1152 if (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
1153 && GET_CODE (PATTERN (insn
)) != USE
1154 && GET_CODE (PATTERN (insn
)) != CLOBBER
1155 && get_attr_type (insn
) == TYPE_LDSYM
)
1161 /* Return 1 if GP is dead at after INSN. */
1164 alpha_gp_dead_after (insn
)
1171 /* If we aren't optimizing, don't do this optimization. More importantly,
1172 JUMP_LABEL isn't properly set when not optimizing. */
1177 /* If we are followed by a BARRIER, we don't return. */
1178 if (NEXT_INSN (insn
) && GET_CODE (NEXT_INSN (insn
)) == BARRIER
)
1181 /* Otherwise search for a use of GP before a return. */
1183 for (p
= next_active_insn (insn
); p
; p
= next_active_insn (p
))
1185 if (get_attr_type (p
) == TYPE_LDSYM
1186 || get_attr_type (p
) == TYPE_JSR
)
1192 if (GET_CODE (p
) == JUMP_INSN
)
1194 if (GET_CODE (PATTERN (p
)) == RETURN
)
1197 if (! simplejump_p (p
) || jump_count
++ > 10)
1207 /* Restore any operands destroyed by the attribute calls above. */
1208 insn_extract (insn
);
1213 /* Return 1 if this function can directly return via $26. */
1218 return (reload_completed
&& alpha_sa_size () == 0
1219 && get_frame_size () == 0
1220 && current_function_pretend_args_size
== 0);
1223 /* Write function prologue. */
1226 output_prolog (file
, size
)
1230 HOST_WIDE_INT frame_size
= ((size
+ current_function_outgoing_args_size
1231 + current_function_pretend_args_size
1232 + alpha_sa_size () + 15) & ~15);
1233 int reg_offset
= current_function_outgoing_args_size
;
1234 int start_reg_offset
= reg_offset
;
1235 unsigned reg_mask
= 0;
1238 /* If we need a GP, load it first. */
1239 alpha_function_needs_gp
= alpha_need_gp ();
1241 if (alpha_function_needs_gp
)
1245 fprintf (file
, "\tldgp $29,0($27)\n");
1247 /* If we have a recursive call, put a special label here. */
1248 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1249 if (GET_CODE (insn
) == CALL_INSN
1250 && get_attr_type (insn
) != TYPE_JSR
)
1252 fprintf (file
, "%s..ng:\n", current_function_name
);
1257 /* Adjust the stack by the frame size. If the frame size is > 32768
1258 bytes, we have to load it into a register first and then subtract
1259 from sp. Note that we are only allowed to adjust sp once in the
1262 if (frame_size
> 32768)
1264 HOST_WIDE_INT low
= (frame_size
& 0xffff) - 2 * (frame_size
& 0x8000);
1265 HOST_WIDE_INT tmp1
= frame_size
- low
;
1267 = ((tmp1
>> 16) & 0xfff) - 2 * ((tmp1
>> 16) & 0x8000);
1268 HOST_WIDE_INT tmp2
= frame_size
- (high
<< 16) - low
;
1269 HOST_WIDE_INT extra
= 0;
1272 /* We haven't written code to handle frames > 4GB. */
1273 #if HOST_BITS_PER_LONG_INT == 64
1274 if ((unsigned HOST_WIDE_INT
) frame_size
>> 32 != 0)
1282 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1287 fprintf (file
, "\tlda $28,%d($%d)\n", low
, in_reg
);
1293 fprintf (file
, "\tldah $28,%d($%d)\n", extra
, in_reg
);
1297 fprintf (file
, "\tldah $28,%d($%d)\n", high
, in_reg
);
1299 fprintf (file
, "\tsubq $30,$28,$30\n");
1301 else if (frame_size
)
1302 fprintf (file
, "\tlda $30,-%d($30)\n", frame_size
);
1304 /* Write out the .frame line. If we need a frame pointer, we use
1305 an offset of zero. */
1307 if (frame_pointer_needed
)
1308 fprintf (file
, "\t.frame $15,0,$26\n");
1310 fprintf (file
, "\t.frame $30,%d,$26\n", frame_size
);
1313 /* Save register 26 if it is used. */
1314 if (regs_ever_live
[26])
1316 reg_mask
|= 1 << 26;
1317 fprintf (file
, "\tstq $26,%d($30)\n", reg_offset
);
1321 /* Now save any other used register that are required to be saved. */
1322 for (i
= 0; i
< 32; i
++)
1323 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
] && i
!= 26)
1326 fprintf (file
, "\tstq $%d,%d($30)\n", i
, reg_offset
);
1330 /* Print the register mask and do floating-point saves. */
1332 fprintf (file
, "\t.mask 0x%x,%d\n", reg_mask
,
1333 start_reg_offset
- frame_size
);
1335 start_reg_offset
= reg_offset
;
1338 for (i
= 0; i
< 32; i
++)
1339 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1340 && regs_ever_live
[i
+ 32])
1343 fprintf (file
, "\tstt $f%d,%d($30)\n", i
, reg_offset
);
1347 /* Print the floating-point mask, if we've saved any fp register. */
1349 fprintf (file
, "\t.fmask 0x%x,%d\n", reg_mask
, start_reg_offset
);
1351 /* If we need a frame pointer, set it to the value of incoming stack
1352 which we compute by adding back the frame size pointer. Because we
1353 can subtract one more than we can add, we have to special-case
1354 frame sizes of 32K. Note that there is no restriction that the frame
1355 pointer be updated in one instruction. */
1357 if (frame_pointer_needed
)
1359 if (frame_size
== 32768)
1360 fprintf (file
, "\tlda $15,16384($30)\n\tlda $15,16384($15)\n");
1361 else if (frame_size
> 32768)
1362 fprintf (file
, "\taddq $30,$28,$15\n");
1364 fprintf (file
, "\tlda $15,%d($30)\n", frame_size
);
1368 /* Write function epilogue. */
1371 output_epilog (file
, size
)
1375 rtx insn
= get_last_insn ();
1376 HOST_WIDE_INT frame_size
= ((size
+ current_function_outgoing_args_size
1377 + current_function_pretend_args_size
1378 + alpha_sa_size () + 15) & ~15);
1379 int reg_offset
= current_function_outgoing_args_size
;
1380 int reg_offset_from
= STACK_POINTER_REGNUM
;
1383 /* If the last insn was a BARRIER, we don't have to write anything except
1384 the .end pseudo-op. */
1385 if (GET_CODE (insn
) == NOTE
)
1386 insn
= prev_nonnote_insn (insn
);
1387 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
1389 /* If we have a frame pointer, we restore the registers from an
1390 offset from it, assuming that we can reach the offset. If not,
1391 we have to compute the address using a scratch register. This is
1392 messy, but should not be common. We have to copy the frame
1393 pointer elsewhere here since we will be restoring it before we can
1394 use it to restore the stack pointer. We use $25. */
1396 if (frame_pointer_needed
)
1398 fprintf (file
, "\tbis $15,$15,$25\n");
1400 if (frame_size
< 32768)
1401 reg_offset
-= frame_size
, reg_offset_from
= 25;
1405 = (frame_size
& 0xffff) - 2 * (frame_size
& 0x8000);
1406 HOST_WIDE_INT tmp1
= frame_size
- low
;
1408 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1409 HOST_WIDE_INT tmp2
= frame_size
- (high
<< 16) - low
;
1417 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1422 fprintf (file
, "\tlda $28,%d($%d)\n", low
, in_reg
);
1428 fprintf (file
, "\tldah $28,%d($%d)\n", extra
, in_reg
);
1432 fprintf (file
, "\tldah $28,%d($%d)\n", high
, in_reg
);
1434 fprintf (file
, "\taddq $25,$28,$28\n");
1436 reg_offset_from
= 28;
1440 /* Restore all the registers, starting with the return address
1442 if (regs_ever_live
[26])
1444 fprintf (file
, "\tldq $26,%d($%d)\n", reg_offset
, reg_offset_from
);
1448 /* Now restore any other used register that that we saved. */
1449 for (i
= 0; i
< 32; i
++)
1450 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
]
1453 fprintf (file
, "\tldq $%d,%d($%d)\n",
1454 i
, reg_offset
, reg_offset_from
);
1458 for (i
= 0; i
< 32; i
++)
1459 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1460 && regs_ever_live
[i
+ 32])
1462 fprintf (file
, "\tldt $f%d,%d($%d)\n",
1463 i
, reg_offset
, reg_offset_from
);
1467 /* Restore the stack. If we have a frame pointer, use it. Otherwise,
1468 add the size back into the stack, handling the large frame size. */
1470 if (frame_pointer_needed
)
1471 fprintf (file
, "\tbis $25,$25,$30\n");
1472 else if (frame_size
> 32767)
1475 = (frame_size
& 0xffff) - 2 * (frame_size
& 0x8000);
1476 HOST_WIDE_INT tmp1
= frame_size
- low
;
1478 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1479 HOST_WIDE_INT tmp2
= frame_size
- (high
<< 16) - low
;
1480 HOST_WIDE_INT extra
= 0;
1483 /* We haven't written code to handle frames > 4GB. */
1484 #if HOST_BITS_PER_LONG_INT == 64
1485 if ((unsigned HOST_WIDE_INT
) frame_size
>> 32 != 0)
1493 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1498 fprintf (file
, "\tlda $28,%d($%d)\n", low
, in_reg
);
1504 fprintf (file
, "\tldah $28,%d($%d)\n", extra
, in_reg
);
1508 fprintf (file
, "\tldah $28,%d($%d)\n", high
, in_reg
);
1510 fprintf (file
, "\taddq $30,$28,$30\n");
1512 else if (frame_size
)
1513 fprintf (file
, "\tlda $30,%d($30)\n", frame_size
);
1515 /* Now return to the caller. */
1516 fprintf (file
, "\tret $31,($26),1\n");
1519 /* End the function. */
1520 fprintf (file
, "\t.end %s\n", alpha_function_name
);