]> gcc.gnu.org Git - gcc.git/blame - gcc/config/sparc/sparc.c
*** empty log message ***
[gcc.git] / gcc / config / sparc / sparc.c
CommitLineData
ab835497
RK
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)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <stdio.h>
22#include "config.h"
210aa14a 23#include "tree.h"
ab835497
RK
24#include "rtl.h"
25#include "regs.h"
26#include "hard-reg-set.h"
27#include "real.h"
28#include "insn-config.h"
29#include "conditions.h"
30#include "insn-flags.h"
31#include "output.h"
32#include "insn-attr.h"
33#include "flags.h"
34#include "expr.h"
35#include "recog.h"
36
37/* Global variables for machine-dependent things. */
38
39/* Save the operands last given to a compare for use when we
40 generate a scc or bcc insn. */
41
42rtx sparc_compare_op0, sparc_compare_op1;
43
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. */
46static rtx leaf_label;
47
48#ifdef LEAF_REGISTERS
49
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
53 to get that. */
54char 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,
59
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};
64
65char 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,
70
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};
75#endif
76
77/* Global variables set by FUNCTION_PROLOGUE. */
78/* Size of frame. Need to know this to emit return insns from
79 leaf procedures. */
80int apparent_fsize;
81int actual_fsize;
82
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". */
86char *frame_base_name;
87
88static rtx find_addr_reg ();
89
90/* Return non-zero only if OP is a register of mode MODE,
91 or const0_rtx. */
92int
93reg_or_0_operand (op, mode)
94 rtx op;
95 enum machine_mode mode;
96{
97 if (op == const0_rtx || register_operand (op, mode))
98 return 1;
99 if (GET_CODE (op) == CONST_DOUBLE
100 && CONST_DOUBLE_HIGH (op) == 0
101 && CONST_DOUBLE_LOW (op) == 0)
102 return 1;
103 return 0;
104}
105
106/* Nonzero if OP can appear as the dest of a RESTORE insn. */
107int
108restore_operand (op, mode)
109 rtx op;
110 enum machine_mode mode;
111{
112 return (GET_CODE (op) == REG && GET_MODE (op) == mode
113 && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));
114}
115
116/* PC-relative call insn on SPARC is independent of `memory_operand'. */
117
118int
119call_operand (op, mode)
120 rtx op;
121 enum machine_mode mode;
122{
123 if (GET_CODE (op) != MEM)
124 abort ();
125 op = XEXP (op, 0);
126 return (REG_P (op) || CONSTANT_P (op));
127}
128
129int
130call_operand_address (op, mode)
131 rtx op;
132 enum machine_mode mode;
133{
134 return (REG_P (op) || CONSTANT_P (op));
135}
136
137/* Returns 1 if OP is either a symbol reference or a sum of a symbol
138 reference and a constant. */
139
140int
141symbolic_operand (op, mode)
142 register rtx op;
143 enum machine_mode mode;
144{
145 switch (GET_CODE (op))
146 {
147 case SYMBOL_REF:
148 case LABEL_REF:
149 return 1;
150
151 case CONST:
152 op = XEXP (op, 0);
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);
156
157 /* This clause seems to be irrelevant. */
158 case CONST_DOUBLE:
159 return GET_MODE (op) == mode;
160
161 default:
162 return 0;
163 }
164}
165
166/* Return truth value of statement that OP is a symbolic memory
167 operand of mode MODE. */
168
169int
170symbolic_memory_operand (op, mode)
171 rtx op;
172 enum machine_mode mode;
173{
174 if (GET_CODE (op) == SUBREG)
175 op = SUBREG_REG (op);
176 if (GET_CODE (op) != MEM)
177 return 0;
178 op = XEXP (op, 0);
179 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
180 || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
181}
182
183/* Return 1 if the operand is either a register or a memory operand that is
184 not symbolic. */
185
186int
187reg_or_nonsymb_mem_operand (op, mode)
188 register rtx op;
189 enum machine_mode mode;
190{
191 if (register_operand (op, mode))
192 return 1;
193
194 if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
195 return 1;
196
197 return 0;
198}
199
200int
201sparc_operand (op, mode)
202 rtx op;
203 enum machine_mode mode;
204{
205 if (register_operand (op, mode))
206 return 1;
207 if (GET_CODE (op) == CONST_INT)
208 return SMALL_INT (op);
209 if (GET_MODE (op) != mode)
210 return 0;
211 if (GET_CODE (op) == SUBREG)
212 op = SUBREG_REG (op);
213 if (GET_CODE (op) != MEM)
214 return 0;
215
216 op = XEXP (op, 0);
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);
221}
222
223int
224move_operand (op, mode)
225 rtx op;
226 enum machine_mode mode;
227{
228 if (mode == DImode && arith_double_operand (op, mode))
229 return 1;
230 if (register_operand (op, mode))
231 return 1;
232 if (GET_CODE (op) == CONST_INT)
233 return (SMALL_INT (op) || (INTVAL (op) & 0x3ff) == 0);
234
235 if (GET_MODE (op) != mode)
236 return 0;
237 if (GET_CODE (op) == SUBREG)
238 op = SUBREG_REG (op);
239 if (GET_CODE (op) != MEM)
240 return 0;
241 op = XEXP (op, 0);
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);
246}
247
248int
249move_pic_label (op, mode)
250 rtx op;
251 enum machine_mode mode;
252{
253 /* Special case for PIC. */
254 if (flag_pic && GET_CODE (op) == LABEL_REF)
255 return 1;
256 return 0;
257}
258\f
259/* The rtx for the global offset table which is a special form
260 that *is* a position independent symbolic constant. */
261rtx pic_pc_rtx;
262
263/* Ensure that we are not using patterns that are not OK with PIC. */
264
265int
266check_pic (i)
267 int i;
268{
269 switch (flag_pic)
270 {
271 case 1:
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])))
275 abort ();
276 case 2:
277 default:
278 return 1;
279 }
280}
281
282/* Return true if X is an address which needs a temporary register when
283 reloaded while generating PIC code. */
284
285int
286pic_address_needs_scratch (x)
287 rtx x;
288{
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)))
294 return 1;
295
296 return 0;
297}
298
299int
300memop (op, mode)
301 rtx op;
302 enum machine_mode mode;
303{
304 if (GET_CODE (op) == MEM)
305 return (mode == VOIDmode || mode == GET_MODE (op));
306 return 0;
307}
308
309/* Return truth value of whether OP is EQ or NE. */
310
311int
312eq_or_neq (op, mode)
313 rtx op;
314 enum machine_mode mode;
315{
316 return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
317}
318
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. */
321
322int
323normal_comp_operator (op, mode)
324 rtx op;
325 enum machine_mode mode;
326{
327 enum rtx_code code = GET_CODE (op);
328
329 if (GET_RTX_CLASS (code) != '<')
330 return 0;
331
332 if (GET_MODE (XEXP (op, 0)) == CCFPmode)
333 return 1;
334
335 return (code != NE && code != EQ && code != GEU && code != LTU);
336}
337
338/* Return 1 if this is a comparison operator. This allows the use of
339 MATCH_OPERATOR to recognize all the branch insns. */
340
341int
342noov_compare_op (op, mode)
343 register rtx op;
344 enum machine_mode mode;
345{
346 enum rtx_code code = GET_CODE (op);
347
348 if (GET_RTX_CLASS (code) != '<')
349 return 0;
350
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);
354 return 1;
355}
356
357/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
358
359int
360extend_op (op, mode)
361 rtx op;
362 enum machine_mode mode;
363{
364 return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
365}
366
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. */
370
371int
372cc_arithop (op, mode)
373 rtx op;
374 enum machine_mode mode;
375{
376 if (GET_CODE (op) == AND
377 || GET_CODE (op) == IOR
378 || GET_CODE (op) == XOR)
379 return 1;
380
381 return 0;
382}
383
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. */
386
387int
388cc_arithopn (op, mode)
389 rtx op;
390 enum machine_mode mode;
391{
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);
396}
397\f
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. */
400
401int
402arith_operand (op, mode)
403 rtx op;
404 enum machine_mode mode;
405{
406 return (register_operand (op, mode)
407 || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
408}
409
ab835497
RK
410/* Return truth value of whether OP is a register or a CONST_DOUBLE. */
411
412int
413arith_double_operand (op, mode)
414 rtx op;
415 enum machine_mode mode;
416{
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));
428}
429
430/* Return truth value of whether OP is a integer which fits the
431 range constraining immediate operands in three-address insns. */
432
433int
434small_int (op, mode)
435 rtx op;
436 enum machine_mode mode;
437{
438 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
439}
440
441/* Return truth value of statement that OP is a call-clobbered register. */
442int
443clobbered_register (op, mode)
444 rtx op;
445 enum machine_mode mode;
446{
447 return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]);
448}
449\f
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. */
452
453rtx
454gen_compare_reg (code, x, y)
455 enum rtx_code code;
456 rtx x, y;
457{
458 enum machine_mode mode = SELECT_CC_MODE (code, x);
459 rtx cc_reg = gen_rtx (REG, mode, 0);
460
461 emit_insn (gen_rtx (SET, VOIDmode, cc_reg,
462 gen_rtx (COMPARE, mode, x, y)));
463
464 return cc_reg;
465}
466\f
467/* Return nonzero if a return peephole merging return with
468 setting of output register is ok. */
469int
470leaf_return_peephole_ok ()
471{
472 return (actual_fsize == 0);
473}
474
475/* Return nonzero if TRIAL can go into the function epilogue's
476 delay slot. SLOT is the slot we are trying to fill. */
477
478int
479eligible_for_epilogue_delay (trial, slot)
480 rtx trial;
481 int slot;
482{
483 static char *this_function_name;
484 rtx pat, src;
485
486 if (slot >= 1)
487 return 0;
488 if (GET_CODE (trial) != INSN
489 || GET_CODE (PATTERN (trial)) != SET)
490 return 0;
491 if (get_attr_length (trial) != 1)
492 return 0;
493
915f619f
JW
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. */
ab835497
RK
497 if (leaf_function)
498 {
499 if (leaf_return_peephole_ok ())
500 return (get_attr_in_branch_delay (trial) == IN_BRANCH_DELAY_TRUE);
501 return 0;
502 }
503
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
915f619f
JW
509 || REGNO (SET_DEST (pat)) >= 32
510 || REGNO (SET_DEST (pat)) < 24)
ab835497 511 return 0;
915f619f 512
ab835497
RK
513 src = SET_SRC (pat);
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)
519 {
520 if (register_operand (XEXP (src, 0), SImode)
521 && arith_operand (XEXP (src, 1), SImode))
522 return 1;
523 if (register_operand (XEXP (src, 1), SImode)
524 && arith_operand (XEXP (src, 0), SImode))
525 return 1;
526 if (register_operand (XEXP (src, 0), DImode)
527 && arith_double_operand (XEXP (src, 1), DImode))
528 return 1;
529 if (register_operand (XEXP (src, 1), DImode)
530 && arith_double_operand (XEXP (src, 0), DImode))
531 return 1;
532 }
533 if (GET_CODE (src) == MINUS
534 && register_operand (XEXP (src, 0), SImode)
535 && small_int (XEXP (src, 1), VOIDmode))
536 return 1;
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))
541 return 1;
542 return 0;
543}
544
545int
546short_branch (uid1, uid2)
547 int uid1, uid2;
548{
549 unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2];
550 if (delta + 1024 < 2048)
551 return 1;
552 /* warning ("long branch, distance %d", delta); */
553 return 0;
554}
555
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. */
559int
560reg_unused_after (reg, insn)
561 rtx reg;
562 rtx insn;
563{
564 enum rtx_code code, prev_code = UNKNOWN;
565
566 while (insn = NEXT_INSN (insn))
567 {
568 if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)])
569 return 1;
570
571 code = GET_CODE (insn);
572 if (GET_CODE (insn) == CODE_LABEL)
573 return 1;
574
575 if (GET_RTX_CLASS (code) == 'i')
576 {
577 rtx set = single_set (insn);
578 int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set));
579 if (set && in_src)
580 return 0;
581 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
582 return 1;
583 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
584 return 0;
585 }
586 prev_code = code;
587 }
588 return 1;
589}
590\f
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. */
597
598rtx
599legitimize_pic_address (orig, mode, reg, scratch)
600 rtx orig;
601 enum machine_mode mode;
602 rtx reg, scratch;
603{
604 if (GET_CODE (orig) == SYMBOL_REF)
605 {
606 rtx pic_ref, address;
607 rtx insn;
608
609 if (reg == 0)
610 {
01c0e9dc 611 if (reload_in_progress || reload_completed)
ab835497
RK
612 abort ();
613 else
614 reg = gen_reg_rtx (Pmode);
615 }
616
617 if (flag_pic == 2)
618 {
619 /* If not during reload, allocate another temp reg here for loading
620 in the address, so that these instructions can be optimized
621 properly. */
01c0e9dc
JW
622 rtx temp_reg = ((reload_in_progress || reload_completed)
623 ? reg : gen_reg_rtx (Pmode));
ab835497 624
b4ac57ab
RS
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. */
ab835497 629 emit_insn (gen_rtx (SET, VOIDmode, temp_reg,
b4ac57ab
RS
630 gen_rtx (HIGH, Pmode,
631 gen_rtx (UNSPEC, Pmode,
632 gen_rtvec (1, orig),
633 0))));
ab835497 634 emit_insn (gen_rtx (SET, VOIDmode, temp_reg,
b4ac57ab
RS
635 gen_rtx (LO_SUM, Pmode, temp_reg,
636 gen_rtx (UNSPEC, Pmode,
637 gen_rtvec (1, orig),
638 0))));
ab835497
RK
639 address = temp_reg;
640 }
641 else
642 address = orig;
643
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
651 by loop. */
652 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig,
653 REG_NOTES (insn));
654 return reg;
655 }
656 else if (GET_CODE (orig) == CONST)
657 {
658 rtx base, offset;
659
660 if (GET_CODE (XEXP (orig, 0)) == PLUS
661 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
662 return orig;
663
664 if (reg == 0)
665 {
01c0e9dc 666 if (reload_in_progress || reload_completed)
ab835497
RK
667 abort ();
668 else
669 reg = gen_reg_rtx (Pmode);
670 }
671
672 if (GET_CODE (XEXP (orig, 0)) == PLUS)
673 {
674 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode,
675 reg, 0);
676 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
677 base == reg ? 0 : reg, 0);
678 }
679 else
680 abort ();
681
682 if (GET_CODE (offset) == CONST_INT)
683 {
684 if (SMALL_INT (offset))
685 return plus_constant_for_output (base, INTVAL (offset));
01c0e9dc 686 else if (! reload_in_progress && ! reload_completed)
ab835497
RK
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. */
690 else if (scratch)
691 {
692 emit_move_insn (scratch, offset);
693 offset = scratch;
694 }
695 else
696 /* If we reach here, then the SECONDARY_INPUT_RELOAD_CLASS
697 macro needs to be adjusted so that a scratch reg is provided
698 for this address. */
699 abort ();
700 }
701 return gen_rtx (PLUS, Pmode, base, offset);
702 }
703 else if (GET_CODE (orig) == LABEL_REF)
704 current_function_uses_pic_offset_table = 1;
705
706 return orig;
707}
708
709/* Set up PIC-specific rtl. This should not cause any insns
710 to be emitted. */
711
712void
713initialize_pic ()
714{
715}
716
717/* Emit special PIC prologues and epilogues. */
718
719void
720finalize_pic ()
721{
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. */
725 rtx l1, l2;
726 rtx seq;
727 int orig_flag_pic = flag_pic;
728
729 if (current_function_uses_pic_offset_table == 0)
730 return;
731
732 if (! flag_pic)
733 abort ();
734
735 flag_pic = 0;
736 l1 = gen_label_rtx ();
737 l2 = gen_label_rtx ();
738
739 start_sequence ();
740
741 emit_label (l1);
742 /* Note that we pun calls and jumps here! */
743 emit_jump_insn (gen_rtx (PARALLEL, VOIDmode,
744 gen_rtvec (2,
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)))));
747 emit_label (l2);
748
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,
754 global_offset_table,
755 gen_rtx (CONST, Pmode,
756 gen_rtx (MINUS, Pmode,
757 gen_rtx (LABEL_REF, VOIDmode, l1),
758 pc_rtx))));
759
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;
774
775 seq = gen_sequence ();
776 end_sequence ();
777 emit_insn_after (seq, get_insns ());
778
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));
782}
783\f
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.
786
787 We make REG+REG slightly more expensive because it might keep
788 a register live for longer than we might like.
789
790 PIC addresses are very expensive.
791
792 It is no coincidence that this has the same structure
793 as GO_IF_LEGITIMATE_ADDRESS. */
794int
795sparc_address_cost (X)
796 rtx X;
797{
798#if 0
799 /* Handled before calling here. */
800 if (GET_CODE (X) == REG)
801 { return 1; }
802#endif
803 if (GET_CODE (X) == PLUS)
804 {
805 if (GET_CODE (XEXP (X, 0)) == REG
806 && GET_CODE (XEXP (X, 1)) == REG)
807 return 2;
808 return 1;
809 }
810 else if (GET_CODE (X) == LO_SUM)
811 return 1;
812 else if (GET_CODE (X) == HIGH)
813 return 2;
814 return 4;
815}
816\f
817/* Emit insns to move operands[1] into operands[0].
818
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
821 normally.
822
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. */
825
826int
827emit_move_sequence (operands, mode, scratch_reg)
828 rtx *operands;
829 enum machine_mode mode;
830 rtx scratch_reg;
831{
832 register rtx operand0 = operands[0];
833 register rtx operand1 = operands[1];
834
835 /* Handle most common case first: storing into a register. */
836 if (register_operand (operand0, mode))
837 {
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)
845 {
846 /* Run this case quickly. */
847 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
848 return 1;
849 }
850 }
851 else if (GET_CODE (operand0) == MEM)
852 {
853 if (register_operand (operand1, mode) || operand1 == const0_rtx)
854 {
855 /* Run this case quickly. */
856 emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
857 return 1;
858 }
859 if (! reload_in_progress)
860 {
861 operands[0] = validize_mem (operand0);
862 operands[1] = operand1 = force_reg (mode, operand1);
863 }
864 }
865
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))
870 {
871 if (flag_pic && symbolic_operand (operand1, mode))
872 {
873 rtx temp_reg = reload_in_progress ? operand0 : 0;
874
875 operands[1] = legitimize_pic_address (operand1, mode, temp_reg,
876 scratch_reg);
877 }
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)
883 : 1))
884 {
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
889 never be set.
890
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));
900
901 emit_insn (gen_rtx (SET, VOIDmode, temp,
902 gen_rtx (HIGH, mode, operand1)));
903 operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
904 }
905 }
906
907 if (GET_CODE (operand1) == LABEL_REF && flag_pic)
908 {
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,
913 gen_rtvec (2,
914 gen_rtx (SET, VOIDmode, operand0,
915 operand1),
916 gen_rtx (SET, VOIDmode,
917 gen_rtx (REG, mode, 15),
918 pc_rtx))));
919 return 1;
920 }
921
922 /* Now have insn-emit do whatever it normally does. */
923 return 0;
924}
925\f
926/* Return the best assembler insn template
927 for moving operands[1] into operands[0] as a fullword. */
928
929char *
930singlemove_string (operands)
931 rtx *operands;
932{
933 if (GET_CODE (operands[0]) == MEM)
934 {
935 if (GET_CODE (operands[1]) != MEM)
936 return "st %r1,%0";
937 else
938 abort ();
939 }
940 if (GET_CODE (operands[1]) == MEM)
941 return "ld %1,%0";
942 if (GET_CODE (operands[1]) == CONST_INT
943 && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
944 {
945 int i = INTVAL (operands[1]);
946
915f619f 947 /* If all low order 10 bits are clear, then we only need a single
ab835497 948 sethi insn to load the constant. */
915f619f 949 if ((i & 0x000003FF) != 0)
ab835497
RK
950 return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
951 else
952 return "sethi %%hi(%a1),%0";
953 }
954 /* ??? Wrong if target is DImode? */
955 return "mov %1,%0";
956}
957\f
795068a4
JW
958/* Return non-zero if it is OK to assume that the given memory operand is
959 aligned at least to a 8-byte boundary. This should only be called
960 for memory accesses whose size is 8 bytes or larger. */
961
962static int
963mem_aligned_8 (mem)
964 register rtx mem;
965{
966 register rtx addr;
967 register rtx base;
968 register rtx offset;
969
970 if (GET_CODE (mem) != MEM)
971 abort (); /* It's gotta be a MEM! */
972
973 addr = XEXP (mem, 0);
974
975#if 1
976 /* Now that all misaligned double parms are copied on function entry,
977 we can assume any 64-bit object is 64-bit aligned. */
978
979 /* See what register we use in the address. */
980 base = 0;
981 if (GET_CODE (addr) == PLUS)
982 {
983 if (GET_CODE (XEXP (addr, 0)) == REG
984 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
985 {
986 base = XEXP (addr, 0);
987 offset = XEXP (addr, 1);
988 }
989 }
990 else if (GET_CODE (addr) == REG)
991 {
992 base = addr;
993 offset = const0_rtx;
994 }
995
996 /* If it's the stack or frame pointer, check offset alignment.
997 We can have improper aligment in the function entry code. */
998 if (base
999 && (REGNO (base) == FRAME_POINTER_REGNUM
1000 || REGNO (base) == STACK_POINTER_REGNUM))
1001 {
1002 if ((INTVAL (offset) & 0x7) == 0)
1003 return 1;
1004 }
1005 else
1006 /* Anything else, we know is properly aligned. */
1007 return 1;
1008#else
1009 /* If the operand is known to have been allocated in static storage, then
1010 it must be aligned. */
1011
1012 if (CONSTANT_P (addr) || GET_CODE (addr) == LO_SUM)
1013 return 1;
1014
1015 base = 0;
1016 if (GET_CODE (addr) == PLUS)
1017 {
1018 if (GET_CODE (XEXP (addr, 0)) == REG
1019 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
1020 {
1021 base = XEXP (addr, 0);
1022 offset = XEXP (addr, 1);
1023 }
1024 }
1025 else if (GET_CODE (addr) == REG)
1026 {
1027 base = addr;
1028 offset = const0_rtx;
1029 }
1030
1031 /* Trust round enough offsets from the stack or frame pointer.
1032 If TARGET_HOPE_ALIGN, trust round enough offset from any register.
1033 If it is obviously unaligned, don't ever return true. */
1034 if (base
1035 && (REGNO (base) == FRAME_POINTER_REGNUM
1036 || REGNO (base) == STACK_POINTER_REGNUM
1037 || TARGET_HOPE_ALIGN))
1038 {
1039 if ((INTVAL (offset) & 0x7) == 0)
1040 return 1;
1041 }
1042 /* Otherwise, we can assume that an access is aligned if it is to an
1043 aggregate. Also, if TARGET_HOPE_ALIGN, then assume everything that isn't
1044 obviously unaligned is aligned. */
1045 else if (MEM_IN_STRUCT_P (mem) || TARGET_HOPE_ALIGN)
1046 return 1;
1047#endif
1048
1049 /* An obviously unaligned address. */
1050 return 0;
1051}
1052
1053enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP };
1054
ab835497 1055/* Output assembler code to perform a doubleword move insn
795068a4
JW
1056 with operands OPERANDS. This is very similar to the following
1057 output_move_quad function. */
ab835497
RK
1058
1059char *
1060output_move_double (operands)
1061 rtx *operands;
1062{
795068a4
JW
1063 register rtx op0 = operands[0];
1064 register rtx op1 = operands[1];
1065 register enum optype optype0;
1066 register enum optype optype1;
ab835497 1067 rtx latehalf[2];
795068a4
JW
1068 rtx addreg0 = 0;
1069 rtx addreg1 = 0;
ab835497
RK
1070
1071 /* First classify both operands. */
1072
795068a4 1073 if (REG_P (op0))
ab835497 1074 optype0 = REGOP;
795068a4 1075 else if (offsettable_memref_p (op0))
ab835497 1076 optype0 = OFFSOP;
795068a4 1077 else if (GET_CODE (op0) == MEM)
ab835497
RK
1078 optype0 = MEMOP;
1079 else
1080 optype0 = RNDOP;
1081
795068a4 1082 if (REG_P (op1))
ab835497 1083 optype1 = REGOP;
795068a4 1084 else if (CONSTANT_P (op1))
ab835497 1085 optype1 = CNSTOP;
795068a4 1086 else if (offsettable_memref_p (op1))
ab835497 1087 optype1 = OFFSOP;
795068a4 1088 else if (GET_CODE (op1) == MEM)
ab835497
RK
1089 optype1 = MEMOP;
1090 else
1091 optype1 = RNDOP;
1092
1093 /* Check for the cases that the operand constraints are not
1094 supposed to allow to happen. Abort if we get one,
1095 because generating code for these cases is painful. */
1096
795068a4
JW
1097 if (optype0 == RNDOP || optype1 == RNDOP
1098 || (optype0 == MEM && optype1 == MEM))
ab835497
RK
1099 abort ();
1100
1101 /* If an operand is an unoffsettable memory ref, find a register
1102 we can increment temporarily to make it refer to the second word. */
1103
1104 if (optype0 == MEMOP)
795068a4 1105 addreg0 = find_addr_reg (XEXP (op0, 0));
ab835497
RK
1106
1107 if (optype1 == MEMOP)
795068a4 1108 addreg1 = find_addr_reg (XEXP (op1, 0));
ab835497
RK
1109
1110 /* Ok, we can do one word at a time.
795068a4 1111 Set up in LATEHALF the operands to use for the
ab835497
RK
1112 high-numbered (least significant) word and in some cases alter the
1113 operands in OPERANDS to be suitable for the low-numbered word. */
1114
1115 if (optype0 == REGOP)
795068a4 1116 latehalf[0] = gen_rtx (REG, SImode, REGNO (op0) + 1);
ab835497 1117 else if (optype0 == OFFSOP)
795068a4 1118 latehalf[0] = adj_offsettable_operand (op0, 4);
ab835497 1119 else
795068a4 1120 latehalf[0] = op0;
ab835497
RK
1121
1122 if (optype1 == REGOP)
795068a4 1123 latehalf[1] = gen_rtx (REG, SImode, REGNO (op1) + 1);
ab835497 1124 else if (optype1 == OFFSOP)
795068a4 1125 latehalf[1] = adj_offsettable_operand (op1, 4);
ab835497 1126 else if (optype1 == CNSTOP)
795068a4 1127 split_double (op1, &operands[1], &latehalf[1]);
ab835497 1128 else
795068a4 1129 latehalf[1] = op1;
ab835497 1130
795068a4
JW
1131 /* Easy case: try moving both words at once. Check for moving between
1132 an even/odd register pair and a memory location. */
ab835497 1133 if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP
795068a4 1134 && (REGNO (op0) & 1) == 0)
ab835497 1135 || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP
795068a4 1136 && (REGNO (op1) & 1) == 0))
ab835497 1137 {
795068a4 1138 register rtx mem;
bc961ed7
RS
1139
1140 if (optype0 == REGOP)
795068a4 1141 mem = op1;
bc961ed7 1142 else
795068a4 1143 mem = op0;
bc961ed7 1144
795068a4
JW
1145 if (mem_aligned_8 (mem))
1146 return (mem == op1 ? "ldd %1,%0" : "std %1,%0");
ab835497
RK
1147 }
1148
795068a4
JW
1149 /* If the first move would clobber the source of the second one,
1150 do them in the other order. */
1151
1152 /* Overlapping registers. */
ab835497 1153 if (optype0 == REGOP && optype1 == REGOP
795068a4 1154 && REGNO (op0) == REGNO (latehalf[1]))
ab835497 1155 {
ab835497
RK
1156 /* Do that word. */
1157 output_asm_insn (singlemove_string (latehalf), latehalf);
ab835497
RK
1158 /* Do low-numbered word. */
1159 return singlemove_string (operands);
1160 }
795068a4 1161 /* Loading into a register which overlaps a register used in the address. */
ab835497 1162 else if (optype0 == REGOP && optype1 != REGOP
795068a4 1163 && reg_overlap_mentioned_p (op0, op1))
ab835497 1164 {
795068a4
JW
1165 /* ??? This fails if the address is a double register address, each
1166 of which is clobbered by operand 0. */
ab835497
RK
1167 /* Do the late half first. */
1168 output_asm_insn (singlemove_string (latehalf), latehalf);
1169 /* Then clobber. */
1170 return singlemove_string (operands);
1171 }
1172
1173 /* Normal case: do the two words, low-numbered first. */
1174
1175 output_asm_insn (singlemove_string (operands), operands);
1176
1177 /* Make any unoffsettable addresses point at high-numbered word. */
1178 if (addreg0)
1179 output_asm_insn ("add %0,0x4,%0", &addreg0);
1180 if (addreg1)
1181 output_asm_insn ("add %0,0x4,%0", &addreg1);
1182
1183 /* Do that word. */
1184 output_asm_insn (singlemove_string (latehalf), latehalf);
1185
1186 /* Undo the adds we just did. */
1187 if (addreg0)
1188 output_asm_insn ("add %0,-0x4,%0", &addreg0);
1189 if (addreg1)
1190 output_asm_insn ("add %0,-0x4,%0", &addreg1);
1191
1192 return "";
1193}
795068a4
JW
1194
1195/* Output assembler code to perform a quadword move insn
1196 with operands OPERANDS. This is very similar to the preceeding
1197 output_move_double function. */
1198
1199char *
1200output_move_quad (operands)
1201 rtx *operands;
1202{
1203 register rtx op0 = operands[0];
1204 register rtx op1 = operands[1];
1205 register enum optype optype0;
1206 register enum optype optype1;
1207 rtx wordpart[4][2];
1208 rtx addreg0 = 0;
1209 rtx addreg1 = 0;
1210
1211 /* First classify both operands. */
1212
1213 if (REG_P (op0))
1214 optype0 = REGOP;
1215 else if (offsettable_memref_p (op0))
1216 optype0 = OFFSOP;
1217 else if (GET_CODE (op0) == MEM)
1218 optype0 = MEMOP;
1219 else
1220 optype0 = RNDOP;
1221
1222 if (REG_P (op1))
1223 optype1 = REGOP;
1224 else if (CONSTANT_P (op1))
1225 optype1 = CNSTOP;
1226 else if (offsettable_memref_p (op1))
1227 optype1 = OFFSOP;
1228 else if (GET_CODE (op1) == MEM)
1229 optype1 = MEMOP;
1230 else
1231 optype1 = RNDOP;
1232
1233 /* Check for the cases that the operand constraints are not
1234 supposed to allow to happen. Abort if we get one,
1235 because generating code for these cases is painful. */
1236
1237 if (optype0 == RNDOP || optype1 == RNDOP
1238 || (optype0 == MEM && optype1 == MEM))
1239 abort ();
1240
1241 /* If an operand is an unoffsettable memory ref, find a register
1242 we can increment temporarily to make it refer to the later words. */
1243
1244 if (optype0 == MEMOP)
1245 addreg0 = find_addr_reg (XEXP (op0, 0));
1246
1247 if (optype1 == MEMOP)
1248 addreg1 = find_addr_reg (XEXP (op1, 0));
1249
1250 /* Ok, we can do one word at a time.
1251 Set up in wordpart the operands to use for each word of the arguments. */
1252
1253 if (optype0 == REGOP)
1254 {
1255 wordpart[0][0] = gen_rtx (REG, SImode, REGNO (op0) + 0);
1256 wordpart[1][0] = gen_rtx (REG, SImode, REGNO (op0) + 1);
1257 wordpart[2][0] = gen_rtx (REG, SImode, REGNO (op0) + 2);
1258 wordpart[3][0] = gen_rtx (REG, SImode, REGNO (op0) + 3);
1259 }
1260 else if (optype0 == OFFSOP)
1261 {
1262 wordpart[0][0] = adj_offsettable_operand (op0, 0);
1263 wordpart[1][0] = adj_offsettable_operand (op0, 4);
1264 wordpart[2][0] = adj_offsettable_operand (op0, 8);
1265 wordpart[3][0] = adj_offsettable_operand (op0, 12);
1266 }
1267 else
1268 {
1269 wordpart[0][0] = op0;
1270 wordpart[1][0] = op0;
1271 wordpart[2][0] = op0;
1272 wordpart[3][0] = op0;
1273 }
1274
1275 if (optype1 == REGOP)
1276 {
1277 wordpart[0][1] = gen_rtx (REG, SImode, REGNO (op1) + 0);
1278 wordpart[1][1] = gen_rtx (REG, SImode, REGNO (op1) + 1);
1279 wordpart[2][1] = gen_rtx (REG, SImode, REGNO (op1) + 2);
1280 wordpart[3][1] = gen_rtx (REG, SImode, REGNO (op1) + 3);
1281 }
1282 else if (optype1 == OFFSOP)
1283 {
1284 wordpart[0][1] = adj_offsettable_operand (op1, 0);
1285 wordpart[1][1] = adj_offsettable_operand (op1, 4);
1286 wordpart[2][1] = adj_offsettable_operand (op1, 8);
1287 wordpart[3][1] = adj_offsettable_operand (op1, 12);
1288 }
1289 else if (optype1 == CNSTOP)
1290 {
1291 /* This case isn't implemented yet, because there is no internal
1292 representation for quad-word constants, and there is no split_quad
1293 function. */
1294#if 0
1295 split_quad (op1, &wordpart[0][1], &wordpart[1][1],
1296 &wordpart[2][1], &wordpart[3][1]);
1297#else
1298 abort ();
1299#endif
1300 }
1301 else
1302 {
1303 wordpart[0][1] = op1;
1304 wordpart[1][1] = op1;
1305 wordpart[2][1] = op1;
1306 wordpart[3][1] = op1;
1307 }
1308
1309 /* Easy case: try moving the quad as two pairs. Check for moving between
1310 an even/odd register pair and a memory location. */
1311 /* ??? Should also handle the case of non-offsettable addresses here.
1312 We can at least do the first pair as a ldd/std, and then do the third
1313 and fourth words individually. */
1314 if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0)
1315 || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0))
1316 {
1317 rtx mem;
1318
1319 if (optype0 == REGOP)
1320 mem = op1;
1321 else
1322 mem = op0;
1323
1324 if (mem_aligned_8 (mem))
1325 {
1326 operands[2] = adj_offsettable_operand (mem, 8);
1327 if (mem == op1)
1328 return "ldd %1,%0;ldd %2,%S0";
1329 else
1330 return "std %1,%0;std %S1,%2";
1331 }
1332 }
1333
1334 /* If the first move would clobber the source of the second one,
1335 do them in the other order. */
1336
1337 /* Overlapping registers. */
1338 if (optype0 == REGOP && optype1 == REGOP
1339 && (REGNO (op0) == REGNO (wordpart[1][3])
1340 || REGNO (op0) == REGNO (wordpart[1][2])
1341 || REGNO (op0) == REGNO (wordpart[1][1])))
1342 {
1343 /* Do fourth word. */
1344 output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]);
1345 /* Do the third word. */
1346 output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]);
1347 /* Do the second word. */
1348 output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]);
1349 /* Do lowest-numbered word. */
1350 return singlemove_string (wordpart[0]);
1351 }
1352 /* Loading into a register which overlaps a register used in the address. */
1353 if (optype0 == REGOP && optype1 != REGOP
1354 && reg_overlap_mentioned_p (op0, op1))
1355 {
1356 /* ??? Not implemented yet. This is a bit complicated, because we
1357 must load which ever part overlaps the address last. If the address
1358 is a double-reg address, then there are two parts which need to
1359 be done last, which is impossible. We would need a scratch register
1360 in that case. */
1361 abort ();
1362 }
1363
1364 /* Normal case: move the four words in lowest to higest address order. */
1365
1366 output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]);
1367
1368 /* Make any unoffsettable addresses point at the second word. */
1369 if (addreg0)
1370 output_asm_insn ("add %0,0x4,%0", &addreg0);
1371 if (addreg1)
1372 output_asm_insn ("add %0,0x4,%0", &addreg1);
1373
1374 /* Do the second word. */
1375 output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]);
1376
1377 /* Make any unoffsettable addresses point at the third word. */
1378 if (addreg0)
1379 output_asm_insn ("add %0,0x4,%0", &addreg0);
1380 if (addreg1)
1381 output_asm_insn ("add %0,0x4,%0", &addreg1);
1382
1383 /* Do the third word. */
1384 output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]);
1385
1386 /* Make any unoffsettable addresses point at the fourth word. */
1387 if (addreg0)
1388 output_asm_insn ("add %0,0x4,%0", &addreg0);
1389 if (addreg1)
1390 output_asm_insn ("add %0,0x4,%0", &addreg1);
1391
1392 /* Do the fourth word. */
1393 output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]);
1394
1395 /* Undo the adds we just did. */
1396 if (addreg0)
1397 output_asm_insn ("add %0,-0xc,%0", &addreg0);
1398 if (addreg1)
1399 output_asm_insn ("add %0,-0xc,%0", &addreg1);
1400
1401 return "";
1402}
ab835497 1403\f
795068a4 1404/* Output assembler code to perform a doubleword move insn with operands
a3ee5899
JW
1405 OPERANDS, one of which must be a floating point register. */
1406
ab835497
RK
1407char *
1408output_fp_move_double (operands)
1409 rtx *operands;
1410{
1411 rtx addr;
1412
1413 if (FP_REG_P (operands[0]))
1414 {
1415 if (FP_REG_P (operands[1]))
1416 return "fmovs %1,%0\n\tfmovs %R1,%R0";
a3ee5899 1417 else if (GET_CODE (operands[1]) == REG)
ab835497
RK
1418 {
1419 if ((REGNO (operands[1]) & 1) == 0)
1420 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1421 else
1422 return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0";
1423 }
a3ee5899
JW
1424 else
1425 return output_move_double (operands);
ab835497
RK
1426 }
1427 else if (FP_REG_P (operands[1]))
1428 {
1429 if (GET_CODE (operands[0]) == REG)
1430 {
1431 if ((REGNO (operands[0]) & 1) == 0)
1432 return "std %1,[%@-8]\n\tldd [%@-8],%0";
1433 else
1434 return "std %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
1435 }
a3ee5899
JW
1436 else
1437 return output_move_double (operands);
ab835497
RK
1438 }
1439 else abort ();
1440}
795068a4
JW
1441
1442/* Output assembler code to perform a quadword move insn with operands
1443 OPERANDS, one of which must be a floating point register. */
1444
1445char *
1446output_fp_move_quad (operands)
1447 rtx *operands;
1448{
1449 register rtx op0 = operands[0];
1450 register rtx op1 = operands[1];
1451 register rtx addr;
1452
1453 if (FP_REG_P (op0))
1454 {
1455 if (FP_REG_P (op1))
1456 return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0";
1457 if (GET_CODE (op1) == REG)
1458 {
1459 if ((REGNO (op1) & 1) == 0)
1460 return "std %1,[%@-8]\n\tldd [%@-8],%0\n\tstd %S1,[%@-8]\n\tldd [%@-8],%S0";
1461 else
1462 return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0\n\tst %T1,[%@-4]\n\tst %S1,[%@-8]\n\tldd [%@-8],%S0";
1463 }
1464 else
1465 return output_move_quad (operands);
1466 }
1467 else if (FP_REG_P (op1))
1468 {
1469 if (GET_CODE (op0) == REG)
1470 {
1471 if ((REGNO (op0) & 1) == 0)
1472 return "std %1,[%@-8]\n\tldd [%@-8],%0\n\tstd %S1,[%@-8]\n\tldd [%@-8],%S0";
1473 else
1474 return "std %S1,[%@-8]\n\tld [%@-4],%T0\n\tld [%@-8],%S0\n\tstd %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
1475 }
1476 else
1477 return output_move_quad (operands);
1478 }
1479 else
1480 abort ();
1481}
ab835497
RK
1482\f
1483/* Return a REG that occurs in ADDR with coefficient 1.
1484 ADDR can be effectively incremented by incrementing REG. */
1485
1486static rtx
1487find_addr_reg (addr)
1488 rtx addr;
1489{
1490 while (GET_CODE (addr) == PLUS)
1491 {
1492 /* We absolutely can not fudge the frame pointer here, because the
1493 frame pointer must always be 8 byte aligned. It also confuses
1494 debuggers. */
1495 if (GET_CODE (XEXP (addr, 0)) == REG
1496 && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM)
1497 addr = XEXP (addr, 0);
1498 else if (GET_CODE (XEXP (addr, 1)) == REG
1499 && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM)
1500 addr = XEXP (addr, 1);
1501 else if (CONSTANT_P (XEXP (addr, 0)))
1502 addr = XEXP (addr, 1);
1503 else if (CONSTANT_P (XEXP (addr, 1)))
1504 addr = XEXP (addr, 0);
1505 else
1506 abort ();
1507 }
1508 if (GET_CODE (addr) == REG)
1509 return addr;
1510 abort ();
1511}
1512
1513void
1514output_sized_memop (opname, mode, signedp)
1515 char *opname;
1516 enum machine_mode mode;
1517 int signedp;
1518{
1519 static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" };
1520 static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" };
1521 static char *st_size_suffix[] = { "b", "h", "", "?", "d" };
1522 char **opnametab, *modename;
1523
1524 if (opname[0] == 'l')
1525 if (signedp)
1526 opnametab = ld_size_suffix_s;
1527 else
1528 opnametab = ld_size_suffix_u;
1529 else
1530 opnametab = st_size_suffix;
1531 modename = opnametab[GET_MODE_SIZE (mode) >> 1];
1532
1533 fprintf (asm_out_file, "\t%s%s", opname, modename);
1534}
1535\f
1536void
1537output_move_with_extension (operands)
1538 rtx *operands;
1539{
1540 if (GET_MODE (operands[2]) == HImode)
1541 output_asm_insn ("sll %2,0x10,%0", operands);
1542 else if (GET_MODE (operands[2]) == QImode)
1543 output_asm_insn ("sll %2,0x18,%0", operands);
1544 else
1545 abort ();
1546}
1547\f
1548/* Load the address specified by OPERANDS[3] into the register
1549 specified by OPERANDS[0].
1550
1551 OPERANDS[3] may be the result of a sum, hence it could either be:
1552
1553 (1) CONST
1554 (2) REG
1555 (2) REG + CONST_INT
1556 (3) REG + REG + CONST_INT
1557 (4) REG + REG (special case of 3).
1558
1559 Note that (3) is not a legitimate address.
1560 All cases are handled here. */
1561
1562void
1563output_load_address (operands)
1564 rtx *operands;
1565{
1566 rtx base, offset;
1567
1568 if (CONSTANT_P (operands[3]))
1569 {
1570 output_asm_insn ("set %3,%0", operands);
1571 return;
1572 }
1573
1574 if (REG_P (operands[3]))
1575 {
1576 if (REGNO (operands[0]) != REGNO (operands[3]))
1577 output_asm_insn ("mov %3,%0", operands);
1578 return;
1579 }
1580
1581 if (GET_CODE (operands[3]) != PLUS)
1582 abort ();
1583
1584 base = XEXP (operands[3], 0);
1585 offset = XEXP (operands[3], 1);
1586
1587 if (GET_CODE (base) == CONST_INT)
1588 {
1589 rtx tmp = base;
1590 base = offset;
1591 offset = tmp;
1592 }
1593
1594 if (GET_CODE (offset) != CONST_INT)
1595 {
1596 /* Operand is (PLUS (REG) (REG)). */
1597 base = operands[3];
1598 offset = const0_rtx;
1599 }
1600
1601 if (REG_P (base))
1602 {
1603 operands[6] = base;
1604 operands[7] = offset;
1605 if (SMALL_INT (offset))
1606 output_asm_insn ("add %6,%7,%0", operands);
1607 else
1608 output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands);
1609 }
1610 else if (GET_CODE (base) == PLUS)
1611 {
1612 operands[6] = XEXP (base, 0);
1613 operands[7] = XEXP (base, 1);
1614 operands[8] = offset;
1615
1616 if (SMALL_INT (offset))
1617 output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands);
1618 else
1619 output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands);
1620 }
1621 else
1622 abort ();
1623}
1624
1625/* Output code to place a size count SIZE in register REG.
1626 ALIGN is the size of the unit of transfer.
1627
1628 Because block moves are pipelined, we don't include the
1629 first element in the transfer of SIZE to REG. */
1630
1631static void
1632output_size_for_block_move (size, reg, align)
1633 rtx size, reg;
1634 rtx align;
1635{
1636 rtx xoperands[3];
1637
1638 xoperands[0] = reg;
1639 xoperands[1] = size;
1640 xoperands[2] = align;
1641 if (GET_CODE (size) == REG)
1642 output_asm_insn ("sub %1,%2,%0", xoperands);
1643 else
1644 {
1645 xoperands[1]
1646 = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
1647 output_asm_insn ("set %1,%0", xoperands);
1648 }
1649}
1650
1651/* Emit code to perform a block move.
1652
1653 OPERANDS[0] is the destination.
1654 OPERANDS[1] is the source.
1655 OPERANDS[2] is the size.
1656 OPERANDS[3] is the alignment safe to use.
1657 OPERANDS[4] is a register we can safely clobber as a temp. */
1658
1659char *
1660output_block_move (operands)
1661 rtx *operands;
1662{
1663 /* A vector for our computed operands. Note that load_output_address
1664 makes use of (and can clobber) up to the 8th element of this vector. */
1665 rtx xoperands[10];
1666 rtx zoperands[10];
1667 static int movstrsi_label = 0;
1668 int i;
1669 rtx temp1 = operands[4];
1670 rtx sizertx = operands[2];
1671 rtx alignrtx = operands[3];
1672 int align = INTVAL (alignrtx);
210aa14a 1673 char label3[30], label5[30];
ab835497
RK
1674
1675 xoperands[0] = operands[0];
1676 xoperands[1] = operands[1];
1677 xoperands[2] = temp1;
1678
391b99c9
RS
1679 /* We can't move more than this many bytes at a time because we have only
1680 one register, %g1, to move them through. */
1681 if (align > UNITS_PER_WORD)
ab835497 1682 {
391b99c9
RS
1683 align = UNITS_PER_WORD;
1684 alignrtx = gen_rtx (CONST_INT, VOIDmode, UNITS_PER_WORD);
ab835497
RK
1685 }
1686
391b99c9
RS
1687 /* We consider 8 ld/st pairs, for a total of 16 inline insns to be
1688 reasonable here. (Actually will emit a maximum of 18 inline insns for
1689 the case of size == 31 and align == 4). */
1690
1691 if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8
1692 && memory_address_p (QImode, plus_constant_for_output (xoperands[0],
1693 INTVAL (sizertx)))
1694 && memory_address_p (QImode, plus_constant_for_output (xoperands[1],
1695 INTVAL (sizertx))))
ab835497
RK
1696 {
1697 int size = INTVAL (sizertx);
391b99c9 1698 int offset = 0;
ab835497 1699
391b99c9
RS
1700 /* We will store different integers into this particular RTX. */
1701 xoperands[2] = rtx_alloc (CONST_INT);
1702 PUT_MODE (xoperands[2], VOIDmode);
ab835497 1703
391b99c9
RS
1704 /* This case is currently not handled. Abort instead of generating
1705 bad code. */
1706 if (align > 4)
1707 abort ();
ab835497 1708
391b99c9 1709 if (align >= 4)
ab835497 1710 {
391b99c9 1711 for (i = (size >> 2) - 1; i >= 0; i--)
ab835497 1712 {
391b99c9
RS
1713 INTVAL (xoperands[2]) = (i << 2) + offset;
1714 output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]",
1715 xoperands);
ab835497 1716 }
391b99c9
RS
1717 offset += (size & ~0x3);
1718 size = size & 0x3;
1719 if (size == 0)
1720 return "";
ab835497 1721 }
391b99c9
RS
1722
1723 if (align >= 2)
ab835497 1724 {
391b99c9 1725 for (i = (size >> 1) - 1; i >= 0; i--)
ab835497 1726 {
391b99c9
RS
1727 INTVAL (xoperands[2]) = (i << 1) + offset;
1728 output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]",
1729 xoperands);
ab835497 1730 }
391b99c9
RS
1731 offset += (size & ~0x1);
1732 size = size & 0x1;
1733 if (size == 0)
1734 return "";
ab835497 1735 }
391b99c9
RS
1736
1737 if (align >= 1)
ab835497 1738 {
391b99c9 1739 for (i = size - 1; i >= 0; i--)
ab835497 1740 {
391b99c9
RS
1741 INTVAL (xoperands[2]) = i + offset;
1742 output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]",
1743 xoperands);
ab835497 1744 }
391b99c9 1745 return "";
ab835497 1746 }
391b99c9
RS
1747
1748 /* We should never reach here. */
1749 abort ();
ab835497
RK
1750 }
1751
391b99c9
RS
1752 /* If the size isn't known to be a multiple of the alignment,
1753 we have to do it in smaller pieces. If we could determine that
1754 the size was a multiple of 2 (or whatever), we could be smarter
1755 about this. */
1756 if (GET_CODE (sizertx) != CONST_INT)
1757 align = 1;
1758 else
1759 {
1760 int size = INTVAL (sizertx);
1761 while (size % align)
1762 align >>= 1;
1763 }
1764
1765 if (align != INTVAL (alignrtx))
1766 alignrtx = gen_rtx (CONST_INT, VOIDmode, align);
1767
ab835497
RK
1768 xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1769 xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align);
1770 xoperands[5] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1771
210aa14a
RS
1772 ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3]));
1773 ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5]));
1774
391b99c9
RS
1775 /* This is the size of the transfer. Emit code to decrement the size
1776 value by ALIGN, and store the result in the temp1 register. */
ab835497
RK
1777 output_size_for_block_move (sizertx, temp1, alignrtx);
1778
1779 /* Must handle the case when the size is zero or negative, so the first thing
1780 we do is compare the size against zero, and only copy bytes if it is
1781 zero or greater. Note that we have already subtracted off the alignment
1782 once, so we must copy 1 alignment worth of bytes if the size is zero
1783 here.
1784
1785 The SUN assembler complains about labels in branch delay slots, so we
b4ac57ab 1786 do this before outputting the load address, so that there will always
ab835497
RK
1787 be a harmless insn between the branch here and the next label emitted
1788 below. */
1789
210aa14a
RS
1790 {
1791 char pattern[100];
1792
1793 sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]);
1794 output_asm_insn (pattern, xoperands);
1795 }
ab835497
RK
1796
1797 zoperands[0] = operands[0];
1798 zoperands[3] = plus_constant_for_output (operands[0], align);
1799 output_load_address (zoperands);
1800
1801 /* ??? This might be much faster if the loops below were preconditioned
1802 and unrolled.
1803
1804 That is, at run time, copy enough bytes one at a time to ensure that the
1805 target and source addresses are aligned to the the largest possible
1806 alignment. Then use a preconditioned unrolled loop to copy say 16
1807 bytes at a time. Then copy bytes one at a time until finish the rest. */
1808
1809 /* Output the first label separately, so that it is spaced properly. */
1810
ab835497 1811 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3]));
ab835497 1812
210aa14a
RS
1813 {
1814 char pattern[200];
1815 register char *ld_suffix = (align == 1) ? "ub" : (align == 2) ? "uh" : "";
1816 register char *st_suffix = (align == 1) ? "b" : (align == 2) ? "h" : "";
1817
1818 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]);
1819 output_asm_insn (pattern, xoperands);
1820 }
1821
ab835497 1822 return "";
ab835497
RK
1823}
1824\f
1825/* Output reasonable peephole for set-on-condition-code insns.
1826 Note that these insns assume a particular way of defining
1827 labels. Therefore, *both* sparc.h and this function must
1828 be changed if a new syntax is needed. */
1829
1830char *
1831output_scc_insn (operands, insn)
1832 rtx operands[];
1833 rtx insn;
1834{
1835 static char string[100];
1836 rtx label = 0, next = insn;
1837 int need_label = 0;
1838
1839 /* Try doing a jump optimization which jump.c can't do for us
1840 because we did not expose that setcc works by using branches.
1841
1842 If this scc insn is followed by an unconditional branch, then have
1843 the jump insn emitted here jump to that location, instead of to
1844 the end of the scc sequence as usual. */
1845
1846 do
1847 {
1848 if (GET_CODE (next) == CODE_LABEL)
1849 label = next;
1850 next = NEXT_INSN (next);
1851 if (next == 0)
1852 break;
1853 }
1854 while (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL);
1855
1856 /* If we are in a sequence, and the following insn is a sequence also,
1857 then just following the current insn's next field will take us to the
1858 first insn of the next sequence, which is the wrong place. We don't
1859 want to optimize with a branch that has had its delay slot filled.
1860 Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next
1861 which fails only if NEXT is such a branch. */
1862
1863 if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next)
1864 && (! final_sequence || NEXT_INSN (PREV_INSN (next)) == next))
1865 label = JUMP_LABEL (next);
1866 /* If not optimizing, jump label fields are not set. To be safe, always
1867 check here to whether label is still zero. */
1868 if (label == 0)
1869 {
1870 label = gen_label_rtx ();
1871 need_label = 1;
1872 }
1873
1874 LABEL_NUSES (label) += 1;
1875
1876 operands[2] = label;
1877
1878 /* If we are in a delay slot, assume it is the delay slot of an fpcc
1879 insn since our type isn't allowed anywhere else. */
1880
1881 /* ??? Fpcc instructions no longer have delay slots, so this code is
1882 probably obsolete. */
1883
1884 /* The fastest way to emit code for this is an annulled branch followed
1885 by two move insns. This will take two cycles if the branch is taken,
1886 and three cycles if the branch is not taken.
1887
1888 However, if we are in the delay slot of another branch, this won't work,
1889 because we can't put a branch in the delay slot of another branch.
1890 The above sequence would effectively take 3 or 4 cycles respectively
1891 since a no op would have be inserted between the two branches.
1892 In this case, we want to emit a move, annulled branch, and then the
1893 second move. This sequence always takes 3 cycles, and hence is faster
1894 when we are in a branch delay slot. */
1895
1896 if (final_sequence)
1897 {
1898 strcpy (string, "mov 0,%0\n\t");
1899 strcat (string, output_cbranch (operands[1], 2, 0, 1, 0));
1900 strcat (string, "\n\tmov 1,%0");
1901 }
1902 else
1903 {
1904 strcpy (string, output_cbranch (operands[1], 2, 0, 1, 0));
1905 strcat (string, "\n\tmov 1,%0\n\tmov 0,%0");
1906 }
1907
1908 if (need_label)
1909 strcat (string, "\n%l2:");
1910
1911 return string;
1912}
1913\f
1914/* Vectors to keep interesting information about registers where
1915 it can easily be got. */
1916
1917/* Modes for condition codes. */
1918#define C_MODES \
1919 ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) | (1 << (int) CCFPmode))
1920
1921/* Modes for single-word (and smaller) quantities. */
1922#define S_MODES \
1923 (~C_MODES \
1924 & ~ ((1 << (int) DImode) | (1 << (int) TImode) \
1925 | (1 << (int) DFmode) | (1 << (int) TFmode)))
1926
1927/* Modes for double-word (and smaller) quantities. */
1928#define D_MODES \
1929 (~C_MODES \
1930 & ~ ((1 << (int) TImode) | (1 << (int) TFmode)))
1931
1932/* Modes for quad-word quantities. */
1933#define T_MODES (~C_MODES)
1934
1935/* Modes for single-float quantities. */
1936#define SF_MODES ((1 << (int) SFmode))
1937
1938/* Modes for double-float quantities. */
1939#define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode))
1940
1941/* Modes for quad-float quantities. */
1942#define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode))
1943
1944/* Value is 1 if register/mode pair is acceptable on sparc.
1945 The funny mixture of D and T modes is because integer operations
1946 do not specially operate on tetra quantities, so non-quad-aligned
1947 registers can hold quadword quantities (except %o4 and %i4 because
1948 they cross fixed registers. */
1949
1950int hard_regno_mode_ok[] = {
1951 C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1952 T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
1953 T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES,
1954 T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES,
1955
1956 TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1957 TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1958 TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES,
1959 TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES};
1960\f
1961#ifdef __GNUC__
1962inline
1963#endif
1964static int
1965save_regs (file, low, high, base, offset, n_fregs)
1966 FILE *file;
1967 int low, high;
1968 char *base;
1969 int offset;
1970 int n_fregs;
1971{
1972 int i;
1973
1974 for (i = low; i < high; i += 2)
1975 {
1976 if (regs_ever_live[i] && ! call_used_regs[i])
1977 if (regs_ever_live[i+1] && ! call_used_regs[i+1])
1978 fprintf (file, "\tstd %s,[%s+%d]\n",
1979 reg_names[i], base, offset + 4 * n_fregs),
1980 n_fregs += 2;
1981 else
1982 fprintf (file, "\tst %s,[%s+%d]\n",
1983 reg_names[i], base, offset + 4 * n_fregs),
1984 n_fregs += 2;
1985 else if (regs_ever_live[i+1] && ! call_used_regs[i+1])
1986 fprintf (file, "\tst %s,[%s+%d]\n",
1987 reg_names[i+1], base, offset + 4 * n_fregs),
1988 n_fregs += 2;
1989 }
1990 return n_fregs;
1991}
1992
1993#ifdef __GNUC__
1994inline
1995#endif
1996static int
1997restore_regs (file, low, high, base, offset, n_fregs)
1998 FILE *file;
1999 int low, high;
2000 char *base;
2001 int offset;
2002{
2003 int i;
2004
2005 for (i = low; i < high; i += 2)
2006 {
2007 if (regs_ever_live[i] && ! call_used_regs[i])
2008 if (regs_ever_live[i+1] && ! call_used_regs[i+1])
2009 fprintf (file, "\tldd [%s+%d], %s\n",
2010 base, offset + 4 * n_fregs, reg_names[i]),
2011 n_fregs += 2;
2012 else
2013 fprintf (file, "\tld [%s+%d],%s\n",
2014 base, offset + 4 * n_fregs, reg_names[i]),
2015 n_fregs += 2;
2016 else if (regs_ever_live[i+1] && ! call_used_regs[i+1])
2017 fprintf (file, "\tld [%s+%d],%s\n",
2018 base, offset + 4 * n_fregs, reg_names[i+1]),
2019 n_fregs += 2;
2020 }
2021 return n_fregs;
2022}
2023
2024/* Static variables we want to share between prologue and epilogue. */
2025
2026/* Number of live floating point registers needed to be saved. */
2027static int num_fregs;
2028
2029/* Nonzero if any floating point register was ever used. */
2030static int fregs_ever_live;
2031
2032int
2033compute_frame_size (size, leaf_function)
2034 int size;
2035 int leaf_function;
2036{
2037 int fregs_ever_live = 0;
2038 int n_fregs = 0, i;
2039 int outgoing_args_size = (current_function_outgoing_args_size
2040 + REG_PARM_STACK_SPACE (current_function_decl));
2041
2042 apparent_fsize = ((size) + 7 - STARTING_FRAME_OFFSET) & -8;
2043 for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2)
2044 fregs_ever_live |= regs_ever_live[i]|regs_ever_live[i+1];
2045
2046 if (TARGET_EPILOGUE && fregs_ever_live)
2047 {
2048 for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2)
2049 if ((regs_ever_live[i] && ! call_used_regs[i])
2050 || (regs_ever_live[i+1] && ! call_used_regs[i+1]))
2051 n_fregs += 2;
2052 }
2053
2054 /* Set up values for use in `function_epilogue'. */
2055 num_fregs = n_fregs;
2056
2057 apparent_fsize += (outgoing_args_size+7) & -8;
2058 if (leaf_function && n_fregs == 0
2059 && apparent_fsize == (REG_PARM_STACK_SPACE (current_function_decl)
2060 - STARTING_FRAME_OFFSET))
2061 apparent_fsize = 0;
2062
2063 actual_fsize = apparent_fsize + n_fregs*4;
2064
2065 /* Make sure nothing can clobber our register windows.
2066 If a SAVE must be done, or there is a stack-local variable,
2067 the register window area must be allocated. */
2068 if (leaf_function == 0 || size > 0)
2069 actual_fsize += (16 * UNITS_PER_WORD)+8;
2070
2071 return actual_fsize;
2072}
2073
915f619f
JW
2074/* Output code for the function prologue. */
2075
ab835497
RK
2076void
2077output_function_prologue (file, size, leaf_function)
2078 FILE *file;
2079 int size;
915f619f 2080 int leaf_function;
ab835497
RK
2081{
2082 if (leaf_function)
2083 frame_base_name = "%sp+80";
2084 else
2085 frame_base_name = "%fp";
2086
915f619f
JW
2087 /* Need to use actual_fsize, since we are also allocating
2088 space for our callee (and our own register save area). */
ab835497
RK
2089 actual_fsize = compute_frame_size (size, leaf_function);
2090
2091 fprintf (file, "\t!#PROLOGUE# 0\n");
915f619f
JW
2092 if (actual_fsize == 0)
2093 /* do nothing. */ ;
2094 else if (actual_fsize <= 4096)
ab835497
RK
2095 {
2096 if (! leaf_function)
2097 fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize);
2098 else
2099 fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize);
2100 }
915f619f 2101 else if (actual_fsize <= 8192)
ab835497 2102 {
915f619f
JW
2103 /* For frames in the range 4097..8192, we can use just two insns. */
2104 if (! leaf_function)
2105 {
2106 fprintf (file, "\tsave %%sp,-4096,%%sp\n");
2107 fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
2108 }
2109 else
2110 {
2111 fprintf (file, "\tadd %%sp,-4096,%%sp\n");
2112 fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
2113 }
ab835497
RK
2114 }
2115 else
2116 {
915f619f
JW
2117 if (! leaf_function)
2118 {
2119 fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
2120 if ((actual_fsize & 0x3ff) != 0)
2121 fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
2122 fprintf (file, "\tsave %%sp,%%g1,%%sp\n");
2123 }
2124 else
2125 {
2126 fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
2127 if ((actual_fsize & 0x3ff) != 0)
2128 fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
2129 fprintf (file, "\tadd %%sp,%%g1,%%sp\n");
2130 }
ab835497
RK
2131 }
2132
2133 /* If doing anything with PIC, do it now. */
2134 if (! flag_pic)
2135 fprintf (file, "\t!#PROLOGUE# 1\n");
2136
2137 /* Figure out where to save any special registers. */
2138 if (num_fregs)
2139 {
2140 int offset, n_fregs = num_fregs;
2141
2142 if (! leaf_function)
2143 offset = -apparent_fsize;
2144 else
2145 offset = 0;
2146
2147 if (TARGET_EPILOGUE && ! leaf_function)
2148 n_fregs = save_regs (file, 0, 16, frame_base_name, offset, 0);
2149 else if (leaf_function)
2150 n_fregs = save_regs (file, 0, 32, frame_base_name, offset, 0);
2151 if (TARGET_EPILOGUE)
2152 save_regs (file, 32, FIRST_PSEUDO_REGISTER,
2153 frame_base_name, offset, n_fregs);
2154 }
2155
2156 if (regs_ever_live[62])
2157 fprintf (file, "\tst %s,[%s-16]\n\tst %s,[%s-12]\n",
2158 reg_names[0], frame_base_name,
2159 reg_names[0], frame_base_name);
2160
2161 leaf_label = 0;
2162 if (leaf_function && actual_fsize != 0)
2163 {
2164 /* warning ("leaf procedure with frame size %d", actual_fsize); */
2165 if (! TARGET_EPILOGUE)
2166 leaf_label = gen_label_rtx ();
2167 }
2168}
2169
915f619f
JW
2170/* Output code for the function epilogue. */
2171
ab835497 2172void
ef8200df 2173output_function_epilogue (file, size, leaf_function)
ab835497
RK
2174 FILE *file;
2175 int size;
ef8200df 2176 int leaf_function;
ab835497
RK
2177{
2178 int n_fregs, i;
2179 char *ret;
2180
2181 if (leaf_label)
2182 {
ab835497
RK
2183 emit_label_after (leaf_label, get_last_insn ());
2184 final_scan_insn (get_last_insn (), file, 0, 0, 1);
2185 }
2186
2187 if (num_fregs)
2188 {
2189 int offset, n_fregs = num_fregs;
2190
2191 if (! leaf_function)
2192 offset = -apparent_fsize;
2193 else
2194 offset = 0;
2195
2196 if (TARGET_EPILOGUE && ! leaf_function)
2197 n_fregs = restore_regs (file, 0, 16, frame_base_name, offset, 0);
2198 else if (leaf_function)
2199 n_fregs = restore_regs (file, 0, 32, frame_base_name, offset, 0);
2200 if (TARGET_EPILOGUE)
2201 restore_regs (file, 32, FIRST_PSEUDO_REGISTER,
2202 frame_base_name, offset, n_fregs);
2203 }
2204
2205 /* Work out how to skip the caller's unimp instruction if required. */
2206 if (leaf_function)
2207 ret = (current_function_returns_struct ? "jmp %o7+12" : "retl");
2208 else
2209 ret = (current_function_returns_struct ? "jmp %i7+12" : "ret");
2210
ef8200df 2211 if (TARGET_EPILOGUE || leaf_label)
ab835497 2212 {
ef8200df
JW
2213 int old_target_epilogue = TARGET_EPILOGUE;
2214 target_flags &= ~old_target_epilogue;
ab835497 2215
ef8200df
JW
2216 if (! leaf_function)
2217 {
2218 /* If we wound up with things in our delay slot, flush them here. */
2219 if (current_function_epilogue_delay_list)
ab835497 2220 {
ef8200df
JW
2221 rtx insn = emit_jump_insn_after (gen_rtx (RETURN, VOIDmode),
2222 get_last_insn ());
2223 PATTERN (insn) = gen_rtx (PARALLEL, VOIDmode,
2224 gen_rtvec (2,
2225 PATTERN (XEXP (current_function_epilogue_delay_list, 0)),
2226 PATTERN (insn)));
2227 final_scan_insn (insn, file, 1, 0, 1);
ab835497
RK
2228 }
2229 else
ef8200df
JW
2230 fprintf (file, "\t%s\n\trestore\n", ret);
2231 }
915f619f
JW
2232 /* All of the following cases are for leaf functions. */
2233 else if (current_function_epilogue_delay_list)
ef8200df 2234 {
915f619f
JW
2235 /* eligible_for_epilogue_delay_slot ensures that if this is a
2236 leaf function, then we will only have insn in the delay slot
2237 if the frame size is zero, thus no adjust for the stack is
2238 needed here. */
2239 if (actual_fsize != 0)
ef8200df 2240 abort ();
915f619f
JW
2241 fprintf (file, "\t%s\n", ret);
2242 final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
2243 file, 1, 0, 1);
ab835497 2244 }
915f619f
JW
2245 else if (actual_fsize <= 4096)
2246 fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize);
2247 else if (actual_fsize <= 8192)
2248 fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n",
2249 ret, actual_fsize - 4096);
2250 else if ((actual_fsize & 0x3ff) == 0)
2251 fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2252 actual_fsize, ret);
2253 else
2254 fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
2255 actual_fsize, actual_fsize, ret);
ef8200df 2256 target_flags |= old_target_epilogue;
ab835497
RK
2257 }
2258}
2259\f
2260/* Return the string to output a conditional branch to LABEL, which is
2261 the operand number of the label. OP is the conditional expression. The
2262 mode of register 0 says what kind of comparison we made.
2263
2264 REVERSED is non-zero if we should reverse the sense of the comparison.
2265
2266 ANNUL is non-zero if we should generate an annulling branch.
2267
2268 NOOP is non-zero if we have to follow this branch by a noop. */
2269
2270char *
2271output_cbranch (op, label, reversed, annul, noop)
2272 rtx op;
2273 int label;
2274 int reversed, annul, noop;
2275{
2276 static char string[20];
2277 enum rtx_code code = GET_CODE (op);
2278 enum machine_mode mode = GET_MODE (XEXP (op, 0));
2279 static char labelno[] = " %lX";
2280
b4ac57ab 2281 /* ??? FP branches can not be preceded by another floating point insn.
ab835497
RK
2282 Because there is currently no concept of pre-delay slots, we can fix
2283 this only by always emitting a nop before a floating point branch. */
2284
2285 if (mode == CCFPmode)
2286 strcpy (string, "nop\n\t");
2287
2288 /* If not floating-point or if EQ or NE, we can just reverse the code. */
2289 if (reversed && (mode != CCFPmode || code == EQ || code == NE))
2290 code = reverse_condition (code), reversed = 0;
2291
2292 /* Start by writing the branch condition. */
2293 switch (code)
2294 {
2295 case NE:
2296 if (mode == CCFPmode)
2297 strcat (string, "fbne");
2298 else
2299 strcpy (string, "bne");
2300 break;
2301
2302 case EQ:
2303 if (mode == CCFPmode)
2304 strcat (string, "fbe");
2305 else
2306 strcpy (string, "be");
2307 break;
2308
2309 case GE:
2310 if (mode == CCFPmode)
2311 {
2312 if (reversed)
2313 strcat (string, "fbul");
2314 else
2315 strcat (string, "fbge");
2316 }
2317 else if (mode == CC_NOOVmode)
2318 strcpy (string, "bpos");
2319 else
2320 strcpy (string, "bge");
2321 break;
2322
2323 case GT:
2324 if (mode == CCFPmode)
2325 {
2326 if (reversed)
2327 strcat (string, "fbule");
2328 else
2329 strcat (string, "fbg");
2330 }
2331 else
2332 strcpy (string, "bg");
2333 break;
2334
2335 case LE:
2336 if (mode == CCFPmode)
2337 {
2338 if (reversed)
2339 strcat (string, "fbug");
2340 else
2341 strcat (string, "fble");
2342 }
2343 else
2344 strcpy (string, "ble");
2345 break;
2346
2347 case LT:
2348 if (mode == CCFPmode)
2349 {
2350 if (reversed)
2351 strcat (string, "fbuge");
2352 else
2353 strcat (string, "fbl");
2354 }
2355 else if (mode == CC_NOOVmode)
2356 strcpy (string, "bneg");
2357 else
2358 strcpy (string, "bl");
2359 break;
2360
2361 case GEU:
2362 strcpy (string, "bgeu");
2363 break;
2364
2365 case GTU:
2366 strcpy (string, "bgu");
2367 break;
2368
2369 case LEU:
2370 strcpy (string, "bleu");
2371 break;
2372
2373 case LTU:
2374 strcpy (string, "blu");
2375 break;
2376 }
2377
2378 /* Now add the annulling, the label, and a possible noop. */
2379 if (annul)
2380 strcat (string, ",a");
2381
2382 labelno[3] = label + '0';
2383 strcat (string, labelno);
2384
2385 if (noop)
2386 strcat (string, "\n\tnop");
2387
2388 return string;
2389}
2390
795068a4
JW
2391/* Output assembler code to return from a function. */
2392
ab835497
RK
2393char *
2394output_return (operands)
2395 rtx *operands;
2396{
2397 if (leaf_label)
2398 {
2399 operands[0] = leaf_label;
2400 return "b,a %l0";
2401 }
2402 else if (leaf_function)
2403 {
915f619f
JW
2404 /* If we didn't allocate a frame pointer for the current function,
2405 the stack pointer might have been adjusted. Output code to
2406 restore it now. */
2407
ab835497 2408 operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize);
915f619f
JW
2409
2410 /* Use sub of negated value in first two cases instead of add to
2411 allow actual_fsize == 4096. */
2412
2413 if (actual_fsize <= 4096)
ab835497
RK
2414 {
2415 if (current_function_returns_struct)
915f619f 2416 return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp";
ab835497 2417 else
915f619f 2418 return "retl\n\tsub %%sp,-%0,%%sp";
ab835497 2419 }
915f619f 2420 else if (actual_fsize <= 8192)
ab835497 2421 {
915f619f 2422 operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096);
ab835497 2423 if (current_function_returns_struct)
915f619f
JW
2424 return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp";
2425 else
2426 return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp";
2427 }
2428 else if (current_function_returns_struct)
2429 {
2430 if ((actual_fsize & 0x3ff) != 0)
ab835497
RK
2431 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2432 else
915f619f
JW
2433 return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
2434 }
2435 else
2436 {
2437 if ((actual_fsize & 0x3ff) != 0)
ab835497 2438 return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
915f619f
JW
2439 else
2440 return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
ab835497
RK
2441 }
2442 }
2443 else
2444 {
2445 if (current_function_returns_struct)
2446 return "jmp %%i7+12\n\trestore";
2447 else
2448 return "ret\n\trestore";
2449 }
2450}
2451
795068a4
JW
2452/* Output assembler code for a SImode to SFmode conversion. */
2453
ab835497
RK
2454char *
2455output_floatsisf2 (operands)
2456 rtx *operands;
2457{
2458 if (GET_CODE (operands[1]) == MEM)
2459 return "ld %1,%0\n\tfitos %0,%0";
2460 else if (FP_REG_P (operands[1]))
2461 return "fitos %1,%0";
2462 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitos %0,%0";
2463}
2464
795068a4
JW
2465/* Output assembler code for a SImode to DFmode conversion. */
2466
ab835497
RK
2467char *
2468output_floatsidf2 (operands)
2469 rtx *operands;
2470{
2471 if (GET_CODE (operands[1]) == MEM)
2472 return "ld %1,%0\n\tfitod %0,%0";
2473 else if (FP_REG_P (operands[1]))
2474 return "fitod %1,%0";
2475 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitod %0,%0";
2476}
795068a4
JW
2477
2478/* Output assembler code for a SImode to TFmode conversion. */
2479
2480char *
2481output_floatsitf2 (operands)
2482 rtx *operands;
2483{
2484 if (GET_CODE (operands[1]) == MEM)
2485 return "ld %1,%0\n\tfitoq %0,%0";
2486 else if (FP_REG_P (operands[1]))
2487 return "fitoq %1,%0";
2488 return "st %r1,[%%fp-4]\n\tld [%%fp-4],%0\n\tfitoq %0,%0";
2489}
ab835497
RK
2490\f
2491/* Leaf functions and non-leaf functions have different needs. */
2492
2493static int
2494reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER;
2495
2496static int
2497reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER;
2498
2499static int *reg_alloc_orders[] = {
2500 reg_leaf_alloc_order,
2501 reg_nonleaf_alloc_order};
2502
2503void
2504order_regs_for_local_alloc ()
2505{
2506 static int last_order_nonleaf = 1;
2507
2508 if (regs_ever_live[15] != last_order_nonleaf)
2509 {
2510 last_order_nonleaf = !last_order_nonleaf;
2511 bcopy (reg_alloc_orders[last_order_nonleaf], reg_alloc_order,
2512 FIRST_PSEUDO_REGISTER * sizeof (int));
2513 }
2514}
2515\f
2516/* Machine dependent routines for the branch probability, arc profiling
2517 code. */
2518
2519/* The label used by the arc profiling code. */
2520
2521static rtx profiler_label;
2522
2523void
2524init_arc_profiler ()
2525{
2526 /* Generate and save a copy of this so it can be shared. */
2527 profiler_label = gen_rtx (SYMBOL_REF, Pmode, "*LPBX2");
2528}
2529
2530void
2531output_arc_profiler (arcno, insert_after)
2532 int arcno;
2533 rtx insert_after;
2534{
2535 rtx profiler_target_addr
2536 = gen_rtx (CONST, Pmode,
2537 gen_rtx (PLUS, Pmode, profiler_label,
2538 gen_rtx (CONST_INT, VOIDmode, 4 * arcno)));
2539 register rtx profiler_reg = gen_reg_rtx (SImode);
b4ac57ab
RS
2540 register rtx address_reg = gen_reg_rtx (Pmode);
2541 rtx mem_ref;
2542
2543 insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, address_reg,
2544 gen_rtx (HIGH, Pmode,
2545 profiler_target_addr)),
2546 insert_after);
2547
2548 mem_ref = gen_rtx (MEM, SImode, gen_rtx (LO_SUM, Pmode, address_reg,
2549 profiler_target_addr));
2550 insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg,
2551 mem_ref),
2552 insert_after);
2553
2554 insert_after = emit_insn_after (gen_rtx (SET, VOIDmode, profiler_reg,
2555 gen_rtx (PLUS, SImode, profiler_reg,
2556 const1_rtx)),
2557 insert_after);
2558
2559 /* This is the same rtx as above, but it is not legal to share this rtx. */
2560 mem_ref = gen_rtx (MEM, SImode, gen_rtx (LO_SUM, Pmode, address_reg,
2561 profiler_target_addr));
2562 emit_insn_after (gen_rtx (SET, VOIDmode, mem_ref, profiler_reg),
ab835497
RK
2563 insert_after);
2564}
35016322
JW
2565
2566/* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1.
2567 This makes them candidates for using ldd and std insns.
2568
2569 Note reg1 and reg2 *must* be hard registers. To be sure we will
2570 abort if we are passed pseudo registers. */
2571
2572int
2573registers_ok_for_ldd (reg1, reg2)
2574 rtx reg1, reg2;
2575{
2576
2577 /* We might have been passed a SUBREG. */
2578 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
2579 return 0;
2580
2581 /* Should never happen. */
2582 if (REGNO (reg1) > FIRST_PSEUDO_REGISTER
2583 || REGNO (reg2) > FIRST_PSEUDO_REGISTER)
2584 abort ();
2585
2586 if (REGNO (reg1) % 2 != 0)
2587 return 0;
2588
2589 return (REGNO (reg1) == REGNO (reg2) - 1);
2590
2591}
2592
2593/* Return 1 if addr1 and addr2 are suitable for use in an ldd or
2594 std insn.
2595
2596 This can only happen when addr1 and addr2 are consecutive memory
2597 locations (addr1 + 4 == addr2). addr1 must also be aligned on a
2598 64 bit boundary (addr1 % 8 == 0).
2599
2600 We know %sp and %fp are kept aligned on a 64 bit boundary. Other
2601 registers are assumed to *never* be properly aligned and are
2602 rejected.
2603
2604 Knowing %sp and %fp are kept aligned on a 64 bit boundary, we
2605 need only check that the offset for addr1 % 8 == 0. */
2606
2607int
2608memory_ok_for_ldd (addr1, addr2)
2609 rtx addr1, addr2;
2610{
2611 int reg1, offset1;
2612
2613 /* Extract a register number and offset (if used) from the first addr. */
2614 if (GET_CODE (addr1) == PLUS)
2615 {
2616 /* If not a REG, return zero. */
2617 if (GET_CODE (XEXP (addr1, 0)) != REG)
2618 return 0;
2619 else
2620 {
2621 reg1 = REGNO (XEXP (addr1, 0));
2622 /* The offset must be constant! */
2623 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
2624 return 0;
2625 offset1 = INTVAL (XEXP (addr1, 1));
2626 }
2627 }
2628 else if (GET_CODE (addr1) != REG)
2629 return 0;
2630 else
2631 {
2632 reg1 = REGNO (addr1);
2633 /* This was a simple (mem (reg)) expression. Offset is 0. */
2634 offset1 = 0;
2635 }
2636
2637 /* Make sure the second address is a (mem (plus (reg) (const_int). */
2638 if (GET_CODE (addr2) != PLUS)
2639 return 0;
2640
2641 if (GET_CODE (XEXP (addr2, 0)) != REG
2642 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
2643 return 0;
2644
2645 /* Only %fp and %sp are allowed. Additionally both addresses must
2646 use the same register. */
2647 if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM)
2648 return 0;
2649
2650 if (reg1 != REGNO (XEXP (addr2, 0)))
2651 return 0;
2652
2653 /* The first offset must be evenly divisable by 8 to ensure the
2654 address is 64 bit aligned. */
2655 if (offset1 % 8 != 0)
2656 return 0;
2657
2658 /* The offset for the second addr must be 4 more than the first addr. */
2659 if (INTVAL (XEXP (addr2, 1)) != offset1 + 4)
2660 return 0;
2661
2662 /* All the tests passed. addr1 and addr2 are valid for ldd and std
2663 instructions. */
2664 return 1;
2665}
ab835497 2666\f
ab835497
RK
2667/* Print operand X (an rtx) in assembler syntax to file FILE.
2668 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2669 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2670
2671void
2672print_operand (file, x, code)
2673 FILE *file;
2674 rtx x;
2675 int code;
2676{
2677 switch (code)
2678 {
2679 case '#':
2680 /* Output a 'nop' if there's nothing for the delay slot. */
2681 if (dbr_sequence_length () == 0)
2682 fputs ("\n\tnop", file);
2683 return;
2684 case '*':
2685 /* Output an annul flag if there's nothing for the delay slot. */
2686 if (dbr_sequence_length () == 0)
2687 fputs (",a", file);
2688 return;
2689 case 'Y':
2690 /* Adjust the operand to take into account a RESTORE operation. */
2691 if (GET_CODE (x) != REG)
2692 abort ();
2693 if (REGNO (x) < 8)
2694 fputs (reg_names[REGNO (x)], file);
2695 else if (REGNO (x) >= 24 && REGNO (x) < 32)
2696 fputs (reg_names[REGNO (x)-16], file);
2697 else
2698 abort ();
2699 return;
2700 case '@':
2701 /* Print out what we are using as the frame pointer. This might
2702 be %fp, or might be %sp+offset. */
2703 fputs (frame_base_name, file);
2704 return;
2705 case 'R':
795068a4 2706 /* Print out the second register name of a register pair or quad.
ab835497
RK
2707 I.e., R (%o0) => %o1. */
2708 fputs (reg_names[REGNO (x)+1], file);
2709 return;
795068a4
JW
2710 case 'S':
2711 /* Print out the third register name of a register quad.
2712 I.e., S (%o0) => %o2. */
2713 fputs (reg_names[REGNO (x)+2], file);
2714 return;
2715 case 'T':
2716 /* Print out the fourth register name of a register quad.
2717 I.e., T (%o0) => %o3. */
2718 fputs (reg_names[REGNO (x)+3], file);
2719 return;
ab835497
RK
2720 case 'm':
2721 /* Print the operand's address only. */
2722 output_address (XEXP (x, 0));
2723 return;
2724 case 'r':
2725 /* In this case we need a register. Use %g0 if the
2726 operand in const0_rtx. */
2727 if (x == const0_rtx)
2728 {
2729 fputs ("%g0", file);
2730 return;
2731 }
2732 else
2733 break;
2734
2735 case 'A':
2736 switch (GET_CODE (x))
2737 {
2738 case IOR: fputs ("or", file); break;
2739 case AND: fputs ("and", file); break;
2740 case XOR: fputs ("xor", file); break;
2741 default: abort ();
2742 }
2743 return;
2744
2745 case 'B':
2746 switch (GET_CODE (x))
2747 {
2748 case IOR: fputs ("orn", file); break;
2749 case AND: fputs ("andn", file); break;
2750 case XOR: fputs ("xnor", file); break;
2751 default: abort ();
2752 }
2753 return;
2754
2755 case 'b':
2756 {
2757 /* Print a sign-extended character. */
2758 int i = INTVAL (x) & 0xff;
2759 if (i & 0x80)
2760 i |= 0xffffff00;
2761 fprintf (file, "%d", i);
2762 return;
2763 }
2764
2765 case 0:
2766 /* Do nothing special. */
2767 break;
2768
2769 default:
2770 /* Undocumented flag. */
2771 abort ();
2772 }
2773
2774 if (GET_CODE (x) == REG)
2775 fputs (reg_names[REGNO (x)], file);
2776 else if (GET_CODE (x) == MEM)
2777 {
2778 fputc ('[', file);
2779 if (CONSTANT_P (XEXP (x, 0)))
2780 /* Poor Sun assembler doesn't understand absolute addressing. */
2781 fputs ("%g0+", file);
2782 output_address (XEXP (x, 0));
2783 fputc (']', file);
2784 }
2785 else if (GET_CODE (x) == HIGH)
2786 {
2787 fputs ("%hi(", file);
2788 output_addr_const (file, XEXP (x, 0));
2789 fputc (')', file);
2790 }
2791 else if (GET_CODE (x) == LO_SUM)
2792 {
2793 print_operand (file, XEXP (x, 0), 0);
2794 fputs ("+%lo(", file);
2795 output_addr_const (file, XEXP (x, 1));
2796 fputc (')', file);
2797 }
2798 else if (GET_CODE (x) == CONST_DOUBLE)
2799 {
2800 if (CONST_DOUBLE_HIGH (x) == 0)
2801 fprintf (file, "%u", CONST_DOUBLE_LOW (x));
2802 else if (CONST_DOUBLE_HIGH (x) == -1
2803 && CONST_DOUBLE_LOW (x) < 0)
2804 fprintf (file, "%d", CONST_DOUBLE_LOW (x));
2805 else
2806 abort ();
2807 }
2808 else { output_addr_const (file, x); }
2809}
2810\f
2811/* This function outputs assembler code for VALUE to FILE, where VALUE is
2812 a 64 bit (DImode) value. */
2813
2814/* ??? If there is a 64 bit counterpart to .word that the assembler
2815 understands, then using that would simply this code greatly. */
2816
2817void
2818output_double_int (file, value)
2819 FILE *file;
2820 rtx value;
2821{
2822 if (GET_CODE (value) == CONST_INT)
2823 {
2824 if (INTVAL (value) < 0)
2825 ASM_OUTPUT_INT (file, constm1_rtx);
2826 else
2827 ASM_OUTPUT_INT (file, const0_rtx);
2828 ASM_OUTPUT_INT (file, value);
2829 }
2830 else if (GET_CODE (value) == CONST_DOUBLE)
2831 {
2832 ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode,
2833 CONST_DOUBLE_HIGH (value)));
2834 ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode,
2835 CONST_DOUBLE_LOW (value)));
2836 }
2837 else if (GET_CODE (value) == SYMBOL_REF
2838 || GET_CODE (value) == CONST
2839 || GET_CODE (value) == PLUS)
2840 {
2841 /* Addresses are only 32 bits. */
2842 ASM_OUTPUT_INT (file, const0_rtx);
2843 ASM_OUTPUT_INT (file, value);
2844 }
2845 else
2846 abort ();
2847}
210aa14a
RS
2848\f
2849/* Compute the code to put in the .proc statement
2850 for a function that returns type TYPE. */
2851
2852unsigned long
2853sparc_type_code (type)
2854 register tree type;
2855{
2856 register unsigned long qualifiers = 0;
2857 register unsigned shift = 6;
2858
2859 for (;;)
2860 {
2861 switch (TREE_CODE (type))
2862 {
2863 case ERROR_MARK:
2864 return qualifiers;
2865
2866 case ARRAY_TYPE:
2867 qualifiers |= (3 << shift);
2868 shift += 2;
2869 type = TREE_TYPE (type);
2870 break;
2871
2872 case FUNCTION_TYPE:
2873 case METHOD_TYPE:
2874 qualifiers |= (2 << shift);
2875 shift += 2;
2876 type = TREE_TYPE (type);
2877 break;
2878
2879 case POINTER_TYPE:
2880 case REFERENCE_TYPE:
2881 case OFFSET_TYPE:
2882 qualifiers |= (1 << shift);
2883 shift += 2;
2884 type = TREE_TYPE (type);
2885 break;
ab835497 2886
210aa14a
RS
2887 case RECORD_TYPE:
2888 return (qualifiers | 8);
2889
2890 case UNION_TYPE:
2891 return (qualifiers | 9);
2892
2893 case ENUMERAL_TYPE:
2894 return (qualifiers | 10);
2895
2896 case VOID_TYPE:
2897 return (qualifiers | 16);
2898
2899 case INTEGER_TYPE:
2900 /* This return value is not always completely the same as Sun's
2901 but the Sun assembler's peephole optimizer probably doesn't
2902 care. */
2903 return (qualifiers | 4);
2904
2905 case REAL_TYPE:
2906 if (TYPE_PRECISION (type) == 32)
2907 return (qualifiers | 6);
2908 else
2909 return (qualifiers | 7); /* Who knows? */
2910
2911 case COMPLEX_TYPE: /* GNU Fortran COMPLEX type. */
2912 case CHAR_TYPE: /* GNU Pascal CHAR type. Not used in C. */
2913 case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */
2914 case FILE_TYPE: /* GNU Pascal FILE type. */
2915 case STRING_TYPE: /* GNU Fortran STRING type. */
2916 case LANG_TYPE: /* ? */
2917 abort ();
2918
2919 default:
2920 abort (); /* Not a type! */
2921 }
2922 }
2923}
ead69aea
JW
2924\f
2925#ifdef HANDLE_PRAGMA
2926
2927/* Handle a pragma directive. HANDLE_PRAGMA conspires to parse the
2928 input following #pragma into tokens based on yylex. TOKEN is the
2929 current token, and STRING is its printable form. */
2930
2931void
2932handle_pragma_token (string, token)
2933 char *string;
2934 tree token;
2935{
2936 static enum pragma_state
2937 {
2938 ps_start,
2939 ps_done,
2940 ps_bad,
2941 ps_weak,
2942 ps_name,
2943 ps_equals,
2944 ps_value,
2945 } state = ps_start, type;
2946 static char *name;
2947 static char *value;
2948 static int align;
2949
2950 if (string == 0)
2951 {
2952#ifdef WEAK_ASM_OP
2953 if (type == ps_weak)
2954 {
2955 if (state == ps_name || state == ps_value)
2956 {
2957 fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
2958 ASM_OUTPUT_LABELREF (asm_out_file, name);
2959 fputc ('\n', asm_out_file);
2960 if (state == ps_value)
2961 {
2962 fputc ('\t', asm_out_file);
2963 ASM_OUTPUT_LABELREF (asm_out_file, name);
2964 fputs (" = ", asm_out_file);
2965 ASM_OUTPUT_LABELREF (asm_out_file, value);
2966 fputc ('\n', asm_out_file);
2967 }
2968 }
2969 else if (! (state == ps_done || state == ps_start))
2970 warning ("ignoring malformed #pragma weak symbol [=value]");
2971 }
2972#endif /* WEAK_ASM_OP */
2973
2974 type = state = ps_start;
2975 return;
2976 }
2977
2978 switch (state)
2979 {
2980 case ps_start:
2981 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
2982 {
2983#ifdef WEAK_ASM_OP
2984 if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
2985 type = state = ps_weak;
2986 else
2987#endif
2988 type = state = ps_done;
2989 }
2990 else
2991 type = state = ps_done;
2992 break;
2993
2994#ifdef WEAK_ASM_OP
2995 case ps_weak:
2996 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
2997 {
2998 name = IDENTIFIER_POINTER (token);
2999 state = ps_name;
3000 }
3001 else
3002 state = ps_bad;
3003 break;
3004
3005 case ps_name:
3006 state = (strcmp (string, "=") ? ps_bad : ps_equals);
3007 break;
3008
3009 case ps_equals:
3010 if (token && TREE_CODE (token) == IDENTIFIER_NODE)
3011 {
3012 value = IDENTIFIER_POINTER (token);
3013 state = ps_value;
3014 }
3015 else
3016 state = ps_bad;
3017 break;
3018
3019 case ps_value:
3020 state = ps_bad;
3021 break;
3022#endif /* WEAK_ASM_OP */
3023
3024 case ps_bad:
3025 case ps_done:
3026 break;
3027
3028 default:
3029 abort ();
3030 }
3031}
3032#endif /* HANDLE_PRAGMA */
This page took 0.386571 seconds and 5 git commands to generate.