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 go into the delay slot.
495 A delay slot only exists however if the frame size is zero, otherwise
496 we will put an insn to adjust the stack after the return. */
499 if (leaf_return_peephole_ok ())
500 return (get_attr_in_branch_delay (trial
) == IN_BRANCH_DELAY_TRUE
);
504 /* Otherwise, only operations which can be done in tandem with
505 a `restore' insn can go into the delay slot. */
506 pat
= PATTERN (trial
);
507 if (GET_CODE (SET_DEST (pat
)) != REG
508 || REGNO (SET_DEST (pat
)) == 0
509 || REGNO (SET_DEST (pat
)) >= 32
510 || REGNO (SET_DEST (pat
)) < 24)
514 if (arith_operand (src
, GET_MODE (src
)))
515 return GET_MODE_SIZE (GET_MODE (src
)) <= GET_MODE_SIZE (SImode
);
516 if (arith_double_operand (src
, GET_MODE (src
)))
517 return GET_MODE_SIZE (GET_MODE (src
)) <= GET_MODE_SIZE (DImode
);
518 if (GET_CODE (src
) == PLUS
)
520 if (register_operand (XEXP (src
, 0), SImode
)
521 && arith_operand (XEXP (src
, 1), SImode
))
523 if (register_operand (XEXP (src
, 1), SImode
)
524 && arith_operand (XEXP (src
, 0), SImode
))
526 if (register_operand (XEXP (src
, 0), DImode
)
527 && arith_double_operand (XEXP (src
, 1), DImode
))
529 if (register_operand (XEXP (src
, 1), DImode
)
530 && arith_double_operand (XEXP (src
, 0), DImode
))
533 if (GET_CODE (src
) == MINUS
534 && register_operand (XEXP (src
, 0), SImode
)
535 && small_int (XEXP (src
, 1), VOIDmode
))
537 if (GET_CODE (src
) == MINUS
538 && register_operand (XEXP (src
, 0), DImode
)
539 && !register_operand (XEXP (src
, 1), DImode
)
540 && arith_double_operand (XEXP (src
, 1), DImode
))
546 short_branch (uid1
, uid2
)
549 unsigned int delta
= insn_addresses
[uid1
] - insn_addresses
[uid2
];
550 if (delta
+ 1024 < 2048)
552 /* warning ("long branch, distance %d", delta); */
556 /* Return non-zero if REG is not used after INSN.
557 We assume REG is a reload reg, and therefore does
558 not live past labels or calls or jumps. */
560 reg_unused_after (reg
, insn
)
564 enum rtx_code code
, prev_code
= UNKNOWN
;
566 while (insn
= NEXT_INSN (insn
))
568 if (prev_code
== CALL_INSN
&& call_used_regs
[REGNO (reg
)])
571 code
= GET_CODE (insn
);
572 if (GET_CODE (insn
) == CODE_LABEL
)
575 if (GET_RTX_CLASS (code
) == 'i')
577 rtx set
= single_set (insn
);
578 int in_src
= set
&& reg_overlap_mentioned_p (reg
, SET_SRC (set
));
581 if (set
&& reg_overlap_mentioned_p (reg
, SET_DEST (set
)))
583 if (set
== 0 && reg_overlap_mentioned_p (reg
, PATTERN (insn
)))
591 /* Legitimize PIC addresses. If the address is already position-independent,
592 we return ORIG. Newly generated position-independent addresses go into a
593 reg. This is REG if non zero, otherwise we allocate register(s) as
594 necessary. If this is called during reload, and we need a second temp
595 register, then we use SCRATCH, which is provided via the
596 SECONDARY_INPUT_RELOAD_CLASS mechanism. */
599 legitimize_pic_address (orig
, mode
, reg
, scratch
)
601 enum machine_mode mode
;
604 if (GET_CODE (orig
) == SYMBOL_REF
)
606 rtx pic_ref
, address
;
611 if (reload_in_progress
|| reload_completed
)
614 reg
= gen_reg_rtx (Pmode
);
619 /* If not during reload, allocate another temp reg here for loading
620 in the address, so that these instructions can be optimized
622 rtx temp_reg
= ((reload_in_progress
|| reload_completed
)
623 ? reg
: gen_reg_rtx (Pmode
));
625 /* Must put the SYMBOL_REF inside an UNSPEC here so that cse
626 won't get confused into thinking that these two instructions
627 are loading in the true address of the symbol. If in the
628 future a PIC rtx exists, that should be used instead. */
629 emit_insn (gen_rtx (SET
, VOIDmode
, temp_reg
,
630 gen_rtx (HIGH
, Pmode
,
631 gen_rtx (UNSPEC
, Pmode
,
634 emit_insn (gen_rtx (SET
, VOIDmode
, temp_reg
,
635 gen_rtx (LO_SUM
, Pmode
, temp_reg
,
636 gen_rtx (UNSPEC
, Pmode
,
644 pic_ref
= gen_rtx (MEM
, Pmode
,
645 gen_rtx (PLUS
, Pmode
,
646 pic_offset_table_rtx
, address
));
647 current_function_uses_pic_offset_table
= 1;
648 RTX_UNCHANGING_P (pic_ref
) = 1;
649 insn
= emit_move_insn (reg
, pic_ref
);
650 /* Put a REG_EQUAL note on this insn, so that it can be optimized
652 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
, orig
,
656 else if (GET_CODE (orig
) == CONST
)
660 if (GET_CODE (XEXP (orig
, 0)) == PLUS
661 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
666 if (reload_in_progress
|| reload_completed
)
669 reg
= gen_reg_rtx (Pmode
);
672 if (GET_CODE (XEXP (orig
, 0)) == PLUS
)
674 base
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 0), Pmode
,
676 offset
= legitimize_pic_address (XEXP (XEXP (orig
, 0), 1), Pmode
,
677 base
== reg
? 0 : reg
, 0);
682 if (GET_CODE (offset
) == CONST_INT
)
684 if (SMALL_INT (offset
))
685 return plus_constant_for_output (base
, INTVAL (offset
));
686 else if (! reload_in_progress
&& ! reload_completed
)
687 offset
= force_reg (Pmode
, offset
);
688 /* We can't create any new registers during reload, so use the
689 SCRATCH reg provided by the reload_insi pattern. */
692 emit_move_insn (scratch
, offset
);
696 /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
697 macro needs to be adjusted so that a scratch reg is provided
701 return gen_rtx (PLUS
, Pmode
, base
, offset
);
703 else if (GET_CODE (orig
) == LABEL_REF
)
704 current_function_uses_pic_offset_table
= 1;
709 /* Set up PIC-specific rtl. This should not cause any insns
717 /* Emit special PIC prologues and epilogues. */
722 /* The table we use to reference PIC data. */
723 rtx global_offset_table
;
724 /* Labels to get the PC in the prologue of this function. */
727 int orig_flag_pic
= flag_pic
;
729 if (current_function_uses_pic_offset_table
== 0)
736 l1
= gen_label_rtx ();
737 l2
= gen_label_rtx ();
742 /* Note that we pun calls and jumps here! */
743 emit_jump_insn (gen_rtx (PARALLEL
, VOIDmode
,
745 gen_rtx (SET
, VOIDmode
, pc_rtx
, gen_rtx (LABEL_REF
, VOIDmode
, l2
)),
746 gen_rtx (SET
, VOIDmode
, gen_rtx (REG
, SImode
, 15), gen_rtx (LABEL_REF
, VOIDmode
, l2
)))));
749 /* Initialize every time through, since we can't easily
750 know this to be permanent. */
751 global_offset_table
= gen_rtx (SYMBOL_REF
, Pmode
, "*__GLOBAL_OFFSET_TABLE_");
752 pic_pc_rtx
= gen_rtx (CONST
, Pmode
,
753 gen_rtx (MINUS
, Pmode
,
755 gen_rtx (CONST
, Pmode
,
756 gen_rtx (MINUS
, Pmode
,
757 gen_rtx (LABEL_REF
, VOIDmode
, l1
),
760 emit_insn (gen_rtx (SET
, VOIDmode
, pic_offset_table_rtx
,
761 gen_rtx (HIGH
, Pmode
, pic_pc_rtx
)));
762 emit_insn (gen_rtx (SET
, VOIDmode
,
763 pic_offset_table_rtx
,
764 gen_rtx (LO_SUM
, Pmode
,
765 pic_offset_table_rtx
, pic_pc_rtx
)));
766 emit_insn (gen_rtx (SET
, VOIDmode
,
767 pic_offset_table_rtx
,
768 gen_rtx (PLUS
, Pmode
,
769 pic_offset_table_rtx
, gen_rtx (REG
, Pmode
, 15))));
770 /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */
771 LABEL_PRESERVE_P (l1
) = 1;
772 LABEL_PRESERVE_P (l2
) = 1;
773 flag_pic
= orig_flag_pic
;
775 seq
= gen_sequence ();
777 emit_insn_after (seq
, get_insns ());
779 /* Need to emit this whether or not we obey regdecls,
780 since setjmp/longjmp can cause life info to screw up. */
781 emit_insn (gen_rtx (USE
, VOIDmode
, pic_offset_table_rtx
));
784 /* For the SPARC, REG and REG+CONST is cost 0, REG+REG is cost 1,
785 and addresses involving symbolic constants are cost 2.
787 We make REG+REG slightly more expensive because it might keep
788 a register live for longer than we might like.
790 PIC addresses are very expensive.
792 It is no coincidence that this has the same structure
793 as GO_IF_LEGITIMATE_ADDRESS. */
795 sparc_address_cost (X
)
799 /* Handled before calling here. */
800 if (GET_CODE (X
) == REG
)
803 if (GET_CODE (X
) == PLUS
)
805 if (GET_CODE (XEXP (X
, 0)) == REG
806 && GET_CODE (XEXP (X
, 1)) == REG
)
810 else if (GET_CODE (X
) == LO_SUM
)
812 else if (GET_CODE (X
) == HIGH
)
817 /* Emit insns to move operands[1] into operands[0].
819 Return 1 if we have written out everything that needs to be done to
820 do the move. Otherwise, return 0 and the caller will emit the move
823 SCRATCH_REG if non zero can be used as a scratch register for the move
824 operation. It is provided by a SECONDARY_RELOAD_* macro if needed. */
827 emit_move_sequence (operands
, mode
, scratch_reg
)
829 enum machine_mode mode
;
832 register rtx operand0
= operands
[0];
833 register rtx operand1
= operands
[1];
835 /* Handle most common case first: storing into a register. */
836 if (register_operand (operand0
, mode
))
838 if (register_operand (operand1
, mode
)
839 || (GET_CODE (operand1
) == CONST_INT
&& SMALL_INT (operand1
))
840 || (GET_CODE (operand1
) == CONST_DOUBLE
841 && arith_double_operand (operand1
, DImode
))
842 || (GET_CODE (operand1
) == HIGH
&& GET_MODE (operand1
) != DImode
)
843 /* Only `general_operands' can come here, so MEM is ok. */
844 || GET_CODE (operand1
) == MEM
)
846 /* Run this case quickly. */
847 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
851 else if (GET_CODE (operand0
) == MEM
)
853 if (register_operand (operand1
, mode
) || operand1
== const0_rtx
)
855 /* Run this case quickly. */
856 emit_insn (gen_rtx (SET
, VOIDmode
, operand0
, operand1
));
859 if (! reload_in_progress
)
861 operands
[0] = validize_mem (operand0
);
862 operands
[1] = operand1
= force_reg (mode
, operand1
);
866 /* Simplify the source if we need to. Must handle DImode HIGH operators
867 here because such a move needs a clobber added. */
868 if ((GET_CODE (operand1
) != HIGH
&& immediate_operand (operand1
, mode
))
869 || (GET_CODE (operand1
) == HIGH
&& GET_MODE (operand1
) == DImode
))
871 if (flag_pic
&& symbolic_operand (operand1
, mode
))
873 rtx temp_reg
= reload_in_progress
? operand0
: 0;
875 operands
[1] = legitimize_pic_address (operand1
, mode
, temp_reg
,
878 else if (GET_CODE (operand1
) == CONST_INT
879 ? (! SMALL_INT (operand1
)
880 && (INTVAL (operand1
) & 0x3ff) != 0)
881 : (GET_CODE (operand1
) == CONST_DOUBLE
882 ? ! arith_double_operand (operand1
, DImode
)
885 /* For DImode values, temp must be operand0 because of the way
886 HI and LO_SUM work. The LO_SUM operator only copies half of
887 the LSW from the dest of the HI operator. If the LO_SUM dest is
888 not the same as the HI dest, then the MSW of the LO_SUM dest will
891 ??? The real problem here is that the ...(HI:DImode pattern emits
892 multiple instructions, and the ...(LO_SUM:DImode pattern emits
893 one instruction. This fails, because the compiler assumes that
894 LO_SUM copies all bits of the first operand to its dest. Better
895 would be to have the HI pattern emit one instruction and the
896 LO_SUM pattern multiple instructions. Even better would be
897 to use four rtl insns. */
898 rtx temp
= ((reload_in_progress
|| mode
== DImode
)
899 ? operand0
: gen_reg_rtx (mode
));
901 emit_insn (gen_rtx (SET
, VOIDmode
, temp
,
902 gen_rtx (HIGH
, mode
, operand1
)));
903 operands
[1] = gen_rtx (LO_SUM
, mode
, temp
, operand1
);
907 if (GET_CODE (operand1
) == LABEL_REF
&& flag_pic
)
909 /* The procedure for doing this involves using a call instruction to
910 get the pc into o7. We need to indicate this explicitly because
911 the tablejump pattern assumes that it can use this value also. */
912 emit_insn (gen_rtx (PARALLEL
, VOIDmode
,
914 gen_rtx (SET
, VOIDmode
, operand0
,
916 gen_rtx (SET
, VOIDmode
,
917 gen_rtx (REG
, mode
, 15),
922 /* Now have insn-emit do whatever it normally does. */
926 /* Return the best assembler insn template
927 for moving operands[1] into operands[0] as a fullword. */
930 singlemove_string (operands
)
933 if (GET_CODE (operands
[0]) == MEM
)
935 if (GET_CODE (operands
[1]) != MEM
)
940 if (GET_CODE (operands
[1]) == MEM
)
942 if (GET_CODE (operands
[1]) == CONST_INT
943 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands
[1]), 'I'))
945 int i
= INTVAL (operands
[1]);
947 /* If all low order 10 bits are clear, then we only need a single
948 sethi insn to load the constant. */
949 if ((i
& 0x000003FF) != 0)
950 return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
952 return "sethi %%hi(%a1),%0";
954 /* ??? Wrong if target is DImode? */
958 /* Output assembler code to perform a doubleword move insn
959 with operands OPERANDS. */
962 output_move_double (operands
)
965 enum { REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype0
, optype1
;
967 rtx addreg0
= 0, addreg1
= 0;
969 /* First classify both operands. */
971 if (REG_P (operands
[0]))
973 else if (offsettable_memref_p (operands
[0]))
975 else if (GET_CODE (operands
[0]) == MEM
)
980 if (REG_P (operands
[1]))
982 else if (CONSTANT_P (operands
[1]))
984 else if (offsettable_memref_p (operands
[1]))
986 else if (GET_CODE (operands
[1]) == MEM
)
991 /* Check for the cases that the operand constraints are not
992 supposed to allow to happen. Abort if we get one,
993 because generating code for these cases is painful. */
995 if (optype0
== RNDOP
|| optype1
== RNDOP
)
998 /* If an operand is an unoffsettable memory ref, find a register
999 we can increment temporarily to make it refer to the second word. */
1001 if (optype0
== MEMOP
)
1002 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
1004 if (optype1
== MEMOP
)
1005 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
1007 /* Ok, we can do one word at a time.
1008 Normally we do the low-numbered word first,
1009 but if either operand is autodecrementing then we
1010 do the high-numbered word first.
1012 In either case, set up in LATEHALF the operands to use for the
1013 high-numbered (least significant) word and in some cases alter the
1014 operands in OPERANDS to be suitable for the low-numbered word. */
1016 if (optype0
== REGOP
)
1017 latehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 1);
1018 else if (optype0
== OFFSOP
)
1019 latehalf
[0] = adj_offsettable_operand (operands
[0], 4);
1021 latehalf
[0] = operands
[0];
1023 if (optype1
== REGOP
)
1024 latehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 1);
1025 else if (optype1
== OFFSOP
)
1026 latehalf
[1] = adj_offsettable_operand (operands
[1], 4);
1027 else if (optype1
== CNSTOP
)
1028 split_double (operands
[1], &operands
[1], &latehalf
[1]);
1030 latehalf
[1] = operands
[1];
1032 /* If the first move would clobber the source of the second one,
1033 do them in the other order.
1035 RMS says "This happens only for registers;
1036 such overlap can't happen in memory unless the user explicitly
1037 sets it up, and that is an undefined circumstance."
1039 but it happens on the sparc when loading parameter registers,
1040 so I am going to define that circumstance, and make it work
1043 /* Easy case: try moving both words at once. */
1044 /* First check for moving between an even/odd register pair
1045 and a memory location. */
1046 if ((optype0
== REGOP
&& optype1
!= REGOP
&& optype1
!= CNSTOP
1047 && (REGNO (operands
[0]) & 1) == 0)
1048 || (optype0
!= REGOP
&& optype0
!= CNSTOP
&& optype1
== REGOP
1049 && (REGNO (operands
[1]) & 1) == 0))
1052 rtx base
= 0, offset
= const0_rtx
;
1054 /* OP1 gets the register pair, and OP2 gets the memory address. */
1055 if (optype0
== REGOP
)
1056 op1
= operands
[0], op2
= operands
[1];
1058 op1
= operands
[1], op2
= operands
[0];
1060 /* Now see if we can trust the address to be 8-byte aligned. */
1061 /* Trust double-precision floats in global variables. */
1063 if (GET_CODE (XEXP (op2
, 0)) == LO_SUM
&& GET_MODE (op2
) == DFmode
)
1067 return (op1
== operands
[0] ? "ldd %1,%0" : "std %1,%0");
1070 if (GET_CODE (XEXP (op2
, 0)) == PLUS
)
1072 rtx temp
= XEXP (op2
, 0);
1073 if (GET_CODE (XEXP (temp
, 0)) == REG
)
1074 base
= XEXP (temp
, 0), offset
= XEXP (temp
, 1);
1075 else if (GET_CODE (XEXP (temp
, 1)) == REG
)
1076 base
= XEXP (temp
, 1), offset
= XEXP (temp
, 0);
1079 /* Trust round enough offsets from the stack or frame pointer. */
1081 && (REGNO (base
) == FRAME_POINTER_REGNUM
1082 || REGNO (base
) == STACK_POINTER_REGNUM
))
1084 if (GET_CODE (offset
) == CONST_INT
1085 && (INTVAL (offset
) & 0x7) == 0)
1087 if (op1
== operands
[0])
1093 /* We know structs not on the stack are properly aligned. Since a
1094 double asks for 8-byte alignment, we know it must have got that
1095 if it is in a struct. But a DImode need not be 8-byte aligned,
1096 because it could be a struct containing two ints or pointers. */
1097 else if (GET_CODE (operands
[1]) == MEM
1098 && GET_MODE (operands
[1]) == DFmode
1099 && (CONSTANT_P (XEXP (operands
[1], 0))
1100 /* Let user ask for it anyway. */
1101 || TARGET_HOPE_ALIGN
))
1103 else if (GET_CODE (operands
[0]) == MEM
1104 && GET_MODE (operands
[0]) == DFmode
1105 && (CONSTANT_P (XEXP (operands
[0], 0))
1106 || TARGET_HOPE_ALIGN
))
1110 if (optype0
== REGOP
&& optype1
== REGOP
1111 && REGNO (operands
[0]) == REGNO (latehalf
[1]))
1113 /* Make any unoffsettable addresses point at high-numbered word. */
1115 output_asm_insn ("add %0,0x4,%0", &addreg0
);
1117 output_asm_insn ("add %0,0x4,%0", &addreg1
);
1120 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1122 /* Undo the adds we just did. */
1124 output_asm_insn ("add %0,-0x4,%0", &addreg0
);
1126 output_asm_insn ("add %0,-0x4,%0", &addreg1
);
1128 /* Do low-numbered word. */
1129 return singlemove_string (operands
);
1131 else if (optype0
== REGOP
&& optype1
!= REGOP
1132 && reg_overlap_mentioned_p (operands
[0], operands
[1]))
1134 /* Do the late half first. */
1135 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1137 return singlemove_string (operands
);
1140 /* Normal case: do the two words, low-numbered first. */
1142 output_asm_insn (singlemove_string (operands
), operands
);
1144 /* Make any unoffsettable addresses point at high-numbered word. */
1146 output_asm_insn ("add %0,0x4,%0", &addreg0
);
1148 output_asm_insn ("add %0,0x4,%0", &addreg1
);
1151 output_asm_insn (singlemove_string (latehalf
), latehalf
);
1153 /* Undo the adds we just did. */
1155 output_asm_insn ("add %0,-0x4,%0", &addreg0
);
1157 output_asm_insn ("add %0,-0x4,%0", &addreg1
);
1163 output_fp_move_double (operands
)
1168 if (FP_REG_P (operands
[0]))
1170 if (FP_REG_P (operands
[1]))
1171 return "fmovs %1,%0\n\tfmovs %R1,%R0";
1172 if (GET_CODE (operands
[1]) == REG
)
1174 if ((REGNO (operands
[1]) & 1) == 0)
1175 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1177 return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0";
1179 addr
= XEXP (operands
[1], 0);
1181 /* Use ldd if known to be aligned. */
1182 if (TARGET_HOPE_ALIGN
1183 || (GET_CODE (addr
) == PLUS
1184 && (((XEXP (addr
, 0) == frame_pointer_rtx
1185 || XEXP (addr
, 0) == stack_pointer_rtx
)
1186 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
1187 && (INTVAL (XEXP (addr
, 1)) & 0x7) == 0)
1188 /* Arrays are known to be aligned,
1189 and reg+reg addresses are used (on this machine)
1190 only for array accesses. */
1191 || (REG_P (XEXP (addr
, 0)) && REG_P (XEXP (addr
, 1)))))
1192 || (GET_MODE (operands
[0]) == DFmode
1193 && (GET_CODE (addr
) == LO_SUM
|| CONSTANT_P (addr
))))
1196 /* Otherwise use two ld insns. */
1198 = gen_rtx (MEM
, GET_MODE (operands
[1]),
1199 plus_constant_for_output (addr
, 4));
1200 return "ld %1,%0\n\tld %2,%R0";
1202 else if (FP_REG_P (operands
[1]))
1204 if (GET_CODE (operands
[0]) == REG
)
1206 if ((REGNO (operands
[0]) & 1) == 0)
1207 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1209 return "std %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
1211 addr
= XEXP (operands
[0], 0);
1213 /* Use std if we can be sure it is well-aligned. */
1214 if (TARGET_HOPE_ALIGN
1215 || (GET_CODE (addr
) == PLUS
1216 && (((XEXP (addr
, 0) == frame_pointer_rtx
1217 || XEXP (addr
, 0) == stack_pointer_rtx
)
1218 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
1219 && (INTVAL (XEXP (addr
, 1)) & 0x7) == 0)
1220 /* Arrays are known to be aligned,
1221 and reg+reg addresses are used (on this machine)
1222 only for array accesses. */
1223 || (REG_P (XEXP (addr
, 0)) && REG_P (XEXP (addr
, 1)))))
1224 || (GET_MODE (operands
[1]) == DFmode
1225 && (GET_CODE (addr
) == LO_SUM
|| CONSTANT_P (addr
))))
1228 /* Otherwise use two st insns. */
1230 = gen_rtx (MEM
, GET_MODE (operands
[0]),
1231 plus_constant_for_output (addr
, 4));
1232 return "st %r1,%0\n\tst %R1,%2";
1237 /* Return a REG that occurs in ADDR with coefficient 1.
1238 ADDR can be effectively incremented by incrementing REG. */
1241 find_addr_reg (addr
)
1244 while (GET_CODE (addr
) == PLUS
)
1246 /* We absolutely can not fudge the frame pointer here, because the
1247 frame pointer must always be 8 byte aligned. It also confuses
1249 if (GET_CODE (XEXP (addr
, 0)) == REG
1250 && REGNO (XEXP (addr
, 0)) != FRAME_POINTER_REGNUM
)
1251 addr
= XEXP (addr
, 0);
1252 else if (GET_CODE (XEXP (addr
, 1)) == REG
1253 && REGNO (XEXP (addr
, 1)) != FRAME_POINTER_REGNUM
)
1254 addr
= XEXP (addr
, 1);
1255 else if (CONSTANT_P (XEXP (addr
, 0)))
1256 addr
= XEXP (addr
, 1);
1257 else if (CONSTANT_P (XEXP (addr
, 1)))
1258 addr
= XEXP (addr
, 0);
1262 if (GET_CODE (addr
) == REG
)
1268 output_sized_memop (opname
, mode
, signedp
)
1270 enum machine_mode mode
;
1273 static char *ld_size_suffix_u
[] = { "ub", "uh", "", "?", "d" };
1274 static char *ld_size_suffix_s
[] = { "sb", "sh", "", "?", "d" };
1275 static char *st_size_suffix
[] = { "b", "h", "", "?", "d" };
1276 char **opnametab
, *modename
;
1278 if (opname
[0] == 'l')
1280 opnametab
= ld_size_suffix_s
;
1282 opnametab
= ld_size_suffix_u
;
1284 opnametab
= st_size_suffix
;
1285 modename
= opnametab
[GET_MODE_SIZE (mode
) >> 1];
1287 fprintf (asm_out_file
, "\t%s%s", opname
, modename
);
1291 output_move_with_extension (operands
)
1294 if (GET_MODE (operands
[2]) == HImode
)
1295 output_asm_insn ("sll %2,0x10,%0", operands
);
1296 else if (GET_MODE (operands
[2]) == QImode
)
1297 output_asm_insn ("sll %2,0x18,%0", operands
);
1302 /* Load the address specified by OPERANDS[3] into the register
1303 specified by OPERANDS[0].
1305 OPERANDS[3] may be the result of a sum, hence it could either be:
1310 (3) REG + REG + CONST_INT
1311 (4) REG + REG (special case of 3).
1313 Note that (3) is not a legitimate address.
1314 All cases are handled here. */
1317 output_load_address (operands
)
1322 if (CONSTANT_P (operands
[3]))
1324 output_asm_insn ("set %3,%0", operands
);
1328 if (REG_P (operands
[3]))
1330 if (REGNO (operands
[0]) != REGNO (operands
[3]))
1331 output_asm_insn ("mov %3,%0", operands
);
1335 if (GET_CODE (operands
[3]) != PLUS
)
1338 base
= XEXP (operands
[3], 0);
1339 offset
= XEXP (operands
[3], 1);
1341 if (GET_CODE (base
) == CONST_INT
)
1348 if (GET_CODE (offset
) != CONST_INT
)
1350 /* Operand is (PLUS (REG) (REG)). */
1352 offset
= const0_rtx
;
1358 operands
[7] = offset
;
1359 if (SMALL_INT (offset
))
1360 output_asm_insn ("add %6,%7,%0", operands
);
1362 output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands
);
1364 else if (GET_CODE (base
) == PLUS
)
1366 operands
[6] = XEXP (base
, 0);
1367 operands
[7] = XEXP (base
, 1);
1368 operands
[8] = offset
;
1370 if (SMALL_INT (offset
))
1371 output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands
);
1373 output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands
);
1379 /* Output code to place a size count SIZE in register REG.
1380 ALIGN is the size of the unit of transfer.
1382 Because block moves are pipelined, we don't include the
1383 first element in the transfer of SIZE to REG. */
1386 output_size_for_block_move (size
, reg
, align
)
1393 xoperands
[1] = size
;
1394 xoperands
[2] = align
;
1395 if (GET_CODE (size
) == REG
)
1396 output_asm_insn ("sub %1,%2,%0", xoperands
);
1400 = gen_rtx (CONST_INT
, VOIDmode
, INTVAL (size
) - INTVAL (align
));
1401 output_asm_insn ("set %1,%0", xoperands
);
1405 /* Emit code to perform a block move.
1407 OPERANDS[0] is the destination.
1408 OPERANDS[1] is the source.
1409 OPERANDS[2] is the size.
1410 OPERANDS[3] is the alignment safe to use.
1411 OPERANDS[4] is a register we can safely clobber as a temp. */
1414 output_block_move (operands
)
1417 /* A vector for our computed operands. Note that load_output_address
1418 makes use of (and can clobber) up to the 8th element of this vector. */
1421 static int movstrsi_label
= 0;
1423 rtx temp1
= operands
[4];
1424 rtx sizertx
= operands
[2];
1425 rtx alignrtx
= operands
[3];
1426 int align
= INTVAL (alignrtx
);
1427 char label3
[30], label5
[30];
1429 xoperands
[0] = operands
[0];
1430 xoperands
[1] = operands
[1];
1431 xoperands
[2] = temp1
;
1433 /* We can't move more than this many bytes at a time because we have only
1434 one register, %g1, to move them through. */
1435 if (align
> UNITS_PER_WORD
)
1437 align
= UNITS_PER_WORD
;
1438 alignrtx
= gen_rtx (CONST_INT
, VOIDmode
, UNITS_PER_WORD
);
1441 /* We consider 8 ld/st pairs, for a total of 16 inline insns to be
1442 reasonable here. (Actually will emit a maximum of 18 inline insns for
1443 the case of size == 31 and align == 4). */
1445 if (GET_CODE (sizertx
) == CONST_INT
&& (INTVAL (sizertx
) / align
) <= 8
1446 && memory_address_p (QImode
, plus_constant_for_output (xoperands
[0],
1448 && memory_address_p (QImode
, plus_constant_for_output (xoperands
[1],
1451 int size
= INTVAL (sizertx
);
1454 /* We will store different integers into this particular RTX. */
1455 xoperands
[2] = rtx_alloc (CONST_INT
);
1456 PUT_MODE (xoperands
[2], VOIDmode
);
1458 /* This case is currently not handled. Abort instead of generating
1465 for (i
= (size
>> 2) - 1; i
>= 0; i
--)
1467 INTVAL (xoperands
[2]) = (i
<< 2) + offset
;
1468 output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]",
1471 offset
+= (size
& ~0x3);
1479 for (i
= (size
>> 1) - 1; i
>= 0; i
--)
1481 INTVAL (xoperands
[2]) = (i
<< 1) + offset
;
1482 output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]",
1485 offset
+= (size
& ~0x1);
1493 for (i
= size
- 1; i
>= 0; i
--)
1495 INTVAL (xoperands
[2]) = i
+ offset
;
1496 output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]",
1502 /* We should never reach here. */
1506 /* If the size isn't known to be a multiple of the alignment,
1507 we have to do it in smaller pieces. If we could determine that
1508 the size was a multiple of 2 (or whatever), we could be smarter
1510 if (GET_CODE (sizertx
) != CONST_INT
)
1514 int size
= INTVAL (sizertx
);
1515 while (size
% align
)
1519 if (align
!= INTVAL (alignrtx
))
1520 alignrtx
= gen_rtx (CONST_INT
, VOIDmode
, align
);
1522 xoperands
[3] = gen_rtx (CONST_INT
, VOIDmode
, movstrsi_label
++);
1523 xoperands
[4] = gen_rtx (CONST_INT
, VOIDmode
, align
);
1524 xoperands
[5] = gen_rtx (CONST_INT
, VOIDmode
, movstrsi_label
++);
1526 ASM_GENERATE_INTERNAL_LABEL (label3
, "Lm", INTVAL (xoperands
[3]));
1527 ASM_GENERATE_INTERNAL_LABEL (label5
, "Lm", INTVAL (xoperands
[5]));
1529 /* This is the size of the transfer. Emit code to decrement the size
1530 value by ALIGN, and store the result in the temp1 register. */
1531 output_size_for_block_move (sizertx
, temp1
, alignrtx
);
1533 /* Must handle the case when the size is zero or negative, so the first thing
1534 we do is compare the size against zero, and only copy bytes if it is
1535 zero or greater. Note that we have already subtracted off the alignment
1536 once, so we must copy 1 alignment worth of bytes if the size is zero
1539 The SUN assembler complains about labels in branch delay slots, so we
1540 do this before outputting the load address, so that there will always
1541 be a harmless insn between the branch here and the next label emitted
1547 sprintf (pattern
, "cmp %%2,0\n\tbl %s", &label5
[1]);
1548 output_asm_insn (pattern
, xoperands
);
1551 zoperands
[0] = operands
[0];
1552 zoperands
[3] = plus_constant_for_output (operands
[0], align
);
1553 output_load_address (zoperands
);
1555 /* ??? This might be much faster if the loops below were preconditioned
1558 That is, at run time, copy enough bytes one at a time to ensure that the
1559 target and source addresses are aligned to the the largest possible
1560 alignment. Then use a preconditioned unrolled loop to copy say 16
1561 bytes at a time. Then copy bytes one at a time until finish the rest. */
1563 /* Output the first label separately, so that it is spaced properly. */
1565 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, "Lm", INTVAL (xoperands
[3]));
1569 register char *ld_suffix
= (align
== 1) ? "ub" : (align
== 2) ? "uh" : "";
1570 register char *st_suffix
= (align
== 1) ? "b" : (align
== 2) ? "h" : "";
1572 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]);
1573 output_asm_insn (pattern
, xoperands
);
1579 /* Output reasonable peephole for set-on-condition-code insns.
1580 Note that these insns assume a particular way of defining
1581 labels. Therefore, *both* sparc.h and this function must
1582 be changed if a new syntax is needed. */
1585 output_scc_insn (operands
, insn
)
1589 static char string
[100];
1590 rtx label
= 0, next
= insn
;
1593 /* Try doing a jump optimization which jump.c can't do for us
1594 because we did not expose that setcc works by using branches.
1596 If this scc insn is followed by an unconditional branch, then have
1597 the jump insn emitted here jump to that location, instead of to
1598 the end of the scc sequence as usual. */
1602 if (GET_CODE (next
) == CODE_LABEL
)
1604 next
= NEXT_INSN (next
);
1608 while (GET_CODE (next
) == NOTE
|| GET_CODE (next
) == CODE_LABEL
);
1610 /* If we are in a sequence, and the following insn is a sequence also,
1611 then just following the current insn's next field will take us to the
1612 first insn of the next sequence, which is the wrong place. We don't
1613 want to optimize with a branch that has had its delay slot filled.
1614 Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next
1615 which fails only if NEXT is such a branch. */
1617 if (next
&& GET_CODE (next
) == JUMP_INSN
&& simplejump_p (next
)
1618 && (! final_sequence
|| NEXT_INSN (PREV_INSN (next
)) == next
))
1619 label
= JUMP_LABEL (next
);
1620 /* If not optimizing, jump label fields are not set. To be safe, always
1621 check here to whether label is still zero. */
1624 label
= gen_label_rtx ();
1628 LABEL_NUSES (label
) += 1;
1630 operands
[2] = label
;
1632 /* If we are in a delay slot, assume it is the delay slot of an fpcc
1633 insn since our type isn't allowed anywhere else. */
1635 /* ??? Fpcc instructions no longer have delay slots, so this code is
1636 probably obsolete. */
1638 /* The fastest way to emit code for this is an annulled branch followed
1639 by two move insns. This will take two cycles if the branch is taken,
1640 and three cycles if the branch is not taken.
1642 However, if we are in the delay slot of another branch, this won't work,
1643 because we can't put a branch in the delay slot of another branch.
1644 The above sequence would effectively take 3 or 4 cycles respectively
1645 since a no op would have be inserted between the two branches.
1646 In this case, we want to emit a move, annulled branch, and then the
1647 second move. This sequence always takes 3 cycles, and hence is faster
1648 when we are in a branch delay slot. */
1652 strcpy (string
, "mov 0,%0\n\t");
1653 strcat (string
, output_cbranch (operands
[1], 2, 0, 1, 0));
1654 strcat (string
, "\n\tmov 1,%0");
1658 strcpy (string
, output_cbranch (operands
[1], 2, 0, 1, 0));
1659 strcat (string
, "\n\tmov 1,%0\n\tmov 0,%0");
1663 strcat (string
, "\n%l2:");
1668 /* Vectors to keep interesting information about registers where
1669 it can easily be got. */
1671 /* Modes for condition codes. */
1673 ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) | (1 << (int) CCFPmode))
1675 /* Modes for single-word (and smaller) quantities. */
1678 & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
1679 | (1 << (int) DFmode) | (1 << (int) TFmode)))
1681 /* Modes for double-word (and smaller) quantities. */
1684 & ~ ((1 << (int) TImode) | (1 << (int) TFmode)))
1686 /* Modes for quad-word quantities. */
1687 #define T_MODES (~C_MODES)
1689 /* Modes for single-float quantities. */
1690 #define SF_MODES ((1 << (int) SFmode))
1692 /* Modes for double-float quantities. */
1693 #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1695 /* Modes for quad-float quantities. */
1696 #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1698 /* Value is 1 if register/mode pair is acceptable on sparc.
1699 The funny mixture of D and T modes is because integer operations
1700 do not specially operate on tetra quantities, so non-quad-aligned
1701 registers can hold quadword quantities (except %o4 and %i4 because
1702 they cross fixed registers. */
1704 int hard_regno_mode_ok
[] = {
1705 C_MODES
, S_MODES
, T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
,
1706 T_MODES
, S_MODES
, T_MODES
, S_MODES
, D_MODES
, S_MODES
, D_MODES
, S_MODES
,
1707 T_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
,
1710 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
,
1711 TF_MODES
, SF_MODES
, DF_MODES
, SF_MODES
, TF_MODES
, SF_MODES
, DF_MODES
, SF_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
};
1719 save_regs (file
, low
, high
, base
, offset
, n_fregs
)
1728 for (i
= low
; i
< high
; i
+= 2)
1730 if (regs_ever_live
[i
] && ! call_used_regs
[i
])
1731 if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1732 fprintf (file
, "\tstd %s,[%s+%d]\n",
1733 reg_names
[i
], base
, offset
+ 4 * n_fregs
),
1736 fprintf (file
, "\tst %s,[%s+%d]\n",
1737 reg_names
[i
], base
, offset
+ 4 * n_fregs
),
1739 else if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1740 fprintf (file
, "\tst %s,[%s+%d]\n",
1741 reg_names
[i
+1], base
, offset
+ 4 * n_fregs
),
1751 restore_regs (file
, low
, high
, base
, offset
, n_fregs
)
1759 for (i
= low
; i
< high
; i
+= 2)
1761 if (regs_ever_live
[i
] && ! call_used_regs
[i
])
1762 if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1763 fprintf (file
, "\tldd [%s+%d], %s\n",
1764 base
, offset
+ 4 * n_fregs
, reg_names
[i
]),
1767 fprintf (file
, "\tld [%s+%d],%s\n",
1768 base
, offset
+ 4 * n_fregs
, reg_names
[i
]),
1770 else if (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1])
1771 fprintf (file
, "\tld [%s+%d],%s\n",
1772 base
, offset
+ 4 * n_fregs
, reg_names
[i
+1]),
1778 /* Static variables we want to share between prologue and epilogue. */
1780 /* Number of live floating point registers needed to be saved. */
1781 static int num_fregs
;
1783 /* Nonzero if any floating point register was ever used. */
1784 static int fregs_ever_live
;
1787 compute_frame_size (size
, leaf_function
)
1791 int fregs_ever_live
= 0;
1793 int outgoing_args_size
= (current_function_outgoing_args_size
1794 + REG_PARM_STACK_SPACE (current_function_decl
));
1796 apparent_fsize
= ((size
) + 7 - STARTING_FRAME_OFFSET
) & -8;
1797 for (i
= 32; i
< FIRST_PSEUDO_REGISTER
; i
+= 2)
1798 fregs_ever_live
|= regs_ever_live
[i
]|regs_ever_live
[i
+1];
1800 if (TARGET_EPILOGUE
&& fregs_ever_live
)
1802 for (i
= 32; i
< FIRST_PSEUDO_REGISTER
; i
+= 2)
1803 if ((regs_ever_live
[i
] && ! call_used_regs
[i
])
1804 || (regs_ever_live
[i
+1] && ! call_used_regs
[i
+1]))
1808 /* Set up values for use in `function_epilogue'. */
1809 num_fregs
= n_fregs
;
1811 apparent_fsize
+= (outgoing_args_size
+7) & -8;
1812 if (leaf_function
&& n_fregs
== 0
1813 && apparent_fsize
== (REG_PARM_STACK_SPACE (current_function_decl
)
1814 - STARTING_FRAME_OFFSET
))
1817 actual_fsize
= apparent_fsize
+ n_fregs
*4;
1819 /* Make sure nothing can clobber our register windows.
1820 If a SAVE must be done, or there is a stack-local variable,
1821 the register window area must be allocated. */
1822 if (leaf_function
== 0 || size
> 0)
1823 actual_fsize
+= (16 * UNITS_PER_WORD
)+8;
1825 return actual_fsize
;
1828 /* Output code for the function prologue. */
1831 output_function_prologue (file
, size
, leaf_function
)
1837 frame_base_name
= "%sp+80";
1839 frame_base_name
= "%fp";
1841 /* Need to use actual_fsize, since we are also allocating
1842 space for our callee (and our own register save area). */
1843 actual_fsize
= compute_frame_size (size
, leaf_function
);
1845 fprintf (file
, "\t!#PROLOGUE# 0\n");
1846 if (actual_fsize
== 0)
1848 else if (actual_fsize
<= 4096)
1850 if (! leaf_function
)
1851 fprintf (file
, "\tsave %%sp,-%d,%%sp\n", actual_fsize
);
1853 fprintf (file
, "\tadd %%sp,-%d,%%sp\n", actual_fsize
);
1855 else if (actual_fsize
<= 8192)
1857 /* For frames in the range 4097..8192, we can use just two insns. */
1858 if (! leaf_function
)
1860 fprintf (file
, "\tsave %%sp,-4096,%%sp\n");
1861 fprintf (file
, "\tadd %%sp,-%d,%%sp\n", actual_fsize
- 4096);
1865 fprintf (file
, "\tadd %%sp,-4096,%%sp\n");
1866 fprintf (file
, "\tadd %%sp,-%d,%%sp\n", actual_fsize
- 4096);
1871 if (! leaf_function
)
1873 fprintf (file
, "\tsethi %%hi(-%d),%%g1\n", actual_fsize
);
1874 if ((actual_fsize
& 0x3ff) != 0)
1875 fprintf (file
, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize
);
1876 fprintf (file
, "\tsave %%sp,%%g1,%%sp\n");
1880 fprintf (file
, "\tsethi %%hi(-%d),%%g1\n", actual_fsize
);
1881 if ((actual_fsize
& 0x3ff) != 0)
1882 fprintf (file
, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize
);
1883 fprintf (file
, "\tadd %%sp,%%g1,%%sp\n");
1887 /* If doing anything with PIC, do it now. */
1889 fprintf (file
, "\t!#PROLOGUE# 1\n");
1891 /* Figure out where to save any special registers. */
1894 int offset
, n_fregs
= num_fregs
;
1896 if (! leaf_function
)
1897 offset
= -apparent_fsize
;
1901 if (TARGET_EPILOGUE
&& ! leaf_function
)
1902 n_fregs
= save_regs (file
, 0, 16, frame_base_name
, offset
, 0);
1903 else if (leaf_function
)
1904 n_fregs
= save_regs (file
, 0, 32, frame_base_name
, offset
, 0);
1905 if (TARGET_EPILOGUE
)
1906 save_regs (file
, 32, FIRST_PSEUDO_REGISTER
,
1907 frame_base_name
, offset
, n_fregs
);
1910 if (regs_ever_live
[62])
1911 fprintf (file
, "\tst %s,[%s-16]\n\tst %s,[%s-12]\n",
1912 reg_names
[0], frame_base_name
,
1913 reg_names
[0], frame_base_name
);
1916 if (leaf_function
&& actual_fsize
!= 0)
1918 /* warning ("leaf procedure with frame size %d", actual_fsize); */
1919 if (! TARGET_EPILOGUE
)
1920 leaf_label
= gen_label_rtx ();
1924 /* Output code for the function epilogue. */
1927 output_function_epilogue (file
, size
, leaf_function
)
1937 emit_label_after (leaf_label
, get_last_insn ());
1938 final_scan_insn (get_last_insn (), file
, 0, 0, 1);
1943 int offset
, n_fregs
= num_fregs
;
1945 if (! leaf_function
)
1946 offset
= -apparent_fsize
;
1950 if (TARGET_EPILOGUE
&& ! leaf_function
)
1951 n_fregs
= restore_regs (file
, 0, 16, frame_base_name
, offset
, 0);
1952 else if (leaf_function
)
1953 n_fregs
= restore_regs (file
, 0, 32, frame_base_name
, offset
, 0);
1954 if (TARGET_EPILOGUE
)
1955 restore_regs (file
, 32, FIRST_PSEUDO_REGISTER
,
1956 frame_base_name
, offset
, n_fregs
);
1959 /* Work out how to skip the caller's unimp instruction if required. */
1961 ret
= (current_function_returns_struct
? "jmp %o7+12" : "retl");
1963 ret
= (current_function_returns_struct
? "jmp %i7+12" : "ret");
1965 if (TARGET_EPILOGUE
|| leaf_label
)
1967 int old_target_epilogue
= TARGET_EPILOGUE
;
1968 target_flags
&= ~old_target_epilogue
;
1970 if (! leaf_function
)
1972 /* If we wound up with things in our delay slot, flush them here. */
1973 if (current_function_epilogue_delay_list
)
1975 rtx insn
= emit_jump_insn_after (gen_rtx (RETURN
, VOIDmode
),
1977 PATTERN (insn
) = gen_rtx (PARALLEL
, VOIDmode
,
1979 PATTERN (XEXP (current_function_epilogue_delay_list
, 0)),
1981 final_scan_insn (insn
, file
, 1, 0, 1);
1984 fprintf (file
, "\t%s\n\trestore\n", ret
);
1986 /* All of the following cases are for leaf functions. */
1987 else if (current_function_epilogue_delay_list
)
1989 /* eligible_for_epilogue_delay_slot ensures that if this is a
1990 leaf function, then we will only have insn in the delay slot
1991 if the frame size is zero, thus no adjust for the stack is
1993 if (actual_fsize
!= 0)
1995 fprintf (file
, "\t%s\n", ret
);
1996 final_scan_insn (XEXP (current_function_epilogue_delay_list
, 0),
1999 else if (actual_fsize
<= 4096)
2000 fprintf (file
, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret
, actual_fsize
);
2001 else if (actual_fsize
<= 8192)
2002 fprintf (file
, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n",
2003 ret
, actual_fsize
- 4096);
2004 else if ((actual_fsize
& 0x3ff) == 0)
2005 fprintf (file
, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2008 fprintf (file
, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2009 actual_fsize
, actual_fsize
, ret
);
2010 target_flags
|= old_target_epilogue
;
2014 /* Return the string to output a conditional branch to LABEL, which is
2015 the operand number of the label. OP is the conditional expression. The
2016 mode of register 0 says what kind of comparison we made.
2018 REVERSED is non-zero if we should reverse the sense of the comparison.
2020 ANNUL is non-zero if we should generate an annulling branch.
2022 NOOP is non-zero if we have to follow this branch by a noop. */
2025 output_cbranch (op
, label
, reversed
, annul
, noop
)
2028 int reversed
, annul
, noop
;
2030 static char string
[20];
2031 enum rtx_code code
= GET_CODE (op
);
2032 enum machine_mode mode
= GET_MODE (XEXP (op
, 0));
2033 static char labelno
[] = " %lX";
2035 /* ??? FP branches can not be preceded by another floating point insn.
2036 Because there is currently no concept of pre-delay slots, we can fix
2037 this only by always emitting a nop before a floating point branch. */
2039 if (mode
== CCFPmode
)
2040 strcpy (string
, "nop\n\t");
2042 /* If not floating-point or if EQ or NE, we can just reverse the code. */
2043 if (reversed
&& (mode
!= CCFPmode
|| code
== EQ
|| code
== NE
))
2044 code
= reverse_condition (code
), reversed
= 0;
2046 /* Start by writing the branch condition. */
2050 if (mode
== CCFPmode
)
2051 strcat (string
, "fbne");
2053 strcpy (string
, "bne");
2057 if (mode
== CCFPmode
)
2058 strcat (string
, "fbe");
2060 strcpy (string
, "be");
2064 if (mode
== CCFPmode
)
2067 strcat (string
, "fbul");
2069 strcat (string
, "fbge");
2071 else if (mode
== CC_NOOVmode
)
2072 strcpy (string
, "bpos");
2074 strcpy (string
, "bge");
2078 if (mode
== CCFPmode
)
2081 strcat (string
, "fbule");
2083 strcat (string
, "fbg");
2086 strcpy (string
, "bg");
2090 if (mode
== CCFPmode
)
2093 strcat (string
, "fbug");
2095 strcat (string
, "fble");
2098 strcpy (string
, "ble");
2102 if (mode
== CCFPmode
)
2105 strcat (string
, "fbuge");
2107 strcat (string
, "fbl");
2109 else if (mode
== CC_NOOVmode
)
2110 strcpy (string
, "bneg");
2112 strcpy (string
, "bl");
2116 strcpy (string
, "bgeu");
2120 strcpy (string
, "bgu");
2124 strcpy (string
, "bleu");
2128 strcpy (string
, "blu");
2132 /* Now add the annulling, the label, and a possible noop. */
2134 strcat (string
, ",a");
2136 labelno
[3] = label
+ '0';
2137 strcat (string
, labelno
);
2140 strcat (string
, "\n\tnop");
2146 output_return (operands
)
2151 operands
[0] = leaf_label
;
2154 else if (leaf_function
)
2156 /* If we didn't allocate a frame pointer for the current function,
2157 the stack pointer might have been adjusted. Output code to
2160 operands
[0] = gen_rtx (CONST_INT
, VOIDmode
, actual_fsize
);
2162 /* Use sub of negated value in first two cases instead of add to
2163 allow actual_fsize == 4096. */
2165 if (actual_fsize
<= 4096)
2167 if (current_function_returns_struct
)
2168 return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp";
2170 return "retl\n\tsub %%sp,-%0,%%sp";
2172 else if (actual_fsize
<= 8192)
2174 operands
[0] = gen_rtx (CONST_INT
, VOIDmode
, actual_fsize
- 4096);
2175 if (current_function_returns_struct
)
2176 return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp";
2178 return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp";
2180 else if (current_function_returns_struct
)
2182 if ((actual_fsize
& 0x3ff) != 0)
2183 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2185 return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2189 if ((actual_fsize
& 0x3ff) != 0)
2190 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
2192 return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
2197 if (current_function_returns_struct
)
2198 return "jmp %%i7+12\n\trestore";
2200 return "ret\n\trestore";
2205 output_floatsisf2 (operands
)
2208 if (GET_CODE (operands
[1]) == MEM
)
2209 return "ld %1,%0\n\tfitos %0,%0";
2210 else if (FP_REG_P (operands
[1]))
2211 return "fitos %1,%0";
2212 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitos %0,%0";
2216 output_floatsidf2 (operands
)
2219 if (GET_CODE (operands
[1]) == MEM
)
2220 return "ld %1,%0\n\tfitod %0,%0";
2221 else if (FP_REG_P (operands
[1]))
2222 return "fitod %1,%0";
2223 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitod %0,%0";
2226 /* Leaf functions and non-leaf functions have different needs. */
2229 reg_leaf_alloc_order
[] = REG_LEAF_ALLOC_ORDER
;
2232 reg_nonleaf_alloc_order
[] = REG_ALLOC_ORDER
;
2234 static int *reg_alloc_orders
[] = {
2235 reg_leaf_alloc_order
,
2236 reg_nonleaf_alloc_order
};
2239 order_regs_for_local_alloc ()
2241 static int last_order_nonleaf
= 1;
2243 if (regs_ever_live
[15] != last_order_nonleaf
)
2245 last_order_nonleaf
= !last_order_nonleaf
;
2246 bcopy (reg_alloc_orders
[last_order_nonleaf
], reg_alloc_order
,
2247 FIRST_PSEUDO_REGISTER
* sizeof (int));
2251 /* Machine dependent routines for the branch probability, arc profiling
2254 /* The label used by the arc profiling code. */
2256 static rtx profiler_label
;
2259 init_arc_profiler ()
2261 /* Generate and save a copy of this so it can be shared. */
2262 profiler_label
= gen_rtx (SYMBOL_REF
, Pmode
, "*LPBX2");
2266 output_arc_profiler (arcno
, insert_after
)
2270 rtx profiler_target_addr
2271 = gen_rtx (CONST
, Pmode
,
2272 gen_rtx (PLUS
, Pmode
, profiler_label
,
2273 gen_rtx (CONST_INT
, VOIDmode
, 4 * arcno
)));
2274 register rtx profiler_reg
= gen_reg_rtx (SImode
);
2275 register rtx address_reg
= gen_reg_rtx (Pmode
);
2278 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, address_reg
,
2279 gen_rtx (HIGH
, Pmode
,
2280 profiler_target_addr
)),
2283 mem_ref
= gen_rtx (MEM
, SImode
, gen_rtx (LO_SUM
, Pmode
, address_reg
,
2284 profiler_target_addr
));
2285 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, profiler_reg
,
2289 insert_after
= emit_insn_after (gen_rtx (SET
, VOIDmode
, profiler_reg
,
2290 gen_rtx (PLUS
, SImode
, profiler_reg
,
2294 /* This is the same rtx as above, but it is not legal to share this rtx. */
2295 mem_ref
= gen_rtx (MEM
, SImode
, gen_rtx (LO_SUM
, Pmode
, address_reg
,
2296 profiler_target_addr
));
2297 emit_insn_after (gen_rtx (SET
, VOIDmode
, mem_ref
, profiler_reg
),
2301 /* Print operand X (an rtx) in assembler syntax to file FILE.
2302 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2303 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2306 print_operand (file
, x
, code
)
2314 /* Output a 'nop' if there's nothing for the delay slot. */
2315 if (dbr_sequence_length () == 0)
2316 fputs ("\n\tnop", file
);
2319 /* Output an annul flag if there's nothing for the delay slot. */
2320 if (dbr_sequence_length () == 0)
2324 /* Adjust the operand to take into account a RESTORE operation. */
2325 if (GET_CODE (x
) != REG
)
2328 fputs (reg_names
[REGNO (x
)], file
);
2329 else if (REGNO (x
) >= 24 && REGNO (x
) < 32)
2330 fputs (reg_names
[REGNO (x
)-16], file
);
2335 /* Print out what we are using as the frame pointer. This might
2336 be %fp, or might be %sp+offset. */
2337 fputs (frame_base_name
, file
);
2340 /* Print out the second register name of a register pair.
2341 I.e., R (%o0) => %o1. */
2342 fputs (reg_names
[REGNO (x
)+1], file
);
2345 /* Print the operand's address only. */
2346 output_address (XEXP (x
, 0));
2349 /* In this case we need a register. Use %g0 if the
2350 operand in const0_rtx. */
2351 if (x
== const0_rtx
)
2353 fputs ("%g0", file
);
2360 switch (GET_CODE (x
))
2362 case IOR
: fputs ("or", file
); break;
2363 case AND
: fputs ("and", file
); break;
2364 case XOR
: fputs ("xor", file
); break;
2370 switch (GET_CODE (x
))
2372 case IOR
: fputs ("orn", file
); break;
2373 case AND
: fputs ("andn", file
); break;
2374 case XOR
: fputs ("xnor", file
); break;
2381 /* Print a sign-extended character. */
2382 int i
= INTVAL (x
) & 0xff;
2385 fprintf (file
, "%d", i
);
2390 /* Do nothing special. */
2394 /* Undocumented flag. */
2398 if (GET_CODE (x
) == REG
)
2399 fputs (reg_names
[REGNO (x
)], file
);
2400 else if (GET_CODE (x
) == MEM
)
2403 if (CONSTANT_P (XEXP (x
, 0)))
2404 /* Poor Sun assembler doesn't understand absolute addressing. */
2405 fputs ("%g0+", file
);
2406 output_address (XEXP (x
, 0));
2409 else if (GET_CODE (x
) == HIGH
)
2411 fputs ("%hi(", file
);
2412 output_addr_const (file
, XEXP (x
, 0));
2415 else if (GET_CODE (x
) == LO_SUM
)
2417 print_operand (file
, XEXP (x
, 0), 0);
2418 fputs ("+%lo(", file
);
2419 output_addr_const (file
, XEXP (x
, 1));
2422 else if (GET_CODE (x
) == CONST_DOUBLE
)
2424 if (CONST_DOUBLE_HIGH (x
) == 0)
2425 fprintf (file
, "%u", CONST_DOUBLE_LOW (x
));
2426 else if (CONST_DOUBLE_HIGH (x
) == -1
2427 && CONST_DOUBLE_LOW (x
) < 0)
2428 fprintf (file
, "%d", CONST_DOUBLE_LOW (x
));
2432 else { output_addr_const (file
, x
); }
2435 /* This function outputs assembler code for VALUE to FILE, where VALUE is
2436 a 64 bit (DImode) value. */
2438 /* ??? If there is a 64 bit counterpart to .word that the assembler
2439 understands, then using that would simply this code greatly. */
2442 output_double_int (file
, value
)
2446 if (GET_CODE (value
) == CONST_INT
)
2448 if (INTVAL (value
) < 0)
2449 ASM_OUTPUT_INT (file
, constm1_rtx
);
2451 ASM_OUTPUT_INT (file
, const0_rtx
);
2452 ASM_OUTPUT_INT (file
, value
);
2454 else if (GET_CODE (value
) == CONST_DOUBLE
)
2456 ASM_OUTPUT_INT (file
, gen_rtx (CONST_INT
, VOIDmode
,
2457 CONST_DOUBLE_HIGH (value
)));
2458 ASM_OUTPUT_INT (file
, gen_rtx (CONST_INT
, VOIDmode
,
2459 CONST_DOUBLE_LOW (value
)));
2461 else if (GET_CODE (value
) == SYMBOL_REF
2462 || GET_CODE (value
) == CONST
2463 || GET_CODE (value
) == PLUS
)
2465 /* Addresses are only 32 bits. */
2466 ASM_OUTPUT_INT (file
, const0_rtx
);
2467 ASM_OUTPUT_INT (file
, value
);
2473 /* Compute the code to put in the .proc statement
2474 for a function that returns type TYPE. */
2477 sparc_type_code (type
)
2480 register unsigned long qualifiers
= 0;
2481 register unsigned shift
= 6;
2485 switch (TREE_CODE (type
))
2491 qualifiers
|= (3 << shift
);
2493 type
= TREE_TYPE (type
);
2498 qualifiers
|= (2 << shift
);
2500 type
= TREE_TYPE (type
);
2504 case REFERENCE_TYPE
:
2506 qualifiers
|= (1 << shift
);
2508 type
= TREE_TYPE (type
);
2512 return (qualifiers
| 8);
2515 return (qualifiers
| 9);
2518 return (qualifiers
| 10);
2521 return (qualifiers
| 16);
2524 /* This return value is not always completely the same as Sun's
2525 but the Sun assembler's peephole optimizer probably doesn't
2527 return (qualifiers
| 4);
2530 if (TYPE_PRECISION (type
) == 32)
2531 return (qualifiers
| 6);
2533 return (qualifiers
| 7); /* Who knows? */
2535 case COMPLEX_TYPE
: /* GNU Fortran COMPLEX type. */
2536 case CHAR_TYPE
: /* GNU Pascal CHAR type. Not used in C. */
2537 case BOOLEAN_TYPE
: /* GNU Fortran BOOLEAN type. */
2538 case FILE_TYPE
: /* GNU Pascal FILE type. */
2539 case STRING_TYPE
: /* GNU Fortran STRING type. */
2540 case LANG_TYPE
: /* ? */
2544 abort (); /* Not a type! */