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