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