1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993 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 /* Non-zero if inside of a function, because the Alpha asm can't
52 handle .files inside of functions. */
54 static int inside_function = FALSE;
56 /* Whether to suppress issuing .loc's because the user attempted
57 to change the filename within a function. */
59 static int ignore_line_number = FALSE;
61 /* Nonzero if the current function needs gp. */
63 int alpha_function_needs_gp;
65 extern char *version_string;
67 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
75 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
77 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
83 /* Returns 1 if OP is either the constant zero or a register. If a
84 register, it must be in the proper mode unless MODE is VOIDmode. */
87 reg_or_0_operand (op, mode)
89 enum machine_mode mode;
91 return op == const0_rtx || register_operand (op, mode);
94 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
98 reg_or_6bit_operand (op, mode)
100 enum machine_mode mode;
102 return ((GET_CODE (op) == CONST_INT
103 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
104 || register_operand (op, mode));
108 /* Return 1 if OP is an 8-bit constant or any register. */
111 reg_or_8bit_operand (op, mode)
113 enum machine_mode mode;
115 return ((GET_CODE (op) == CONST_INT
116 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
117 || register_operand (op, mode));
120 /* Return 1 if the operand is a valid second operand to an add insn. */
123 add_operand (op, mode)
125 enum machine_mode mode;
127 if (GET_CODE (op) == CONST_INT)
128 return ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000
129 || ((INTVAL (op) & 0xffff) == 0
130 && (INTVAL (op) >> 31 == -1
131 || INTVAL (op) >> 31 == 0)));
133 return register_operand (op, mode);
136 /* Return 1 if the operand is a valid second operand to a sign-extending
140 sext_add_operand (op, mode)
142 enum machine_mode mode;
144 if (GET_CODE (op) == CONST_INT)
145 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
146 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
148 return register_operand (op, mode);
151 /* Return 1 if OP is the constant 4 or 8. */
154 const48_operand (op, mode)
156 enum machine_mode mode;
158 return (GET_CODE (op) == CONST_INT
159 && (INTVAL (op) == 4 || INTVAL (op) == 8));
162 /* Return 1 if OP is a valid first operand to an AND insn. */
165 and_operand (op, mode)
167 enum machine_mode mode;
169 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
170 return (zap_mask (CONST_DOUBLE_LOW (op))
171 && zap_mask (CONST_DOUBLE_HIGH (op)));
173 if (GET_CODE (op) == CONST_INT)
174 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
175 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
176 || zap_mask (INTVAL (op)));
178 return register_operand (op, mode);
181 /* Return 1 if OP is a constant that is the width, in bits, of an integral
182 mode smaller than DImode. */
185 mode_width_operand (op, mode)
187 enum machine_mode mode;
189 return (GET_CODE (op) == CONST_INT
190 && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
193 /* Return 1 if OP is a constant that is the width of an integral machine mode
194 smaller than an integer. */
197 mode_mask_operand (op, mode)
199 enum machine_mode mode;
201 #if HOST_BITS_PER_WIDE_INT == 32
202 if (GET_CODE (op) == CONST_DOUBLE)
203 return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
206 if (GET_CODE (op) == CONST_INT)
207 return (INTVAL (op) == 0xff
208 || INTVAL (op) == 0xffff
209 #if HOST_BITS_PER_WIDE_INT == 64
210 || INTVAL (op) == 0xffffffff
215 /* Return 1 if OP is a multiple of 8 less than 64. */
218 mul8_operand (op, mode)
220 enum machine_mode mode;
222 return (GET_CODE (op) == CONST_INT
223 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
224 && (INTVAL (op) & 7) == 0);
227 /* Return 1 if OP is the constant zero in floating-point. */
230 fp0_operand (op, mode)
232 enum machine_mode mode;
234 return (GET_MODE (op) == mode
235 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
238 /* Return 1 if OP is the floating-point constant zero or a register. */
241 reg_or_fp0_operand (op, mode)
243 enum machine_mode mode;
245 return fp0_operand (op, mode) || register_operand (op, mode);
248 /* Return 1 if OP is a register or a constant integer. */
252 reg_or_cint_operand (op, mode)
254 enum machine_mode mode;
256 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
259 /* Return 1 if OP is a valid operand for the source of a move insn. */
262 input_operand (op, mode)
264 enum machine_mode mode;
266 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
269 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
272 switch (GET_CODE (op))
277 return mode == DImode;
283 if (register_operand (op, mode))
285 /* ... fall through ... */
287 return mode != HImode && mode != QImode && general_operand (op, mode);
290 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
293 return mode == QImode || mode == HImode || add_operand (op, mode);
299 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
303 current_file_function_operand (op, mode)
305 enum machine_mode mode;
307 return (GET_CODE (op) == SYMBOL_REF
308 && (SYMBOL_REF_FLAG (op)
309 || op == XEXP (DECL_RTL (current_function_decl), 0)));
312 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
313 comparisons are valid in which insn. */
316 alpha_comparison_operator (op, mode)
318 enum machine_mode mode;
320 enum rtx_code code = GET_CODE (op);
322 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
325 return (code == EQ || code == LE || code == LT
326 || (mode == DImode && (code == LEU || code == LTU)));
329 /* Return 1 if OP is a signed comparison operation. */
332 signed_comparison_operator (op, mode)
334 enum machine_mode mode;
336 switch (GET_CODE (op))
338 case EQ: case NE: case LE: case LT: case GE: case GT:
345 /* Return 1 if this is a divide or modulus operator. */
348 divmod_operator (op, mode)
350 enum machine_mode mode;
352 switch (GET_CODE (op))
354 case DIV: case MOD: case UDIV: case UMOD:
361 /* Return 1 if this memory address is a known aligned register plus
362 a constant. It must be a valid address. This means that we can do
363 this as an aligned reference plus some offset.
365 Take into account what reload will do.
367 We could say that out-of-range stack slots are alignable, but that would
368 complicate get_aligned_mem and it isn't worth the trouble since few
369 functions have large stack space. */
372 aligned_memory_operand (op, mode)
374 enum machine_mode mode;
376 if (GET_CODE (op) == SUBREG)
378 if (GET_MODE (op) != mode)
380 op = SUBREG_REG (op);
381 mode = GET_MODE (op);
384 if (reload_in_progress && GET_CODE (op) == REG
385 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
386 op = reg_equiv_mem[REGNO (op)];
388 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
389 || ! memory_address_p (mode, XEXP (op, 0)))
394 if (GET_CODE (op) == PLUS)
397 return (GET_CODE (op) == REG
398 && (REGNO (op) == STACK_POINTER_REGNUM || op == frame_pointer_rtx
399 || (REGNO (op) >= FIRST_VIRTUAL_REGISTER
400 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
403 /* Similar, but return 1 if OP is a MEM which is not alignable. */
406 unaligned_memory_operand (op, mode)
408 enum machine_mode mode;
410 if (GET_CODE (op) == SUBREG)
412 if (GET_MODE (op) != mode)
414 op = SUBREG_REG (op);
415 mode = GET_MODE (op);
418 if (reload_in_progress && GET_CODE (op) == REG
419 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
420 op = reg_equiv_mem[REGNO (op)];
422 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
427 if (! memory_address_p (mode, op))
430 if (GET_CODE (op) == PLUS)
433 return (GET_CODE (op) != REG
434 || (REGNO (op) != STACK_POINTER_REGNUM && op != frame_pointer_rtx
435 && (REGNO (op) < FIRST_VIRTUAL_REGISTER
436 || REGNO (op) > LAST_VIRTUAL_REGISTER)));
439 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
442 any_memory_operand (op, mode)
444 enum machine_mode mode;
446 return (GET_CODE (op) == MEM
447 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
448 || (reload_in_progress && GET_CODE (op) == REG
449 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
450 || (reload_in_progress && GET_CODE (op) == SUBREG
451 && GET_CODE (SUBREG_REG (op)) == REG
452 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
455 /* REF is an alignable memory location. Place an aligned SImode
456 reference into *PALIGNED_MEM and the number of bits to shift into
460 get_aligned_mem (ref, paligned_mem, pbitnum)
462 rtx *paligned_mem, *pbitnum;
465 HOST_WIDE_INT offset = 0;
467 if (GET_CODE (ref) == SUBREG)
469 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
470 if (BYTES_BIG_ENDIAN)
471 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
472 - MIN (UNITS_PER_WORD,
473 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
474 ref = SUBREG_REG (ref);
477 if (GET_CODE (ref) == REG)
478 ref = reg_equiv_mem[REGNO (ref)];
480 if (reload_in_progress)
481 base = find_replacement (&XEXP (ref, 0));
483 base = XEXP (ref, 0);
485 if (GET_CODE (base) == PLUS)
486 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
488 *paligned_mem = gen_rtx (MEM, SImode,
489 plus_constant (base, offset & ~3));
490 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
491 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
492 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
494 *pbitnum = GEN_INT ((offset & 3) * 8);
497 /* Similar, but just get the address. Handle the two reload cases. */
500 get_unaligned_address (ref)
504 HOST_WIDE_INT offset = 0;
506 if (GET_CODE (ref) == SUBREG)
508 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
509 if (BYTES_BIG_ENDIAN)
510 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
511 - MIN (UNITS_PER_WORD,
512 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
513 ref = SUBREG_REG (ref);
516 if (GET_CODE (ref) == REG)
517 ref = reg_equiv_mem[REGNO (ref)];
519 if (reload_in_progress)
520 base = find_replacement (&XEXP (ref, 0));
522 base = XEXP (ref, 0);
524 if (GET_CODE (base) == PLUS)
525 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
527 return plus_constant (base, offset);
530 /* Subfunction of the following function. Update the flags of any MEM
531 found in part of X. */
534 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
536 int in_struct_p, volatile_p, unchanging_p;
540 switch (GET_CODE (x))
544 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
545 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
550 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
555 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
557 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
562 MEM_IN_STRUCT_P (x) = in_struct_p;
563 MEM_VOLATILE_P (x) = volatile_p;
564 RTX_UNCHANGING_P (x) = unchanging_p;
569 /* Given INSN, which is either an INSN or a SEQUENCE generated to
570 perform a memory operation, look for any MEMs in either a SET_DEST or
571 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
572 REF into each of the MEMs found. If REF is not a MEM, don't do
576 alpha_set_memflags (insn, ref)
580 /* Note that it is always safe to get these flags, though they won't
581 be what we think if REF is not a MEM. */
582 int in_struct_p = MEM_IN_STRUCT_P (ref);
583 int volatile_p = MEM_VOLATILE_P (ref);
584 int unchanging_p = RTX_UNCHANGING_P (ref);
586 if (GET_CODE (ref) != MEM
587 || (! in_struct_p && ! volatile_p && ! unchanging_p))
590 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
593 /* Try to output insns to set TARGET equal to the constant C if it can be
594 done in less than N insns. Returns 1 if it can be done and the
595 insns have been emitted. If it would take more than N insns, zero is
596 returned and no insns and emitted. */
599 alpha_emit_set_const (target, c, n)
604 HOST_WIDE_INT new = c;
607 #if HOST_BITS_PER_WIDE_INT == 64
608 /* We are only called for SImode and DImode. If this is SImode, ensure that
609 we are sign extended to a full word. This does not make any sense when
610 cross-compiling on a narrow machine. */
612 if (GET_MODE (target) == SImode)
613 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
616 /* If this is a sign-extended 32-bit constant, we can do this in at most
617 three insns, so do it if we have enough insns left. We always have
618 a sign-extended 32-bit constant when compiling on a narrow machine. */
620 if (HOST_BITS_PER_WIDE_INT != 64
621 || c >> 31 == -1 || c >> 31 == 0)
623 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
624 HOST_WIDE_INT tmp1 = c - low;
626 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
627 HOST_WIDE_INT extra = 0;
629 /* If HIGH will be interpreted as negative but the constant is
630 positive, we must adjust it to do two ldha insns. */
632 if ((high & 0x8000) != 0 && c >= 0)
636 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
639 if (c == low || (low == 0 && extra == 0))
641 emit_move_insn (target, GEN_INT (c));
644 else if (n >= 2 + (extra != 0))
646 emit_move_insn (target, GEN_INT (low));
648 emit_insn (gen_add2_insn (target, GEN_INT (extra << 16)));
650 emit_insn (gen_add2_insn (target, GEN_INT (high << 16)));
655 /* If we couldn't do it that way, try some other methods (that depend on
656 being able to compute in the target's word size). But if we have no
657 instructions left, don't bother. Also, don't even try if this is
658 SImode (in which case we should have already done something, but
659 do a sanity check here). */
661 if (n == 1 || HOST_BITS_PER_WIDE_INT < 64 || GET_MODE (target) != DImode)
664 /* First, see if can load a value into the target that is the same as the
665 constant except that all bytes that are 0 are changed to be 0xff. If we
666 can, then we can do a ZAPNOT to obtain the desired constant. */
668 for (i = 0; i < 64; i += 8)
669 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
670 new |= (HOST_WIDE_INT) 0xff << i;
672 if (alpha_emit_set_const (target, new, n - 1))
674 emit_insn (gen_anddi3 (target, target, GEN_INT (c | ~ new)));
678 /* Find, see if we can load a related constant and then shift and possibly
679 negate it to get the constant we want. Try this once each increasing
682 for (i = 1; i < n; i++)
684 /* First try complementing. */
685 if (alpha_emit_set_const (target, ~ c, i))
687 emit_insn (gen_one_cmpldi2 (target, target));
691 /* First try to form a constant and do a left shift. We can do this
692 if some low-order bits are zero; the exact_log2 call below tells
693 us that information. The bits we are shifting out could be any
694 value, but here we'll just try the 0- and sign-extended forms of
695 the constant. To try to increase the chance of having the same
696 constant in more than one insn, start at the highest number of
697 bits to shift, but try all possibilities in case a ZAPNOT will
700 if ((bits = exact_log2 (c & - c)) > 0)
701 for (; bits > 0; bits--)
702 if (alpha_emit_set_const (target, c >> bits, i)
703 || alpha_emit_set_const (target,
704 ((unsigned HOST_WIDE_INT) c) >> bits,
707 emit_insn (gen_ashldi3 (target, target, GEN_INT (bits)));
711 /* Now try high-order zero bits. Here we try the shifted-in bits as
712 all zero and all ones. */
714 if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (c) - 1) > 0)
715 for (; bits > 0; bits--)
716 if (alpha_emit_set_const (target, c << bits, i)
717 || alpha_emit_set_const (target,
719 | (((HOST_WIDE_INT) 1 << bits) - 1)),
722 emit_insn (gen_lshrdi3 (target, target, GEN_INT (bits)));
726 /* Now try high-order 1 bits. We get that with a sign-extension.
727 But one bit isn't enough here. */
729 if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (~ c) - 2) > 0)
730 for (; bits > 0; bits--)
731 if (alpha_emit_set_const (target, c << bits, i)
732 || alpha_emit_set_const (target,
734 | (((HOST_WIDE_INT) 1 << bits) - 1)),
737 emit_insn (gen_ashrdi3 (target, target, GEN_INT (bits)));
745 /* Adjust the cost of a scheduling dependency. Return the new cost of
746 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
749 alpha_adjust_cost (insn, link, dep_insn, cost)
757 /* If the dependence is an anti-dependence, there is no cost. For an
758 output dependence, there is sometimes a cost, but it doesn't seem
759 worth handling those few cases. */
761 if (REG_NOTE_KIND (link) != 0)
764 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
765 we can sometimes lower the cost. */
767 if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
768 && (set = single_set (dep_insn)) != 0
769 && GET_CODE (PATTERN (insn)) == SET
770 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
771 switch (get_attr_type (dep_insn))
774 /* No savings here. */
779 /* In these cases, we save one cycle. */
783 /* In all other cases, we save two cycles. */
784 return MAX (0, cost - 4);
787 /* Another case that needs adjustment is an arithmetic or logical
788 operation. It's cost is usually one cycle, but we default it to
789 two in the MD file. The only case that it is actually two is
790 for the address in loads and stores. */
792 if (recog_memoized (dep_insn) >= 0
793 && get_attr_type (dep_insn) == TYPE_IADDLOG)
794 switch (get_attr_type (insn))
804 /* The final case is when a compare feeds into an integer branch. The cost
805 is only one cycle in that case. */
807 if (recog_memoized (dep_insn) >= 0
808 && get_attr_type (dep_insn) == TYPE_ICMP
809 && recog_memoized (insn) >= 0
810 && get_attr_type (insn) == TYPE_IBR)
813 /* Otherwise, return the default cost. */
818 /* Print an operand. Recognize special options, documented below. */
821 print_operand (file, x, code)
831 /* If this operand is the constant zero, write it as "$31". */
832 if (GET_CODE (x) == REG)
833 fprintf (file, "%s", reg_names[REGNO (x)]);
834 else if (x == CONST0_RTX (GET_MODE (x)))
835 fprintf (file, "$31");
837 output_operand_lossage ("invalid %%r value");
842 /* Similar, but for floating-point. */
843 if (GET_CODE (x) == REG)
844 fprintf (file, "%s", reg_names[REGNO (x)]);
845 else if (x == CONST0_RTX (GET_MODE (x)))
846 fprintf (file, "$f31");
848 output_operand_lossage ("invalid %%R value");
853 /* Write the 1's complement of a constant. */
854 if (GET_CODE (x) != CONST_INT)
855 output_operand_lossage ("invalid %%N value");
857 fprintf (file, "%ld", ~ INTVAL (x));
861 /* Write 1 << C, for a constant C. */
862 if (GET_CODE (x) != CONST_INT)
863 output_operand_lossage ("invalid %%P value");
865 fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
869 /* Write the high-order 16 bits of a constant, sign-extended. */
870 if (GET_CODE (x) != CONST_INT)
871 output_operand_lossage ("invalid %%h value");
873 fprintf (file, "%ld", INTVAL (x) >> 16);
877 /* Write the low-order 16 bits of a constant, sign-extended. */
878 if (GET_CODE (x) != CONST_INT)
879 output_operand_lossage ("invalid %%L value");
881 fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
885 /* Write mask for ZAP insn. */
886 if (GET_CODE (x) == CONST_DOUBLE)
888 HOST_WIDE_INT mask = 0;
891 value = CONST_DOUBLE_LOW (x);
892 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
897 value = CONST_DOUBLE_HIGH (x);
898 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
901 mask |= (1 << (i + sizeof (int)));
903 fprintf (file, "%ld", mask & 0xff);
906 else if (GET_CODE (x) == CONST_INT)
908 HOST_WIDE_INT mask = 0, value = INTVAL (x);
910 for (i = 0; i < 8; i++, value >>= 8)
914 fprintf (file, "%ld", mask);
917 output_operand_lossage ("invalid %%m value");
921 /* 'b', 'w', or 'l' as the value of the constant. */
922 if (GET_CODE (x) != CONST_INT
923 || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
924 output_operand_lossage ("invalid %%M value");
927 INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
931 /* Similar, except do it from the mask. */
932 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
934 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
936 #if HOST_BITS_PER_WIDE_INT == 32
937 else if (GET_CODE (x) == CONST_DOUBLE
938 && CONST_DOUBLE_HIGH (x) == 0
939 && CONST_DOUBLE_LOW (x) == -1)
942 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
946 output_operand_lossage ("invalid %%U value");
950 /* Write the constant value divided by 8. */
951 if (GET_CODE (x) != CONST_INT
952 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
953 && (INTVAL (x) & 7) != 8)
954 output_operand_lossage ("invalid %%s value");
956 fprintf (file, "%ld", INTVAL (x) / 8);
960 /* Same, except compute (64 - c) / 8 */
962 if (GET_CODE (x) != CONST_INT
963 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
964 && (INTVAL (x) & 7) != 8)
965 output_operand_lossage ("invalid %%s value");
967 fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
971 /* Write out comparison name. */
972 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
973 output_operand_lossage ("invalid %%C value");
975 if (GET_CODE (x) == LEU)
976 fprintf (file, "ule");
977 else if (GET_CODE (x) == LTU)
978 fprintf (file, "ult");
980 fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
984 /* Similar, but write reversed code. We can't get an unsigned code
986 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
987 output_operand_lossage ("invalid %%D value");
989 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
993 /* Write the divide or modulus operator. */
994 switch (GET_CODE (x))
997 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
1000 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
1003 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
1006 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
1009 output_operand_lossage ("invalid %%E value");
1015 /* Write "_u" for unaligned access. */
1016 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1017 fprintf (file, "_u");
1021 if (GET_CODE (x) == REG)
1022 fprintf (file, "%s", reg_names[REGNO (x)]);
1023 else if (GET_CODE (x) == MEM)
1024 output_address (XEXP (x, 0));
1026 output_addr_const (file, x);
1030 output_operand_lossage ("invalid %%xn code");
1034 /* Do what is necessary for `va_start'. The argument is ignored;
1035 We look at the current function to determine if stdarg or varargs
1036 is used and fill in an initial va_list. A pointer to this constructor
1040 alpha_builtin_saveregs (arglist)
1043 rtx block, addr, argsize;
1044 tree fntype = TREE_TYPE (current_function_decl);
1045 int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1046 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1047 != void_type_node));
1049 /* Compute the current position into the args, taking into account
1050 both registers and memory. */
1052 argsize = plus_constant (current_function_arg_offset_rtx,
1053 current_function_args_info * UNITS_PER_WORD);
1055 /* Allocate the va_list constructor */
1056 block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
1057 RTX_UNCHANGING_P (block) = 1;
1058 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1060 /* Store the address of the first integer register in the
1061 __va_base member. */
1063 emit_move_insn (change_address (block, DImode, XEXP (block, 0)),
1064 force_operand (plus_constant (virtual_incoming_args_rtx,
1065 6 * UNITS_PER_WORD),
1068 /* Store the argsize as the __va_offset member. */
1069 emit_move_insn (change_address (block, Pmode,
1070 plus_constant (XEXP (block, 0),
1072 force_operand (argsize, NULL_RTX));
1074 /* Return the address of the va_list constructor, but don't put it in a
1075 register. Doing so would fail when not optimizing and produce worse
1076 code when optimizing. */
1077 return XEXP (block, 0);
1080 /* This page contains routines that are used to determine what the function
1081 prologue and epilogue code will do and write them out. */
1083 /* Compute the size of the save area in the stack. */
1091 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1092 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1095 /* If some registers were saved but not reg 26, reg 26 must also
1096 be saved, so leave space for it. */
1097 if (size != 0 && ! regs_ever_live[26])
1103 /* Return 1 if this function can directly return via $26. */
1108 return (reload_completed && alpha_sa_size () == 0
1109 && get_frame_size () == 0
1110 && current_function_pretend_args_size == 0);
1113 /* Write a version stamp. Don't write anything if we are running as a
1114 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1116 #ifndef CROSS_COMPILE
1121 alpha_write_verstamp (file)
1127 fprintf (file, "\t.verstamp %d %d ", MS_STAMP, LS_STAMP);
1128 for (p = version_string; *p != ' ' && *p != 0; p++)
1129 fprintf (file, "%c", *p == '.' ? ' ' : *p);
1130 fprintf (file, "\n");
1134 /* Write code to add constant C to register number IN_REG (possibly 31)
1135 and put the result into OUT_REG. Write the code to FILE. */
1138 add_long_const (file, c, in_reg, out_reg)
1140 int in_reg, out_reg;
1143 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1144 HOST_WIDE_INT tmp1 = c - low;
1145 HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1146 HOST_WIDE_INT extra = 0;
1148 /* We don't have code to write out constants larger than 32 bits. */
1149 #if HOST_BITS_PER_LONG_INT == 64
1150 if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
1154 /* If HIGH will be interpreted as negative, we must adjust it to do two
1155 ldha insns. Note that we will never be building a negative constant
1162 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1167 if (low >= 0 && low < 255)
1168 fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, out_reg);
1170 fprintf (file, "\tlda $%d,%d($%d)\n", out_reg, low, in_reg);
1176 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, extra, in_reg);
1181 fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
1184 /* Write function prologue. */
1187 output_prolog (file, size)
1191 HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1192 + current_function_pretend_args_size
1193 + alpha_sa_size () + 15) & ~15);
1194 HOST_WIDE_INT reg_offset = size + current_function_outgoing_args_size;
1195 HOST_WIDE_INT start_reg_offset = reg_offset;
1196 HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
1198 int reg_offset_base_reg = 30;
1199 unsigned reg_mask = 0;
1202 /* Ecoff can handle multiple .file directives, put out file and lineno.
1203 We have to do that before the .ent directive as we cannot switch
1204 files within procedures with native ecoff because line numbers are
1205 linked to procedure descriptors.
1206 Outputting the lineno helps debugging of one line functions as they
1207 would otherwise get no line number at all. Please note that we would
1208 like to put out last_linenum from final.c, but it is not accesible. */
1210 if (write_symbols == SDB_DEBUG)
1212 ASM_OUTPUT_SOURCE_FILENAME (file,
1213 DECL_SOURCE_FILE (current_function_decl));
1214 if (debug_info_level != DINFO_LEVEL_TERSE)
1215 ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
1218 /* The assembly language programmer's guide states that the second argument
1219 to the .ent directive, the lex_level, is ignored by the assembler,
1220 so we might as well omit it. */
1222 fprintf (file, "\t.ent %s\n", alpha_function_name);
1223 ASM_OUTPUT_LABEL (file, alpha_function_name);
1224 inside_function = TRUE;
1226 /* Set up offsets to alpha virtual arg/local debugging pointer. */
1228 alpha_auto_offset = -frame_size + current_function_pretend_args_size;
1229 alpha_arg_offset = -frame_size + 48;
1231 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
1232 Even if we are a static function, we still need to do this in case
1233 our address is taken and passed to something like qsort. */
1235 alpha_function_needs_gp = 0;
1236 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1237 if ((GET_CODE (insn) == CALL_INSN)
1238 || (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1239 && GET_CODE (PATTERN (insn)) != USE
1240 && GET_CODE (PATTERN (insn)) != CLOBBER
1241 && get_attr_type (insn) == TYPE_LDSYM))
1243 alpha_function_needs_gp = 1;
1247 if (alpha_function_needs_gp)
1248 fprintf (file, "\tldgp $29,0($27)\n");
1250 /* Put a label after the GP load so we can enter the function at it. */
1251 fprintf (file, "%s..ng:\n", alpha_function_name);
1253 /* Adjust the stack by the frame size. If the frame size is > 4096
1254 bytes, we need to be sure we probe somewhere in the first and last
1255 4096 bytes (we can probably get away without the latter test) and
1256 every 8192 bytes in between. If the frame size is > 32768, we
1257 do this in a loop. Otherwise, we generate the explicit probe
1260 Note that we are only allowed to adjust sp once in the prologue. */
1262 if (frame_size < 32768)
1264 if (frame_size > 4096)
1269 fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed);
1271 while (probed + 8192 < frame_size)
1272 fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed += 8192);
1274 if (probed + 4096 < frame_size)
1275 fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed += 4096);
1281 if (frame_size != 0)
1282 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1286 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1287 number of 8192 byte blocks to probe. We then probe each block
1288 in the loop and then set SP to the proper location. If the
1289 amount remaining is > 4096, we have to do one more probe. */
1291 HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
1292 HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
1294 add_long_const (file, blocks, 31, 5);
1296 fprintf (file, "\tlda $4,4096($30)\n");
1297 fprintf (file, "%s..sc:\n", alpha_function_name);
1298 fprintf (file, "\tldq $6,-8192($4)\n");
1299 fprintf (file, "\tsubq $5,1,$5\n");
1300 fprintf (file, "\tlda $4,-8192($4)\n");
1301 fprintf (file, "\tbne $5,%s..sc\n", alpha_function_name);
1302 fprintf (file, "\tlda $30,-%d($4)\n", leftover);
1304 if (leftover > 4096)
1305 fprintf (file, "\tldq $2,%d($30)\n", leftover - 4096);
1308 /* Describe our frame. */
1309 fprintf (file, "\t.frame $%d,%d,$26,%d\n",
1310 frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM,
1311 frame_size, current_function_pretend_args_size);
1313 /* If reg_offset is "close enough" to 2**15 that one of the offsets would
1314 overflow a store instruction, compute the base of the register save
1316 if (reg_offset >= 32768 - alpha_sa_size () && alpha_sa_size () != 0)
1318 add_long_const (file, reg_offset, 30, 28);
1319 reg_offset_base_reg = 28;
1320 reg_offset = start_reg_offset = 0;
1323 /* Save register 26 if it is used or if any other register needs to
1325 if (regs_ever_live[26] || alpha_sa_size () != 0)
1327 reg_mask |= 1 << 26;
1328 fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, reg_offset_base_reg);
1332 /* Now save any other used integer registers required to be saved. */
1333 for (i = 0; i < 32; i++)
1334 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1337 fprintf (file, "\tstq $%d,%d($%d)\n",
1338 i, reg_offset, reg_offset_base_reg);
1342 /* Print the register mask and do floating-point saves. */
1344 fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1345 actual_start_reg_offset - frame_size);
1347 start_reg_offset = reg_offset;
1350 for (i = 0; i < 32; i++)
1351 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1352 && regs_ever_live[i + 32])
1355 fprintf (file, "\tstt $f%d,%d($%d)\n",
1356 i, reg_offset, reg_offset_base_reg);
1360 /* Print the floating-point mask, if we've saved any fp register. */
1362 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask, actual_start_reg_offset);
1364 /* If we need a frame pointer, set it from the stack pointer. Note that
1365 this must always be the last instruction in the prologue. */
1366 if (frame_pointer_needed)
1367 fprintf (file, "\tbis $30,$30,$15\n");
1369 /* End the prologue and say if we used gp. */
1370 fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
1373 /* Write function epilogue. */
1376 output_epilog (file, size)
1380 rtx insn = get_last_insn ();
1381 HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1382 + current_function_pretend_args_size
1383 + alpha_sa_size () + 15) & ~15);
1384 HOST_WIDE_INT reg_offset = size + current_function_outgoing_args_size;
1385 HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
1386 int reg_offset_base_reg = 30;
1389 /* If the last insn was a BARRIER, we don't have to write anything except
1390 the .end pseudo-op. */
1391 if (GET_CODE (insn) == NOTE)
1392 insn = prev_nonnote_insn (insn);
1393 if (insn == 0 || GET_CODE (insn) != BARRIER)
1397 /* If we have a frame pointer, restore SP from it. */
1398 if (frame_pointer_needed)
1399 fprintf (file, "\tbis $15,$15,$30\n");
1401 /* If the register save area is out of range, put its address into
1403 if (reg_offset >= 32768 - alpha_sa_size () && alpha_sa_size () != 0)
1405 add_long_const (file, reg_offset, 30, 28);
1406 reg_offset_base_reg = 28;
1410 /* Restore all the registers, starting with the return address
1412 if (regs_ever_live[26] || alpha_sa_size () != 0)
1414 fprintf (file, "\tldq $26,%d($%d)\n",
1415 reg_offset, reg_offset_base_reg);
1419 /* Now restore any other used integer registers that that we saved,
1420 except for FP if it is being used as FP, since it must be
1423 for (i = 0; i < 32; i++)
1424 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1427 if (i == FRAME_POINTER_REGNUM && frame_pointer_needed)
1428 fp_offset = reg_offset;
1430 fprintf (file, "\tldq $%d,%d($%d)\n",
1431 i, reg_offset, reg_offset_base_reg);
1435 for (i = 0; i < 32; i++)
1436 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1437 && regs_ever_live[i + 32])
1439 fprintf (file, "\tldt $f%d,%d($%d)\n",
1440 i, reg_offset, reg_offset_base_reg);
1444 /* If the stack size is large, compute the size of the stack into
1445 a register because the old FP restore, stack pointer adjust,
1446 and return are required to be consecutive instructions.
1447 However, if the new stack pointer can be computed by adding the
1448 a constant to the start of the register save area, we can do
1450 if (frame_size > 32767
1451 && ! (reg_offset_base_reg != 30
1452 && frame_size_from_reg_save < 32768))
1453 add_long_const (file, frame_size, 31, 1);
1455 /* If we needed a frame pointer and we have to restore it, do it
1456 now. This must be done in one instruction immediately
1457 before the SP update. */
1458 if (frame_pointer_needed && regs_ever_live[FRAME_POINTER_REGNUM])
1459 fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, reg_offset_base_reg);
1461 /* Now update the stack pointer, if needed. This must be done in
1462 one, stylized, instruction. */
1463 if (frame_size > 32768)
1465 if (reg_offset_base_reg != 30
1466 && frame_size_from_reg_save < 32768)
1468 if (frame_size_from_reg_save < 255)
1469 fprintf (file, "\taddq $%d,%d,$30\n",
1470 reg_offset_base_reg, frame_size_from_reg_save);
1472 fprintf (file, "\tlda %30,%d($%d)\n",
1473 frame_size_from_reg_save, reg_offset_base_reg);
1476 fprintf (file, "\taddq $1,$30,$30\n");
1478 else if (frame_size != 0)
1479 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
1481 /* Finally return to the caller. */
1482 fprintf (file, "\tret $31,($26),1\n");
1485 /* End the function. */
1486 fprintf (file, "\t.end %s\n", alpha_function_name);
1487 inside_function = FALSE;
1488 ignore_line_number = FALSE;
1490 /* Show that we know this function if it is called again. */
1491 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
1494 /* Debugging support. */
1498 /* Count the number of sdb related labels are generated (to find block
1499 start and end boundaries). */
1501 int sdb_label_count = 0;
1503 /* Next label # for each statement. */
1505 static int sym_lineno = 0;
1507 /* Count the number of .file directives, so that .loc is up to date. */
1509 static int num_source_filenames = 0;
1511 /* Name of the file containing the current function. */
1513 static char *current_function_file = "";
1515 /* Offsets to alpha virtual arg/local debugging pointers. */
1517 long alpha_arg_offset;
1518 long alpha_auto_offset;
1520 /* Emit a new filename to a stream. */
1523 alpha_output_filename (stream, name)
1527 static int first_time = TRUE;
1528 char ltext_label_name[100];
1533 ++num_source_filenames;
1534 current_function_file = name;
1535 fprintf (stream, "\t.file\t%d ", num_source_filenames);
1536 output_quoted_string (stream, name);
1537 fprintf (stream, "\n");
1538 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1539 fprintf (stream, "\t#@stabs\n");
1542 else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1544 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
1545 fprintf (stream, "%s ", ASM_STABS_OP);
1546 output_quoted_string (stream, name);
1547 fprintf (stream, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]);
1550 else if (name != current_function_file
1551 && strcmp (name, current_function_file) != 0)
1553 if (inside_function && ! TARGET_GAS)
1554 fprintf (stream, "\t#.file\t%d ", num_source_filenames);
1557 ++num_source_filenames;
1558 current_function_file = name;
1559 fprintf (stream, "\t.file\t%d ", num_source_filenames);
1562 output_quoted_string (stream, name);
1563 fprintf (stream, "\n");
1567 /* Emit a linenumber to a stream. */
1570 alpha_output_lineno (stream, line)
1574 if (! TARGET_GAS && write_symbols == DBX_DEBUG)
1576 /* mips-tfile doesn't understand .stabd directives. */
1578 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1579 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
1582 fprintf (stream, "\n\t%s.loc\t%d %d\n", (ignore_line_number) ? "#" : "",
1583 num_source_filenames, line);