1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992, 1993, 1994 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 /* Nonzero if the current function needs gp. */
58 int alpha_function_needs_gp
;
60 extern char *version_string
;
62 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
70 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
72 if ((value
& 0xff) != 0 && (value
& 0xff) != 0xff)
78 /* Returns 1 if OP is either the constant zero or a register. If a
79 register, it must be in the proper mode unless MODE is VOIDmode. */
82 reg_or_0_operand (op
, mode
)
84 enum machine_mode mode
;
86 return op
== const0_rtx
|| register_operand (op
, mode
);
89 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
93 reg_or_6bit_operand (op
, mode
)
95 enum machine_mode mode
;
97 return ((GET_CODE (op
) == CONST_INT
98 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64)
99 || register_operand (op
, mode
));
103 /* Return 1 if OP is an 8-bit constant or any register. */
106 reg_or_8bit_operand (op
, mode
)
108 enum machine_mode mode
;
110 return ((GET_CODE (op
) == CONST_INT
111 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100)
112 || register_operand (op
, mode
));
115 /* Return 1 if the operand is a valid second operand to an add insn. */
118 add_operand (op
, mode
)
120 enum machine_mode mode
;
122 if (GET_CODE (op
) == CONST_INT
)
123 return ((unsigned HOST_WIDE_INT
) (INTVAL (op
) + 0x8000) < 0x10000
124 || ((INTVAL (op
) & 0xffff) == 0
125 && (INTVAL (op
) >> 31 == -1
126 || INTVAL (op
) >> 31 == 0)));
128 return register_operand (op
, mode
);
131 /* Return 1 if the operand is a valid second operand to a sign-extending
135 sext_add_operand (op
, mode
)
137 enum machine_mode mode
;
139 if (GET_CODE (op
) == CONST_INT
)
140 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 255
141 || (unsigned HOST_WIDE_INT
) (- INTVAL (op
)) < 255);
143 return register_operand (op
, mode
);
146 /* Return 1 if OP is the constant 4 or 8. */
149 const48_operand (op
, mode
)
151 enum machine_mode mode
;
153 return (GET_CODE (op
) == CONST_INT
154 && (INTVAL (op
) == 4 || INTVAL (op
) == 8));
157 /* Return 1 if OP is a valid first operand to an AND insn. */
160 and_operand (op
, mode
)
162 enum machine_mode mode
;
164 if (GET_CODE (op
) == CONST_DOUBLE
&& GET_MODE (op
) == VOIDmode
)
165 return (zap_mask (CONST_DOUBLE_LOW (op
))
166 && zap_mask (CONST_DOUBLE_HIGH (op
)));
168 if (GET_CODE (op
) == CONST_INT
)
169 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
170 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100
171 || zap_mask (INTVAL (op
)));
173 return register_operand (op
, mode
);
176 /* Return 1 if OP is a valid first operand to an IOR insn. */
179 ior_operand (op
, mode
)
181 enum machine_mode mode
;
183 if (GET_CODE (op
) == CONST_INT
)
184 return ((unsigned HOST_WIDE_INT
) INTVAL (op
) < 0x100
185 || (unsigned HOST_WIDE_INT
) ~ INTVAL (op
) < 0x100);
187 return register_operand (op
, mode
);
190 /* Return 1 if OP is a constant that is the width, in bits, of an integral
191 mode smaller than DImode. */
194 mode_width_operand (op
, mode
)
196 enum machine_mode mode
;
198 return (GET_CODE (op
) == CONST_INT
199 && (INTVAL (op
) == 8 || INTVAL (op
) == 16 || INTVAL (op
) == 32));
202 /* Return 1 if OP is a constant that is the width of an integral machine mode
203 smaller than an integer. */
206 mode_mask_operand (op
, mode
)
208 enum machine_mode mode
;
210 #if HOST_BITS_PER_WIDE_INT == 32
211 if (GET_CODE (op
) == CONST_DOUBLE
)
212 return CONST_DOUBLE_HIGH (op
) == 0 && CONST_DOUBLE_LOW (op
) == -1;
215 if (GET_CODE (op
) == CONST_INT
)
216 return (INTVAL (op
) == 0xff
217 || INTVAL (op
) == 0xffff
218 #if HOST_BITS_PER_WIDE_INT == 64
219 || INTVAL (op
) == 0xffffffff
224 /* Return 1 if OP is a multiple of 8 less than 64. */
227 mul8_operand (op
, mode
)
229 enum machine_mode mode
;
231 return (GET_CODE (op
) == CONST_INT
232 && (unsigned HOST_WIDE_INT
) INTVAL (op
) < 64
233 && (INTVAL (op
) & 7) == 0);
236 /* Return 1 if OP is the constant zero in floating-point. */
239 fp0_operand (op
, mode
)
241 enum machine_mode mode
;
243 return (GET_MODE (op
) == mode
244 && GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
));
247 /* Return 1 if OP is the floating-point constant zero or a register. */
250 reg_or_fp0_operand (op
, mode
)
252 enum machine_mode mode
;
254 return fp0_operand (op
, mode
) || register_operand (op
, mode
);
257 /* Return 1 if OP is a register or a constant integer. */
261 reg_or_cint_operand (op
, mode
)
263 enum machine_mode mode
;
265 return GET_CODE (op
) == CONST_INT
|| register_operand (op
, mode
);
268 /* Return 1 if OP is a valid operand for the source of a move insn. */
271 input_operand (op
, mode
)
273 enum machine_mode mode
;
275 if (mode
!= VOIDmode
&& GET_MODE (op
) != VOIDmode
&& mode
!= GET_MODE (op
))
278 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& GET_MODE (op
) != mode
)
281 switch (GET_CODE (op
))
286 return mode
== DImode
;
292 if (register_operand (op
, mode
))
294 /* ... fall through ... */
296 return mode
!= HImode
&& mode
!= QImode
&& general_operand (op
, mode
);
299 return GET_MODE_CLASS (mode
) == MODE_FLOAT
&& op
== CONST0_RTX (mode
);
302 return mode
== QImode
|| mode
== HImode
|| add_operand (op
, mode
);
308 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
312 current_file_function_operand (op
, mode
)
314 enum machine_mode mode
;
316 return (GET_CODE (op
) == SYMBOL_REF
317 && (SYMBOL_REF_FLAG (op
)
318 || op
== XEXP (DECL_RTL (current_function_decl
), 0)));
321 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
322 comparisons are valid in which insn. */
325 alpha_comparison_operator (op
, mode
)
327 enum machine_mode mode
;
329 enum rtx_code code
= GET_CODE (op
);
331 if (mode
!= GET_MODE (op
) || GET_RTX_CLASS (code
) != '<')
334 return (code
== EQ
|| code
== LE
|| code
== LT
335 || (mode
== DImode
&& (code
== LEU
|| code
== LTU
)));
338 /* Return 1 if OP is a signed comparison operation. */
341 signed_comparison_operator (op
, mode
)
343 enum machine_mode mode
;
345 switch (GET_CODE (op
))
347 case EQ
: case NE
: case LE
: case LT
: case GE
: case GT
:
354 /* Return 1 if this is a divide or modulus operator. */
357 divmod_operator (op
, mode
)
359 enum machine_mode mode
;
361 switch (GET_CODE (op
))
363 case DIV
: case MOD
: case UDIV
: case UMOD
:
370 /* Return 1 if this memory address is a known aligned register plus
371 a constant. It must be a valid address. This means that we can do
372 this as an aligned reference plus some offset.
374 Take into account what reload will do.
376 We could say that out-of-range stack slots are alignable, but that would
377 complicate get_aligned_mem and it isn't worth the trouble since few
378 functions have large stack space. */
381 aligned_memory_operand (op
, mode
)
383 enum machine_mode mode
;
385 if (GET_CODE (op
) == SUBREG
)
387 if (GET_MODE (op
) != mode
)
389 op
= SUBREG_REG (op
);
390 mode
= GET_MODE (op
);
393 if (reload_in_progress
&& GET_CODE (op
) == REG
394 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
395 op
= reg_equiv_mem
[REGNO (op
)];
397 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
398 || ! memory_address_p (mode
, XEXP (op
, 0)))
403 if (GET_CODE (op
) == PLUS
)
406 return (GET_CODE (op
) == REG
407 && (REGNO (op
) == STACK_POINTER_REGNUM
|| op
== frame_pointer_rtx
408 || (REGNO (op
) >= FIRST_VIRTUAL_REGISTER
409 && REGNO (op
) <= LAST_VIRTUAL_REGISTER
)));
412 /* Similar, but return 1 if OP is a MEM which is not alignable. */
415 unaligned_memory_operand (op
, mode
)
417 enum machine_mode mode
;
419 if (GET_CODE (op
) == SUBREG
)
421 if (GET_MODE (op
) != mode
)
423 op
= SUBREG_REG (op
);
424 mode
= GET_MODE (op
);
427 if (reload_in_progress
&& GET_CODE (op
) == REG
428 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
429 op
= reg_equiv_mem
[REGNO (op
)];
431 if (GET_CODE (op
) != MEM
|| GET_MODE (op
) != mode
)
436 if (! memory_address_p (mode
, op
))
439 if (GET_CODE (op
) == PLUS
)
442 return (GET_CODE (op
) != REG
443 || (REGNO (op
) != STACK_POINTER_REGNUM
&& op
!= frame_pointer_rtx
444 && (REGNO (op
) < FIRST_VIRTUAL_REGISTER
445 || REGNO (op
) > LAST_VIRTUAL_REGISTER
)));
448 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
451 any_memory_operand (op
, mode
)
453 enum machine_mode mode
;
455 return (GET_CODE (op
) == MEM
456 || (GET_CODE (op
) == SUBREG
&& GET_CODE (SUBREG_REG (op
)) == REG
)
457 || (reload_in_progress
&& GET_CODE (op
) == REG
458 && REGNO (op
) >= FIRST_PSEUDO_REGISTER
)
459 || (reload_in_progress
&& GET_CODE (op
) == SUBREG
460 && GET_CODE (SUBREG_REG (op
)) == REG
461 && REGNO (SUBREG_REG (op
)) >= FIRST_PSEUDO_REGISTER
));
464 /* REF is an alignable memory location. Place an aligned SImode
465 reference into *PALIGNED_MEM and the number of bits to shift into
469 get_aligned_mem (ref
, paligned_mem
, pbitnum
)
471 rtx
*paligned_mem
, *pbitnum
;
474 HOST_WIDE_INT offset
= 0;
476 if (GET_CODE (ref
) == SUBREG
)
478 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
479 if (BYTES_BIG_ENDIAN
)
480 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
481 - MIN (UNITS_PER_WORD
,
482 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
483 ref
= SUBREG_REG (ref
);
486 if (GET_CODE (ref
) == REG
)
487 ref
= reg_equiv_mem
[REGNO (ref
)];
489 if (reload_in_progress
)
490 base
= find_replacement (&XEXP (ref
, 0));
492 base
= XEXP (ref
, 0);
494 if (GET_CODE (base
) == PLUS
)
495 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
497 *paligned_mem
= gen_rtx (MEM
, SImode
,
498 plus_constant (base
, offset
& ~3));
499 MEM_IN_STRUCT_P (*paligned_mem
) = MEM_IN_STRUCT_P (ref
);
500 MEM_VOLATILE_P (*paligned_mem
) = MEM_VOLATILE_P (ref
);
501 RTX_UNCHANGING_P (*paligned_mem
) = RTX_UNCHANGING_P (ref
);
503 *pbitnum
= GEN_INT ((offset
& 3) * 8);
506 /* Similar, but just get the address. Handle the two reload cases. */
509 get_unaligned_address (ref
)
513 HOST_WIDE_INT offset
= 0;
515 if (GET_CODE (ref
) == SUBREG
)
517 offset
= SUBREG_WORD (ref
) * UNITS_PER_WORD
;
518 if (BYTES_BIG_ENDIAN
)
519 offset
-= (MIN (UNITS_PER_WORD
, GET_MODE_SIZE (GET_MODE (ref
)))
520 - MIN (UNITS_PER_WORD
,
521 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref
)))));
522 ref
= SUBREG_REG (ref
);
525 if (GET_CODE (ref
) == REG
)
526 ref
= reg_equiv_mem
[REGNO (ref
)];
528 if (reload_in_progress
)
529 base
= find_replacement (&XEXP (ref
, 0));
531 base
= XEXP (ref
, 0);
533 if (GET_CODE (base
) == PLUS
)
534 offset
+= INTVAL (XEXP (base
, 1)), base
= XEXP (base
, 0);
536 return plus_constant (base
, offset
);
539 /* Subfunction of the following function. Update the flags of any MEM
540 found in part of X. */
543 alpha_set_memflags_1 (x
, in_struct_p
, volatile_p
, unchanging_p
)
545 int in_struct_p
, volatile_p
, unchanging_p
;
549 switch (GET_CODE (x
))
553 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
554 alpha_set_memflags_1 (XVECEXP (x
, 0, i
), in_struct_p
, volatile_p
,
559 alpha_set_memflags_1 (PATTERN (x
), in_struct_p
, volatile_p
,
564 alpha_set_memflags_1 (SET_DEST (x
), in_struct_p
, volatile_p
,
566 alpha_set_memflags_1 (SET_SRC (x
), in_struct_p
, volatile_p
,
571 MEM_IN_STRUCT_P (x
) = in_struct_p
;
572 MEM_VOLATILE_P (x
) = volatile_p
;
573 RTX_UNCHANGING_P (x
) = unchanging_p
;
578 /* Given INSN, which is either an INSN or a SEQUENCE generated to
579 perform a memory operation, look for any MEMs in either a SET_DEST or
580 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
581 REF into each of the MEMs found. If REF is not a MEM, don't do
585 alpha_set_memflags (insn
, ref
)
589 /* Note that it is always safe to get these flags, though they won't
590 be what we think if REF is not a MEM. */
591 int in_struct_p
= MEM_IN_STRUCT_P (ref
);
592 int volatile_p
= MEM_VOLATILE_P (ref
);
593 int unchanging_p
= RTX_UNCHANGING_P (ref
);
595 if (GET_CODE (ref
) != MEM
596 || (! in_struct_p
&& ! volatile_p
&& ! unchanging_p
))
599 alpha_set_memflags_1 (insn
, in_struct_p
, volatile_p
, unchanging_p
);
602 /* Try to output insns to set TARGET equal to the constant C if it can be
603 done in less than N insns. Returns 1 if it can be done and the
604 insns have been emitted. If it would take more than N insns, zero is
605 returned and no insns and emitted. */
608 alpha_emit_set_const (target
, c
, n
)
613 HOST_WIDE_INT
new = c
;
616 #if HOST_BITS_PER_WIDE_INT == 64
617 /* We are only called for SImode and DImode. If this is SImode, ensure that
618 we are sign extended to a full word. This does not make any sense when
619 cross-compiling on a narrow machine. */
621 if (GET_MODE (target
) == SImode
)
622 c
= (c
& 0xffffffff) - 2 * (c
& 0x80000000);
625 /* If this is a sign-extended 32-bit constant, we can do this in at most
626 three insns, so do it if we have enough insns left. We always have
627 a sign-extended 32-bit constant when compiling on a narrow machine. */
629 if (HOST_BITS_PER_WIDE_INT
!= 64
630 || c
>> 31 == -1 || c
>> 31 == 0)
632 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
633 HOST_WIDE_INT tmp1
= c
- low
;
635 = ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
636 HOST_WIDE_INT extra
= 0;
638 /* If HIGH will be interpreted as negative but the constant is
639 positive, we must adjust it to do two ldha insns. */
641 if ((high
& 0x8000) != 0 && c
>= 0)
645 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
648 if (c
== low
|| (low
== 0 && extra
== 0))
650 emit_move_insn (target
, GEN_INT (c
));
653 else if (n
>= 2 + (extra
!= 0))
655 emit_move_insn (target
, GEN_INT (low
));
657 emit_insn (gen_add2_insn (target
, GEN_INT (extra
<< 16)));
659 emit_insn (gen_add2_insn (target
, GEN_INT (high
<< 16)));
664 /* If we couldn't do it that way, try some other methods (that depend on
665 being able to compute in the target's word size). But if we have no
666 instructions left, don't bother. Also, don't even try if this is
667 SImode (in which case we should have already done something, but
668 do a sanity check here). */
670 if (n
== 1 || HOST_BITS_PER_WIDE_INT
< 64 || GET_MODE (target
) != DImode
)
673 /* First, see if can load a value into the target that is the same as the
674 constant except that all bytes that are 0 are changed to be 0xff. If we
675 can, then we can do a ZAPNOT to obtain the desired constant. */
677 for (i
= 0; i
< 64; i
+= 8)
678 if ((new & ((HOST_WIDE_INT
) 0xff << i
)) == 0)
679 new |= (HOST_WIDE_INT
) 0xff << i
;
681 if (alpha_emit_set_const (target
, new, n
- 1))
683 emit_insn (gen_anddi3 (target
, target
, GEN_INT (c
| ~ new)));
687 /* Find, see if we can load a related constant and then shift and possibly
688 negate it to get the constant we want. Try this once each increasing
691 for (i
= 1; i
< n
; i
++)
693 /* First try complementing. */
694 if (alpha_emit_set_const (target
, ~ c
, i
))
696 emit_insn (gen_one_cmpldi2 (target
, target
));
700 /* First try to form a constant and do a left shift. We can do this
701 if some low-order bits are zero; the exact_log2 call below tells
702 us that information. The bits we are shifting out could be any
703 value, but here we'll just try the 0- and sign-extended forms of
704 the constant. To try to increase the chance of having the same
705 constant in more than one insn, start at the highest number of
706 bits to shift, but try all possibilities in case a ZAPNOT will
709 if ((bits
= exact_log2 (c
& - c
)) > 0)
710 for (; bits
> 0; bits
--)
711 if (alpha_emit_set_const (target
, c
>> bits
, i
)
712 || alpha_emit_set_const (target
,
713 ((unsigned HOST_WIDE_INT
) c
) >> bits
,
716 emit_insn (gen_ashldi3 (target
, target
, GEN_INT (bits
)));
720 /* Now try high-order zero bits. Here we try the shifted-in bits as
721 all zero and all ones. */
723 if ((bits
= HOST_BITS_PER_WIDE_INT
- floor_log2 (c
) - 1) > 0)
724 for (; bits
> 0; bits
--)
725 if (alpha_emit_set_const (target
, c
<< bits
, i
)
726 || alpha_emit_set_const (target
,
728 | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
731 emit_insn (gen_lshrdi3 (target
, target
, GEN_INT (bits
)));
735 /* Now try high-order 1 bits. We get that with a sign-extension.
736 But one bit isn't enough here. */
738 if ((bits
= HOST_BITS_PER_WIDE_INT
- floor_log2 (~ c
) - 2) > 0)
739 for (; bits
> 0; bits
--)
740 if (alpha_emit_set_const (target
, c
<< bits
, i
)
741 || alpha_emit_set_const (target
,
743 | (((HOST_WIDE_INT
) 1 << bits
) - 1)),
746 emit_insn (gen_ashrdi3 (target
, target
, GEN_INT (bits
)));
754 /* Adjust the cost of a scheduling dependency. Return the new cost of
755 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
758 alpha_adjust_cost (insn
, link
, dep_insn
, cost
)
766 /* If the dependence is an anti-dependence, there is no cost. For an
767 output dependence, there is sometimes a cost, but it doesn't seem
768 worth handling those few cases. */
770 if (REG_NOTE_KIND (link
) != 0)
773 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
774 we can sometimes lower the cost. */
776 if (recog_memoized (insn
) >= 0 && get_attr_type (insn
) == TYPE_ST
777 && (set
= single_set (dep_insn
)) != 0
778 && GET_CODE (PATTERN (insn
)) == SET
779 && rtx_equal_p (SET_DEST (set
), SET_SRC (PATTERN (insn
))))
780 switch (get_attr_type (dep_insn
))
783 /* No savings here. */
788 /* In these cases, we save one cycle. */
792 /* In all other cases, we save two cycles. */
793 return MAX (0, cost
- 4);
796 /* Another case that needs adjustment is an arithmetic or logical
797 operation. It's cost is usually one cycle, but we default it to
798 two in the MD file. The only case that it is actually two is
799 for the address in loads and stores. */
801 if (recog_memoized (dep_insn
) >= 0
802 && get_attr_type (dep_insn
) == TYPE_IADDLOG
)
803 switch (get_attr_type (insn
))
813 /* The final case is when a compare feeds into an integer branch. The cost
814 is only one cycle in that case. */
816 if (recog_memoized (dep_insn
) >= 0
817 && get_attr_type (dep_insn
) == TYPE_ICMP
818 && recog_memoized (insn
) >= 0
819 && get_attr_type (insn
) == TYPE_IBR
)
822 /* Otherwise, return the default cost. */
827 /* Print an operand. Recognize special options, documented below. */
830 print_operand (file
, x
, code
)
840 /* If this operand is the constant zero, write it as "$31". */
841 if (GET_CODE (x
) == REG
)
842 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
843 else if (x
== CONST0_RTX (GET_MODE (x
)))
844 fprintf (file
, "$31");
846 output_operand_lossage ("invalid %%r value");
851 /* Similar, but for floating-point. */
852 if (GET_CODE (x
) == REG
)
853 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
854 else if (x
== CONST0_RTX (GET_MODE (x
)))
855 fprintf (file
, "$f31");
857 output_operand_lossage ("invalid %%R value");
862 /* Write the 1's complement of a constant. */
863 if (GET_CODE (x
) != CONST_INT
)
864 output_operand_lossage ("invalid %%N value");
866 fprintf (file
, "%ld", ~ INTVAL (x
));
870 /* Write 1 << C, for a constant C. */
871 if (GET_CODE (x
) != CONST_INT
)
872 output_operand_lossage ("invalid %%P value");
874 fprintf (file
, "%ld", (HOST_WIDE_INT
) 1 << INTVAL (x
));
878 /* Write the high-order 16 bits of a constant, sign-extended. */
879 if (GET_CODE (x
) != CONST_INT
)
880 output_operand_lossage ("invalid %%h value");
882 fprintf (file
, "%ld", INTVAL (x
) >> 16);
886 /* Write the low-order 16 bits of a constant, sign-extended. */
887 if (GET_CODE (x
) != CONST_INT
)
888 output_operand_lossage ("invalid %%L value");
890 fprintf (file
, "%ld", (INTVAL (x
) & 0xffff) - 2 * (INTVAL (x
) & 0x8000));
894 /* Write mask for ZAP insn. */
895 if (GET_CODE (x
) == CONST_DOUBLE
)
897 HOST_WIDE_INT mask
= 0;
900 value
= CONST_DOUBLE_LOW (x
);
901 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
906 value
= CONST_DOUBLE_HIGH (x
);
907 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR
;
910 mask
|= (1 << (i
+ sizeof (int)));
912 fprintf (file
, "%ld", mask
& 0xff);
915 else if (GET_CODE (x
) == CONST_INT
)
917 HOST_WIDE_INT mask
= 0, value
= INTVAL (x
);
919 for (i
= 0; i
< 8; i
++, value
>>= 8)
923 fprintf (file
, "%ld", mask
);
926 output_operand_lossage ("invalid %%m value");
930 /* 'b', 'w', or 'l' as the value of the constant. */
931 if (GET_CODE (x
) != CONST_INT
932 || (INTVAL (x
) != 8 && INTVAL (x
) != 16 && INTVAL (x
) != 32))
933 output_operand_lossage ("invalid %%M value");
936 INTVAL (x
) == 8 ? "b" : INTVAL (x
) == 16 ? "w" : "l");
940 /* Similar, except do it from the mask. */
941 if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xff)
943 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffff)
945 #if HOST_BITS_PER_WIDE_INT == 32
946 else if (GET_CODE (x
) == CONST_DOUBLE
947 && CONST_DOUBLE_HIGH (x
) == 0
948 && CONST_DOUBLE_LOW (x
) == -1)
951 else if (GET_CODE (x
) == CONST_INT
&& INTVAL (x
) == 0xffffffff)
955 output_operand_lossage ("invalid %%U value");
959 /* Write the constant value divided by 8. */
960 if (GET_CODE (x
) != CONST_INT
961 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
962 && (INTVAL (x
) & 7) != 8)
963 output_operand_lossage ("invalid %%s value");
965 fprintf (file
, "%ld", INTVAL (x
) / 8);
969 /* Same, except compute (64 - c) / 8 */
971 if (GET_CODE (x
) != CONST_INT
972 && (unsigned HOST_WIDE_INT
) INTVAL (x
) >= 64
973 && (INTVAL (x
) & 7) != 8)
974 output_operand_lossage ("invalid %%s value");
976 fprintf (file
, "%ld", (64 - INTVAL (x
)) / 8);
980 /* Write out comparison name. */
981 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
982 output_operand_lossage ("invalid %%C value");
984 if (GET_CODE (x
) == LEU
)
985 fprintf (file
, "ule");
986 else if (GET_CODE (x
) == LTU
)
987 fprintf (file
, "ult");
989 fprintf (file
, "%s", GET_RTX_NAME (GET_CODE (x
)));
993 /* Similar, but write reversed code. We can't get an unsigned code
995 if (GET_RTX_CLASS (GET_CODE (x
)) != '<')
996 output_operand_lossage ("invalid %%D value");
998 fprintf (file
, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x
))));
1002 /* Write the divide or modulus operator. */
1003 switch (GET_CODE (x
))
1006 fprintf (file
, "div%s", GET_MODE (x
) == SImode
? "l" : "q");
1009 fprintf (file
, "div%su", GET_MODE (x
) == SImode
? "l" : "q");
1012 fprintf (file
, "rem%s", GET_MODE (x
) == SImode
? "l" : "q");
1015 fprintf (file
, "rem%su", GET_MODE (x
) == SImode
? "l" : "q");
1018 output_operand_lossage ("invalid %%E value");
1024 /* Write "_u" for unaligned access. */
1025 if (GET_CODE (x
) == MEM
&& GET_CODE (XEXP (x
, 0)) == AND
)
1026 fprintf (file
, "_u");
1030 if (GET_CODE (x
) == REG
)
1031 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
1032 else if (GET_CODE (x
) == MEM
)
1033 output_address (XEXP (x
, 0));
1035 output_addr_const (file
, x
);
1039 output_operand_lossage ("invalid %%xn code");
1043 /* Do what is necessary for `va_start'. The argument is ignored;
1044 We look at the current function to determine if stdarg or varargs
1045 is used and fill in an initial va_list. A pointer to this constructor
1049 alpha_builtin_saveregs (arglist
)
1052 rtx block
, addr
, argsize
;
1053 tree fntype
= TREE_TYPE (current_function_decl
);
1054 int stdarg
= (TYPE_ARG_TYPES (fntype
) != 0
1055 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
1056 != void_type_node
));
1058 /* Compute the current position into the args, taking into account
1059 both registers and memory. Both of these are already included in
1060 current_function_args_info. */
1062 argsize
= GEN_INT (current_function_args_info
* UNITS_PER_WORD
);
1064 /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1065 storing fp arg registers in the first 48 bytes, and the integer arg
1066 registers in the next 48 bytes. This is only done, however, if any
1067 integer registers need to be stored.
1069 If no integer registers need be stored, then we must subtract 48 in
1070 order to account for the integer arg registers which are counted in
1071 argsize above, but which are not actually stored on the stack. */
1073 addr
= (current_function_args_info
< 6
1074 ? plus_constant (virtual_incoming_args_rtx
, 6 * UNITS_PER_WORD
)
1075 : plus_constant (virtual_incoming_args_rtx
, - (6 * UNITS_PER_WORD
)));
1077 /* Allocate the va_list constructor */
1078 block
= assign_stack_local (BLKmode
, 2 * UNITS_PER_WORD
, BITS_PER_WORD
);
1079 RTX_UNCHANGING_P (block
) = 1;
1080 RTX_UNCHANGING_P (XEXP (block
, 0)) = 1;
1082 /* Store the address of the first integer register in the
1083 __va_base member. */
1084 emit_move_insn (change_address (block
, Pmode
, XEXP (block
, 0)),
1085 force_operand (addr
, NULL_RTX
));
1087 /* Store the argsize as the __va_offset member. */
1088 emit_move_insn (change_address (block
, Pmode
,
1089 plus_constant (XEXP (block
, 0),
1091 force_operand (argsize
, NULL_RTX
));
1093 /* Return the address of the va_list constructor, but don't put it in a
1094 register. Doing so would fail when not optimizing and produce worse
1095 code when optimizing. */
1096 return XEXP (block
, 0);
1099 /* This page contains routines that are used to determine what the function
1100 prologue and epilogue code will do and write them out. */
1102 /* Compute the size of the save area in the stack. */
1110 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1111 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
])
1114 /* If some registers were saved but not reg 26, reg 26 must also
1115 be saved, so leave space for it. */
1116 if (size
!= 0 && ! regs_ever_live
[26])
1122 /* Return 1 if this function can directly return via $26. */
1127 return (reload_completed
&& alpha_sa_size () == 0
1128 && get_frame_size () == 0
1129 && current_function_pretend_args_size
== 0);
1132 /* Write a version stamp. Don't write anything if we are running as a
1133 cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
1135 #ifndef CROSS_COMPILE
1140 alpha_write_verstamp (file
)
1146 fprintf (file
, "\t.verstamp %d %d ", MS_STAMP
, LS_STAMP
);
1147 for (p
= version_string
; *p
!= ' ' && *p
!= 0; p
++)
1148 fprintf (file
, "%c", *p
== '.' ? ' ' : *p
);
1149 fprintf (file
, "\n");
1153 /* Write code to add constant C to register number IN_REG (possibly 31)
1154 and put the result into OUT_REG. Write the code to FILE. */
1157 add_long_const (file
, c
, in_reg
, out_reg
)
1159 int in_reg
, out_reg
;
1162 HOST_WIDE_INT low
= (c
& 0xffff) - 2 * (c
& 0x8000);
1163 HOST_WIDE_INT tmp1
= c
- low
;
1164 HOST_WIDE_INT high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1165 HOST_WIDE_INT extra
= 0;
1167 /* We don't have code to write out constants larger than 32 bits. */
1168 #if HOST_BITS_PER_LONG_INT == 64
1169 if ((unsigned HOST_WIDE_INT
) c
>> 32 != 0)
1173 /* If HIGH will be interpreted as negative, we must adjust it to do two
1174 ldha insns. Note that we will never be building a negative constant
1181 high
= ((tmp1
>> 16) & 0xffff) - 2 * ((tmp1
>> 16) & 0x8000);
1186 if (low
>= 0 && low
< 255)
1187 fprintf (file
, "\taddq $%d,%d,$%d\n", in_reg
, low
, out_reg
);
1189 fprintf (file
, "\tlda $%d,%d($%d)\n", out_reg
, low
, in_reg
);
1195 fprintf (file
, "\tldah $%d,%d($%d)\n", out_reg
, extra
, in_reg
);
1200 fprintf (file
, "\tldah $%d,%d($%d)\n", out_reg
, high
, in_reg
);
1203 /* Write function prologue. */
1206 output_prolog (file
, size
)
1210 HOST_WIDE_INT vars_size
= (size
+ 7) & ~7;
1211 HOST_WIDE_INT frame_size
= ((vars_size
+ current_function_outgoing_args_size
1212 + current_function_pretend_args_size
1213 + alpha_sa_size () + 15) & ~15);
1214 HOST_WIDE_INT reg_offset
= vars_size
+ current_function_outgoing_args_size
;
1215 HOST_WIDE_INT start_reg_offset
= reg_offset
;
1216 HOST_WIDE_INT actual_start_reg_offset
= start_reg_offset
;
1217 int int_reg_save_area_size
= 0;
1219 int reg_offset_base_reg
= 30;
1220 unsigned reg_mask
= 0;
1223 /* Ecoff can handle multiple .file directives, put out file and lineno.
1224 We have to do that before the .ent directive as we cannot switch
1225 files within procedures with native ecoff because line numbers are
1226 linked to procedure descriptors.
1227 Outputting the lineno helps debugging of one line functions as they
1228 would otherwise get no line number at all. Please note that we would
1229 like to put out last_linenum from final.c, but it is not accesible. */
1231 if (write_symbols
== SDB_DEBUG
)
1233 ASM_OUTPUT_SOURCE_FILENAME (file
,
1234 DECL_SOURCE_FILE (current_function_decl
));
1235 if (debug_info_level
!= DINFO_LEVEL_TERSE
)
1236 ASM_OUTPUT_SOURCE_LINE (file
, DECL_SOURCE_LINE (current_function_decl
));
1239 /* The assembly language programmer's guide states that the second argument
1240 to the .ent directive, the lex_level, is ignored by the assembler,
1241 so we might as well omit it. */
1243 fprintf (file
, "\t.ent ");
1244 assemble_name (file
, alpha_function_name
);
1245 fprintf (file
, "\n");
1246 ASM_OUTPUT_LABEL (file
, alpha_function_name
);
1247 inside_function
= TRUE
;
1249 /* Set up offsets to alpha virtual arg/local debugging pointer. */
1251 alpha_auto_offset
= -frame_size
+ current_function_pretend_args_size
;
1252 alpha_arg_offset
= -frame_size
+ 48;
1254 /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
1255 Even if we are a static function, we still need to do this in case
1256 our address is taken and passed to something like qsort. */
1258 alpha_function_needs_gp
= 0;
1259 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
1260 if ((GET_CODE (insn
) == CALL_INSN
)
1261 || (GET_RTX_CLASS (GET_CODE (insn
)) == 'i'
1262 && GET_CODE (PATTERN (insn
)) != USE
1263 && GET_CODE (PATTERN (insn
)) != CLOBBER
1264 && (get_attr_type (insn
) == TYPE_LDSYM
1265 || get_attr_type (insn
) == TYPE_ISUBR
)))
1267 alpha_function_needs_gp
= 1;
1271 if (alpha_function_needs_gp
)
1272 fprintf (file
, "\tldgp $29,0($27)\n");
1274 /* Put a label after the GP load so we can enter the function at it. */
1275 assemble_name (file
, alpha_function_name
);
1276 fprintf (file
, "..ng:\n");
1278 /* Adjust the stack by the frame size. If the frame size is > 4096
1279 bytes, we need to be sure we probe somewhere in the first and last
1280 4096 bytes (we can probably get away without the latter test) and
1281 every 8192 bytes in between. If the frame size is > 32768, we
1282 do this in a loop. Otherwise, we generate the explicit probe
1285 Note that we are only allowed to adjust sp once in the prologue. */
1287 if (frame_size
< 32768)
1289 if (frame_size
> 4096)
1294 fprintf (file
, "\tldq $%d,-%d($30)\n", regnum
++, probed
);
1296 while (probed
+ 8192 < frame_size
)
1297 fprintf (file
, "\tldq $%d,-%d($30)\n", regnum
++, probed
+= 8192);
1299 if (probed
+ 4096 < frame_size
)
1300 fprintf (file
, "\tldq $%d,-%d($30)\n", regnum
++, probed
+= 4096);
1306 if (frame_size
!= 0)
1307 fprintf (file
, "\tlda $30,-%d($30)\n", frame_size
);
1311 /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1312 number of 8192 byte blocks to probe. We then probe each block
1313 in the loop and then set SP to the proper location. If the
1314 amount remaining is > 4096, we have to do one more probe. */
1316 HOST_WIDE_INT blocks
= (frame_size
+ 4096) / 8192;
1317 HOST_WIDE_INT leftover
= frame_size
+ 4096 - blocks
* 8192;
1319 add_long_const (file
, blocks
, 31, 5);
1321 fprintf (file
, "\tlda $4,4096($30)\n");
1323 assemble_name (file
, alpha_function_name
);
1324 fprintf (file
, "..sc:\n");
1326 fprintf (file
, "\tldq $6,-8192($4)\n");
1327 fprintf (file
, "\tsubq $5,1,$5\n");
1328 fprintf (file
, "\tlda $4,-8192($4)\n");
1330 fprintf (file
, "\tbne $5,");
1331 assemble_name (file
, alpha_function_name
);
1332 fprintf (file
, "..sc\n");
1334 fprintf (file
, "\tlda $30,-%d($4)\n", leftover
);
1336 if (leftover
> 4096)
1337 fprintf (file
, "\tldq $2,%d($30)\n", leftover
- 4096);
1340 /* Describe our frame. */
1341 fprintf (file
, "\t.frame $%d,%d,$26,%d\n",
1342 frame_pointer_needed
? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
,
1343 frame_size
, current_function_pretend_args_size
);
1345 /* If reg_offset is "close enough" to 2**15 that one of the offsets would
1346 overflow a store instruction, compute the base of the register save
1348 if (reg_offset
>= 32768 - alpha_sa_size () && alpha_sa_size () != 0)
1350 add_long_const (file
, reg_offset
, 30, 28);
1351 reg_offset_base_reg
= 28;
1352 reg_offset
= start_reg_offset
= 0;
1355 /* Save register 26 if it is used or if any other register needs to
1357 if (regs_ever_live
[26] || alpha_sa_size () != 0)
1359 reg_mask
|= 1 << 26;
1360 fprintf (file
, "\tstq $26,%d($%d)\n", reg_offset
, reg_offset_base_reg
);
1362 int_reg_save_area_size
+= 8;
1365 /* Now save any other used integer registers required to be saved. */
1366 for (i
= 0; i
< 32; i
++)
1367 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
] && i
!= 26)
1370 fprintf (file
, "\tstq $%d,%d($%d)\n",
1371 i
, reg_offset
, reg_offset_base_reg
);
1373 int_reg_save_area_size
+= 8;
1376 /* Print the register mask and do floating-point saves. */
1378 fprintf (file
, "\t.mask 0x%x,%d\n", reg_mask
,
1379 actual_start_reg_offset
- frame_size
);
1381 start_reg_offset
= reg_offset
;
1384 for (i
= 0; i
< 32; i
++)
1385 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1386 && regs_ever_live
[i
+ 32])
1389 fprintf (file
, "\tstt $f%d,%d($%d)\n",
1390 i
, reg_offset
, reg_offset_base_reg
);
1394 /* Print the floating-point mask, if we've saved any fp register. */
1396 fprintf (file
, "\t.fmask 0x%x,%d\n", reg_mask
,
1397 actual_start_reg_offset
- frame_size
+ int_reg_save_area_size
);
1399 /* If we need a frame pointer, set it from the stack pointer. Note that
1400 this must always be the last instruction in the prologue. */
1401 if (frame_pointer_needed
)
1402 fprintf (file
, "\tbis $30,$30,$15\n");
1404 /* End the prologue and say if we used gp. */
1405 fprintf (file
, "\t.prologue %d\n", alpha_function_needs_gp
);
1408 /* Write function epilogue. */
1411 output_epilog (file
, size
)
1415 rtx insn
= get_last_insn ();
1416 HOST_WIDE_INT vars_size
= (size
+ 7) & ~7;
1417 HOST_WIDE_INT frame_size
= ((vars_size
+ current_function_outgoing_args_size
1418 + current_function_pretend_args_size
1419 + alpha_sa_size () + 15) & ~15);
1420 HOST_WIDE_INT reg_offset
= vars_size
+ current_function_outgoing_args_size
;
1421 HOST_WIDE_INT frame_size_from_reg_save
= frame_size
- reg_offset
;
1422 int reg_offset_base_reg
= 30;
1425 /* If the last insn was a BARRIER, we don't have to write anything except
1426 the .end pseudo-op. */
1427 if (GET_CODE (insn
) == NOTE
)
1428 insn
= prev_nonnote_insn (insn
);
1429 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
1433 /* If we have a frame pointer, restore SP from it. */
1434 if (frame_pointer_needed
)
1435 fprintf (file
, "\tbis $15,$15,$30\n");
1437 /* If the register save area is out of range, put its address into
1439 if (reg_offset
>= 32768 - alpha_sa_size () && alpha_sa_size () != 0)
1441 add_long_const (file
, reg_offset
, 30, 28);
1442 reg_offset_base_reg
= 28;
1446 /* Restore all the registers, starting with the return address
1448 if (regs_ever_live
[26] || alpha_sa_size () != 0)
1450 fprintf (file
, "\tldq $26,%d($%d)\n",
1451 reg_offset
, reg_offset_base_reg
);
1455 /* Now restore any other used integer registers that that we saved,
1456 except for FP if it is being used as FP, since it must be
1459 for (i
= 0; i
< 32; i
++)
1460 if (! fixed_regs
[i
] && ! call_used_regs
[i
] && regs_ever_live
[i
]
1463 if (i
== FRAME_POINTER_REGNUM
&& frame_pointer_needed
)
1464 fp_offset
= reg_offset
;
1466 fprintf (file
, "\tldq $%d,%d($%d)\n",
1467 i
, reg_offset
, reg_offset_base_reg
);
1471 for (i
= 0; i
< 32; i
++)
1472 if (! fixed_regs
[i
+ 32] && ! call_used_regs
[i
+ 32]
1473 && regs_ever_live
[i
+ 32])
1475 fprintf (file
, "\tldt $f%d,%d($%d)\n",
1476 i
, reg_offset
, reg_offset_base_reg
);
1480 /* If the stack size is large, compute the size of the stack into
1481 a register because the old FP restore, stack pointer adjust,
1482 and return are required to be consecutive instructions.
1483 However, if the new stack pointer can be computed by adding the
1484 a constant to the start of the register save area, we can do
1486 if (frame_size
> 32767
1487 && ! (reg_offset_base_reg
!= 30
1488 && frame_size_from_reg_save
< 32768))
1489 add_long_const (file
, frame_size
, 31, 1);
1491 /* If we needed a frame pointer and we have to restore it, do it
1492 now. This must be done in one instruction immediately
1493 before the SP update. */
1494 if (frame_pointer_needed
&& regs_ever_live
[FRAME_POINTER_REGNUM
])
1495 fprintf (file
, "\tldq $15,%d($%d)\n", fp_offset
, reg_offset_base_reg
);
1497 /* Now update the stack pointer, if needed. This must be done in
1498 one, stylized, instruction. */
1499 if (frame_size
> 32768)
1501 if (reg_offset_base_reg
!= 30
1502 && frame_size_from_reg_save
< 32768)
1504 if (frame_size_from_reg_save
< 255)
1505 fprintf (file
, "\taddq $%d,%d,$30\n",
1506 reg_offset_base_reg
, frame_size_from_reg_save
);
1508 fprintf (file
, "\tlda %30,%d($%d)\n",
1509 frame_size_from_reg_save
, reg_offset_base_reg
);
1512 fprintf (file
, "\taddq $1,$30,$30\n");
1514 else if (frame_size
!= 0)
1515 fprintf (file
, "\tlda $30,%d($30)\n", frame_size
);
1517 /* Finally return to the caller. */
1518 fprintf (file
, "\tret $31,($26),1\n");
1521 /* End the function. */
1522 fprintf (file
, "\t.end ");
1523 assemble_name (file
, alpha_function_name
);
1524 fprintf (file
, "\n");
1525 inside_function
= FALSE
;
1527 /* Show that we know this function if it is called again. */
1528 SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl
), 0)) = 1;
1531 /* Debugging support. */
1535 /* Count the number of sdb related labels are generated (to find block
1536 start and end boundaries). */
1538 int sdb_label_count
= 0;
1540 /* Next label # for each statement. */
1542 static int sym_lineno
= 0;
1544 /* Count the number of .file directives, so that .loc is up to date. */
1546 static int num_source_filenames
= 0;
1548 /* Name of the file containing the current function. */
1550 static char *current_function_file
= "";
1552 /* Offsets to alpha virtual arg/local debugging pointers. */
1554 long alpha_arg_offset
;
1555 long alpha_auto_offset
;
1557 /* Emit a new filename to a stream. */
1560 alpha_output_filename (stream
, name
)
1564 static int first_time
= TRUE
;
1565 char ltext_label_name
[100];
1570 ++num_source_filenames
;
1571 current_function_file
= name
;
1572 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
1573 output_quoted_string (stream
, name
);
1574 fprintf (stream
, "\n");
1575 if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1576 fprintf (stream
, "\t#@stabs\n");
1579 else if (!TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1581 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name
, "Ltext", 0);
1582 fprintf (stream
, "%s ", ASM_STABS_OP
);
1583 output_quoted_string (stream
, name
);
1584 fprintf (stream
, ",%d,0,0,%s\n", N_SOL
, <ext_label_name
[1]);
1587 else if (name
!= current_function_file
1588 && strcmp (name
, current_function_file
) != 0)
1590 if (inside_function
&& ! TARGET_GAS
)
1591 fprintf (stream
, "\t#.file\t%d ", num_source_filenames
);
1594 ++num_source_filenames
;
1595 current_function_file
= name
;
1596 fprintf (stream
, "\t.file\t%d ", num_source_filenames
);
1599 output_quoted_string (stream
, name
);
1600 fprintf (stream
, "\n");
1604 /* Emit a linenumber to a stream. */
1607 alpha_output_lineno (stream
, line
)
1611 if (! TARGET_GAS
&& write_symbols
== DBX_DEBUG
)
1613 /* mips-tfile doesn't understand .stabd directives. */
1615 fprintf (stream
, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1616 sym_lineno
, ASM_STABN_OP
, N_SLINE
, line
, sym_lineno
);
1619 fprintf (stream
, "\n\t.loc\t%d %d\n", num_source_filenames
, line
);