1 /* Subroutines for insn-output.c for Sun SPARC.
2 Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3 Contributed by Michael Tiemann (tiemann@cygnus.com)
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"
37 /* Global variables for machine-dependent things. */
39 /* Save the operands last given to a compare for use when we
40 generate a scc or bcc insn. */
42 rtx sparc_compare_op0
, sparc_compare_op1
;
44 /* We may need an epilogue if we spill too many registers.
45 If this is non-zero, then we branch here for the epilogue. */
46 static rtx leaf_label
;
50 /* Vector to say how input registers are mapped to output
51 registers. FRAME_POINTER_REGNUM cannot be remapped by
52 this function to eliminate it. You must use -fomit-frame-pointer
54 char leaf_reg_remap
[] =
55 { 0, 1, 2, 3, 4, 5, 6, 7,
56 -1, -1, -1, -1, -1, -1, 14, -1,
57 -1, -1, -1, -1, -1, -1, -1, -1,
58 8, 9, 10, 11, 12, 13, -1, 15,
60 32, 33, 34, 35, 36, 37, 38, 39,
61 40, 41, 42, 43, 44, 45, 46, 47,
62 48, 49, 50, 51, 52, 53, 54, 55,
63 56, 57, 58, 59, 60, 61, 62, 63};
65 char leaf_reg_backmap
[] =
66 { 0, 1, 2, 3, 4, 5, 6, 7,
67 24, 25, 26, 27, 28, 29, 14, 31,
68 -1, -1, -1, -1, -1, -1, -1, -1,
69 -1, -1, -1, -1, -1, -1, -1, -1,
71 32, 33, 34, 35, 36, 37, 38, 39,
72 40, 41, 42, 43, 44, 45, 46, 47,
73 48, 49, 50, 51, 52, 53, 54, 55,
74 56, 57, 58, 59, 60, 61, 62, 63};
77 /* Global variables set by FUNCTION_PROLOGUE. */
78 /* Size of frame. Need to know this to emit return insns from
83 /* Name of where we pretend to think the frame pointer points.
84 Normally, this is "%fp", but if we are in a leaf procedure,
85 this is "%sp+something". */
86 char *frame_base_name
;
88 static rtx
find_addr_reg ();
90 /* Return non-zero only if OP is a register of mode MODE,
93 reg_or_0_operand (op
, mode
)
95 enum machine_mode mode
;
97 if (op
== const0_rtx
|| register_operand (op
, mode
))
99 if (GET_CODE (op
) == CONST_DOUBLE
100 && CONST_DOUBLE_HIGH (op
) == 0
101 && CONST_DOUBLE_LOW (op
) == 0)
106 /* Nonzero if OP can appear as the dest of a RESTORE insn. */
108 restore_operand (op
, mode
)
110 enum machine_mode mode
;
112 return (GET_CODE (op
) == REG
&& GET_MODE (op
) == mode
113 && (REGNO (op
) < 8 || (REGNO (op
) >= 24 && REGNO (op
) < 32)));
116 /* PC-relative call insn on SPARC is independent of `memory_operand'. */
119 call_operand (op
, mode
)
121 enum machine_mode mode
;
123 if (GET_CODE (op
) != MEM
)
126 return (REG_P (op
) || CONSTANT_P (op
));
130 call_operand_address (op
, mode
)
132 enum machine_mode mode
;
134 return (REG_P (op
) || CONSTANT_P (op
));
137 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
138 reference and a constant. */
141 symbolic_operand (op
, mode
)
143 enum machine_mode mode
;
145 switch (GET_CODE (op
))
153 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
154 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
155 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
157 /* This clause seems to be irrelevant. */
159 return GET_MODE (op
) == mode
;
166 /* Return truth value of statement that OP is a symbolic memory
167 operand of mode MODE. */
170 symbolic_memory_operand (op
, mode
)
172 enum machine_mode mode
;
174 if (GET_CODE (op
) == SUBREG
)
175 op
= SUBREG_REG (op
);
176 if (GET_CODE (op
) != MEM
)
179 return (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == CONST
180 || GET_CODE (op
) == HIGH
|| GET_CODE (op
) == LABEL_REF
);
183 /* Return 1 if the operand is either a register or a memory operand that is
187 reg_or_nonsymb_mem_operand (op
, mode
)
189 enum machine_mode mode
;
191 if (register_operand (op
, mode
))
194 if (memory_operand (op
, mode
) && ! symbolic_memory_operand (op
, mode
))
201 sparc_operand (op
, mode
)
203 enum machine_mode mode
;
205 if (register_operand (op
, mode
))
207 if (GET_CODE (op
) == CONST_INT
)
208 return SMALL_INT (op
);
209 if (GET_MODE (op
) != mode
)
211 if (GET_CODE (op
) == SUBREG
)
212 op
= SUBREG_REG (op
);
213 if (GET_CODE (op
) != MEM
)
217 if (GET_CODE (op
) == LO_SUM
)
218 return (GET_CODE (XEXP (op
, 0)) == REG
219 && symbolic_operand (XEXP (op
, 1), Pmode
));
220 return memory_address_p (mode
, op
);
224 move_operand (op
, mode
)
226 enum machine_mode mode
;
228 if (mode
== DImode
&& arith_double_operand (op
, mode
))
230 if (register_operand (op
, mode
))
232 if (GET_CODE (op
) == CONST_INT
)
233 return (SMALL_INT (op
) || (INTVAL (op
) & 0x3ff) == 0);
235 if (GET_MODE (op
) != mode
)
237 if (GET_CODE (op
) == SUBREG
)
238 op
= SUBREG_REG (op
);
239 if (GET_CODE (op
) != MEM
)
242 if (GET_CODE (op
) == LO_SUM
)
243 return (register_operand (XEXP (op
, 0), Pmode
)
244 && CONSTANT_P (XEXP (op
, 1)));
245 return memory_address_p (mode
, op
);
249 move_pic_label (op
, mode
)
251 enum machine_mode mode
;
253 /* Special case for PIC. */
254 if (flag_pic
&& GET_CODE (op
) == LABEL_REF
)
259 /* The rtx for the global offset table which is a special form
260 that *is* a position independent symbolic constant. */
263 /* Ensure that we are not using patterns that are not OK with PIC. */
272 if (GET_CODE (recog_operand
[i
]) == SYMBOL_REF
273 || (GET_CODE (recog_operand
[i
]) == CONST
274 && ! rtx_equal_p (pic_pc_rtx
, recog_operand
[i
])))
282 /* Return true if X is an address which needs a temporary register when
283 reloaded while generating PIC code. */
286 pic_address_needs_scratch (x
)
289 /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
290 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
291 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
292 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
293 && ! SMALL_INT (XEXP (XEXP (x
, 0), 1)))
302 enum machine_mode mode
;
304 if (GET_CODE (op
) == MEM
)
305 return (mode
== VOIDmode
|| mode
== GET_MODE (op
));
309 /* Return truth value of whether OP is EQ or NE. */
314 enum machine_mode mode
;
316 return (GET_CODE (op
) == EQ
|| GET_CODE (op
) == NE
);
319 /* Return 1 if this is a comparison operator, but not an EQ, NE, GEU,
320 or LTU for non-floating-point. We handle those specially. */
323 normal_comp_operator (op
, mode
)
325 enum machine_mode mode
;
327 enum rtx_code code
= GET_CODE (op
);
329 if (GET_RTX_CLASS (code
) != '<')
332 if (GET_MODE (XEXP (op
, 0)) == CCFPmode
)
335 return (code
!= NE
&& code
!= EQ
&& code
!= GEU
&& code
!= LTU
);
338 /* Return 1 if this is a comparison operator. This allows the use of
339 MATCH_OPERATOR to recognize all the branch insns. */
342 noov_compare_op (op
, mode
)
344 enum machine_mode mode
;
346 enum rtx_code code
= GET_CODE (op
);
348 if (GET_RTX_CLASS (code
) != '<')
351 if (GET_MODE (XEXP (op
, 0)) == CC_NOOVmode
)
352 /* These are the only branches which work with CC_NOOVmode. */
353 return (code
== EQ
|| code
== NE
|| code
== GE
|| code
== LT
);
357 /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
362 enum machine_mode mode
;
364 return GET_CODE (op
) == SIGN_EXTEND
|| GET_CODE (op
) == ZERO_EXTEND
;
367 /* Return nonzero if OP is an operator of mode MODE which can set
368 the condition codes explicitly. We do not include PLUS and MINUS
369 because these require CC_NOOVmode, which we handle explicitly. */
372 cc_arithop (op
, mode
)
374 enum machine_mode mode
;
376 if (GET_CODE (op
) == AND
377 || GET_CODE (op
) == IOR
378 || GET_CODE (op
) == XOR
)
384 /* Return nonzero if OP is an operator of mode MODE which can bitwise
385 complement its second operand and set the condition codes explicitly. */
388 cc_arithopn (op
, mode
)
390 enum machine_mode mode
;
392 /* XOR is not here because combine canonicalizes (xor (not ...) ...)
393 and (xor ... (not ...)) to (not (xor ...)). */
394 return (GET_CODE (op
) == AND
395 || GET_CODE (op
) == IOR
);
398 /* Return truth value of whether OP can be used as an operands in a three
399 address arithmetic insn (such as add %o1,7,%l2) of mode MODE. */
402 arith_operand (op
, mode
)
404 enum machine_mode mode
;
406 return (register_operand (op
, mode
)
407 || (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
)));
410 /* Return truth value of whether OP is a register or a CONST_DOUBLE. */
413 arith_double_operand (op
, mode
)
415 enum machine_mode mode
;
417 return (register_operand (op
, mode
)
418 || (GET_CODE (op
) == CONST_DOUBLE
419 && (GET_MODE (op
) == mode
|| GET_MODE (op
) == VOIDmode
)
420 && (unsigned) (CONST_DOUBLE_LOW (op
) + 0x1000) < 0x2000
421 && ((CONST_DOUBLE_HIGH (op
) == -1
422 && (CONST_DOUBLE_LOW (op
) & 0x1000) == 0x1000)
423 || (CONST_DOUBLE_HIGH (op
) == 0
424 && (CONST_DOUBLE_LOW (op
) & 0x1000) == 0)))
425 || (GET_CODE (op
) == CONST_INT
426 && (GET_MODE (op
) == mode
|| GET_MODE (op
) == VOIDmode
)
427 && (unsigned) (INTVAL (op
) + 0x1000) < 0x2000));
430 /* Return truth value of whether OP is a integer which fits the
431 range constraining immediate operands in three-address insns. */
436 enum machine_mode mode
;
438 return (GET_CODE (op
) == CONST_INT
&& SMALL_INT (op
));
441 /* Return truth value of statement that OP is a call-clobbered register. */
443 clobbered_register (op
, mode
)
445 enum machine_mode mode
;
447 return (GET_CODE (op
) == REG
&& call_used_regs
[REGNO (op
)]);
450 /* X and Y are two things to compare using CODE. Emit the compare insn and
451 return the rtx for register 0 in the proper mode. */
454 gen_compare_reg (code
, x
, y
)
458 enum machine_mode mode
= SELECT_CC_MODE (code
, x
);
459 rtx cc_reg
= gen_rtx (REG
, mode
, 0);
461 emit_insn (gen_rtx (SET
, VOIDmode
, cc_reg
,
462 gen_rtx (COMPARE
, mode
, x
, y
)));
467 /* Return nonzero if a return peephole merging return with
468 setting of output register is ok. */
470 leaf_return_peephole_ok ()
472 return (actual_fsize
== 0);
475 /* Return nonzero if TRIAL can go into the function epilogue's
476 delay slot. SLOT is the slot we are trying to fill. */
479 eligible_for_epilogue_delay (trial
, slot
)
483 static char *this_function_name
;
488 if (GET_CODE (trial
) != INSN
489 || GET_CODE (PATTERN (trial
)) != SET
)
491 if (get_attr_length (trial
) != 1)
494 /* In the case of a true leaf function, anything can
495 go into the delay slot. */
498 if (leaf_return_peephole_ok ())
499 return (get_attr_in_branch_delay (trial
) == IN_BRANCH_DELAY_TRUE
);
503 /* Otherwise, only operations which can be done in tandem with
504 a `restore' insn can go into the delay slot. */
505 pat
= PATTERN (trial
);
506 if (GET_CODE (SET_DEST (pat
)) != REG
507 || REGNO (SET_DEST (pat
)) == 0
509 && REGNO (SET_DEST (pat
)) < 32
510 && REGNO (SET_DEST (pat
)) >= 16)
512 && (REGNO (SET_DEST (pat
)) >= 32
513 || REGNO (SET_DEST (pat
)) < 24)))
516 if (arith_operand (src
, GET_MODE (src
)))
517 return GET_MODE_SIZE (GET_MODE (src
)) <= GET_MODE_SIZE (SImode
);
518 if (arith_double_operand (src
, GET_MODE (src
)))
519 return GET_MODE_SIZE (GET_MODE (src
)) <= GET_MODE_SIZE (DImode
);
520 if (GET_CODE (src
) == PLUS
)
522 if (register_operand (XEXP (src
, 0), SImode
)
523 && arith_operand (XEXP (src
, 1), SImode
))
525 if (register_operand (XEXP (src
, 1), SImode
)
526 && arith_operand (XEXP (src
, 0), SImode
))
528 if (register_operand (XEXP (src
, 0), DImode
)
529 && arith_double_operand (XEXP (src
, 1), DImode
))
531 if (register_operand (XEXP (src
, 1), DImode
)
532 && arith_double_operand (XEXP (src
, 0), DImode
))
535 if (GET_CODE (src
) == MINUS
536 && register_operand (XEXP (src
, 0), SImode
)
537 && small_int (XEXP (src
, 1), VOIDmode
))
539 if (GET_CODE (src
) == MINUS
540 && register_operand (XEXP (src
, 0), DImode
)
541 && !register_operand (XEXP (src
, 1), DImode
)
542 && arith_double_operand (XEXP (src
, 1), DImode
))
548 short_branch (uid1
, uid2
)
551 unsigned int delta
= insn_addresses
[uid1
] - insn_addresses
[uid2
];
552 if (delta
+ 1024 < 2048)
554 /* warning ("long branch, distance %d", delta); */
558 /* Return non-zero if REG is not used after INSN.
559 We assume REG is a reload reg, and therefore does
560 not live past labels or calls or jumps. */
562 reg_unused_after (reg
, insn
)
566 enum rtx_code code
, prev_code
= UNKNOWN
;
568 while (insn
= NEXT_INSN (insn
))
570 if (prev_code
== CALL_INSN
&& call_used_regs
[REGNO (reg
)])
573 code
= GET_CODE (insn
);
574 if (GET_CODE (insn
) == CODE_LABEL
)
577 if (GET_RTX_CLASS (code
) == 'i')
579 rtx set
= single_set (insn
);
580 int in_src
= set
&& reg_overlap_mentioned_p (reg
, SET_SRC (set
));
583 if (set
&& reg_overlap_mentioned_p (reg
, SET_DEST (set
)))
585 if (set
== 0 && reg_overlap_mentioned_p (reg
, PATTERN (insn
)))
593 /* Legitimize PIC addresses. If the address is already position-independent,
594 we return ORIG. Newly generated position-independent addresses go into a
595 reg. This is REG if non zero, otherwise we allocate register(s) as
596 necessary. If this is called during reload, and we need a second temp
597 register, then we use SCRATCH, which is provided via the
598 SECONDARY_INPUT_RELOAD_CLASS mechanism. */
601 legitimize_pic_address (orig
, mode
, reg
, scratch
)
603 enum machine_mode mode
;
606 if (GET_CODE (orig
) == SYMBOL_REF
)
608 rtx pic_ref
, address
;
613 if (reload_in_progress
|| reload_completed
)
616 reg
= gen_reg_rtx (Pmode
);
621 /* If not during reload, allocate another temp reg here for loading
622 in the address, so that these instructions can be optimized
624 rtx temp_reg
= ((reload_in_progress
|| reload_completed
)
625 ? reg
: gen_reg_rtx (Pmode
));
627 /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
628 won't get confused into thinking that these two instructions
629 are loading in the true address of the symbol. If in the
630 future a PIC rtx exists, that should be used instead. */
631 emit_insn (gen_rtx (SET
, VOIDmode
, temp_reg
,
632 gen_rtx (HIGH
, Pmode
,
633 gen_rtx (UNSPEC
, Pmode
,
636 emit_insn (gen_rtx (SET
, VOIDmode
, temp_reg
,
637 gen_rtx (LO_SUM
, Pmode
, temp_reg
,
638 gen_rtx (UNSPEC
, Pmode
,
646 pic_ref
= gen_rtx (MEM
, Pmode
,
647 gen_rtx (PLUS
, Pmode
,
648 pic_offset_table_rtx
, address
));
649 current_function_uses_pic_offset_table
= 1;
650 RTX_UNCHANGING_P (pic_ref
) = 1;
651 insn
= emit_move_insn (reg
, pic_ref
);
652 /* Put a REG_EQUAL note on this insn, so that it can be optimized
654 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
, orig
,
658 else if (GET_CODE (orig
) == CONST
)
662 if (GET_CODE (XEXP (orig
, 0)) == PLUS
663 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
668 if (reload_in_progress
|| reload_completed
)
671 reg
= gen_reg_rtx (Pmode
);
674 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
676 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
,
678 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
679 base
== reg
? 0 : reg
, 0);
684 if (GET_CODE (offset
) == CONST_INT
)
686 if (SMALL_INT (offset
))
687 return plus_constant_for_output (base
, INTVAL (offset
));
688 else if (! reload_in_progress
&& ! reload_completed
)
689 offset
= force_reg (Pmode
, offset
);
690 /* We can't create any new registers during reload, so use the
691 SCRATCH reg provided by the reload_insi pattern. */
694 emit_move_insn (scratch
, offset
);
698 /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
699 macro needs to be adjusted so that a scratch reg is provided
703 return gen_rtx (PLUS
, Pmode
, base
, offset
);
705 else if (GET_CODE (orig
) == LABEL_REF
)
706 current_function_uses_pic_offset_table
= 1;
711 /* Set up PIC-specific rtl. This should not cause any insns
719 /* Emit special PIC prologues and epilogues. */
724 /* The table we use to reference PIC data. */
725 rtx global_offset_table
;
726 /* Labels to get the PC in the prologue of this function. */
729 int orig_flag_pic
= flag_pic
;
731 if (current_function_uses_pic_offset_table
== 0)
738 l1
= gen_label_rtx ();
739 l2
= gen_label_rtx ();
744 /* Note that we pun calls and jumps here! */
745 emit_jump_insn (gen_rtx (PARALLEL
, VOIDmode
,
747 gen_rtx (SET
, VOIDmode
, pc_rtx
, gen_rtx (LABEL_REF
, VOIDmode
, l2
)),
748 gen_rtx (SET
, VOIDmode
, gen_rtx (REG
, SImode
, 15), gen_rtx (LABEL_REF
, VOIDmode
, l2
)))));
751 /* Initialize every time through, since we can't easily
752 know this to be permanent. */
753 global_offset_table
= gen_rtx (SYMBOL_REF
, Pmode
, "*__GLOBAL_OFFSET_TABLE_");
754 pic_pc_rtx
= gen_rtx (CONST
, Pmode
,
755 gen_rtx (MINUS
, Pmode
,
757 gen_rtx (CONST
, Pmode
,
758 gen_rtx (MINUS
, Pmode
,
759 gen_rtx (LABEL_REF
, VOIDmode
, l1
),
762 emit_insn (gen_rtx (SET
, VOIDmode
, pic_offset_table_rtx
,
763 gen_rtx (HIGH
, Pmode
, pic_pc_rtx
)));
764 emit_insn (gen_rtx (SET
, VOIDmode
,
765 pic_offset_table_rtx
,
766 gen_rtx (LO_SUM
, Pmode
,
767 pic_offset_table_rtx
, pic_pc_rtx
)));
768 emit_insn (gen_rtx (SET
, VOIDmode
,
769 pic_offset_table_rtx
,
770 gen_rtx (PLUS
, Pmode
,
771 pic_offset_table_rtx
, gen_rtx (REG
, Pmode
, 15))));
772 /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */
773 LABEL_PRESERVE_P (l1
) = 1;
774 LABEL_PRESERVE_P (l2
) = 1;
775 flag_pic
= orig_flag_pic
;
777 seq
= gen_sequence ();
779 emit_insn_after (seq
, get_insns ());
781 /* Need to emit this whether or not we obey regdecls,
782 since setjmp/longjmp can cause life info to screw up. */
783 emit_insn (gen_rtx (USE
, VOIDmode
, pic_offset_table_rtx
));
786 /* For the SPARC, REG and REG+CONST is cost 0, REG+REG is cost 1,
787 and addresses involving symbolic constants are cost 2.
789 We make REG+REG slightly more expensive because it might keep
790 a register live for longer than we might like.
792 PIC addresses are very expensive.
794 It is no coincidence that this has the same structure
795 as GO_IF_LEGITIMATE_ADDRESS. */
797 sparc_address_cost (X
)
801 /* Handled before calling here. */
802 if (GET_CODE (X
) == REG
)
805 if (GET_CODE (X
) == PLUS
)
807 if (GET_CODE (XEXP (X
, 0)) == REG
808 && GET_CODE (XEXP (X
, 1)) == REG
)
812 else if (GET_CODE (X
) == LO_SUM
)
814 else if (GET_CODE (X
) == HIGH
)
819 /* Emit insns to move operands[1] into operands[0].
821 Return 1 if we have written out everything that needs to be done to
822 do the move. Otherwise, return 0 and the caller will emit the move
825 SCRATCH_REG if non zero can be used as a scratch register for the move
826 operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */
829 emit_move_sequence (operands
, mode
, scratch_reg
)
831 enum machine_mode mode
;
834 register rtx operand0
= operands
[0];
835 register rtx operand1
= operands
[1];
837 /* Handle most common case first: storing into a register. */
838 if (register_operand (operand0
, mode
))
840 if (register_operand (operand1
, mode
)
841 || (GET_CODE (operand1
) == CONST_INT
&& SMALL_INT (operand1
))
842 || (GET_CODE (operand1
) == CONST_DOUBLE
843 && arith_double_operand (operand1
, DImode
))
844 || (GET_CODE (operand1
) == HIGH
&& GET_MODE (operand1
) != DImode
)
845 /* Only `general_operands' can come here, so MEM is ok. */
846 || GET_CODE (operand1
) == MEM
)
848 /* Run this case quickly. */
849 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
853 else if (GET_CODE (operand0
) == MEM
)
855 if (register_operand (operand1
, mode
) || operand1
== const0_rtx
)
857 /* Run this case quickly. */
858 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
861 if (! reload_in_progress
)
863 operands
[0] = validize_mem (operand0
);
864 operands
[1] = operand1
= force_reg (mode
, operand1
);
868 /* Simplify the source if we need to. Must handle DImode HIGH operators
869 here because such a move needs a clobber added. */
870 if ((GET_CODE (operand1
) != HIGH
&& immediate_operand (operand1
, mode
))
871 || (GET_CODE (operand1
) == HIGH
&& GET_MODE (operand1
) == DImode
))
873 if (flag_pic
&& symbolic_operand (operand1
, mode
))
875 rtx temp_reg
= reload_in_progress
? operand0
: 0;
877 operands
[1] = legitimize_pic_address (operand1
, mode
, temp_reg
,
880 else if (GET_CODE (operand1
) == CONST_INT
881 ? (! SMALL_INT (operand1
)
882 && (INTVAL (operand1
) & 0x3ff) != 0)
883 : (GET_CODE (operand1
) == CONST_DOUBLE
884 ? ! arith_double_operand (operand1
, DImode
)
887 /* For DImode values, temp must be operand0 because of the way
888 HI and LO_SUM work. The LO_SUM operator only copies half of
889 the LSW from the dest of the HI operator. If the LO_SUM dest is
890 not the same as the HI dest, then the MSW of the LO_SUM dest will
893 ??? The real problem here is that the ...(HI:DImode pattern emits
894 multiple instructions, and the ...(LO_SUM:DImode pattern emits
895 one instruction. This fails, because the compiler assumes that
896 LO_SUM copies all bits of the first operand to its dest. Better
897 would be to have the HI pattern emit one instruction and the
898 LO_SUM pattern multiple instructions. Even better would be
899 to use four rtl insns. */
900 rtx temp
= ((reload_in_progress
|| mode
== DImode
)
901 ? operand0
: gen_reg_rtx (mode
));
903 emit_insn (gen_rtx (SET
, VOIDmode
, temp
,
904 gen_rtx (HIGH
, mode
, operand1
)));
905 operands
[1] = gen_rtx (LO_SUM
, mode
, temp
, operand1
);
909 if (GET_CODE (operand1
) == LABEL_REF
&& flag_pic
)
911 /* The procedure for doing this involves using a call instruction to
912 get the pc into o7. We need to indicate this explicitly because
913 the tablejump pattern assumes that it can use this value also. */
914 emit_insn (gen_rtx (PARALLEL
, VOIDmode
,
916 gen_rtx (SET
, VOIDmode
, operand0
,
918 gen_rtx (SET
, VOIDmode
,
919 gen_rtx (REG
, mode
, 15),
924 /* Now have insn-emit do whatever it normally does. */
928 /* Return the best assembler insn template
929 for moving operands[1] into operands[0] as a fullword. */
932 singlemove_string (operands
)
935 if (GET_CODE (operands
[0]) == MEM
)
937 if (GET_CODE (operands
[1]) != MEM
)
942 if (GET_CODE (operands
[1]) == MEM
)
944 if (GET_CODE (operands
[1]) == CONST_INT
945 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands
[1]), 'I'))
947 int i
= INTVAL (operands
[1]);
949 /* If all low order 12 bits are clear, then we only need a single
950 sethi insn to load the constant. */
952 return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
954 return "sethi %%hi(%a1),%0";
956 /* ??? Wrong if target is DImode? */
960 /* Output assembler code to perform a doubleword move insn
961 with operands OPERANDS. */
964 output_move_double (operands
)
967 enum { REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype0
, optype1
;
969 rtx addreg0
= 0, addreg1
= 0;
971 /* First classify both operands. */
973 if (REG_P (operands
[0]))
975 else if (offsettable_memref_p (operands
[0]))
977 else if (GET_CODE (operands
[0]) == MEM
)
982 if (REG_P (operands
[1]))
984 else if (CONSTANT_P (operands
[1]))
986 else if (offsettable_memref_p (operands
[1]))
988 else if (GET_CODE (operands
[1]) == MEM
)
993 /* Check for the cases that the operand constraints are not
994 supposed to allow to happen. Abort if we get one,
995 because generating code for these cases is painful. */
997 if (optype0
== RNDOP
|| optype1
== RNDOP
)
1000 /* If an operand is an unoffsettable memory ref, find a register
1001 we can increment temporarily to make it refer to the second word. */
1003 if (optype0
== MEMOP
)
1004 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1006 if (optype1
== MEMOP
)
1007 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1009 /* Ok, we can do one word at a time.
1010 Normally we do the low-numbered word first,
1011 but if either operand is autodecrementing then we
1012 do the high-numbered word first.
1014 In either case, set up in LATEHALF the operands to use for the
1015 high-numbered (least significant) word and in some cases alter the
1016 operands in OPERANDS to be suitable for the low-numbered word. */
1018 if (optype0
== REGOP
)
1019 latehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 1);
1020 else if (optype0
== OFFSOP
)
1021 latehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1023 latehalf
[0] = operands
[0];
1025 if (optype1
== REGOP
)
1026 latehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 1);
1027 else if (optype1
== OFFSOP
)
1028 latehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1029 else if (optype1
== CNSTOP
)
1030 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1032 latehalf
[1] = operands
[1];
1034 /* If the first move would clobber the source of the second one,
1035 do them in the other order.
1037 RMS says "This happens only for registers;
1038 such overlap can't happen in memory unless the user explicitly
1039 sets it up, and that is an undefined circumstance."
1041 but it happens on the sparc when loading parameter registers,
1042 so I am going to define that circumstance, and make it work
1045 /* Easy case: try moving both words at once. */
1046 /* First check for moving between an even/odd register pair
1047 and a memory location. */
1048 if ((optype0
== REGOP
&& optype1
!= REGOP
&& optype1
!= CNSTOP
1049 && (REGNO (operands
[0]) & 1) == 0)
1050 || (optype0
!= REGOP
&& optype0
!= CNSTOP
&& optype1
== REGOP
1051 && (REGNO (operands
[1]) & 1) == 0))
1054 rtx base
= 0, offset
= const0_rtx
;
1056 /* OP1 gets the register pair, and OP2 gets the memory address. */
1057 if (optype0
== REGOP
)
1058 op1
= operands
[0], op2
= operands
[1];
1060 op1
= operands
[1], op2
= operands
[0];
1062 /* Now see if we can trust the address to be 8-byte aligned. */
1063 /* Trust double-precision floats in global variables. */
1065 if (GET_CODE (XEXP (op2
, 0)) == LO_SUM
&& GET_MODE (op2
) == DFmode
)
1069 return (op1
== operands
[0] ? "ldd %1,%0" : "std %1,%0");
1072 if (GET_CODE (XEXP (op2
, 0)) == PLUS
)
1074 rtx temp
= XEXP (op2
, 0);
1075 if (GET_CODE (XEXP (temp
, 0)) == REG
)
1076 base
= XEXP (temp
, 0), offset
= XEXP (temp
, 1);
1077 else if (GET_CODE (XEXP (temp
, 1)) == REG
)
1078 base
= XEXP (temp
, 1), offset
= XEXP (temp
, 0);
1081 /* Trust round enough offsets from the stack or frame pointer. */
1083 && (REGNO (base
) == FRAME_POINTER_REGNUM
1084 || REGNO (base
) == STACK_POINTER_REGNUM
))
1086 if (GET_CODE (offset
) == CONST_INT
1087 && (INTVAL (offset
) & 0x7) == 0)
1089 if (op1
== operands
[0])
1095 /* We know structs not on the stack are properly aligned. Since a
1096 double asks for 8-byte alignment, we know it must have got that
1097 if it is in a struct. But a DImode need not be 8-byte aligned,
1098 because it could be a struct containing two ints or pointers. */
1099 else if (GET_CODE (operands
[1]) == MEM
1100 && GET_MODE (operands
[1]) == DFmode
1101 && (CONSTANT_P (XEXP (operands
[1], 0))
1102 /* Let user ask for it anyway. */
1103 || TARGET_HOPE_ALIGN
))
1105 else if (GET_CODE (operands
[0]) == MEM
1106 && GET_MODE (operands
[0]) == DFmode
1107 && (CONSTANT_P (XEXP (operands
[0], 0))
1108 || TARGET_HOPE_ALIGN
))
1112 if (optype0
== REGOP
&& optype1
== REGOP
1113 && REGNO (operands
[0]) == REGNO (latehalf
[1]))
1115 /* Make any unoffsettable addresses point at high-numbered word. */
1117 output_asm_insn ("add %0,0x4,%0", &addreg0
);
1119 output_asm_insn ("add %0,0x4,%0", &addreg1
);
1122 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1124 /* Undo the adds we just did. */
1126 output_asm_insn ("add %0,-0x4,%0", &addreg0
);
1128 output_asm_insn ("add %0,-0x4,%0", &addreg1
);
1130 /* Do low-numbered word. */
1131 return singlemove_string (operands
);
1133 else if (optype0
== REGOP
&& optype1
!= REGOP
1134 && reg_overlap_mentioned_p (operands
[0], operands
[1]))
1136 /* Do the late half first. */
1137 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1139 return singlemove_string (operands
);
1142 /* Normal case: do the two words, low-numbered first. */
1144 output_asm_insn (singlemove_string (operands
), operands
);
1146 /* Make any unoffsettable addresses point at high-numbered word. */
1148 output_asm_insn ("add %0,0x4,%0", &addreg0
);
1150 output_asm_insn ("add %0,0x4,%0", &addreg1
);
1153 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1155 /* Undo the adds we just did. */
1157 output_asm_insn ("add %0,-0x4,%0", &addreg0
);
1159 output_asm_insn ("add %0,-0x4,%0", &addreg1
);
1165 output_fp_move_double (operands
)
1170 if (FP_REG_P (operands
[0]))
1172 if (FP_REG_P (operands
[1]))
1173 return "fmovs %1,%0\n\tfmovs %R1,%R0";
1174 if (GET_CODE (operands
[1]) == REG
)
1176 if ((REGNO (operands
[1]) & 1) == 0)
1177 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1179 return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0";
1181 addr
= XEXP (operands
[1], 0);
1183 /* Use ldd if known to be aligned. */
1184 if (TARGET_HOPE_ALIGN
1185 || (GET_CODE (addr
) == PLUS
1186 && (((XEXP (addr
, 0) == frame_pointer_rtx
1187 || XEXP (addr
, 0) == stack_pointer_rtx
)
1188 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
1189 && (INTVAL (XEXP (addr
, 1)) & 0x7) == 0)
1190 /* Arrays are known to be aligned,
1191 and reg+reg addresses are used (on this machine)
1192 only for array accesses. */
1193 || (REG_P (XEXP (addr
, 0)) && REG_P (XEXP (addr
, 1)))))
1194 || (GET_MODE (operands
[0]) == DFmode
1195 && (GET_CODE (addr
) == LO_SUM
|| CONSTANT_P (addr
))))
1198 /* Otherwise use two ld insns. */
1200 = gen_rtx (MEM
, GET_MODE (operands
[1]),
1201 plus_constant_for_output (addr
, 4));
1202 return "ld %1,%0\n\tld %2,%R0";
1204 else if (FP_REG_P (operands
[1]))
1206 if (GET_CODE (operands
[0]) == REG
)
1208 if ((REGNO (operands
[0]) & 1) == 0)
1209 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1211 return "std %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
1213 addr
= XEXP (operands
[0], 0);
1215 /* Use std if we can be sure it is well-aligned. */
1216 if (TARGET_HOPE_ALIGN
1217 || (GET_CODE (addr
) == PLUS
1218 && (((XEXP (addr
, 0) == frame_pointer_rtx
1219 || XEXP (addr
, 0) == stack_pointer_rtx
)
1220 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
1221 && (INTVAL (XEXP (addr
, 1)) & 0x7) == 0)
1222 /* Arrays are known to be aligned,
1223 and reg+reg addresses are used (on this machine)
1224 only for array accesses. */
1225 || (REG_P (XEXP (addr
, 0)) && REG_P (XEXP (addr
, 1)))))
1226 || (GET_MODE (operands
[1]) == DFmode
1227 && (GET_CODE (addr
) == LO_SUM
|| CONSTANT_P (addr
))))
1230 /* Otherwise use two st insns. */
1232 = gen_rtx (MEM
, GET_MODE (operands
[0]),
1233 plus_constant_for_output (addr
, 4));
1234 return "st %r1,%0\n\tst %R1,%2";
1239 /* Return a REG that occurs in ADDR with coefficient 1.
1240 ADDR can be effectively incremented by incrementing REG. */
1243 find_addr_reg (addr
)
1246 while (GET_CODE (addr
) == PLUS
)
1248 /* We absolutely can not fudge the frame pointer here, because the
1249 frame pointer must always be 8 byte aligned. It also confuses
1251 if (GET_CODE (XEXP (addr
, 0)) == REG
1252 && REGNO (XEXP (addr
, 0)) != FRAME_POINTER_REGNUM
)
1253 addr
= XEXP (addr
, 0);
1254 else if (GET_CODE (XEXP (addr
, 1)) == REG
1255 && REGNO (XEXP (addr
, 1)) != FRAME_POINTER_REGNUM
)
1256 addr
= XEXP (addr
, 1);
1257 else if (CONSTANT_P (XEXP (addr
, 0)))
1258 addr
= XEXP (addr
, 1);
1259 else if (CONSTANT_P (XEXP (addr
, 1)))
1260 addr
= XEXP (addr
, 0);
1264 if (GET_CODE (addr
) == REG
)
1270 output_sized_memop (opname
, mode
, signedp
)
1272 enum machine_mode mode
;
1275 static char *ld_size_suffix_u
[] = { "ub", "uh", "", "?", "d" };
1276 static char *ld_size_suffix_s
[] = { "sb", "sh", "", "?", "d" };
1277 static char *st_size_suffix
[] = { "b", "h", "", "?", "d" };
1278 char **opnametab
, *modename
;
1280 if (opname
[0] == 'l')
1282 opnametab
= ld_size_suffix_s
;
1284 opnametab
= ld_size_suffix_u
;
1286 opnametab
= st_size_suffix
;
1287 modename
= opnametab
[GET_MODE_SIZE (mode
) >> 1];
1289 fprintf (asm_out_file
, "\t%s%s", opname
, modename
);
1293 output_move_with_extension (operands
)
1296 if (GET_MODE (operands
[2]) == HImode
)
1297 output_asm_insn ("sll %2,0x10,%0", operands
);
1298 else if (GET_MODE (operands
[2]) == QImode
)
1299 output_asm_insn ("sll %2,0x18,%0", operands
);
1304 /* Load the address specified by OPERANDS[3] into the register
1305 specified by OPERANDS[0].
1307 OPERANDS[3] may be the result of a sum, hence it could either be:
1312 (3) REG + REG + CONST_INT
1313 (4) REG + REG (special case of 3).
1315 Note that (3) is not a legitimate address.
1316 All cases are handled here. */
1319 output_load_address (operands
)
1324 if (CONSTANT_P (operands
[3]))
1326 output_asm_insn ("set %3,%0", operands
);
1330 if (REG_P (operands
[3]))
1332 if (REGNO (operands
[0]) != REGNO (operands
[3]))
1333 output_asm_insn ("mov %3,%0", operands
);
1337 if (GET_CODE (operands
[3]) != PLUS
)
1340 base
= XEXP (operands
[3], 0);
1341 offset
= XEXP (operands
[3], 1);
1343 if (GET_CODE (base
) == CONST_INT
)
1350 if (GET_CODE (offset
) != CONST_INT
)
1352 /* Operand is (PLUS (REG) (REG)). */
1354 offset
= const0_rtx
;
1360 operands
[7] = offset
;
1361 if (SMALL_INT (offset
))
1362 output_asm_insn ("add %6,%7,%0", operands
);
1364 output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands
);
1366 else if (GET_CODE (base
) == PLUS
)
1368 operands
[6] = XEXP (base
, 0);
1369 operands
[7] = XEXP (base
, 1);
1370 operands
[8] = offset
;
1372 if (SMALL_INT (offset
))
1373 output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands
);
1375 output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands
);
1381 /* Output code to place a size count SIZE in register REG.
1382 ALIGN is the size of the unit of transfer.
1384 Because block moves are pipelined, we don't include the
1385 first element in the transfer of SIZE to REG. */
1388 output_size_for_block_move (size
, reg
, align
)
1395 xoperands
[1] = size
;
1396 xoperands
[2] = align
;
1397 if (GET_CODE (size
) == REG
)
1398 output_asm_insn ("sub %1,%2,%0", xoperands
);
1402 = gen_rtx (CONST_INT
, VOIDmode
, INTVAL (size
) - INTVAL (align
));
1403 output_asm_insn ("set %1,%0", xoperands
);
1407 /* Emit code to perform a block move.
1409 OPERANDS[0] is the destination.
1410 OPERANDS[1] is the source.
1411 OPERANDS[2] is the size.
1412 OPERANDS[3] is the alignment safe to use.
1413 OPERANDS[4] is a register we can safely clobber as a temp. */
1416 output_block_move (operands
)
1419 /* A vector for our computed operands. Note that load_output_address
1420 makes use of (and can clobber) up to the 8th element of this vector. */
1423 static int movstrsi_label
= 0;
1425 rtx temp1
= operands
[4];
1426 rtx sizertx
= operands
[2];
1427 rtx alignrtx
= operands
[3];
1428 int align
= INTVAL (alignrtx
);
1429 char label3
[30], label5
[30];
1431 xoperands
[0] = operands
[0];
1432 xoperands
[1] = operands
[1];
1433 xoperands
[2] = temp1
;
1435 /* We can't move more than this many bytes at a time because we have only
1436 one register, %g1, to move them through. */
1437 if (align
> UNITS_PER_WORD
)
1439 align
= UNITS_PER_WORD
;
1440 alignrtx
= gen_rtx (CONST_INT
, VOIDmode
, UNITS_PER_WORD
);
1443 /* We consider 8 ld/st pairs, for a total of 16 inline insns to be
1444 reasonable here. (Actually will emit a maximum of 18 inline insns for
1445 the case of size == 31 and align == 4). */
1447 if (GET_CODE (sizertx
) == CONST_INT
&& (INTVAL (sizertx
) / align
) <= 8
1448 && memory_address_p (QImode
, plus_constant_for_output (xoperands
[0],
1450 && memory_address_p (QImode
, plus_constant_for_output (xoperands
[1],
1453 int size
= INTVAL (sizertx
);
1456 /* We will store different integers into this particular RTX. */
1457 xoperands
[2] = rtx_alloc (CONST_INT
);
1458 PUT_MODE (xoperands
[2], VOIDmode
);
1460 /* This case is currently not handled. Abort instead of generating
1467 for (i
= (size
>> 2) - 1; i
>= 0; i
--)
1469 INTVAL (xoperands
[2]) = (i
<< 2) + offset
;
1470 output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]",
1473 offset
+= (size
& ~0x3);
1481 for (i
= (size
>> 1) - 1; i
>= 0; i
--)
1483 INTVAL (xoperands
[2]) = (i
<< 1) + offset
;
1484 output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]",
1487 offset
+= (size
& ~0x1);
1495 for (i
= size
- 1; i
>= 0; i
--)
1497 INTVAL (xoperands
[2]) = i
+ offset
;
1498 output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]",
1504 /* We should never reach here. */
1508 /* If the size isn't known to be a multiple of the alignment,
1509 we have to do it in smaller pieces. If we could determine that
1510 the size was a multiple of 2 (or whatever), we could be smarter
1512 if (GET_CODE (sizertx
) != CONST_INT
)
1516 int size
= INTVAL (sizertx
);
1517 while (size
% align
)
1521 if (align
!= INTVAL (alignrtx
))
1522 alignrtx
= gen_rtx (CONST_INT
, VOIDmode
, align
);
1524 xoperands
[3] = gen_rtx (CONST_INT
, VOIDmode
, movstrsi_label
++);
1525 xoperands
[4] = gen_rtx (CONST_INT
, VOIDmode
, align
);
1526 xoperands
[5] = gen_rtx (CONST_INT
, VOIDmode
, movstrsi_label
++);
1528 ASM_GENERATE_INTERNAL_LABEL (label3
, "Lm", INTVAL (xoperands
[3]));
1529 ASM_GENERATE_INTERNAL_LABEL (label5
, "Lm", INTVAL (xoperands
[5]));
1531 /* This is the size of the transfer. Emit code to decrement the size
1532 value by ALIGN, and store the result in the temp1 register. */
1533 output_size_for_block_move (sizertx
, temp1
, alignrtx
);
1535 /* Must handle the case when the size is zero or negative, so the first thing
1536 we do is compare the size against zero, and only copy bytes if it is
1537 zero or greater. Note that we have already subtracted off the alignment
1538 once, so we must copy 1 alignment worth of bytes if the size is zero
1541 The SUN assembler complains about labels in branch delay slots, so we
1542 do this before outputting the load address, so that there will always
1543 be a harmless insn between the branch here and the next label emitted
1549 sprintf (pattern
, "cmp %%2,0\n\tbl %s", &label5
[1]);
1550 output_asm_insn (pattern
, xoperands
);
1553 zoperands
[0] = operands
[0];
1554 zoperands
[3] = plus_constant_for_output (operands
[0], align
);
1555 output_load_address (zoperands
);
1557 /* ??? This might be much faster if the loops below were preconditioned
1560 That is, at run time, copy enough bytes one at a time to ensure that the
1561 target and source addresses are aligned to the the largest possible
1562 alignment. Then use a preconditioned unrolled loop to copy say 16
1563 bytes at a time. Then copy bytes one at a time until finish the rest. */
1565 /* Output the first label separately, so that it is spaced properly. */
1567 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "Lm", INTVAL (xoperands
[3]));
1571 register char *ld_suffix
= (align
== 1) ? "ub" : (align
== 2) ? "uh" : "";
1572 register char *st_suffix
= (align
== 1) ? "b" : (align
== 2) ? "h" : "";
1574 sprintf (pattern
, "ld%s [%%1+%%2],%%%%g1\n\tsubcc %%2,%%4,%%2\n\tbge %s\n\tst%s %%%%g1,[%%0+%%2]\n%s:", ld_suffix
, &label3
[1], st_suffix
, &label5
[1]);
1575 output_asm_insn (pattern
, xoperands
);
1581 /* Output reasonable peephole for set-on-condition-code insns.
1582 Note that these insns assume a particular way of defining
1583 labels. Therefore, *both* sparc.h and this function must
1584 be changed if a new syntax is needed. */
1587 output_scc_insn (operands
, insn
)
1591 static char string
[100];
1592 rtx label
= 0, next
= insn
;
1595 /* Try doing a jump optimization which jump.c can't do for us
1596 because we did not expose that setcc works by using branches.
1598 If this scc insn is followed by an unconditional branch, then have
1599 the jump insn emitted here jump to that location, instead of to
1600 the end of the scc sequence as usual. */
1604 if (GET_CODE (next
) == CODE_LABEL
)
1606 next
= NEXT_INSN (next
);
1610 while (GET_CODE (next
) == NOTE
|| GET_CODE (next
) == CODE_LABEL
);
1612 /* If we are in a sequence, and the following insn is a sequence also,
1613 then just following the current insn's next field will take us to the
1614 first insn of the next sequence, which is the wrong place. We don't
1615 want to optimize with a branch that has had its delay slot filled.
1616 Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next
1617 which fails only if NEXT is such a branch. */
1619 if (next
&& GET_CODE (next
) == JUMP_INSN
&& simplejump_p (next
)
1620 && (! final_sequence
|| NEXT_INSN (PREV_INSN (next
)) == next
))
1621 label
= JUMP_LABEL (next
);
1622 /* If not optimizing, jump label fields are not set. To be safe, always
1623 check here to whether label is still zero. */
1626 label
= gen_label_rtx ();
1630 LABEL_NUSES (label
) += 1;
1632 operands
[2] = label
;
1634 /* If we are in a delay slot, assume it is the delay slot of an fpcc
1635 insn since our type isn't allowed anywhere else. */
1637 /* ??? Fpcc instructions no longer have delay slots, so this code is
1638 probably obsolete. */
1640 /* The fastest way to emit code for this is an annulled branch followed
1641 by two move insns. This will take two cycles if the branch is taken,
1642 and three cycles if the branch is not taken.
1644 However, if we are in the delay slot of another branch, this won't work,
1645 because we can't put a branch in the delay slot of another branch.
1646 The above sequence would effectively take 3 or 4 cycles respectively
1647 since a no op would have be inserted between the two branches.
1648 In this case, we want to emit a move, annulled branch, and then the
1649 second move. This sequence always takes 3 cycles, and hence is faster
1650 when we are in a branch delay slot. */
1654 strcpy (string
, "mov 0,%0\n\t");
1655 strcat (string
, output_cbranch (operands
[1], 2, 0, 1, 0));
1656 strcat (string
, "\n\tmov 1,%0");
1660 strcpy (string
, output_cbranch (operands
[1], 2, 0, 1, 0));
1661 strcat (string
, "\n\tmov 1,%0\n\tmov 0,%0");
1665 strcat (string
, "\n%l2:");
1670 /* Vectors to keep interesting information about registers where
1671 it can easily be got. */
1673 /* Modes for condition codes. */
1675 ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) | (1 << (int) CCFPmode))
1677 /* Modes for single-word (and smaller) quantities. */
1680 & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
1681 | (1 << (int) DFmode) | (1 << (int) TFmode)))
1683 /* Modes for double-word (and smaller) quantities. */
1686 & ~ ((1 << (int) TImode) | (1 << (int) TFmode)))
1688 /* Modes for quad-word quantities. */
1689 #define T_MODES (~C_MODES)
1691 /* Modes for single-float quantities. */
1692 #define SF_MODES ((1 << (int) SFmode))
1694 /* Modes for double-float quantities. */
1695 #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1697 /* Modes for quad-float quantities. */
1698 #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1700 /* Value is 1 if register/mode pair is acceptable on sparc.
1701 The funny mixture of D and T modes is because integer operations
1702 do not specially operate on tetra quantities, so non-quad-aligned
1703 registers can hold quadword quantities (except %o4 and %i4 because
1704 they cross fixed registers. */
1706 int hard_regno_mode_ok
[] = {
1707 C_MODES
, S_MODES
, T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
,
1708 T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
, D_MODES
, S_MODES
,
1709 T_MODES
, S_MODES
, T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
,
1710 T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
, D_MODES
, S_MODES
,
1712 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
,
1713 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
,
1714 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
,
1715 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
};
1721 save_regs (file
, low
, high
, base
, offset
, n_fregs
)
1730 for (i
= low
; i
< high
; i
+= 2)
1732 if (regs_ever_live
[i
] && ! call_used_regs
[i
])
1733 if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1734 fprintf (file
, "\tstd %s,[%s+%d]\n",
1735 reg_names
[i
], base
, offset
+ 4 * n_fregs
),
1738 fprintf (file
, "\tst %s,[%s+%d]\n",
1739 reg_names
[i
], base
, offset
+ 4 * n_fregs
),
1741 else if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1742 fprintf (file
, "\tst %s,[%s+%d]\n",
1743 reg_names
[i
+1], base
, offset
+ 4 * n_fregs
),
1753 restore_regs (file
, low
, high
, base
, offset
, n_fregs
)
1761 for (i
= low
; i
< high
; i
+= 2)
1763 if (regs_ever_live
[i
] && ! call_used_regs
[i
])
1764 if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1765 fprintf (file
, "\tldd [%s+%d], %s\n",
1766 base
, offset
+ 4 * n_fregs
, reg_names
[i
]),
1769 fprintf (file
, "\tld [%s+%d],%s\n",
1770 base
, offset
+ 4 * n_fregs
, reg_names
[i
]),
1772 else if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1773 fprintf (file
, "\tld [%s+%d],%s\n",
1774 base
, offset
+ 4 * n_fregs
, reg_names
[i
+1]),
1780 /* Static variables we want to share between prologue and epilogue. */
1782 /* Number of live floating point registers needed to be saved. */
1783 static int num_fregs
;
1785 /* Nonzero if any floating point register was ever used. */
1786 static int fregs_ever_live
;
1789 compute_frame_size (size
, leaf_function
)
1793 int fregs_ever_live
= 0;
1795 int outgoing_args_size
= (current_function_outgoing_args_size
1796 + REG_PARM_STACK_SPACE (current_function_decl
));
1798 apparent_fsize
= ((size
) + 7 - STARTING_FRAME_OFFSET
) & -8;
1799 for (i
= 32; i
< FIRST_PSEUDO_REGISTER
; i
+= 2)
1800 fregs_ever_live
|= regs_ever_live
[i
]|regs_ever_live
[i
+1];
1802 if (TARGET_EPILOGUE
&& fregs_ever_live
)
1804 for (i
= 32; i
< FIRST_PSEUDO_REGISTER
; i
+= 2)
1805 if ((regs_ever_live
[i
] && ! call_used_regs
[i
])
1806 || (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1]))
1810 /* Set up values for use in `function_epilogue'. */
1811 num_fregs
= n_fregs
;
1813 apparent_fsize
+= (outgoing_args_size
+7) & -8;
1814 if (leaf_function
&& n_fregs
== 0
1815 && apparent_fsize
== (REG_PARM_STACK_SPACE (current_function_decl
)
1816 - STARTING_FRAME_OFFSET
))
1819 actual_fsize
= apparent_fsize
+ n_fregs
*4;
1821 /* Make sure nothing can clobber our register windows.
1822 If a SAVE must be done, or there is a stack-local variable,
1823 the register window area must be allocated. */
1824 if (leaf_function
== 0 || size
> 0)
1825 actual_fsize
+= (16 * UNITS_PER_WORD
)+8;
1827 return actual_fsize
;
1830 /* If this were a leaf function, how far would we have to reach
1831 from the stack pointer to the last arg on the stack?
1833 If we don't know, return 4096 (i.e., "too far".) */
1836 compute_last_arg_offset ()
1838 if (GET_CODE (current_function_arg_offset_rtx
) == CONST_INT
)
1839 return (compute_frame_size (get_frame_size (), 1)
1840 + INTVAL (current_function_arg_offset_rtx
));
1845 output_function_prologue (file
, size
, leaf_function
)
1850 frame_base_name
= "%sp+80";
1852 frame_base_name
= "%fp";
1854 actual_fsize
= compute_frame_size (size
, leaf_function
);
1856 fprintf (file
, "\t!#PROLOGUE# 0\n");
1857 if (actual_fsize
== 0) /* do nothing. */ ;
1858 else if (actual_fsize
< 4096)
1860 if (! leaf_function
)
1861 fprintf (file
, "\tsave %%sp,-%d,%%sp\n", actual_fsize
);
1863 fprintf (file
, "\tadd %%sp,-%d,%%sp\n", actual_fsize
);
1865 else if (! leaf_function
)
1867 /* Need to use actual_fsize, since we are also allocating space for
1868 our callee (and our own register save area). */
1869 fprintf (file
, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n",
1870 -actual_fsize
, -actual_fsize
);
1871 fprintf (file
, "\tsave %%sp,%%g1,%%sp\n");
1875 /* The rest of the support for this case hasn't been implemented,
1876 but FRAME_POINTER_REQUIRED is supposed to prevent it from arising,
1877 by checking the frame size. */
1880 /* Put pointer to parameters into %g4, and allocate
1881 frame space using result computed into %g1. actual_fsize
1882 used instead of apparent_fsize for reasons stated above. */
1883 fprintf (file
, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n",
1884 -actual_fsize
, -actual_fsize
);
1885 fprintf (file
, "\tadd %%sp,64,%%g4\n\tadd %%sp,%%g1,%%sp\n");
1888 /* If doing anything with PIC, do it now. */
1890 fprintf (file
, "\t!#PROLOGUE# 1\n");
1892 /* Figure out where to save any special registers. */
1895 int offset
, n_fregs
= num_fregs
;
1897 if (! leaf_function
)
1898 offset
= -apparent_fsize
;
1902 if (TARGET_EPILOGUE
&& ! leaf_function
)
1903 n_fregs
= save_regs (file
, 0, 16, frame_base_name
, offset
, 0);
1904 else if (leaf_function
)
1905 n_fregs
= save_regs (file
, 0, 32, frame_base_name
, offset
, 0);
1906 if (TARGET_EPILOGUE
)
1907 save_regs (file
, 32, FIRST_PSEUDO_REGISTER
,
1908 frame_base_name
, offset
, n_fregs
);
1911 if (regs_ever_live
[62])
1912 fprintf (file
, "\tst %s,[%s-16]\n\tst %s,[%s-12]\n",
1913 reg_names
[0], frame_base_name
,
1914 reg_names
[0], frame_base_name
);
1917 if (leaf_function
&& actual_fsize
!= 0)
1919 /* warning ("leaf procedure with frame size %d", actual_fsize); */
1920 if (! TARGET_EPILOGUE
)
1921 leaf_label
= gen_label_rtx ();
1926 output_function_epilogue (file
, size
, leaf_function
)
1936 emit_label_after (leaf_label
, get_last_insn ());
1937 final_scan_insn (get_last_insn (), file
, 0, 0, 1);
1942 int offset
, n_fregs
= num_fregs
;
1944 if (! leaf_function
)
1945 offset
= -apparent_fsize
;
1949 if (TARGET_EPILOGUE
&& ! leaf_function
)
1950 n_fregs
= restore_regs (file
, 0, 16, frame_base_name
, offset
, 0);
1951 else if (leaf_function
)
1952 n_fregs
= restore_regs (file
, 0, 32, frame_base_name
, offset
, 0);
1953 if (TARGET_EPILOGUE
)
1954 restore_regs (file
, 32, FIRST_PSEUDO_REGISTER
,
1955 frame_base_name
, offset
, n_fregs
);
1958 /* Work out how to skip the caller's unimp instruction if required. */
1960 ret
= (current_function_returns_struct
? "jmp %o7+12" : "retl");
1962 ret
= (current_function_returns_struct
? "jmp %i7+12" : "ret");
1964 if (TARGET_EPILOGUE
|| leaf_label
)
1966 int old_target_epilogue
= TARGET_EPILOGUE
;
1967 target_flags
&= ~old_target_epilogue
;
1969 if (! leaf_function
)
1971 /* If we wound up with things in our delay slot, flush them here. */
1972 if (current_function_epilogue_delay_list
)
1974 rtx insn
= emit_jump_insn_after (gen_rtx (RETURN
, VOIDmode
),
1976 PATTERN (insn
) = gen_rtx (PARALLEL
, VOIDmode
,
1978 PATTERN (XEXP (current_function_epilogue_delay_list
, 0)),
1980 final_scan_insn (insn
, file
, 1, 0, 1);
1983 fprintf (file
, "\t%s\n\trestore\n", ret
);
1985 else if (actual_fsize
< 4096)
1987 if (current_function_epilogue_delay_list
)
1989 fprintf (file
, "\t%s\n", ret
);
1990 final_scan_insn (XEXP (current_function_epilogue_delay_list
, 0),
1994 fprintf (file
, "\t%s\n\tadd %%sp,%d,%%sp\n", ret
, actual_fsize
);
1998 if (current_function_epilogue_delay_list
)
2000 fprintf (file
, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2001 actual_fsize
, actual_fsize
, ret
);
2003 target_flags
|= old_target_epilogue
;
2007 /* Return the string to output a conditional branch to LABEL, which is
2008 the operand number of the label. OP is the conditional expression. The
2009 mode of register 0 says what kind of comparison we made.
2011 REVERSED is non-zero if we should reverse the sense of the comparison.
2013 ANNUL is non-zero if we should generate an annulling branch.
2015 NOOP is non-zero if we have to follow this branch by a noop. */
2018 output_cbranch (op
, label
, reversed
, annul
, noop
)
2021 int reversed
, annul
, noop
;
2023 static char string
[20];
2024 enum rtx_code code
= GET_CODE (op
);
2025 enum machine_mode mode
= GET_MODE (XEXP (op
, 0));
2026 static char labelno
[] = " %lX";
2028 /* ??? FP branches can not be preceded by another floating point insn.
2029 Because there is currently no concept of pre-delay slots, we can fix
2030 this only by always emitting a nop before a floating point branch. */
2032 if (mode
== CCFPmode
)
2033 strcpy (string
, "nop\n\t");
2035 /* If not floating-point or if EQ or NE, we can just reverse the code. */
2036 if (reversed
&& (mode
!= CCFPmode
|| code
== EQ
|| code
== NE
))
2037 code
= reverse_condition (code
), reversed
= 0;
2039 /* Start by writing the branch condition. */
2043 if (mode
== CCFPmode
)
2044 strcat (string
, "fbne");
2046 strcpy (string
, "bne");
2050 if (mode
== CCFPmode
)
2051 strcat (string
, "fbe");
2053 strcpy (string
, "be");
2057 if (mode
== CCFPmode
)
2060 strcat (string
, "fbul");
2062 strcat (string
, "fbge");
2064 else if (mode
== CC_NOOVmode
)
2065 strcpy (string
, "bpos");
2067 strcpy (string
, "bge");
2071 if (mode
== CCFPmode
)
2074 strcat (string
, "fbule");
2076 strcat (string
, "fbg");
2079 strcpy (string
, "bg");
2083 if (mode
== CCFPmode
)
2086 strcat (string
, "fbug");
2088 strcat (string
, "fble");
2091 strcpy (string
, "ble");
2095 if (mode
== CCFPmode
)
2098 strcat (string
, "fbuge");
2100 strcat (string
, "fbl");
2102 else if (mode
== CC_NOOVmode
)
2103 strcpy (string
, "bneg");
2105 strcpy (string
, "bl");
2109 strcpy (string
, "bgeu");
2113 strcpy (string
, "bgu");
2117 strcpy (string
, "bleu");
2121 strcpy (string
, "blu");
2125 /* Now add the annulling, the label, and a possible noop. */
2127 strcat (string
, ",a");
2129 labelno
[3] = label
+ '0';
2130 strcat (string
, labelno
);
2133 strcat (string
, "\n\tnop");
2139 output_return (operands
)
2144 operands
[0] = leaf_label
;
2147 else if (leaf_function
)
2149 operands
[0] = gen_rtx (CONST_INT
, VOIDmode
, actual_fsize
);
2150 if (actual_fsize
< 4096)
2152 if (current_function_returns_struct
)
2153 return "jmp %%o7+12\n\tadd %%sp,%0,%%sp";
2155 return "retl\n\tadd %%sp,%0,%%sp";
2159 if (current_function_returns_struct
)
2160 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2162 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
2167 if (current_function_returns_struct
)
2168 return "jmp %%i7+12\n\trestore";
2170 return "ret\n\trestore";
2175 output_floatsisf2 (operands
)
2178 if (GET_CODE (operands
[1]) == MEM
)
2179 return "ld %1,%0\n\tfitos %0,%0";
2180 else if (FP_REG_P (operands
[1]))
2181 return "fitos %1,%0";
2182 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitos %0,%0";
2186 output_floatsidf2 (operands
)
2189 if (GET_CODE (operands
[1]) == MEM
)
2190 return "ld %1,%0\n\tfitod %0,%0";
2191 else if (FP_REG_P (operands
[1]))
2192 return "fitod %1,%0";
2193 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitod %0,%0";
2196 /* Leaf functions and non-leaf functions have different needs. */
2199 reg_leaf_alloc_order
[] = REG_LEAF_ALLOC_ORDER
;
2202 reg_nonleaf_alloc_order
[] = REG_ALLOC_ORDER
;
2204 static int *reg_alloc_orders
[] = {
2205 reg_leaf_alloc_order
,
2206 reg_nonleaf_alloc_order
};
2209 order_regs_for_local_alloc ()
2211 static int last_order_nonleaf
= 1;
2213 if (regs_ever_live
[15] != last_order_nonleaf
)
2215 last_order_nonleaf
= !last_order_nonleaf
;
2216 bcopy (reg_alloc_orders
[last_order_nonleaf
], reg_alloc_order
,
2217 FIRST_PSEUDO_REGISTER
* sizeof (int));
2221 /* Machine dependent routines for the branch probability, arc profiling
2224 /* The label used by the arc profiling code. */
2226 static rtx profiler_label
;
2229 init_arc_profiler ()
2231 /* Generate and save a copy of this so it can be shared. */
2232 profiler_label
= gen_rtx (SYMBOL_REF
, Pmode
, "*LPBX2");
2236 output_arc_profiler (arcno
, insert_after
)
2240 rtx profiler_target_addr
2241 = gen_rtx (CONST
, Pmode
,
2242 gen_rtx (PLUS
, Pmode
, profiler_label
,
2243 gen_rtx (CONST_INT
, VOIDmode
, 4 * arcno
)));
2244 register rtx profiler_reg
= gen_reg_rtx (SImode
);
2245 register rtx address_reg
= gen_reg_rtx (Pmode
);
2248 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, address_reg
,
2249 gen_rtx (HIGH
, Pmode
,
2250 profiler_target_addr
)),
2253 mem_ref
= gen_rtx (MEM
, SImode
, gen_rtx (LO_SUM
, Pmode
, address_reg
,
2254 profiler_target_addr
));
2255 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, profiler_reg
,
2259 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, profiler_reg
,
2260 gen_rtx (PLUS
, SImode
, profiler_reg
,
2264 /* This is the same rtx as above, but it is not legal to share this rtx. */
2265 mem_ref
= gen_rtx (MEM
, SImode
, gen_rtx (LO_SUM
, Pmode
, address_reg
,
2266 profiler_target_addr
));
2267 emit_insn_after (gen_rtx (SET
, VOIDmode
, mem_ref
, profiler_reg
),
2271 /* Print operand X (an rtx) in assembler syntax to file FILE.
2272 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2273 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2276 print_operand (file
, x
, code
)
2284 /* Output a 'nop' if there's nothing for the delay slot. */
2285 if (dbr_sequence_length () == 0)
2286 fputs ("\n\tnop", file
);
2289 /* Output an annul flag if there's nothing for the delay slot. */
2290 if (dbr_sequence_length () == 0)
2294 /* Adjust the operand to take into account a RESTORE operation. */
2295 if (GET_CODE (x
) != REG
)
2298 fputs (reg_names
[REGNO (x
)], file
);
2299 else if (REGNO (x
) >= 24 && REGNO (x
) < 32)
2300 fputs (reg_names
[REGNO (x
)-16], file
);
2305 /* Print out what we are using as the frame pointer. This might
2306 be %fp, or might be %sp+offset. */
2307 fputs (frame_base_name
, file
);
2310 /* Print out the second register name of a register pair.
2311 I.e., R (%o0) => %o1. */
2312 fputs (reg_names
[REGNO (x
)+1], file
);
2315 /* Print the operand's address only. */
2316 output_address (XEXP (x
, 0));
2319 /* In this case we need a register. Use %g0 if the
2320 operand in const0_rtx. */
2321 if (x
== const0_rtx
)
2323 fputs ("%g0", file
);
2330 switch (GET_CODE (x
))
2332 case IOR
: fputs ("or", file
); break;
2333 case AND
: fputs ("and", file
); break;
2334 case XOR
: fputs ("xor", file
); break;
2340 switch (GET_CODE (x
))
2342 case IOR
: fputs ("orn", file
); break;
2343 case AND
: fputs ("andn", file
); break;
2344 case XOR
: fputs ("xnor", file
); break;
2351 /* Print a sign-extended character. */
2352 int i
= INTVAL (x
) & 0xff;
2355 fprintf (file
, "%d", i
);
2360 /* Do nothing special. */
2364 /* Undocumented flag. */
2368 if (GET_CODE (x
) == REG
)
2369 fputs (reg_names
[REGNO (x
)], file
);
2370 else if (GET_CODE (x
) == MEM
)
2373 if (CONSTANT_P (XEXP (x
, 0)))
2374 /* Poor Sun assembler doesn't understand absolute addressing. */
2375 fputs ("%g0+", file
);
2376 output_address (XEXP (x
, 0));
2379 else if (GET_CODE (x
) == HIGH
)
2381 fputs ("%hi(", file
);
2382 output_addr_const (file
, XEXP (x
, 0));
2385 else if (GET_CODE (x
) == LO_SUM
)
2387 print_operand (file
, XEXP (x
, 0), 0);
2388 fputs ("+%lo(", file
);
2389 output_addr_const (file
, XEXP (x
, 1));
2392 else if (GET_CODE (x
) == CONST_DOUBLE
)
2394 if (CONST_DOUBLE_HIGH (x
) == 0)
2395 fprintf (file
, "%u", CONST_DOUBLE_LOW (x
));
2396 else if (CONST_DOUBLE_HIGH (x
) == -1
2397 && CONST_DOUBLE_LOW (x
) < 0)
2398 fprintf (file
, "%d", CONST_DOUBLE_LOW (x
));
2402 else { output_addr_const (file
, x
); }
2405 /* This function outputs assembler code for VALUE to FILE, where VALUE is
2406 a 64 bit (DImode) value. */
2408 /* ??? If there is a 64 bit counterpart to .word that the assembler
2409 understands, then using that would simply this code greatly. */
2412 output_double_int (file
, value
)
2416 if (GET_CODE (value
) == CONST_INT
)
2418 if (INTVAL (value
) < 0)
2419 ASM_OUTPUT_INT (file
, constm1_rtx
);
2421 ASM_OUTPUT_INT (file
, const0_rtx
);
2422 ASM_OUTPUT_INT (file
, value
);
2424 else if (GET_CODE (value
) == CONST_DOUBLE
)
2426 ASM_OUTPUT_INT (file
, gen_rtx (CONST_INT
, VOIDmode
,
2427 CONST_DOUBLE_HIGH (value
)));
2428 ASM_OUTPUT_INT (file
, gen_rtx (CONST_INT
, VOIDmode
,
2429 CONST_DOUBLE_LOW (value
)));
2431 else if (GET_CODE (value
) == SYMBOL_REF
2432 || GET_CODE (value
) == CONST
2433 || GET_CODE (value
) == PLUS
)
2435 /* Addresses are only 32 bits. */
2436 ASM_OUTPUT_INT (file
, const0_rtx
);
2437 ASM_OUTPUT_INT (file
, value
);
2443 /* Compute the code to put in the .proc statement
2444 for a function that returns type TYPE. */
2447 sparc_type_code (type
)
2450 register unsigned long qualifiers
= 0;
2451 register unsigned shift
= 6;
2455 switch (TREE_CODE (type
))
2461 qualifiers
|= (3 << shift
);
2463 type
= TREE_TYPE (type
);
2468 qualifiers
|= (2 << shift
);
2470 type
= TREE_TYPE (type
);
2474 case REFERENCE_TYPE
:
2476 qualifiers
|= (1 << shift
);
2478 type
= TREE_TYPE (type
);
2482 return (qualifiers
| 8);
2485 return (qualifiers
| 9);
2488 return (qualifiers
| 10);
2491 return (qualifiers
| 16);
2494 /* This return value is not always completely the same as Sun's
2495 but the Sun assembler's peephole optimizer probably doesn't
2497 return (qualifiers
| 4);
2500 if (TYPE_PRECISION (type
) == 32)
2501 return (qualifiers
| 6);
2503 return (qualifiers
| 7); /* Who knows? */
2505 case COMPLEX_TYPE
: /* GNU Fortran COMPLEX type. */
2506 case CHAR_TYPE
: /* GNU Pascal CHAR type. Not used in C. */
2507 case BOOLEAN_TYPE
: /* GNU Fortran BOOLEAN type. */
2508 case FILE_TYPE
: /* GNU Pascal FILE type. */
2509 case STRING_TYPE
: /* GNU Fortran STRING type. */
2510 case LANG_TYPE
: /* ? */
2514 abort (); /* Not a type! */