]> gcc.gnu.org Git - gcc.git/blame - gcc/config/i860/i860.c
restore portion accidentally deleted last time
[gcc.git] / gcc / config / i860 / i860.c
CommitLineData
de86a82e
RS
1/* Subroutines for insn-output.c for Intel 860
2 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
3 Derived from sparc.c.
4
5 Written by Richard Stallman (rms@ai.mit.edu).
6
7 Hacked substantially by Ron Guilmette (rfg@ncd.com) to cater
8 to the whims of the System V Release 4 assembler.
9
10This file is part of GNU CC.
11
12GNU CC is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2, or (at your option)
15any later version.
16
17GNU CC is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with GNU CC; see the file COPYING. If not, write to
24the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25
26
27#include "config.h"
28#include "flags.h"
29#include "rtl.h"
30#include "regs.h"
31#include "hard-reg-set.h"
32#include "real.h"
33#include "insn-config.h"
34#include "conditions.h"
35#include "insn-flags.h"
36#include "output.h"
37#include "recog.h"
38#include "insn-attr.h"
39
40#include <stdio.h>
41
42static rtx find_addr_reg ();
43
44#ifndef I860_REG_PREFIX
45#define I860_REG_PREFIX ""
46#endif
47
48char *i860_reg_prefix = I860_REG_PREFIX;
49
50/* Save information from a "cmpxx" operation until the branch is emitted. */
51
52rtx i860_compare_op0, i860_compare_op1;
53\f
54/* Return non-zero if this pattern, can be evaluated safely, even if it
55 was not asked for. */
56int
57safe_insn_src_p (op, mode)
58 rtx op;
59 enum machine_mode mode;
60{
61 /* Just experimenting. */
62
63 /* No floating point src is safe if it contains an arithmetic
64 operation, since that operation may trap. */
65 switch (GET_CODE (op))
66 {
67 case CONST_INT:
68 case LABEL_REF:
69 case SYMBOL_REF:
70 case CONST:
71 return 1;
72
73 case REG:
74 return 1;
75
76 case MEM:
77 return CONSTANT_ADDRESS_P (XEXP (op, 0));
78
79 /* We never need to negate or complement constants. */
80 case NEG:
81 return (mode != SFmode && mode != DFmode);
82 case NOT:
83 case ZERO_EXTEND:
84 return 1;
85
86 case EQ:
87 case NE:
88 case LT:
89 case GT:
90 case LE:
91 case GE:
92 case LTU:
93 case GTU:
94 case LEU:
95 case GEU:
96 case MINUS:
97 case PLUS:
98 return (mode != SFmode && mode != DFmode);
99 case AND:
100 case IOR:
101 case XOR:
102 case LSHIFT:
103 case ASHIFT:
104 case ASHIFTRT:
105 case LSHIFTRT:
106 if ((GET_CODE (XEXP (op, 0)) == CONST_INT && ! SMALL_INT (XEXP (op, 0)))
107 || (GET_CODE (XEXP (op, 1)) == CONST_INT && ! SMALL_INT (XEXP (op, 1))))
108 return 0;
109 return 1;
110
111 default:
112 return 0;
113 }
114}
115
116/* Return 1 if REG is clobbered in IN.
117 Return 2 if REG is used in IN.
118 Return 3 if REG is both used and clobbered in IN.
119 Return 0 if neither. */
120
121static int
122reg_clobbered_p (reg, in)
123 rtx reg;
124 rtx in;
125{
126 register enum rtx_code code;
127
128 if (in == 0)
129 return 0;
130
131 code = GET_CODE (in);
132
133 if (code == SET || code == CLOBBER)
134 {
135 rtx dest = SET_DEST (in);
136 int set = 0;
137 int used = 0;
138
139 while (GET_CODE (dest) == STRICT_LOW_PART
140 || GET_CODE (dest) == SUBREG
141 || GET_CODE (dest) == SIGN_EXTRACT
142 || GET_CODE (dest) == ZERO_EXTRACT)
143 dest = XEXP (dest, 0);
144
145 if (dest == reg)
146 set = 1;
147 else if (GET_CODE (dest) == REG
148 && refers_to_regno_p (REGNO (reg),
149 REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
150 SET_DEST (in), 0))
151 {
152 set = 1;
153 /* Anything that sets just part of the register
154 is considered using as well as setting it.
155 But note that a straight SUBREG of a single-word value
156 clobbers the entire value. */
157 if (dest != SET_DEST (in)
158 && ! (GET_CODE (SET_DEST (in)) == SUBREG
159 || UNITS_PER_WORD >= GET_MODE_SIZE (GET_MODE (dest))))
160 used = 1;
161 }
162
163 if (code == SET)
164 {
165 if (set)
166 used = refers_to_regno_p (REGNO (reg),
167 REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
168 SET_SRC (in), 0);
169 else
170 used = refers_to_regno_p (REGNO (reg),
171 REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
172 in, 0);
173 }
174
175 return set + used * 2;
176 }
177
178 if (refers_to_regno_p (REGNO (reg),
179 REGNO (reg) + HARD_REGNO_NREGS (reg, GET_MODE (reg)),
180 in, 0))
181 return 2;
182 return 0;
183}
184
185/* Return non-zero if OP can be written to without screwing up
186 GCC's model of what's going on. It is assumed that this operand
187 appears in the dest position of a SET insn in a conditional
188 branch's delay slot. AFTER is the label to start looking from. */
189int
190operand_clobbered_before_used_after (op, after)
191 rtx op;
192 rtx after;
193{
194 /* Just experimenting. */
195 if (GET_CODE (op) == CC0)
196 return 1;
197 if (GET_CODE (op) == REG)
198 {
199 rtx insn;
200
201 if (op == stack_pointer_rtx)
202 return 0;
203
204 /* Scan forward from the label, to see if the value of OP
205 is clobbered before the first use. */
206
207 for (insn = NEXT_INSN (after); insn; insn = NEXT_INSN (insn))
208 {
209 if (GET_CODE (insn) == NOTE)
210 continue;
211 if (GET_CODE (insn) == INSN
212 || GET_CODE (insn) == JUMP_INSN
213 || GET_CODE (insn) == CALL_INSN)
214 {
215 switch (reg_clobbered_p (op, PATTERN (insn)))
216 {
217 default:
218 return 0;
219 case 1:
220 return 1;
221 case 0:
222 break;
223 }
224 }
225 /* If we reach another label without clobbering OP,
226 then we cannot safely write it here. */
227 else if (GET_CODE (insn) == CODE_LABEL)
228 return 0;
229 if (GET_CODE (insn) == JUMP_INSN)
230 {
231 if (condjump_p (insn))
232 return 0;
233 /* This is a jump insn which has already
234 been mangled. We can't tell what it does. */
235 if (GET_CODE (PATTERN (insn)) == PARALLEL)
236 return 0;
237 if (! JUMP_LABEL (insn))
238 return 0;
239 /* Keep following jumps. */
240 insn = JUMP_LABEL (insn);
241 }
242 }
243 return 1;
244 }
245
246 /* In both of these cases, the first insn executed
247 for this op will be a orh whatever%h,%?r0,%?r31,
248 which is tolerable. */
249 if (GET_CODE (op) == MEM)
250 return (CONSTANT_ADDRESS_P (XEXP (op, 0)));
251
252 return 0;
253}
254
255/* Return non-zero if this pattern, as a source to a "SET",
256 is known to yield an instruction of unit size. */
257int
258single_insn_src_p (op, mode)
259 rtx op;
260 enum machine_mode mode;
261{
262 switch (GET_CODE (op))
263 {
264 case CONST_INT:
265 /* This is not always a single insn src, technically,
266 but output_delayed_branch knows how to deal with it. */
267 return 1;
268
269 case SYMBOL_REF:
270 case CONST:
271 /* This is not a single insn src, technically,
272 but output_delayed_branch knows how to deal with it. */
273 return 1;
274
275 case REG:
276 return 1;
277
278 case MEM:
279 return 1;
280
281 /* We never need to negate or complement constants. */
282 case NEG:
283 return (mode != DFmode);
284 case NOT:
285 case ZERO_EXTEND:
286 return 1;
287
288 case PLUS:
289 case MINUS:
290 /* Detect cases that require multiple instructions. */
291 if (CONSTANT_P (XEXP (op, 1))
292 && !(GET_CODE (XEXP (op, 1)) == CONST_INT
293 && SMALL_INT (XEXP (op, 1))))
294 return 0;
295 case EQ:
296 case NE:
297 case LT:
298 case GT:
299 case LE:
300 case GE:
301 case LTU:
302 case GTU:
303 case LEU:
304 case GEU:
305 /* Not doing floating point, since they probably
306 take longer than the branch slot they might fill. */
307 return (mode != SFmode && mode != DFmode);
308
309 case AND:
310 if (GET_CODE (XEXP (op, 1)) == NOT)
311 {
312 rtx arg = XEXP (XEXP (op, 1), 0);
313 if (CONSTANT_P (arg)
314 && !(GET_CODE (arg) == CONST_INT
315 && (SMALL_INT (arg)
316 || INTVAL (arg) & 0xffff == 0)))
317 return 0;
318 }
319 case IOR:
320 case XOR:
321 /* Both small and round numbers take one instruction;
322 others take two. */
323 if (CONSTANT_P (XEXP (op, 1))
324 && !(GET_CODE (XEXP (op, 1)) == CONST_INT
325 && (SMALL_INT (XEXP (op, 1))
326 || INTVAL (XEXP (op, 1)) & 0xffff == 0)))
327 return 0;
328
329 case LSHIFT:
330 case ASHIFT:
331 case ASHIFTRT:
332 case LSHIFTRT:
333 return 1;
334
335 case SUBREG:
336 if (SUBREG_WORD (op) != 0)
337 return 0;
338 return single_insn_src_p (SUBREG_REG (op), mode);
339
340 /* Not doing floating point, since they probably
341 take longer than the branch slot they might fill. */
342 case FLOAT_EXTEND:
343 case FLOAT_TRUNCATE:
344 case FLOAT:
345 case FIX:
346 case UNSIGNED_FLOAT:
347 case UNSIGNED_FIX:
348 return 0;
349
350 default:
351 return 0;
352 }
353}
235d6e4f
RS
354\f
355/* Return non-zero only if OP is a register of mode MODE,
356 or const0_rtx. */
357int
358reg_or_0_operand (op, mode)
359 rtx op;
360 enum machine_mode mode;
361{
362 return (op == const0_rtx || register_operand (op, mode)
363 || op == CONST0_RTX (mode));
364}
365
366/* Return truth value of whether OP can be used as an operands in a three
367 address add/subtract insn (such as add %o1,7,%l2) of mode MODE. */
368
369int
370arith_operand (op, mode)
371 rtx op;
372 enum machine_mode mode;
373{
374 return (register_operand (op, mode)
375 || (GET_CODE (op) == CONST_INT && SMALL_INT (op)));
376}
377
378/* Return 1 if OP is a valid first operand for a logical insn of mode MODE. */
379
380int
381logic_operand (op, mode)
382 rtx op;
383 enum machine_mode mode;
384{
385 return (register_operand (op, mode)
386 || (GET_CODE (op) == CONST_INT && LOGIC_INT (op)));
387}
388
389/* Return 1 if OP is a valid first operand for a shift insn of mode MODE. */
390
391int
392shift_operand (op, mode)
393 rtx op;
394 enum machine_mode mode;
395{
396 return (register_operand (op, mode)
397 || (GET_CODE (op) == CONST_INT));
398}
399
400/* Return 1 if OP is a valid first operand for either a logical insn
401 or an add insn of mode MODE. */
402
403int
404compare_operand (op, mode)
405 rtx op;
406 enum machine_mode mode;
407{
408 return (register_operand (op, mode)
409 || (GET_CODE (op) == CONST_INT && SMALL_INT (op) && LOGIC_INT (op)));
410}
411
412/* Return truth value of whether OP can be used as the 5-bit immediate
413 operand of a bte or btne insn. */
414
415int
416bte_operand (op, mode)
417 rtx op;
418 enum machine_mode mode;
419{
420 return (register_operand (op, mode)
421 || (GET_CODE (op) == CONST_INT
422 && (unsigned) INTVAL (op) < 0x20));
423}
424
425/* Return 1 if OP is an indexed memory reference of mode MODE. */
426
427int
428indexed_operand (op, mode)
429 rtx op;
430 enum machine_mode mode;
431{
432 return (GET_CODE (op) == MEM && GET_MODE (op) == mode
433 && GET_CODE (XEXP (op, 0)) == PLUS
434 && GET_MODE (XEXP (op, 0)) == SImode
435 && register_operand (XEXP (XEXP (op, 0), 0), SImode)
436 && register_operand (XEXP (XEXP (op, 0), 1), SImode));
437}
438
439/* Return 1 if OP is a suitable source operand for a load insn
440 with mode MODE. */
441
442int
443load_operand (op, mode)
444 rtx op;
445 enum machine_mode mode;
446{
447 return (memory_operand (op, mode) || indexed_operand (op, mode));
448}
449
450/* Return truth value of whether OP is a integer which fits the
451 range constraining immediate operands in add/subtract insns. */
452
453int
454small_int (op, mode)
455 rtx op;
456 enum machine_mode mode;
457{
458 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
459}
460
461/* Return truth value of whether OP is a integer which fits the
462 range constraining immediate operands in logic insns. */
463
464int
465logic_int (op, mode)
466 rtx op;
467 enum machine_mode mode;
468{
469 return (GET_CODE (op) == CONST_INT && LOGIC_INT (op));
470}
471\f
472/* Return the best assembler insn template
473 for moving operands[1] into operands[0] as a fullword. */
474
475static char *
476singlemove_string (operands)
477 rtx *operands;
478{
479 if (GET_CODE (operands[0]) == MEM)
480 {
481 if (GET_CODE (operands[1]) != MEM)
482 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
483 {
484 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
485 && (cc_prev_status.flags & CC_HI_R31_ADJ)
486 && cc_prev_status.mdep == XEXP (operands[0], 0)))
487 {
488 CC_STATUS_INIT;
489 output_asm_insn ("orh %h0,%?r0,%?r31", operands);
490 }
491 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
492 cc_status.mdep = XEXP (operands[0], 0);
493 return "st.l %r1,%L0(%?r31)";
494 }
495 else
496 return "st.l %r1,%0";
497 else
498 abort ();
499#if 0
500 {
501 rtx xoperands[2];
502
503 cc_status.flags &= ~CC_F0_IS_0;
504 xoperands[0] = gen_rtx (REG, SFmode, 32);
505 xoperands[1] = operands[1];
506 output_asm_insn (singlemove_string (xoperands), xoperands);
507 xoperands[1] = xoperands[0];
508 xoperands[0] = operands[0];
509 output_asm_insn (singlemove_string (xoperands), xoperands);
510 return "";
511 }
512#endif
513 }
514 if (GET_CODE (operands[1]) == MEM)
515 {
516 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
517 {
518 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
519 && (cc_prev_status.flags & CC_HI_R31_ADJ)
520 && cc_prev_status.mdep == XEXP (operands[1], 0)))
521 {
522 CC_STATUS_INIT;
523 output_asm_insn ("orh %h1,%?r0,%?r31", operands);
524 }
525 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
526 cc_status.mdep = XEXP (operands[1], 0);
527 return "ld.l %L1(%?r31),%0";
528 }
529 return "ld.l %m1,%0";
530 }
531 if (GET_CODE (operands[1]) == CONST_INT)
532 {
b505fab8
RS
533 if (operands[1] == const0_rtx)
534 return "mov %?r0,%0";
235d6e4f
RS
535 if((INTVAL (operands[1]) & 0xffff0000) == 0)
536 return "or %L1,%?r0,%0";
b505fab8
RS
537 if((INTVAL (operands[1]) & 0xffff8000) == 0xffff8000)
538 return "adds %1,%?r0,%0";
235d6e4f
RS
539 if((INTVAL (operands[1]) & 0x0000ffff) == 0)
540 return "orh %H1,%?r0,%0";
235d6e4f
RS
541 }
542 return "mov %1,%0";
543}
544\f
545/* Output assembler code to perform a doubleword move insn
546 with operands OPERANDS. */
547
548char *
549output_move_double (operands)
550 rtx *operands;
551{
552 enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
553 rtx latehalf[2];
554 rtx addreg0 = 0, addreg1 = 0;
555
556 /* First classify both operands. */
557
558 if (REG_P (operands[0]))
559 optype0 = REGOP;
560 else if (offsettable_memref_p (operands[0]))
561 optype0 = OFFSOP;
562 else if (GET_CODE (operands[0]) == MEM)
563 optype0 = MEMOP;
564 else
565 optype0 = RNDOP;
566
567 if (REG_P (operands[1]))
568 optype1 = REGOP;
569 else if (CONSTANT_P (operands[1]))
570 optype1 = CNSTOP;
571 else if (offsettable_memref_p (operands[1]))
572 optype1 = OFFSOP;
573 else if (GET_CODE (operands[1]) == MEM)
574 optype1 = MEMOP;
575 else
576 optype1 = RNDOP;
577
578 /* Check for the cases that the operand constraints are not
579 supposed to allow to happen. Abort if we get one,
580 because generating code for these cases is painful. */
581
582 if (optype0 == RNDOP || optype1 == RNDOP)
583 abort ();
584
585 /* If an operand is an unoffsettable memory ref, find a register
586 we can increment temporarily to make it refer to the second word. */
587
588 if (optype0 == MEMOP)
589 addreg0 = find_addr_reg (XEXP (operands[0], 0));
590
591 if (optype1 == MEMOP)
592 addreg1 = find_addr_reg (XEXP (operands[1], 0));
593
594/* ??? Perhaps in some cases move double words
595 if there is a spare pair of floating regs. */
596
597 /* Ok, we can do one word at a time.
598 Normally we do the low-numbered word first,
599 but if either operand is autodecrementing then we
600 do the high-numbered word first.
601
602 In either case, set up in LATEHALF the operands to use
603 for the high-numbered word and in some cases alter the
604 operands in OPERANDS to be suitable for the low-numbered word. */
605
606 if (optype0 == REGOP)
607 latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
608 else if (optype0 == OFFSOP)
609 latehalf[0] = adj_offsettable_operand (operands[0], 4);
610 else
611 latehalf[0] = operands[0];
612
613 if (optype1 == REGOP)
614 latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
615 else if (optype1 == OFFSOP)
616 latehalf[1] = adj_offsettable_operand (operands[1], 4);
617 else if (optype1 == CNSTOP)
618 {
619 if (GET_CODE (operands[1]) == CONST_DOUBLE)
620 split_double (operands[1], &operands[1], &latehalf[1]);
621 else if (CONSTANT_P (operands[1]))
622 latehalf[1] = const0_rtx;
623 }
624 else
625 latehalf[1] = operands[1];
626
627 /* If the first move would clobber the source of the second one,
628 do them in the other order.
629
630 RMS says "This happens only for registers;
631 such overlap can't happen in memory unless the user explicitly
632 sets it up, and that is an undefined circumstance."
633
634 but it happens on the sparc when loading parameter registers,
635 so I am going to define that circumstance, and make it work
636 as expected. */
637
638 if (optype0 == REGOP && optype1 == REGOP
639 && REGNO (operands[0]) == REGNO (latehalf[1]))
640 {
641 CC_STATUS_PARTIAL_INIT;
642 /* Make any unoffsettable addresses point at high-numbered word. */
643 if (addreg0)
644 output_asm_insn ("adds 0x4,%0,%0", &addreg0);
645 if (addreg1)
646 output_asm_insn ("adds 0x4,%0,%0", &addreg1);
647
648 /* Do that word. */
649 output_asm_insn (singlemove_string (latehalf), latehalf);
650
651 /* Undo the adds we just did. */
652 if (addreg0)
653 output_asm_insn ("adds -0x4,%0,%0", &addreg0);
654 if (addreg1)
655 output_asm_insn ("adds -0x4,%0,%0", &addreg1);
656
657 /* Do low-numbered word. */
658 return singlemove_string (operands);
659 }
660 else if (optype0 == REGOP && optype1 != REGOP
661 && reg_overlap_mentioned_p (operands[0], operands[1]))
662 {
663 /* Do the late half first. */
664 output_asm_insn (singlemove_string (latehalf), latehalf);
665 /* Then clobber. */
666 return singlemove_string (operands);
667 }
668
669 /* Normal case: do the two words, low-numbered first. */
670
671 output_asm_insn (singlemove_string (operands), operands);
672
673 CC_STATUS_PARTIAL_INIT;
674 /* Make any unoffsettable addresses point at high-numbered word. */
675 if (addreg0)
676 output_asm_insn ("adds 0x4,%0,%0", &addreg0);
677 if (addreg1)
678 output_asm_insn ("adds 0x4,%0,%0", &addreg1);
679
680 /* Do that word. */
681 output_asm_insn (singlemove_string (latehalf), latehalf);
682
683 /* Undo the adds we just did. */
684 if (addreg0)
685 output_asm_insn ("adds -0x4,%0,%0", &addreg0);
686 if (addreg1)
687 output_asm_insn ("adds -0x4,%0,%0", &addreg1);
688
689 return "";
690}
691\f
692char *
693output_fp_move_double (operands)
694 rtx *operands;
695{
696 /* If the source operand is any sort of zero, use f0 instead. */
697
698 if (operands[1] == CONST0_RTX (GET_MODE (operands[1])))
699 operands[1] = gen_rtx (REG, DFmode, F0_REGNUM);
700
701 if (FP_REG_P (operands[0]))
702 {
703 if (FP_REG_P (operands[1]))
704 return "fmov.dd %1,%0";
705 if (GET_CODE (operands[1]) == REG)
706 {
707 output_asm_insn ("ixfr %1,%0", operands);
708 operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
709 operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
710 return "ixfr %1,%0";
711 }
712 if (operands[1] == CONST0_RTX (DFmode))
713 return "fmov.dd f0,%0";
714 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))
715 {
716 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
717 && (cc_prev_status.flags & CC_HI_R31_ADJ)
718 && cc_prev_status.mdep == XEXP (operands[1], 0)))
719 {
720 CC_STATUS_INIT;
721 output_asm_insn ("orh %h1,%?r0,%?r31", operands);
722 }
723 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
724 cc_status.mdep = XEXP (operands[1], 0);
725 return "fld.d %L1(%?r31),%0";
726 }
727 return "fld.d %1,%0";
728 }
729 else if (FP_REG_P (operands[1]))
730 {
731 if (GET_CODE (operands[0]) == REG)
732 {
733 output_asm_insn ("fxfr %1,%0", operands);
734 operands[0] = gen_rtx (REG, VOIDmode, REGNO (operands[0]) + 1);
735 operands[1] = gen_rtx (REG, VOIDmode, REGNO (operands[1]) + 1);
736 return "fxfr %1,%0";
737 }
738 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
739 {
740 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
741 && (cc_prev_status.flags & CC_HI_R31_ADJ)
742 && cc_prev_status.mdep == XEXP (operands[0], 0)))
743 {
744 CC_STATUS_INIT;
745 output_asm_insn ("orh %h0,%?r0,%?r31", operands);
746 }
747 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
748 cc_status.mdep = XEXP (operands[0], 0);
749 return "fst.d %1,%L0(%?r31)";
750 }
751 return "fst.d %1,%0";
752 }
753 else
754 abort ();
755 /* NOTREACHED */
756 return NULL;
757}
758\f
759/* Return a REG that occurs in ADDR with coefficient 1.
760 ADDR can be effectively incremented by incrementing REG. */
761
762static rtx
763find_addr_reg (addr)
764 rtx addr;
765{
766 while (GET_CODE (addr) == PLUS)
767 {
768 if (GET_CODE (XEXP (addr, 0)) == REG)
769 addr = XEXP (addr, 0);
770 else if (GET_CODE (XEXP (addr, 1)) == REG)
771 addr = XEXP (addr, 1);
772 else if (CONSTANT_P (XEXP (addr, 0)))
773 addr = XEXP (addr, 1);
774 else if (CONSTANT_P (XEXP (addr, 1)))
775 addr = XEXP (addr, 0);
776 else
777 abort ();
778 }
779 if (GET_CODE (addr) == REG)
780 return addr;
781 abort ();
782 /* NOTREACHED */
783 return NULL;
784}
785
786/* Return a template for a load instruction with mode MODE and
787 arguments from the string ARGS.
788
789 This string is in static storage. */
790
791static char *
792load_opcode (mode, args, reg)
793 enum machine_mode mode;
794 char *args;
795 rtx reg;
796{
797 static char buf[30];
798 char *opcode;
799
800 switch (mode)
801 {
802 case QImode:
803 opcode = "ld.b";
804 break;
805
806 case HImode:
807 opcode = "ld.s";
808 break;
809
810 case SImode:
811 case SFmode:
812 if (FP_REG_P (reg))
813 opcode = "fld.l";
814 else
815 opcode = "ld.l";
816 break;
817
818 case DImode:
819 if (!FP_REG_P (reg))
820 abort ();
821 case DFmode:
822 opcode = "fld.d";
823 break;
824
825 default:
826 abort ();
827 }
828
829 sprintf (buf, "%s %s", opcode, args);
830 return buf;
831}
832
833/* Return a template for a store instruction with mode MODE and
834 arguments from the string ARGS.
835
836 This string is in static storage. */
837
838static char *
839store_opcode (mode, args, reg)
840 enum machine_mode mode;
841 char *args;
842 rtx reg;
843{
844 static char buf[30];
845 char *opcode;
846
847 switch (mode)
848 {
849 case QImode:
850 opcode = "st.b";
851 break;
852
853 case HImode:
854 opcode = "st.s";
855 break;
856
857 case SImode:
858 case SFmode:
859 if (FP_REG_P (reg))
860 opcode = "fst.l";
861 else
862 opcode = "st.l";
863 break;
864
865 case DImode:
866 if (!FP_REG_P (reg))
867 abort ();
868 case DFmode:
869 opcode = "fst.d";
870 break;
871
872 default:
873 abort ();
874 }
875
876 sprintf (buf, "%s %s", opcode, args);
877 return buf;
878}
879\f
880/* Output a store-in-memory whose operands are OPERANDS[0,1].
881 OPERANDS[0] is a MEM, and OPERANDS[1] is a reg or zero.
882
883 This function returns a template for an insn.
884 This is in static storage.
885
886 It may also output some insns directly.
887 It may alter the values of operands[0] and operands[1]. */
888
889char *
890output_store (operands)
891 rtx *operands;
892{
893 enum machine_mode mode = GET_MODE (operands[0]);
894 rtx address = XEXP (operands[0], 0);
895 char *string;
896
897 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
898 cc_status.mdep = address;
899
900 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
901 && (cc_prev_status.flags & CC_HI_R31_ADJ)
902 && address == cc_prev_status.mdep))
903 {
904 CC_STATUS_INIT;
905 output_asm_insn ("orh %h0,%?r0,%?r31", operands);
906 cc_prev_status.mdep = address;
907 }
908
909 /* Store zero in two parts when appropriate. */
910 if (mode == DFmode && operands[1] == CONST0_RTX (DFmode))
911 return store_opcode (DFmode, "%r1,%L0(%?r31)", operands[1]);
912
913 /* Code below isn't smart enough to move a doubleword in two parts,
914 so use output_move_double to do that in the cases that require it. */
915 if ((mode == DImode || mode == DFmode)
916 && ! FP_REG_P (operands[1]))
917 return output_move_double (operands);
918
919 return store_opcode (mode, "%r1,%L0(%?r31)", operands[1]);
920}
921
922/* Output a load-from-memory whose operands are OPERANDS[0,1].
923 OPERANDS[0] is a reg, and OPERANDS[1] is a mem.
924
925 This function returns a template for an insn.
926 This is in static storage.
927
928 It may also output some insns directly.
929 It may alter the values of operands[0] and operands[1]. */
930
931char *
932output_load (operands)
933 rtx *operands;
934{
935 enum machine_mode mode = GET_MODE (operands[0]);
936 rtx address = XEXP (operands[1], 0);
937
938 /* We don't bother trying to see if we know %hi(address).
939 This is because we are doing a load, and if we know the
940 %hi value, we probably also know that value in memory. */
941 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ;
942 cc_status.mdep = address;
943
944 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
945 && (cc_prev_status.flags & CC_HI_R31_ADJ)
946 && address == cc_prev_status.mdep
947 && cc_prev_status.mdep == cc_status.mdep))
948 {
949 CC_STATUS_INIT;
950 output_asm_insn ("orh %h1,%?r0,%?r31", operands);
951 cc_prev_status.mdep = address;
952 }
953
954 /* Code below isn't smart enough to move a doubleword in two parts,
955 so use output_move_double to do that in the cases that require it. */
956 if ((mode == DImode || mode == DFmode)
957 && ! FP_REG_P (operands[0]))
958 return output_move_double (operands);
959
960 return load_opcode (mode, "%L1(%?r31),%0", operands[0]);
961}
962\f
963#if 0
964/* Load the address specified by OPERANDS[3] into the register
965 specified by OPERANDS[0].
966
967 OPERANDS[3] may be the result of a sum, hence it could either be:
968
969 (1) CONST
970 (2) REG
971 (2) REG + CONST_INT
972 (3) REG + REG + CONST_INT
973 (4) REG + REG (special case of 3).
974
975 Note that (3) is not a legitimate address.
976 All cases are handled here. */
977
978void
979output_load_address (operands)
980 rtx *operands;
981{
982 rtx base, offset;
983
984 if (CONSTANT_P (operands[3]))
985 {
986 output_asm_insn ("mov %3,%0", operands);
987 return;
988 }
989
990 if (REG_P (operands[3]))
991 {
992 if (REGNO (operands[0]) != REGNO (operands[3]))
993 output_asm_insn ("shl %?r0,%3,%0", operands);
994 return;
995 }
996
997 if (GET_CODE (operands[3]) != PLUS)
998 abort ();
999
1000 base = XEXP (operands[3], 0);
1001 offset = XEXP (operands[3], 1);
1002
1003 if (GET_CODE (base) == CONST_INT)
1004 {
1005 rtx tmp = base;
1006 base = offset;
1007 offset = tmp;
1008 }
1009
1010 if (GET_CODE (offset) != CONST_INT)
1011 {
1012 /* Operand is (PLUS (REG) (REG)). */
1013 base = operands[3];
1014 offset = const0_rtx;
1015 }
1016
1017 if (REG_P (base))
1018 {
1019 operands[6] = base;
1020 operands[7] = offset;
1021 CC_STATUS_PARTIAL_INIT;
1022 if (SMALL_INT (offset))
1023 output_asm_insn ("adds %7,%6,%0", operands);
1024 else
1025 output_asm_insn ("mov %7,%0\n\tadds %0,%6,%0", operands);
1026 }
1027 else if (GET_CODE (base) == PLUS)
1028 {
1029 operands[6] = XEXP (base, 0);
1030 operands[7] = XEXP (base, 1);
1031 operands[8] = offset;
1032
1033 CC_STATUS_PARTIAL_INIT;
1034 if (SMALL_INT (offset))
1035 output_asm_insn ("adds %6,%7,%0\n\tadds %8,%0,%0", operands);
1036 else
1037 output_asm_insn ("mov %8,%0\n\tadds %0,%6,%0\n\tadds %0,%7,%0", operands);
1038 }
1039 else
1040 abort ();
1041}
1042#endif
1043
1044/* Output code to place a size count SIZE in register REG.
1045 Because block moves are pipelined, we don't include the
1046 first element in the transfer of SIZE to REG.
1047 For this, we subtract ALIGN. (Actually, I think it is not
1048 right to subtract on this machine, so right now we don't.) */
1049
1050static void
1051output_size_for_block_move (size, reg, align)
1052 rtx size, reg, align;
1053{
1054 rtx xoperands[3];
1055
1056 xoperands[0] = reg;
1057 xoperands[1] = size;
1058 xoperands[2] = align;
1059
1060#if 1
1061 cc_status.flags &= ~ CC_KNOW_HI_R31;
b505fab8 1062 output_asm_insn (singlemove_string (xoperands), xoperands);
235d6e4f
RS
1063#else
1064 if (GET_CODE (size) == REG)
1065 output_asm_insn ("sub %2,%1,%0", xoperands);
1066 else
1067 {
1068 xoperands[1]
1069 = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align));
1070 cc_status.flags &= ~ CC_KNOW_HI_R31;
1071 output_asm_insn ("mov %1,%0", xoperands);
1072 }
1073#endif
1074}
1075
1076/* Emit code to perform a block move.
1077
1078 OPERANDS[0] is the destination.
1079 OPERANDS[1] is the source.
1080 OPERANDS[2] is the size.
1081 OPERANDS[3] is the known safe alignment.
1082 OPERANDS[4..6] are pseudos we can safely clobber as temps. */
1083
1084char *
1085output_block_move (operands)
1086 rtx *operands;
1087{
1088 /* A vector for our computed operands. Note that load_output_address
1089 makes use of (and can clobber) up to the 8th element of this vector. */
1090 rtx xoperands[10];
1091 rtx zoperands[10];
1092 static int movstrsi_label = 0;
1093 int i, j;
1094 rtx temp1 = operands[4];
1095 rtx alignrtx = operands[3];
1096 int align = INTVAL (alignrtx);
1097 int chunk_size;
1098
1099 xoperands[0] = operands[0];
1100 xoperands[1] = operands[1];
1101 xoperands[2] = temp1;
1102
1103 /* We can't move more than four bytes at a time
1104 because we have only one register to move them through. */
1105 if (align > 4)
1106 {
1107 align = 4;
1108 alignrtx = gen_rtx (CONST_INT, VOIDmode, 4);
1109 }
1110
1111 /* Recognize special cases of block moves. These occur
1112 when GNU C++ is forced to treat something as BLKmode
1113 to keep it in memory, when its mode could be represented
1114 with something smaller.
1115
1116 We cannot do this for global variables, since we don't know
1117 what pages they don't cross. Sigh. */
1118 if (GET_CODE (operands[2]) == CONST_INT
1119 && ! CONSTANT_ADDRESS_P (operands[0])
1120 && ! CONSTANT_ADDRESS_P (operands[1]))
1121 {
1122 int size = INTVAL (operands[2]);
1123 rtx op0 = xoperands[0];
1124 rtx op1 = xoperands[1];
1125
1126 if ((align & 3) == 0 && (size & 3) == 0 && (size >> 2) <= 16)
1127 {
1128 if (memory_address_p (SImode, plus_constant (op0, size))
1129 && memory_address_p (SImode, plus_constant (op1, size)))
1130 {
1131 cc_status.flags &= ~CC_KNOW_HI_R31;
1132 for (i = (size>>2)-1; i >= 0; i--)
1133 {
1134 xoperands[0] = plus_constant (op0, i * 4);
1135 xoperands[1] = plus_constant (op1, i * 4);
1136 output_asm_insn ("ld.l %a1,%?r31\n\tst.l %?r31,%a0",
1137 xoperands);
1138 }
1139 return "";
1140 }
1141 }
1142 else if ((align & 1) == 0 && (size & 1) == 0 && (size >> 1) <= 16)
1143 {
1144 if (memory_address_p (HImode, plus_constant (op0, size))
1145 && memory_address_p (HImode, plus_constant (op1, size)))
1146 {
1147 cc_status.flags &= ~CC_KNOW_HI_R31;
1148 for (i = (size>>1)-1; i >= 0; i--)
1149 {
1150 xoperands[0] = plus_constant (op0, i * 2);
1151 xoperands[1] = plus_constant (op1, i * 2);
1152 output_asm_insn ("ld.s %a1,%?r31\n\tst.s %?r31,%a0",
1153 xoperands);
1154 }
1155 return "";
1156 }
1157 }
1158 else if (size <= 16)
1159 {
1160 if (memory_address_p (QImode, plus_constant (op0, size))
1161 && memory_address_p (QImode, plus_constant (op1, size)))
1162 {
1163 cc_status.flags &= ~CC_KNOW_HI_R31;
1164 for (i = size-1; i >= 0; i--)
1165 {
1166 xoperands[0] = plus_constant (op0, i);
1167 xoperands[1] = plus_constant (op1, i);
1168 output_asm_insn ("ld.b %a1,%?r31\n\tst.b %?r31,%a0",
1169 xoperands);
1170 }
1171 return "";
1172 }
1173 }
1174 }
1175
1176 /* Since we clobber untold things, nix the condition codes. */
1177 CC_STATUS_INIT;
1178
1179 /* This is the size of the transfer.
1180 Either use the register which already contains the size,
1181 or use a free register (used by no operands). */
1182 output_size_for_block_move (operands[2], operands[4], alignrtx);
1183
1184#if 0
1185 /* Also emit code to decrement the size value by ALIGN. */
1186 zoperands[0] = operands[0];
1187 zoperands[3] = plus_constant (operands[0], align);
1188 output_load_address (zoperands);
1189#endif
1190
1191 /* Generate number for unique label. */
1192
1193 xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++);
1194
1195 /* Calculate the size of the chunks we will be trying to move first. */
1196
1197#if 0
1198 if ((align & 3) == 0)
1199 chunk_size = 4;
1200 else if ((align & 1) == 0)
1201 chunk_size = 2;
1202 else
1203#endif
1204 chunk_size = 1;
1205
1206 /* Copy the increment (negative) to a register for bla insn. */
1207
1208 xoperands[4] = gen_rtx (CONST_INT, VOIDmode, - chunk_size);
1209 xoperands[5] = operands[5];
1210 output_asm_insn ("adds %4,%?r0,%5", xoperands);
1211
1212 /* Predecrement the loop counter. This happens again also in the `bla'
b4ac57ab
RS
1213 instruction which precedes the loop, but we need to have it done
1214 two times before we enter the loop because of the bizarre semantics
235d6e4f
RS
1215 of the bla instruction. */
1216
1217 output_asm_insn ("adds %5,%2,%2", xoperands);
1218
1219 /* Check for the case where the original count was less than or equal to
1220 zero. Avoid going through the loop at all if the original count was
1221 indeed less than or equal to zero. Note that we treat the count as
1222 if it were a signed 32-bit quantity here, rather than an unsigned one,
1223 even though we really shouldn't. We have to do this because of the
1224 semantics of the `ble' instruction, which assume that the count is
1225 a signed 32-bit value. Anyway, in practice it won't matter because
1226 nobody is going to try to do a memcpy() of more than half of the
1227 entire address space (i.e. 2 gigabytes) anyway. */
1228
1229 output_asm_insn ("bc .Le%3", xoperands);
1230
1231 /* Make available a register which is a temporary. */
1232
1233 xoperands[6] = operands[6];
1234
1235 /* Now the actual loop.
1236 In xoperands, elements 1 and 0 are the input and output vectors.
1237 Element 2 is the loop index. Element 5 is the increment. */
1238
1239 output_asm_insn ("subs %1,%5,%1", xoperands);
1240 output_asm_insn ("bla %5,%2,.Lm%3", xoperands);
1241 output_asm_insn ("adds %0,%2,%6", xoperands);
1242 output_asm_insn ("\n.Lm%3:", xoperands); /* Label for bla above. */
1243 output_asm_insn ("\n.Ls%3:", xoperands); /* Loop start label. */
1244 output_asm_insn ("adds %5,%6,%6", xoperands);
1245
1246 /* NOTE: The code here which is supposed to handle the cases where the
1247 sources and destinations are known to start on a 4 or 2 byte boundary
1248 are currently broken. They fail to do anything about the overflow
1249 bytes which might still need to be copied even after we have copied
1250 some number of words or halfwords. Thus, for now we use the lowest
1251 common denominator, i.e. the code which just copies some number of
1252 totally unaligned individual bytes. (See the calculation of
1253 chunk_size above. */
1254
1255 if (chunk_size == 4)
1256 {
1257 output_asm_insn ("ld.l %2(%1),%?r31", xoperands);
1258 output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1259 output_asm_insn ("st.l %?r31,8(%6)", xoperands);
1260 }
1261 else if (chunk_size == 2)
1262 {
1263 output_asm_insn ("ld.s %2(%1),%?r31", xoperands);
1264 output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1265 output_asm_insn ("st.s %?r31,4(%6)", xoperands);
1266 }
1267 else /* chunk_size == 1 */
1268 {
1269 output_asm_insn ("ld.b %2(%1),%?r31", xoperands);
1270 output_asm_insn ("bla %5,%2,.Ls%3", xoperands);
1271 output_asm_insn ("st.b %?r31,2(%6)", xoperands);
1272 }
1273 output_asm_insn ("\n.Le%3:", xoperands); /* Here if count <= 0. */
1274
1275 return "";
1276}
1277\f
1278/* Output a delayed branch insn with the delay insn in its
1279 branch slot. The delayed branch insn template is in TEMPLATE,
1280 with operands OPERANDS. The insn in its delay slot is INSN.
1281
1282 As a special case, since we know that all memory transfers are via
1283 ld/st insns, if we see a (MEM (SYMBOL_REF ...)) we divide the memory
1284 reference around the branch as
1285
1286 orh ha%x,%?r0,%?r31
1287 b ...
1288 ld/st l%x(%?r31),...
1289
1290 As another special case, we handle loading (SYMBOL_REF ...) and
1291 other large constants around branches as well:
1292
1293 orh h%x,%?r0,%0
1294 b ...
1295 or l%x,%0,%1
1296
1297 */
1298
1299char *
1300output_delayed_branch (template, operands, insn)
1301 char *template;
1302 rtx *operands;
1303 rtx insn;
1304{
1305 rtx src = XVECEXP (PATTERN (insn), 0, 1);
1306 rtx dest = XVECEXP (PATTERN (insn), 0, 0);
1307
1308 /* See if we are doing some branch together with setting some register
1309 to some 32-bit value which does (or may) have some of the high-order
1310 16 bits set. If so, we need to set the register in two stages. One
1311 stage must be done before the branch, and the other one can be done
1312 in the delay slot. */
1313
1314 if ( (GET_CODE (src) == CONST_INT
1315 && ((unsigned) INTVAL (src) & (unsigned) 0xffff0000) != (unsigned) 0)
1316 || (GET_CODE (src) == SYMBOL_REF)
1317 || (GET_CODE (src) == LABEL_REF)
1318 || (GET_CODE (src) == CONST))
1319 {
1320 rtx xoperands[2];
1321 xoperands[0] = dest;
1322 xoperands[1] = src;
1323
1324 CC_STATUS_PARTIAL_INIT;
1325 /* Output the `orh' insn. */
1326 output_asm_insn ("orh %H1,%?r0,%0", xoperands);
1327
1328 /* Output the branch instruction next. */
1329 output_asm_insn (template, operands);
1330
1331 /* Now output the `or' insn. */
1332 output_asm_insn ("or %L1,%0,%0", xoperands);
1333 }
1334 else if ((GET_CODE (src) == MEM
1335 && CONSTANT_ADDRESS_P (XEXP (src, 0)))
1336 || (GET_CODE (dest) == MEM
1337 && CONSTANT_ADDRESS_P (XEXP (dest, 0))))
1338 {
1339 rtx xoperands[2];
1340 char *split_template;
1341 xoperands[0] = dest;
1342 xoperands[1] = src;
1343
1344 /* Output the `orh' insn. */
1345 if (GET_CODE (src) == MEM)
1346 {
1347 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1348 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1349 && cc_prev_status.mdep == XEXP (operands[1], 0)))
1350 {
1351 CC_STATUS_INIT;
1352 output_asm_insn ("orh %h1,%?r0,%?r31", xoperands);
1353 }
1354 split_template = load_opcode (GET_MODE (dest),
1355 "%L1(%?r31),%0", dest);
1356 }
1357 else
1358 {
1359 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31)
1360 && (cc_prev_status.flags & CC_HI_R31_ADJ)
1361 && cc_prev_status.mdep == XEXP (operands[0], 0)))
1362 {
1363 CC_STATUS_INIT;
1364 output_asm_insn ("orh %h0,%?r0,%?r31", xoperands);
1365 }
1366 split_template = store_opcode (GET_MODE (dest),
1367 "%r1,%L0(%?r31)", src);
1368 }
1369
1370 /* Output the branch instruction next. */
1371 output_asm_insn (template, operands);
1372
1373 /* Now output the load or store.
1374 No need to do a CC_STATUS_INIT, because we are branching anyway. */
1375 output_asm_insn (split_template, xoperands);
1376 }
1377 else
1378 {
1379 int insn_code_number;
1380 rtx pat = gen_rtx (SET, VOIDmode, dest, src);
1381 rtx delay_insn = gen_rtx (INSN, VOIDmode, 0, 0, 0, pat, -1, 0, 0);
1382 int i;
1383
1384 /* Output the branch instruction first. */
1385 output_asm_insn (template, operands);
1386
1387 /* Now recognize the insn which we put in its delay slot.
b4ac57ab 1388 We must do this after outputting the branch insn,
235d6e4f
RS
1389 since operands may just be a pointer to `recog_operand'. */
1390 INSN_CODE (delay_insn) = insn_code_number = recog (pat, delay_insn);
1391 if (insn_code_number == -1)
1392 abort ();
1393
1394 for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1395 {
1396 if (GET_CODE (recog_operand[i]) == SUBREG)
1397 recog_operand[i] = alter_subreg (recog_operand[i]);
1398 }
1399
1400 insn_extract (delay_insn);
1401 if (! constrain_operands (insn_code_number, 1))
1402 fatal_insn_not_found (delay_insn);
1403
1404 template = insn_template[insn_code_number];
1405 if (template == 0)
1406 template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
1407 output_asm_insn (template, recog_operand);
1408 }
1409 CC_STATUS_INIT;
1410 return "";
1411}
1412
1413/* Output a newly constructed insn DELAY_INSN. */
1414char *
1415output_delay_insn (delay_insn)
1416 rtx delay_insn;
1417{
1418 char *template;
1419 int insn_code_number;
1420 int i;
1421
1422 /* Now recognize the insn which we put in its delay slot.
b4ac57ab 1423 We must do this after outputting the branch insn,
235d6e4f
RS
1424 since operands may just be a pointer to `recog_operand'. */
1425 insn_code_number = recog_memoized (delay_insn);
1426 if (insn_code_number == -1)
1427 abort ();
1428
1429 /* Extract the operands of this delay insn. */
1430 INSN_CODE (delay_insn) = insn_code_number;
1431 insn_extract (delay_insn);
1432
b4ac57ab 1433 /* It is possible that this insn has not been properly scanned by final
235d6e4f
RS
1434 yet. If this insn's operands don't appear in the peephole's
1435 actual operands, then they won't be fixed up by final, so we
1436 make sure they get fixed up here. -- This is a kludge. */
1437 for (i = 0; i < insn_n_operands[insn_code_number]; i++)
1438 {
1439 if (GET_CODE (recog_operand[i]) == SUBREG)
1440 recog_operand[i] = alter_subreg (recog_operand[i]);
1441 }
1442
1443#ifdef REGISTER_CONSTRAINTS
1444 if (! constrain_operands (insn_code_number))
1445 abort ();
1446#endif
1447
1448 cc_prev_status = cc_status;
1449
1450 /* Update `cc_status' for this instruction.
1451 The instruction's output routine may change it further.
1452 If the output routine for a jump insn needs to depend
1453 on the cc status, it should look at cc_prev_status. */
1454
1455 NOTICE_UPDATE_CC (PATTERN (delay_insn), delay_insn);
1456
1457 /* Now get the template for what this insn would
1458 have been, without the branch. */
1459
1460 template = insn_template[insn_code_number];
1461 if (template == 0)
1462 template = (*insn_outfun[insn_code_number]) (recog_operand, delay_insn);
1463 output_asm_insn (template, recog_operand);
1464 return "";
1465}
1466\f
1467/* Special routine to convert an SFmode value represented as a
1468 CONST_DOUBLE into its equivalent unsigned long bit pattern.
1469 We convert the value from a double precision floating-point
1470 value to single precision first, and thence to a bit-wise
1471 equivalent unsigned long value. This routine is used when
1472 generating an immediate move of an SFmode value directly
1473 into a general register because the svr4 assembler doesn't
1474 grok floating literals in instruction operand contexts. */
1475
1476unsigned long
1477sfmode_constant_to_ulong (x)
1478 rtx x;
1479{
05795922 1480 REAL_VALUE_TYPE d;
235d6e4f
RS
1481 union { float f; unsigned long i; } u2;
1482
1483 if (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != SFmode)
1484 abort ();
1485
05795922 1486#if TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT
b505fab8 1487 error IEEE emulation needed
235d6e4f 1488#endif
b4ac57ab 1489 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
05795922 1490 u2.f = d;
235d6e4f
RS
1491 return u2.i;
1492}
1493\f
1494/* This function generates the assembly code for function entry.
1495 The macro FUNCTION_PROLOGUE in i860.h is defined to call this function.
1496
1497 ASM_FILE is a stdio stream to output the code to.
1498 SIZE is an int: how many units of temporary storage to allocate.
1499
1500 Refer to the array `regs_ever_live' to determine which registers
1501 to save; `regs_ever_live[I]' is nonzero if register number I
1502 is ever used in the function. This macro is responsible for
1503 knowing which registers should not be saved even if used.
1504
1505 NOTE: `frame_lower_bytes' is the count of bytes which will lie
1506 between the new `fp' value and the new `sp' value after the
1507 prologue is done. `frame_upper_bytes' is the count of bytes
1508 that will lie between the new `fp' and the *old* `sp' value
1509 after the new `fp' is setup (in the prologue). The upper
1510 part of each frame always includes at least 2 words (8 bytes)
1511 to hold the saved frame pointer and the saved return address.
1512
1513 The svr4 ABI for the i860 now requires that the values of the
1514 stack pointer and frame pointer registers be kept aligned to
1515 16-byte boundaries at all times. We obey that restriction here.
1516
1517 The svr4 ABI for the i860 is entirely vague when it comes to specifying
1518 exactly where the "preserved" registers should be saved. The native
1519 svr4 C compiler I now have doesn't help to clarify the requirements
1520 very much because it is plainly out-of-date and non-ABI-compliant
1521 (in at least one important way, i.e. how it generates function
1522 epilogues).
1523
1524 The native svr4 C compiler saves the "preserved" registers (i.e.
1525 r4-r15 and f2-f7) in the lower part of a frame (i.e. at negative
1526 offsets from the frame pointer).
1527
1528 Previous versions of GCC also saved the "preserved" registers in the
b4ac57ab 1529 "negative" part of the frame, but they saved them using positive
235d6e4f
RS
1530 offsets from the (adjusted) stack pointer (after it had been adjusted
1531 to allocate space for the new frame). That's just plain wrong
1532 because if the current function calls alloca(), the stack pointer
1533 will get moved, and it will be impossible to restore the registers
1534 properly again after that.
1535
1536 Both compilers handled parameter registers (i.e. r16-r27 and f8-f15)
1537 by copying their values either into various "preserved" registers or
1538 into stack slots in the lower part of the current frame (as seemed
1539 appropriate, depending upon subsequent usage of these values).
1540
1541 Here we want to save the preserved registers at some offset from the
1542 frame pointer register so as to avoid any possible problems arising
1543 from calls to alloca(). We can either save them at small positive
1544 offsets from the frame pointer, or at small negative offsets from
1545 the frame pointer. If we save them at small negative offsets from
1546 the frame pointer (i.e. in the lower part of the frame) then we
1547 must tell the rest of GCC (via STARTING_FRAME_OFFSET) exactly how
1548 many bytes of space we plan to use in the lower part of the frame
1549 for this purpose. Since other parts of the compiler reference the
1550 value of STARTING_FRAME_OFFSET long before final() calls this function,
1551 we would have to go ahead and assume the worst-case storage requirements
1552 for saving all of the "preserved" registers (and use that number, i.e.
1553 `80', to define STARTING_FRAME_OFFSET) if we wanted to save them in
1554 the lower part of the frame. That could potentially be very wasteful,
de86a82e 1555 and that wastefulness could really hamper people compiling for embedded
235d6e4f
RS
1556 i860 targets with very tight limits on stack space. Thus, we choose
1557 here to save the preserved registers in the upper part of the
1558 frame, so that we can decide at the very last minute how much (or how
1559 little) space we must allocate for this purpose.
1560
1561 To satisfy the needs of the svr4 ABI "tdesc" scheme, preserved
1562 registers must always be saved so that the saved values of registers
1563 with higher numbers are at higher addresses. We obey that restriction
1564 here.
1565
1566 There are two somewhat different ways that you can generate prologues
1567 here... i.e. pedantically ABI-compliant, and the "other" way. The
b4ac57ab 1568 "other" way is more consistent with what is currently generated by the
235d6e4f
RS
1569 "native" svr4 C compiler for the i860. That's important if you want
1570 to use the current (as of 8/91) incarnation of svr4 SDB for the i860.
1571 The SVR4 SDB for the i860 insists on having function prologues be
1572 non-ABI-compliant!
1573
1574 To get fully ABI-compliant prologues, define I860_STRICT_ABI_PROLOGUES
1575 in the i860svr4.h file. (By default this is *not* defined).
1576
1577 The differences between the ABI-compliant and non-ABI-compliant prologues
1578 are that (a) the ABI version seems to require the use of *signed*
1579 (rather than unsigned) adds and subtracts, and (b) the ordering of
1580 the various steps (e.g. saving preserved registers, saving the
1581 return address, setting up the new frame pointer value) is different.
1582
1583 For strict ABI compliance, it seems to be the case that the very last
1584 thing that is supposed to happen in the prologue is getting the frame
1585 pointer set to its new value (but only after everything else has
1586 already been properly setup). We do that here, but only if the symbol
1587 I860_STRICT_ABI_PROLOGUES is defined.
1588*/
1589
1590#ifndef STACK_ALIGNMENT
1591#define STACK_ALIGNMENT 16
1592#endif
1593
1594extern char call_used_regs[];
1595extern int leaf_function_p ();
1596
1597char *current_function_original_name;
1598
1599static int must_preserve_r1;
1600static unsigned must_preserve_bytes;
1601
1602void
1603function_prologue (asm_file, local_bytes)
1604 register FILE *asm_file;
1605 register unsigned local_bytes;
1606{
1607 register unsigned frame_lower_bytes;
1608 register unsigned frame_upper_bytes;
1609 register unsigned total_fsize;
1610 register unsigned preserved_reg_bytes = 0;
1611 register unsigned i;
1612 register unsigned preserved_so_far = 0;
1613
1614 must_preserve_r1 = (optimize < 2 || ! leaf_function_p ());
1615 must_preserve_bytes = 4 + (must_preserve_r1 ? 4 : 0);
1616
1617 /* Count registers that need preserving. Ignore r0. It never needs
1618 preserving. */
1619
1620 for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
1621 {
1622 if (regs_ever_live[i] && ! call_used_regs[i])
1623 preserved_reg_bytes += 4;
1624 }
1625
1626 /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
1627
1628 frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1629
1630 /* The upper part of each frame will contain the saved fp,
1631 the saved r1, and stack slots for all of the other "preserved"
1632 registers that we find we will need to save & restore. */
1633
1634 frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
1635
1636 /* Round-up the frame_upper_bytes so that it's a multiple of 16. */
1637
1638 frame_upper_bytes
1639 = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1640
1641 total_fsize = frame_upper_bytes + frame_lower_bytes;
1642
1643#ifndef I860_STRICT_ABI_PROLOGUES
1644
1645 /* There are two kinds of function prologues.
1646 You use the "small" version if the total frame size is
1647 small enough so that it can fit into an immediate 16-bit
1648 value in one instruction. Otherwise, you use the "large"
1649 version of the function prologue. */
1650
1651 if (total_fsize > 0x7fff)
1652 {
1653 /* Adjust the stack pointer. The ABI sez to do this using `adds',
1654 but the native C compiler on svr4 uses `addu'. */
1655
1656 fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
1657 frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
1658
1659 /* Save the old frame pointer. */
1660
1661 fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
1662 i860_reg_prefix, i860_reg_prefix);
1663
1664 /* Setup the new frame pointer. The ABI sez to do this after
1665 preserving registers (using adds), but that's not what the
1666 native C compiler on svr4 does. */
1667
1668 fprintf (asm_file, "\taddu 0,%ssp,%sfp\n",
1669 i860_reg_prefix, i860_reg_prefix);
1670
1671 /* Get the value of frame_lower_bytes into r31. */
1672
1673 fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
1674 frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
1675 fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
1676 frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
1677
1678 /* Now re-adjust the stack pointer using the value in r31.
1679 The ABI sez to do this with `subs' but SDB may prefer `subu'. */
1680
1681 fprintf (asm_file, "\tsubu %ssp,%sr31,%ssp\n",
1682 i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1683
1684 /* Preserve registers. The ABI sez to do this before setting
1685 up the new frame pointer, but that's not what the native
1686 C compiler on svr4 does. */
1687
1688 for (i = 1; i < 32; i++)
1689 if (regs_ever_live[i] && ! call_used_regs[i])
1690 fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
1691 i860_reg_prefix, reg_names[i],
1692 must_preserve_bytes + (4 * preserved_so_far++),
1693 i860_reg_prefix);
1694
1695 for (i = 32; i < 64; i++)
1696 if (regs_ever_live[i] && ! call_used_regs[i])
1697 fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
1698 i860_reg_prefix, reg_names[i],
1699 must_preserve_bytes + (4 * preserved_so_far++),
1700 i860_reg_prefix);
1701
1702 /* Save the return address. */
1703
1704 if (must_preserve_r1)
1705 fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
1706 i860_reg_prefix, i860_reg_prefix);
1707 }
1708 else
1709 {
1710 /* Adjust the stack pointer. The ABI sez to do this using `adds',
1711 but the native C compiler on svr4 uses `addu'. */
1712
1713 fprintf (asm_file, "\taddu -%d,%ssp,%ssp\n",
1714 total_fsize, i860_reg_prefix, i860_reg_prefix);
1715
1716 /* Save the old frame pointer. */
1717
1718 fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
1719 i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
1720
1721 /* Setup the new frame pointer. The ABI sez to do this after
1722 preserving registers and after saving the return address,
1723 (and its saz to do this using adds), but that's not what the
1724 native C compiler on svr4 does. */
1725
1726 fprintf (asm_file, "\taddu %d,%ssp,%sfp\n",
1727 frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
1728
1729 /* Preserve registers. The ABI sez to do this before setting
1730 up the new frame pointer, but that's not what the native
1731 compiler on svr4 does. */
1732
1733 for (i = 1; i < 32; i++)
1734 if (regs_ever_live[i] && ! call_used_regs[i])
1735 fprintf (asm_file, "\tst.l %s%s,%d(%sfp)\n",
1736 i860_reg_prefix, reg_names[i],
1737 must_preserve_bytes + (4 * preserved_so_far++),
1738 i860_reg_prefix);
1739
1740 for (i = 32; i < 64; i++)
1741 if (regs_ever_live[i] && ! call_used_regs[i])
1742 fprintf (asm_file, "\tfst.l %s%s,%d(%sfp)\n",
1743 i860_reg_prefix, reg_names[i],
1744 must_preserve_bytes + (4 * preserved_so_far++),
1745 i860_reg_prefix);
1746
1747 /* Save the return address. The ABI sez to do this earlier,
1748 and also via an offset from %sp, but the native C compiler
1749 on svr4 does it later (i.e. now) and uses an offset from
1750 %fp. */
1751
1752 if (must_preserve_r1)
1753 fprintf (asm_file, "\tst.l %sr1,4(%sfp)\n",
1754 i860_reg_prefix, i860_reg_prefix);
1755 }
1756
1757#else /* defined(I860_STRICT_ABI_PROLOGUES) */
1758
1759 /* There are two kinds of function prologues.
1760 You use the "small" version if the total frame size is
1761 small enough so that it can fit into an immediate 16-bit
1762 value in one instruction. Otherwise, you use the "large"
1763 version of the function prologue. */
1764
1765 if (total_fsize > 0x7fff)
1766 {
1767 /* Adjust the stack pointer (thereby allocating a new frame). */
1768
1769 fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
1770 frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
1771
1772 /* Save the caller's frame pointer. */
1773
1774 fprintf (asm_file, "\tst.l %sfp,0(%ssp)\n",
1775 i860_reg_prefix, i860_reg_prefix);
1776
1777 /* Save return address. */
1778
1779 if (must_preserve_r1)
1780 fprintf (asm_file, "\tst.l %sr1,4(%ssp)\n",
1781 i860_reg_prefix, i860_reg_prefix);
1782
1783 /* Get the value of frame_lower_bytes into r31 for later use. */
1784
1785 fprintf (asm_file, "\torh %d,%sr0,%sr31\n",
1786 frame_lower_bytes >> 16, i860_reg_prefix, i860_reg_prefix);
1787 fprintf (asm_file, "\tor %d,%sr31,%sr31\n",
1788 frame_lower_bytes & 0xffff, i860_reg_prefix, i860_reg_prefix);
1789
1790 /* Now re-adjust the stack pointer using the value in r31. */
1791
1792 fprintf (asm_file, "\tsubs %ssp,%sr31,%ssp\n",
1793 i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1794
1795 /* Pre-compute value to be used as the new frame pointer. */
1796
1797 fprintf (asm_file, "\tadds %ssp,%sr31,%sr31\n",
1798 i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
1799
1800 /* Preserve registers. */
1801
1802 for (i = 1; i < 32; i++)
1803 if (regs_ever_live[i] && ! call_used_regs[i])
1804 fprintf (asm_file, "\tst.l %s%s,%d(%sr31)\n",
1805 i860_reg_prefix, reg_names[i],
1806 must_preserve_bytes + (4 * preserved_so_far++),
1807 i860_reg_prefix);
1808
1809 for (i = 32; i < 64; i++)
1810 if (regs_ever_live[i] && ! call_used_regs[i])
1811 fprintf (asm_file, "\tfst.l %s%s,%d(%sr31)\n",
1812 i860_reg_prefix, reg_names[i],
1813 must_preserve_bytes + (4 * preserved_so_far++),
1814 i860_reg_prefix);
1815
1816 /* Actually set the new value of the frame pointer. */
1817
1818 fprintf (asm_file, "\tmov %sr31,%sfp\n",
1819 i860_reg_prefix, i860_reg_prefix);
1820 }
1821 else
1822 {
1823 /* Adjust the stack pointer. */
1824
1825 fprintf (asm_file, "\tadds -%d,%ssp,%ssp\n",
1826 total_fsize, i860_reg_prefix, i860_reg_prefix);
1827
1828 /* Save the caller's frame pointer. */
1829
1830 fprintf (asm_file, "\tst.l %sfp,%d(%ssp)\n",
1831 i860_reg_prefix, frame_lower_bytes, i860_reg_prefix);
1832
1833 /* Save the return address. */
1834
1835 if (must_preserve_r1)
1836 fprintf (asm_file, "\tst.l %sr1,%d(%ssp)\n",
1837 i860_reg_prefix, frame_lower_bytes + 4, i860_reg_prefix);
1838
1839 /* Preserve registers. */
1840
1841 for (i = 1; i < 32; i++)
1842 if (regs_ever_live[i] && ! call_used_regs[i])
1843 fprintf (asm_file, "\tst.l %s%s,%d(%ssp)\n",
1844 i860_reg_prefix, reg_names[i],
1845 frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
1846 i860_reg_prefix);
1847
1848 for (i = 32; i < 64; i++)
1849 if (regs_ever_live[i] && ! call_used_regs[i])
1850 fprintf (asm_file, "\tfst.l %s%s,%d(%ssp)\n",
1851 i860_reg_prefix, reg_names[i],
1852 frame_lower_bytes + must_preserve_bytes + (4 * preserved_so_far++),
1853 i860_reg_prefix);
1854
1855 /* Setup the new frame pointer. */
1856
1857 fprintf (asm_file, "\tadds %d,%ssp,%sfp\n",
1858 frame_lower_bytes, i860_reg_prefix, i860_reg_prefix);
1859 }
1860#endif /* defined(I860_STRICT_ABI_PROLOGUES) */
1861
1862#ifdef ASM_OUTPUT_PROLOGUE_SUFFIX
1863 ASM_OUTPUT_PROLOGUE_SUFFIX (asm_file);
1864#endif /* defined(ASM_OUTPUT_PROLOGUE_SUFFIX) */
1865}
1866\f
1867/* This function generates the assembly code for function exit.
1868 The macro FUNCTION_EPILOGUE in i860.h is defined to call this function.
1869
1870 ASM_FILE is a stdio stream to output the code to.
1871 SIZE is an int: how many units of temporary storage to allocate.
1872
1873 The function epilogue should not depend on the current stack pointer!
1874 It should use the frame pointer only. This is mandatory because
1875 of alloca; we also take advantage of it to omit stack adjustments
1876 before returning.
1877
1878 Note that when we go to restore the preserved register values we must
1879 not try to address their slots by using offsets from the stack pointer.
1880 That's because the stack pointer may have been moved during the function
1881 execution due to a call to alloca(). Rather, we must restore all
1882 preserved registers via offsets from the frame pointer value.
1883
1884 Note also that when the current frame is being "popped" (by adjusting
1885 the value of the stack pointer) on function exit, we must (for the
1886 sake of alloca) set the new value of the stack pointer based upon
1887 the current value of the frame pointer. We can't just add what we
1888 believe to be the (static) frame size to the stack pointer because
1889 if we did that, and alloca() had been called during this function,
1890 we would end up returning *without* having fully deallocated all of
1891 the space grabbed by alloca. If that happened, and a function
1892 containing one or more alloca() calls was called over and over again,
1893 then the stack would grow without limit!
1894
1895 Finally note that the epilogues generated here are completely ABI
1896 compliant. They go out of their way to insure that the value in
1897 the frame pointer register is never less than the value in the stack
1898 pointer register. It's not clear why this relationship needs to be
1899 maintained at all times, but maintaining it only costs one extra
1900 instruction, so what the hell.
1901*/
1902
e241407e
RS
1903/* This corresponds to a version 4 TDESC structure. Lower numbered
1904 versions successively omit the last word of the structure. We
1905 don't try to handle version 5 here. */
1906
1907typedef struct TDESC_flags {
1908 int version:4;
1909 int reg_packing:1;
1910 int callable_block:1;
1911 int reserved:4;
1912 int fregs:6; /* fp regs 2-7 */
1913 int iregs:16; /* regs 0-15 */
1914} TDESC_flags;
1915
1916typedef struct TDESC {
1917 TDESC_flags flags;
1918 int integer_reg_offset; /* same as must_preserve_bytes */
1919 int floating_point_reg_offset;
1920 unsigned int positive_frame_size; /* same as frame_upper_bytes */
1921 unsigned int negative_frame_size; /* same as frame_lower_bytes */
1922} TDESC;
1923
235d6e4f
RS
1924void
1925function_epilogue (asm_file, local_bytes)
1926 register FILE *asm_file;
1927 register unsigned local_bytes;
1928{
1929 register unsigned frame_upper_bytes;
e241407e 1930 register unsigned frame_lower_bytes;
235d6e4f
RS
1931 register unsigned preserved_reg_bytes = 0;
1932 register unsigned i;
1933 register unsigned restored_so_far = 0;
e241407e
RS
1934 register unsigned int_restored;
1935 register unsigned mask;
1936 unsigned intflags=0;
1937 register TDESC_flags *flags = (TDESC_flags *) &intflags;
1938
1939 flags->version = 4;
1940 flags->reg_packing = 1;
1941 flags->iregs = 8; /* old fp always gets saved */
1942
1943 /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
1944
1945 frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
235d6e4f
RS
1946
1947 /* Count the number of registers that were preserved in the prologue.
1948 Ignore r0. It is never preserved. */
1949
1950 for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
1951 {
1952 if (regs_ever_live[i] && ! call_used_regs[i])
1953 preserved_reg_bytes += 4;
1954 }
1955
1956 /* The upper part of each frame will contain only saved fp,
1957 the saved r1, and stack slots for all of the other "preserved"
1958 registers that we find we will need to save & restore. */
1959
1960 frame_upper_bytes = must_preserve_bytes + preserved_reg_bytes;
1961
1962 /* Round-up frame_upper_bytes so that t is a multiple of 16. */
1963
1964 frame_upper_bytes
1965 = (frame_upper_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
1966
1967 /* Restore all of the "preserved" registers that need restoring. */
1968
e241407e
RS
1969 mask = 2;
1970
1971 for (i = 1; i < 32; i++, mask<<=1)
1972 if (regs_ever_live[i] && ! call_used_regs[i]) {
235d6e4f
RS
1973 fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n",
1974 must_preserve_bytes + (4 * restored_so_far++),
1975 i860_reg_prefix, i860_reg_prefix, reg_names[i]);
e241407e
RS
1976 if (i > 3 && i < 16)
1977 flags->iregs |= mask;
1978 }
1979
1980 int_restored = restored_so_far;
1981 mask = 1;
235d6e4f 1982
e241407e
RS
1983 for (i = 32; i < 64; i++) {
1984 if (regs_ever_live[i] && ! call_used_regs[i]) {
235d6e4f
RS
1985 fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n",
1986 must_preserve_bytes + (4 * restored_so_far++),
1987 i860_reg_prefix, i860_reg_prefix, reg_names[i]);
e241407e
RS
1988 if (i > 33 & i < 40)
1989 flags->fregs |= mask;
1990 }
1991 if (i > 33 && i < 40)
1992 mask<<=1;
1993 }
235d6e4f
RS
1994
1995 /* Get the value we plan to use to restore the stack pointer into r31. */
1996
1997 fprintf (asm_file, "\tadds %d,%sfp,%sr31\n",
1998 frame_upper_bytes, i860_reg_prefix, i860_reg_prefix);
1999
2000 /* Restore the return address and the old frame pointer. */
2001
e241407e 2002 if (must_preserve_r1) {
235d6e4f
RS
2003 fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n",
2004 i860_reg_prefix, i860_reg_prefix);
e241407e
RS
2005 flags->iregs |= 2;
2006 }
235d6e4f
RS
2007
2008 fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n",
2009 i860_reg_prefix, i860_reg_prefix);
2010
2011 /* Return and restore the old stack pointer value. */
2012
2013 fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n",
2014 i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
e241407e
RS
2015
2016#ifdef OUTPUT_TDESC /* Output an ABI-compliant TDESC entry */
2017 if (! frame_lower_bytes) {
2018 flags->version--;
2019 if (! frame_upper_bytes) {
2020 flags->version--;
2021 if (restored_so_far == int_restored) /* No FP saves */
2022 flags->version--;
2023 }
2024 }
2025 assemble_name(asm_file,current_function_original_name);
2026 fputs(".TDESC:\n", asm_file);
2027 fprintf(asm_file, "%s 0x%0x\n", ASM_LONG, intflags);
2028 fprintf(asm_file, "%s %d\n", ASM_LONG,
2029 int_restored ? must_preserve_bytes : 0);
2030 if (flags->version > 1) {
2031 fprintf(asm_file, "%s %d\n", ASM_LONG,
2032 (restored_so_far == int_restored) ? 0 : must_preserve_bytes +
2033 (4 * int_restored));
2034 if (flags->version > 2) {
2035 fprintf(asm_file, "%s %d\n", ASM_LONG, frame_upper_bytes);
2036 if (flags->version > 3)
2037 fprintf(asm_file, "%s %d\n", ASM_LONG, frame_lower_bytes);
2038 }
2039 }
2040 tdesc_section();
2041 fprintf(asm_file, "%s ", ASM_LONG);
2042 assemble_name(asm_file, current_function_original_name);
2043 fprintf(asm_file, "\n%s ", ASM_LONG);
2044 assemble_name(asm_file, current_function_original_name);
2045 fputs(".TDESC\n", asm_file);
2046 text_section();
2047#endif
235d6e4f 2048}
This page took 0.26644 seconds and 5 git commands to generate.