entered into RCS
[gcc.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2 Copyright (C) 1992 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@nyu.edu)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22 #include <stdio.h>
23 #include "config.h"
24 #include "rtl.h"
25 #include "regs.h"
26 #include "hard-reg-set.h"
27 #include "real.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "insn-flags.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "reload.h"
36 #include "expr.h"
37 #include "obstack.h"
38 #include "tree.h"
39
40 /* Save information from a "cmpxx" operation until the branch or scc is
41 emitted. */
42
43 rtx alpha_compare_op0, alpha_compare_op1;
44 int alpha_compare_fp_p;
45
46 /* Save the name of the current function as used by the assembler. This
47 is used by the epilogue. */
48
49 char *alpha_function_name;
50
51 /* Nonzero if the current function needs gp. */
52
53 int alpha_function_needs_gp;
54 \f
55 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
56
57 int
58 zap_mask (value)
59 HOST_WIDE_INT value;
60 {
61 int i;
62
63 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
64 i++, value >>= 8)
65 if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
66 return 0;
67
68 return 1;
69 }
70
71 /* Returns 1 if OP is either the constant zero or a register. If a
72 register, it must be in the proper mode unless MODE is VOIDmode. */
73
74 int
75 reg_or_0_operand (op, mode)
76 register rtx op;
77 enum machine_mode mode;
78 {
79 return op == const0_rtx || register_operand (op, mode);
80 }
81
82 /* Return 1 if OP is an 8-bit constant or any register. */
83
84 int
85 reg_or_8bit_operand (op, mode)
86 register rtx op;
87 enum machine_mode mode;
88 {
89 return ((GET_CODE (op) == CONST_INT
90 && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
91 || register_operand (op, mode));
92 }
93
94 /* Return 1 if the operand is a valid second operand to an add insn. */
95
96 int
97 add_operand (op, mode)
98 register rtx op;
99 enum machine_mode mode;
100 {
101 if (GET_CODE (op) == CONST_INT)
102 return ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000
103 || ((INTVAL (op) & 0xffff) == 0
104 && (INTVAL (op) >> 31 == -1
105 || INTVAL (op) >> 31 == 0)));
106
107 return register_operand (op, mode);
108 }
109
110 /* Return 1 if the operand is a valid second operand to a sign-extending
111 add insn. */
112
113 int
114 sext_add_operand (op, mode)
115 register rtx op;
116 enum machine_mode mode;
117 {
118 if (GET_CODE (op) == CONST_INT)
119 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
120 || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
121
122 return register_operand (op, mode);
123 }
124
125 /* Return 1 if OP is the constant 4 or 8. */
126
127 int
128 const48_operand (op, mode)
129 register rtx op;
130 enum machine_mode mode;
131 {
132 return (GET_CODE (op) == CONST_INT
133 && (INTVAL (op) == 4 || INTVAL (op) == 8));
134 }
135
136 /* Return 1 if OP is a valid first operand to an AND insn. */
137
138 int
139 and_operand (op, mode)
140 register rtx op;
141 enum machine_mode mode;
142 {
143 if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
144 return (zap_mask (CONST_DOUBLE_LOW (op))
145 && zap_mask (CONST_DOUBLE_HIGH (op)));
146
147 if (GET_CODE (op) == CONST_INT)
148 return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
149 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
150 || zap_mask (INTVAL (op)));
151
152 return register_operand (op, mode);
153 }
154
155 /* Return 1 if OP is a constant that is the width, in bits, of an integral
156 mode smaller than DImode. */
157
158 int
159 mode_width_operand (op, mode)
160 register rtx op;
161 enum machine_mode mode;
162 {
163 return (GET_CODE (op) == CONST_INT
164 && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
165 }
166
167 /* Return 1 if OP is a constant that is the width of an integral machine mode
168 smaller than an integer. */
169
170 int
171 mode_mask_operand (op, mode)
172 register rtx op;
173 enum machine_mode mode;
174 {
175 #if HOST_BITS_PER_WIDE_INT == 32
176 if (GET_CODE (op) == CONST_DOUBLE)
177 return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
178 #endif
179
180 if (GET_CODE (op) == CONST_INT)
181 return (INTVAL (op) == 0xff
182 || INTVAL (op) == 0xffff
183 #if HOST_BITS_PER_WIDE_INT == 64
184 || INTVAL (op) == 0xffffffff
185 #endif
186 );
187 }
188
189 /* Return 1 if OP is a multiple of 8 less than 64. */
190
191 int
192 mul8_operand (op, mode)
193 register rtx op;
194 enum machine_mode mode;
195 {
196 return (GET_CODE (op) == CONST_INT
197 && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
198 && (INTVAL (op) & 7) == 0);
199 }
200
201 /* Return 1 if OP is the constant zero in floating-point. */
202
203 int
204 fp0_operand (op, mode)
205 register rtx op;
206 enum machine_mode mode;
207 {
208 return (GET_MODE (op) == mode
209 && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
210 }
211
212 /* Return 1 if OP is the floating-point constant zero or a register. */
213
214 int
215 reg_or_fp0_operand (op, mode)
216 register rtx op;
217 enum machine_mode mode;
218 {
219 return fp0_operand (op, mode) || register_operand (op, mode);
220 }
221
222 /* Return 1 if OP is a register or a constant integer. */
223
224
225 int
226 reg_or_cint_operand (op, mode)
227 register rtx op;
228 enum machine_mode mode;
229 {
230 return GET_CODE (op) == CONST_INT || register_operand (op, mode);
231 }
232
233 /* Return 1 if OP is a valid operand for the source of a move insn. */
234
235 int
236 input_operand (op, mode)
237 register rtx op;
238 enum machine_mode mode;
239 {
240 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
241 return 0;
242
243 if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
244 return 0;
245
246 switch (GET_CODE (op))
247 {
248 case LABEL_REF:
249 case SYMBOL_REF:
250 case CONST:
251 return mode == DImode;
252
253 case REG:
254 return 1;
255
256 case SUBREG:
257 if (register_operand (op, mode))
258 return 1;
259 /* ... fall through ... */
260 case MEM:
261 return mode != HImode && mode != QImode && general_operand (op, mode);
262
263 case CONST_DOUBLE:
264 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
265
266 case CONST_INT:
267 return mode == QImode || mode == HImode || add_operand (op, mode);
268 }
269
270 return 0;
271 }
272
273 /* Return 1 if OP is a SYMBOL_REF for the current function. */
274
275 int
276 current_function_operand (op, mode)
277 rtx op;
278 enum machine_mode mode;
279 {
280 return (GET_CODE (op) == SYMBOL_REF
281 && ! strcmp (XSTR (op, 0), current_function_name));
282 }
283
284 /* Return 1 if OP is a valid Alpha comparison operator. Here we know which
285 comparisons are valid in which insn. */
286
287 int
288 alpha_comparison_operator (op, mode)
289 register rtx op;
290 enum machine_mode mode;
291 {
292 enum rtx_code code = GET_CODE (op);
293
294 if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
295 return 0;
296
297 return (code == EQ || code == LE || code == LT
298 || (mode == DImode && (code == LEU || code == LTU)));
299 }
300
301 /* Return 1 if OP is a signed comparison operation. */
302
303 int
304 signed_comparison_operator (op, mode)
305 register rtx op;
306 enum machine_mode mode;
307 {
308 switch (GET_CODE (op))
309 {
310 case EQ: case NE: case LE: case LT: case GE: case GT:
311 return 1;
312 }
313
314 return 0;
315 }
316
317 /* Return 1 if this is a divide or modulus operator. */
318
319 int
320 divmod_operator (op, mode)
321 register rtx op;
322 enum machine_mode mode;
323 {
324 switch (GET_CODE (op))
325 {
326 case DIV: case MOD: case UDIV: case UMOD:
327 return 1;
328 }
329
330 return 0;
331 }
332
333 /* Return 1 if this memory address is a known aligned register plus
334 a constant. It must be a valid address. This means that we can do
335 this as an aligned reference plus some offset.
336
337 Take into account what reload will do.
338
339 We could say that out-of-range stack slots are alignable, but that would
340 complicate get_aligned_mem and it isn't worth the trouble since few
341 functions have large stack space. */
342
343 int
344 aligned_memory_operand (op, mode)
345 register rtx op;
346 enum machine_mode mode;
347 {
348 if (GET_CODE (op) == SUBREG)
349 {
350 if (GET_MODE (op) != mode)
351 return 0;
352 op = SUBREG_REG (op);
353 mode = GET_MODE (op);
354 }
355
356 if (reload_in_progress && GET_CODE (op) == REG
357 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
358 op = reg_equiv_mem[REGNO (op)];
359
360 if (GET_CODE (op) != MEM || GET_MODE (op) != mode
361 || ! memory_address_p (mode, XEXP (op, 0)))
362 return 0;
363
364 op = XEXP (op, 0);
365
366 if (GET_CODE (op) == PLUS)
367 op = XEXP (op, 0);
368
369 return (GET_CODE (op) == REG
370 && (REGNO (op) == STACK_POINTER_REGNUM || op == frame_pointer_rtx
371 || (REGNO (op) >= FIRST_VIRTUAL_REGISTER
372 && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
373 }
374
375 /* Similar, but return 1 if OP is a MEM which is not alignable. */
376
377 int
378 unaligned_memory_operand (op, mode)
379 register rtx op;
380 enum machine_mode mode;
381 {
382 if (GET_CODE (op) == SUBREG)
383 {
384 if (GET_MODE (op) != mode)
385 return 0;
386 op = SUBREG_REG (op);
387 mode = GET_MODE (op);
388 }
389
390 if (reload_in_progress && GET_CODE (op) == REG
391 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
392 op = reg_equiv_mem[REGNO (op)];
393
394 if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
395 return 0;
396
397 op = XEXP (op, 0);
398
399 if (! memory_address_p (mode, op))
400 return 1;
401
402 if (GET_CODE (op) == PLUS)
403 op = XEXP (op, 0);
404
405 return (GET_CODE (op) != REG
406 || (REGNO (op) != STACK_POINTER_REGNUM && op != frame_pointer_rtx
407 && (REGNO (op) < FIRST_VIRTUAL_REGISTER
408 || REGNO (op) > LAST_VIRTUAL_REGISTER)));
409 }
410
411 /* Return 1 if OP is any memory location. During reload a pseudo matches. */
412
413 int
414 any_memory_operand (op, mode)
415 register rtx op;
416 enum machine_mode mode;
417 {
418 return (GET_CODE (op) == MEM
419 || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
420 || (reload_in_progress && GET_CODE (op) == REG
421 && REGNO (op) >= FIRST_PSEUDO_REGISTER)
422 || (reload_in_progress && GET_CODE (op) == SUBREG
423 && GET_CODE (SUBREG_REG (op)) == REG
424 && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
425 }
426
427 /* REF is an alignable memory location. Place an aligned SImode
428 reference into *PALIGNED_MEM and the number of bits to shift into
429 *PBITNUM. */
430
431 void
432 get_aligned_mem (ref, paligned_mem, pbitnum)
433 rtx ref;
434 rtx *paligned_mem, *pbitnum;
435 {
436 rtx base;
437 HOST_WIDE_INT offset = 0;
438
439 if (GET_CODE (ref) == SUBREG)
440 {
441 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
442 if (BYTES_BIG_ENDIAN)
443 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
444 - MIN (UNITS_PER_WORD,
445 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
446 ref = SUBREG_REG (ref);
447 }
448
449 if (GET_CODE (ref) == REG)
450 ref = reg_equiv_mem[REGNO (ref)];
451
452 if (reload_in_progress)
453 base = find_replacement (&XEXP (ref, 0));
454 else
455 base = XEXP (ref, 0);
456
457 if (GET_CODE (base) == PLUS)
458 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
459
460 *paligned_mem = gen_rtx (MEM, SImode,
461 plus_constant (base, offset & ~3));
462 MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
463 MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
464 RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
465
466 *pbitnum = GEN_INT ((offset & 3) * 8);
467 }
468
469 /* Similar, but just get the address. Handle the two reload cases. */
470
471 rtx
472 get_unaligned_address (ref)
473 rtx ref;
474 {
475 rtx base;
476 HOST_WIDE_INT offset = 0;
477
478 if (GET_CODE (ref) == SUBREG)
479 {
480 offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
481 if (BYTES_BIG_ENDIAN)
482 offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
483 - MIN (UNITS_PER_WORD,
484 GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
485 ref = SUBREG_REG (ref);
486 }
487
488 if (GET_CODE (ref) == REG)
489 ref = reg_equiv_mem[REGNO (ref)];
490
491 if (reload_in_progress)
492 base = find_replacement (&XEXP (ref, 0));
493 else
494 base = XEXP (ref, 0);
495
496 if (GET_CODE (base) == PLUS)
497 offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
498
499 return plus_constant (base, offset);
500 }
501 \f
502 /* Subfunction of the following function. Update the flags of any MEM
503 found in part of X. */
504
505 static void
506 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
507 rtx x;
508 int in_struct_p, volatile_p, unchanging_p;
509 {
510 int i;
511
512 switch (GET_CODE (x))
513 {
514 case SEQUENCE:
515 case PARALLEL:
516 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
517 alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
518 unchanging_p);
519 break;
520
521 case INSN:
522 alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
523 unchanging_p);
524 break;
525
526 case SET:
527 alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
528 unchanging_p);
529 alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
530 unchanging_p);
531 break;
532
533 case MEM:
534 MEM_IN_STRUCT_P (x) = in_struct_p;
535 MEM_VOLATILE_P (x) = volatile_p;
536 RTX_UNCHANGING_P (x) = unchanging_p;
537 break;
538 }
539 }
540
541 /* Given INSN, which is either an INSN or a SEQUENCE generated to
542 perform a memory operation, look for any MEMs in either a SET_DEST or
543 a SET_SRC and copy the in-struct, unchanging, and volatile flags from
544 REF into each of the MEMs found. If REF is not a MEM, don't do
545 anything. */
546
547 void
548 alpha_set_memflags (insn, ref)
549 rtx insn;
550 rtx ref;
551 {
552 /* Note that it is always safe to get these flags, though they won't
553 be what we think if REF is not a MEM. */
554 int in_struct_p = MEM_IN_STRUCT_P (ref);
555 int volatile_p = MEM_VOLATILE_P (ref);
556 int unchanging_p = RTX_UNCHANGING_P (ref);
557
558 if (GET_CODE (ref) != MEM
559 || (! in_struct_p && ! volatile_p && ! unchanging_p))
560 return;
561
562 alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
563 }
564 \f
565 /* Try to output insns to set TARGET equal to the constant C if it can be
566 done in less than N insns. Returns 1 if it can be done and the
567 insns have been emitted. If it would take more than N insns, zero is
568 returned and no insns and emitted. */
569
570 int
571 alpha_emit_set_const (target, c, n)
572 rtx target;
573 HOST_WIDE_INT c;
574 int n;
575 {
576 HOST_WIDE_INT new = c;
577 int i, bits;
578
579 #if HOST_BITS_PER_WIDE_INT == 64
580 /* We are only called for SImode and DImode. If this is SImode, ensure that
581 we are sign extended to a full word. This does not make any sense when
582 cross-compiling on a narrow machine. */
583
584 if (GET_MODE (target) == SImode)
585 c = (c & 0xffffffff) - 2 * (c & 0x80000000);
586 #endif
587
588 /* If this is a sign-extended 32-bit constant, we can do this in at most
589 three insns, so do it if we have enough insns left. We always have
590 a sign-extended 32-bit constant when compiling on a narrow machine. */
591
592 if (HOST_BITS_PER_WIDE_INT != 64
593 || c >> 31 == -1 || c >> 31 == 0)
594 {
595 HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
596 HOST_WIDE_INT tmp1 = c - low;
597 HOST_WIDE_INT high
598 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
599 HOST_WIDE_INT tmp2 = c - (high << 16) - low;
600 HOST_WIDE_INT extra = 0;
601
602 if (tmp2)
603 {
604 extra = 0x4000;
605 tmp1 -= 0x40000000;
606 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
607 }
608
609 if (c == low || (low == 0 && extra == 0))
610 {
611 emit_move_insn (target, GEN_INT (c));
612 return 1;
613 }
614 else if (n >= 2 + (extra != 0))
615 {
616 emit_move_insn (target, GEN_INT (low));
617 if (extra != 0)
618 emit_insn (gen_add2_insn (target, GEN_INT (extra << 16)));
619
620 emit_insn (gen_add2_insn (target, GEN_INT (high << 16)));
621 return 1;
622 }
623 }
624
625 /* If we couldn't do it that way, try some other methods (that depend on
626 being able to compute in the target's word size). But if we have no
627 instructions left, don't bother. Also, don't even try if this is
628 SImode (in which case we should have already done something, but
629 do a sanity check here). */
630
631 if (n == 1 || HOST_BITS_PER_WIDE_INT < 64 || GET_MODE (target) != DImode)
632 return 0;
633
634 /* First, see if can load a value into the target that is the same as the
635 constant except that all bytes that are 0 are changed to be 0xff. If we
636 can, then we can do a ZAPNOT to obtain the desired constant. */
637
638 for (i = 0; i < 64; i += 8)
639 if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
640 new |= (HOST_WIDE_INT) 0xff << i;
641
642 if (alpha_emit_set_const (target, new, n - 1))
643 {
644 emit_insn (gen_anddi3 (target, target, GEN_INT (c | ~ new)));
645 return 1;
646 }
647
648 /* Find, see if we can load a related constant and then shift and possibly
649 negate it to get the constant we want. Try this once each increasing
650 numbers of insns. */
651
652 for (i = 1; i < n; i++)
653 {
654 /* First try complementing. */
655 if (alpha_emit_set_const (target, ~ c, i))
656 {
657 emit_insn (gen_one_cmpldi2 (target, target));
658 return 1;
659 }
660
661 /* First try to form a constant and do a left shift. We can do this
662 if some low-order bits are zero; the exact_log2 call below tells
663 us that information. The bits we are shifting out could be any
664 value, but here we'll just try the 0- and sign-extended forms of
665 the constant. To try to increase the chance of having the same
666 constant in more than one insn, start at the highest number of
667 bits to shift, but try all possibilities in case a ZAPNOT will
668 be useful. */
669
670 if ((bits = exact_log2 (c & - c)) > 0)
671 for (; bits > 0; bits--)
672 if (alpha_emit_set_const (target, c >> bits, i)
673 || alpha_emit_set_const (target,
674 ((unsigned HOST_WIDE_INT) c) >> bits,
675 i))
676 {
677 emit_insn (gen_ashldi3 (target, target, GEN_INT (bits)));
678 return 1;
679 }
680
681 /* Now try high-order zero bits. Here we try the shifted-in bits as
682 all zero and all ones. */
683
684 if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (c) - 1) > 0)
685 for (; bits > 0; bits--)
686 if (alpha_emit_set_const (target, c << bits, i)
687 || alpha_emit_set_const (target,
688 ((c << bits)
689 | (((HOST_WIDE_INT) 1 << bits) - 1)),
690 i))
691 {
692 emit_insn (gen_lshrdi3 (target, target, GEN_INT (bits)));
693 return 1;
694 }
695
696 /* Now try high-order 1 bits. We get that with a sign-extension.
697 But one bit isn't enough here. */
698
699 if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (~ c) - 2) > 0)
700 for (; bits > 0; bits--)
701 if (alpha_emit_set_const (target, c << bits, i)
702 || alpha_emit_set_const (target,
703 ((c << bits)
704 | (((HOST_WIDE_INT) 1 << bits) - 1)),
705 i))
706 {
707 emit_insn (gen_ashrdi3 (target, target, GEN_INT (bits)));
708 return 1;
709 }
710 }
711
712 return 0;
713 }
714 \f
715 /* Adjust the cost of a scheduling dependency. Return the new cost of
716 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
717
718 int
719 alpha_adjust_cost (insn, link, dep_insn, cost)
720 rtx insn;
721 rtx link;
722 rtx dep_insn;
723 int cost;
724 {
725 rtx set;
726
727 /* If the dependence is an anti-dependence, there is no cost. For an
728 output dependence, there is sometimes a cost, but it doesn't seem
729 worth handling those few cases. */
730
731 if (REG_NOTE_KIND (link) != 0)
732 return 0;
733
734 /* If INSN is a store insn and DEP_INSN is setting the data being stored,
735 we can sometimes lower the cost. */
736
737 if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
738 && (set = single_set (dep_insn)) != 0
739 && GET_CODE (PATTERN (insn)) == SET
740 && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
741 switch (get_attr_type (dep_insn))
742 {
743 case TYPE_LD:
744 /* No savings here. */
745 return cost;
746
747 case TYPE_IMULL:
748 case TYPE_IMULQ:
749 /* In these cases, we save one cycle. */
750 return cost - 2;
751
752 default:
753 /* In all other cases, we save two cycles. */
754 return MAX (0, cost - 4);
755 }
756
757 /* Another case that needs adjustment is an arithmetic or logical
758 operation. It's cost is usually one cycle, but we default it to
759 two in the MD file. The only case that it is actually two is
760 for the address in loads and stores. */
761
762 if (recog_memoized (dep_insn) >= 0
763 && get_attr_type (dep_insn) == TYPE_IADDLOG)
764 switch (get_attr_type (insn))
765 {
766 case TYPE_LD:
767 case TYPE_ST:
768 return cost;
769
770 default:
771 return 2;
772 }
773
774 /* The final case is when a compare feeds into an integer branch. The cost
775 is only one cycle in that case. */
776
777 if (recog_memoized (dep_insn) >= 0
778 && get_attr_type (dep_insn) == TYPE_ICMP
779 && recog_memoized (insn) >= 0
780 && get_attr_type (insn) == TYPE_IBR)
781 return 2;
782
783 /* Otherwise, return the default cost. */
784
785 return cost;
786 }
787 \f
788 /* Print an operand. Recognize special options, documented below. */
789
790 void
791 print_operand (file, x, code)
792 FILE *file;
793 rtx x;
794 char code;
795 {
796 int i;
797
798 switch (code)
799 {
800 case 'r':
801 /* If this operand is the constant zero, write it as "$31". */
802 if (GET_CODE (x) == REG)
803 fprintf (file, "%s", reg_names[REGNO (x)]);
804 else if (x == CONST0_RTX (GET_MODE (x)))
805 fprintf (file, "$31");
806 else
807 output_operand_lossage ("invalid %%r value");
808
809 break;
810
811 case 'R':
812 /* Similar, but for floating-point. */
813 if (GET_CODE (x) == REG)
814 fprintf (file, "%s", reg_names[REGNO (x)]);
815 else if (x == CONST0_RTX (GET_MODE (x)))
816 fprintf (file, "$f31");
817 else
818 output_operand_lossage ("invalid %%R value");
819
820 break;
821
822 case 'N':
823 /* Write the 1's complement of a constant. */
824 if (GET_CODE (x) != CONST_INT)
825 output_operand_lossage ("invalid %%N value");
826
827 fprintf (file, "%ld", ~ INTVAL (x));
828 break;
829
830 case 'P':
831 /* Write 1 << C, for a constant C. */
832 if (GET_CODE (x) != CONST_INT)
833 output_operand_lossage ("invalid %%P value");
834
835 fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
836 break;
837
838 case 'h':
839 /* Write the high-order 16 bits of a constant, sign-extended. */
840 if (GET_CODE (x) != CONST_INT)
841 output_operand_lossage ("invalid %%h value");
842
843 fprintf (file, "%ld", INTVAL (x) >> 16);
844 break;
845
846 case 'L':
847 /* Write the low-order 16 bits of a constant, sign-extended. */
848 if (GET_CODE (x) != CONST_INT)
849 output_operand_lossage ("invalid %%L value");
850
851 fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
852 break;
853
854 case 'm':
855 /* Write mask for ZAP insn. */
856 if (GET_CODE (x) == CONST_DOUBLE)
857 {
858 HOST_WIDE_INT mask = 0;
859 HOST_WIDE_INT value;
860
861 value = CONST_DOUBLE_LOW (x);
862 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
863 i++, value >>= 8)
864 if (value & 0xff)
865 mask |= (1 << i);
866
867 value = CONST_DOUBLE_HIGH (x);
868 for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
869 i++, value >>= 8)
870 if (value & 0xff)
871 mask |= (1 << (i + sizeof (int)));
872
873 fprintf (file, "%ld", mask & 0xff);
874 }
875
876 else if (GET_CODE (x) == CONST_INT)
877 {
878 HOST_WIDE_INT mask = 0, value = INTVAL (x);
879
880 for (i = 0; i < 8; i++, value >>= 8)
881 if (value & 0xff)
882 mask |= (1 << i);
883
884 fprintf (file, "%ld", mask);
885 }
886 else
887 output_operand_lossage ("invalid %%m value");
888 break;
889
890 case 'M':
891 /* 'b', 'w', or 'l' as the value of the constant. */
892 if (GET_CODE (x) != CONST_INT
893 || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
894 output_operand_lossage ("invalid %%M value");
895
896 fprintf (file, "%s",
897 INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
898 break;
899
900 case 'U':
901 /* Similar, except do it from the mask. */
902 if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
903 fprintf (file, "b");
904 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
905 fprintf (file, "w");
906 #if HOST_BITS_PER_WIDE_INT == 32
907 else if (GET_CODE (x) == CONST_DOUBLE
908 && CONST_DOUBLE_HIGH (x) == 0
909 && CONST_DOUBLE_LOW (x) == -1)
910 fprintf (file, "l");
911 #else
912 else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
913 fprintf (file, "l");
914 #endif
915 else
916 output_operand_lossage ("invalid %%U value");
917 break;
918
919 case 's':
920 /* Write the constant value divided by 8. */
921 if (GET_CODE (x) != CONST_INT
922 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
923 && (INTVAL (x) & 7) != 8)
924 output_operand_lossage ("invalid %%s value");
925
926 fprintf (file, "%ld", INTVAL (x) / 8);
927 break;
928
929 case 'S':
930 /* Same, except compute (64 - c) / 8 */
931
932 if (GET_CODE (x) != CONST_INT
933 && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
934 && (INTVAL (x) & 7) != 8)
935 output_operand_lossage ("invalid %%s value");
936
937 fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
938 break;
939
940 case 'C':
941 /* Write out comparison name. */
942 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
943 output_operand_lossage ("invalid %%C value");
944
945 if (GET_CODE (x) == LEU)
946 fprintf (file, "ule");
947 else if (GET_CODE (x) == LTU)
948 fprintf (file, "ult");
949 else
950 fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
951 break;
952
953 case 'D':
954 /* Similar, but write reversed code. We can't get an unsigned code
955 here. */
956 if (GET_RTX_CLASS (GET_CODE (x)) != '<')
957 output_operand_lossage ("invalid %%D value");
958
959 fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
960 break;
961
962 case 'E':
963 /* Write the divide or modulus operator. */
964 switch (GET_CODE (x))
965 {
966 case DIV:
967 fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
968 break;
969 case UDIV:
970 fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
971 break;
972 case MOD:
973 fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
974 break;
975 case UMOD:
976 fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
977 break;
978 default:
979 output_operand_lossage ("invalid %%E value");
980 break;
981 }
982 break;
983
984 case 'F':
985 /* Write the symbol; if the current function uses GP, write a
986 modified version. */
987 if (GET_CODE (x) != SYMBOL_REF)
988 output_operand_lossage ("invalid %%F value");
989
990 output_addr_const (file, x);
991 if (alpha_function_needs_gp)
992 fprintf (file, "..ng");
993 break;
994
995 case 'A':
996 /* Write "_u" for unaligned access. */
997 if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
998 fprintf (file, "_u");
999 break;
1000
1001 case 0:
1002 if (GET_CODE (x) == REG)
1003 fprintf (file, "%s", reg_names[REGNO (x)]);
1004 else if (GET_CODE (x) == MEM)
1005 output_address (XEXP (x, 0));
1006 else
1007 output_addr_const (file, x);
1008 break;
1009
1010 default:
1011 output_operand_lossage ("invalid %%xn code");
1012 }
1013 }
1014 \f
1015 /* Do what is necessary for `va_start'. The argument is ignored;
1016 We look at the current function to determine if stdargs or varargs
1017 is used and fill in an initial va_list. A pointer to this constructor
1018 is returned. */
1019
1020 struct rtx_def *
1021 alpha_builtin_saveregs (arglist)
1022 tree arglist;
1023 {
1024 rtx block, addr, argsize;
1025 tree fntype = TREE_TYPE (current_function_decl);
1026 int stdargs = (TYPE_ARG_TYPES (fntype) != 0
1027 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1028 != void_type_node));
1029 int nregs = current_function_args_info;
1030
1031 /* If we have a variable-sized argument already, we will have used all
1032 the registers, so set up to indicate that. */
1033
1034 if (GET_CODE (current_function_arg_offset_rtx) != CONST_INT)
1035 {
1036 argsize = plus_constant (current_function_arg_offset_rtx,
1037 ((6 - stdargs) * UNITS_PER_WORD
1038 + UNITS_PER_WORD - 1));
1039 argsize = expand_shift (RSHIFT_EXPR, Pmode, argsize,
1040 build_int_2 (3, 0), argsize, 0);
1041 }
1042 else
1043 {
1044 /* If we are using memory, deduct the stdarg adjustment from it,
1045 otherwise from the number of registers. Then compute the current
1046 argument number. */
1047
1048 int memargs = ((INTVAL (current_function_arg_offset_rtx)
1049 + UNITS_PER_WORD - 1)
1050 / UNITS_PER_WORD);
1051
1052 if (memargs)
1053 memargs -= stdargs;
1054 else
1055 nregs -= stdargs;
1056
1057 argsize = GEN_INT (MIN (nregs, 6) + memargs);
1058 }
1059
1060 /* Allocate the va_list constructor */
1061 block = assign_stack_local (BLKmode, 4 * UNITS_PER_WORD, BITS_PER_WORD);
1062 RTX_UNCHANGING_P (block) = 1;
1063 RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1064
1065 /* Store the argsize as the __va_arg member. */
1066 emit_move_insn (change_address (block, DImode, XEXP (block, 0)),
1067 argsize);
1068
1069 /* Store the arg pointer in the __va_stack member. */
1070 emit_move_insn (change_address (block, Pmode,
1071 plus_constant (XEXP (block, 0),
1072 UNITS_PER_WORD)),
1073 virtual_incoming_args_rtx);
1074
1075 /* Allocate the integer register space, and store it as the
1076 __va_ireg member. */
1077 addr = assign_stack_local (BLKmode, 6 * UNITS_PER_WORD, -1);
1078 MEM_IN_STRUCT_P (addr) = 1;
1079 RTX_UNCHANGING_P (addr) = 1;
1080 RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
1081
1082 emit_move_insn (change_address (block, Pmode,
1083 plus_constant (XEXP (block, 0),
1084 2 * UNITS_PER_WORD)),
1085 copy_to_reg (XEXP (addr, 0)));
1086
1087 /* Now store the incoming integer registers. */
1088 if (nregs < 6)
1089 move_block_from_reg
1090 (16 + nregs,
1091 change_address (addr, Pmode,
1092 plus_constant (XEXP (addr, 0),
1093 nregs * UNITS_PER_WORD)),
1094 6 - nregs);
1095
1096 /* Allocate the FP register space, and store it as the
1097 __va_freg member. */
1098 addr = assign_stack_local (BLKmode, 6 * UNITS_PER_WORD, -1);
1099 MEM_IN_STRUCT_P (addr) = 1;
1100 RTX_UNCHANGING_P (addr) = 1;
1101 RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
1102
1103 emit_move_insn (change_address (block, Pmode,
1104 plus_constant (XEXP (block, 0),
1105 3 * UNITS_PER_WORD)),
1106 copy_to_reg (XEXP (addr, 0)));
1107
1108 /* Now store the incoming floating-point registers. If we are not
1109 to use the floating-point registers, store the integer registers
1110 in those locations too. */
1111 if (nregs < 6)
1112 move_block_from_reg
1113 (16 + 32 * (TARGET_FPREGS != 0) + nregs,
1114 change_address (addr, Pmode,
1115 plus_constant (XEXP (addr, 0),
1116 nregs * UNITS_PER_WORD)),
1117 6 - nregs);
1118
1119 /* Return the address of the va_list constructor, but don't put it in a
1120 register. This fails when not optimizing and produces worse code when
1121 optimizing. */
1122 return XEXP (block, 0);
1123 }
1124 \f
1125 /* This page contains routines that are used to determine what the function
1126 prologue and epilogue code will do and write them out. */
1127
1128 /* Compute the size of the save area in the stack. */
1129
1130 int
1131 alpha_sa_size ()
1132 {
1133 int size = 0;
1134 int i;
1135
1136 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1137 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1138 size++;
1139
1140 return size * 8;
1141 }
1142
1143 /* Return non-zero if this function needs gp. It does if it has
1144 an LDSYM insn. */
1145
1146 int
1147 alpha_need_gp ()
1148 {
1149 rtx insn;
1150
1151 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1152 if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1153 && GET_CODE (PATTERN (insn)) != USE
1154 && GET_CODE (PATTERN (insn)) != CLOBBER
1155 && get_attr_type (insn) == TYPE_LDSYM)
1156 return 1;
1157
1158 return 0;
1159 }
1160
1161 /* Return 1 if GP is dead at after INSN. */
1162
1163 int
1164 alpha_gp_dead_after (insn)
1165 rtx insn;
1166 {
1167 int jump_count = 0;
1168 int found = 0;
1169 rtx p;
1170
1171 /* If we aren't optimizing, don't do this optimization. More importantly,
1172 JUMP_LABEL isn't properly set when not optimizing. */
1173
1174 if (optimize == 0)
1175 return 0;
1176
1177 /* If we are followed by a BARRIER, we don't return. */
1178 if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == BARRIER)
1179 return 1;
1180
1181 /* Otherwise search for a use of GP before a return. */
1182
1183 for (p = next_active_insn (insn); p; p = next_active_insn (p))
1184 {
1185 if (get_attr_type (p) == TYPE_LDSYM
1186 || get_attr_type (p) == TYPE_JSR)
1187 {
1188 found = 1;
1189 break;
1190 }
1191
1192 if (GET_CODE (p) == JUMP_INSN)
1193 {
1194 if (GET_CODE (PATTERN (p)) == RETURN)
1195 break;
1196
1197 if (! simplejump_p (p) || jump_count++ > 10)
1198 {
1199 found = 1;
1200 break;
1201 }
1202
1203 p = JUMP_LABEL (p);
1204 }
1205 }
1206
1207 /* Restore any operands destroyed by the attribute calls above. */
1208 insn_extract (insn);
1209
1210 return ! found;
1211 }
1212
1213 /* Return 1 if this function can directly return via $26. */
1214
1215 int
1216 direct_return ()
1217 {
1218 return (reload_completed && alpha_sa_size () == 0
1219 && get_frame_size () == 0
1220 && current_function_pretend_args_size == 0);
1221 }
1222
1223 /* Write function prologue. */
1224
1225 void
1226 output_prolog (file, size)
1227 FILE *file;
1228 int size;
1229 {
1230 HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1231 + current_function_pretend_args_size
1232 + alpha_sa_size () + 15) & ~15);
1233 int reg_offset = current_function_outgoing_args_size;
1234 int start_reg_offset = reg_offset;
1235 unsigned reg_mask = 0;
1236 int i;
1237
1238 /* If we need a GP, load it first. */
1239 alpha_function_needs_gp = alpha_need_gp ();
1240
1241 if (alpha_function_needs_gp)
1242 {
1243 rtx insn;
1244
1245 fprintf (file, "\tldgp $29,0($27)\n");
1246
1247 /* If we have a recursive call, put a special label here. */
1248 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1249 if (GET_CODE (insn) == CALL_INSN
1250 && get_attr_type (insn) != TYPE_JSR)
1251 {
1252 fprintf (file, "%s..ng:\n", current_function_name);
1253 break;
1254 }
1255 }
1256
1257 /* Adjust the stack by the frame size. If the frame size is > 32768
1258 bytes, we have to load it into a register first and then subtract
1259 from sp. Note that we are only allowed to adjust sp once in the
1260 prologue. */
1261
1262 if (frame_size > 32768)
1263 {
1264 HOST_WIDE_INT low = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1265 HOST_WIDE_INT tmp1 = frame_size - low;
1266 HOST_WIDE_INT high
1267 = ((tmp1 >> 16) & 0xfff) - 2 * ((tmp1 >> 16) & 0x8000);
1268 HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1269 HOST_WIDE_INT extra = 0;
1270 int in_reg = 31;
1271
1272 /* We haven't written code to handle frames > 4GB. */
1273 #if HOST_BITS_PER_LONG_INT == 64
1274 if ((unsigned HOST_WIDE_INT) frame_size >> 32 != 0)
1275 abort ();
1276 #endif
1277
1278 if (tmp2)
1279 {
1280 extra = 0x4000;
1281 tmp1 -= 0x40000000;
1282 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1283 }
1284
1285 if (low != 0)
1286 {
1287 fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1288 in_reg = 28;
1289 }
1290
1291 if (extra)
1292 {
1293 fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1294 in_reg = 28;
1295 }
1296
1297 fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1298
1299 fprintf (file, "\tsubq $30,$28,$30\n");
1300 }
1301 else if (frame_size)
1302 fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1303
1304 /* Write out the .frame line. If we need a frame pointer, we use
1305 an offset of zero. */
1306
1307 if (frame_pointer_needed)
1308 fprintf (file, "\t.frame $15,0,$26\n");
1309 else
1310 fprintf (file, "\t.frame $30,%d,$26\n", frame_size);
1311
1312
1313 /* Save register 26 if it is used. */
1314 if (regs_ever_live[26])
1315 {
1316 reg_mask |= 1 << 26;
1317 fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1318 reg_offset += 8;
1319 }
1320
1321 /* Now save any other used register that are required to be saved. */
1322 for (i = 0; i < 32; i++)
1323 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1324 {
1325 reg_mask |= 1 << i;
1326 fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1327 reg_offset += 8;
1328 }
1329
1330 /* Print the register mask and do floating-point saves. */
1331 if (reg_mask)
1332 fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1333 start_reg_offset - frame_size);
1334
1335 start_reg_offset = reg_offset;
1336 reg_mask = 0;
1337
1338 for (i = 0; i < 32; i++)
1339 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1340 && regs_ever_live[i + 32])
1341 {
1342 reg_mask |= 1 << i;
1343 fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1344 reg_offset += 8;
1345 }
1346
1347 /* Print the floating-point mask, if we've saved any fp register. */
1348 if (reg_mask)
1349 fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask, start_reg_offset);
1350
1351 /* If we need a frame pointer, set it to the value of incoming stack
1352 which we compute by adding back the frame size pointer. Because we
1353 can subtract one more than we can add, we have to special-case
1354 frame sizes of 32K. Note that there is no restriction that the frame
1355 pointer be updated in one instruction. */
1356
1357 if (frame_pointer_needed)
1358 {
1359 if (frame_size == 32768)
1360 fprintf (file, "\tlda $15,16384($30)\n\tlda $15,16384($15)\n");
1361 else if (frame_size > 32768)
1362 fprintf (file, "\taddq $30,$28,$15\n");
1363 else
1364 fprintf (file, "\tlda $15,%d($30)\n", frame_size);
1365 }
1366 }
1367
1368 /* Write function epilogue. */
1369
1370 void
1371 output_epilog (file, size)
1372 FILE *file;
1373 int size;
1374 {
1375 rtx insn = get_last_insn ();
1376 HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1377 + current_function_pretend_args_size
1378 + alpha_sa_size () + 15) & ~15);
1379 int reg_offset = current_function_outgoing_args_size;
1380 int reg_offset_from = STACK_POINTER_REGNUM;
1381 int i;
1382
1383 /* If the last insn was a BARRIER, we don't have to write anything except
1384 the .end pseudo-op. */
1385 if (GET_CODE (insn) == NOTE)
1386 insn = prev_nonnote_insn (insn);
1387 if (insn == 0 || GET_CODE (insn) != BARRIER)
1388 {
1389 /* If we have a frame pointer, we restore the registers from an
1390 offset from it, assuming that we can reach the offset. If not,
1391 we have to compute the address using a scratch register. This is
1392 messy, but should not be common. We have to copy the frame
1393 pointer elsewhere here since we will be restoring it before we can
1394 use it to restore the stack pointer. We use $25. */
1395
1396 if (frame_pointer_needed)
1397 {
1398 fprintf (file, "\tbis $15,$15,$25\n");
1399
1400 if (frame_size < 32768)
1401 reg_offset -= frame_size, reg_offset_from = 25;
1402 else
1403 {
1404 HOST_WIDE_INT low
1405 = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1406 HOST_WIDE_INT tmp1 = frame_size - low;
1407 HOST_WIDE_INT high
1408 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1409 HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1410 int extra = 0xe;
1411 int in_reg = 31;
1412
1413 if (tmp2)
1414 {
1415 extra = 0x4000;
1416 tmp1 -= 0x40000000;
1417 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1418 }
1419
1420 if (low != 0)
1421 {
1422 fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1423 in_reg = 28;
1424 }
1425
1426 if (extra)
1427 {
1428 fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1429 in_reg = 28;
1430 }
1431
1432 fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1433
1434 fprintf (file, "\taddq $25,$28,$28\n");
1435
1436 reg_offset_from = 28;
1437 }
1438 }
1439
1440 /* Restore all the registers, starting with the return address
1441 register. */
1442 if (regs_ever_live[26])
1443 {
1444 fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, reg_offset_from);
1445 reg_offset += 8;
1446 }
1447
1448 /* Now restore any other used register that that we saved. */
1449 for (i = 0; i < 32; i++)
1450 if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1451 && i != 26)
1452 {
1453 fprintf (file, "\tldq $%d,%d($%d)\n",
1454 i, reg_offset, reg_offset_from);
1455 reg_offset += 8;
1456 }
1457
1458 for (i = 0; i < 32; i++)
1459 if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1460 && regs_ever_live[i + 32])
1461 {
1462 fprintf (file, "\tldt $f%d,%d($%d)\n",
1463 i, reg_offset, reg_offset_from);
1464 reg_offset += 8;
1465 }
1466
1467 /* Restore the stack. If we have a frame pointer, use it. Otherwise,
1468 add the size back into the stack, handling the large frame size. */
1469
1470 if (frame_pointer_needed)
1471 fprintf (file, "\tbis $25,$25,$30\n");
1472 else if (frame_size > 32767)
1473 {
1474 HOST_WIDE_INT low
1475 = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1476 HOST_WIDE_INT tmp1 = frame_size - low;
1477 HOST_WIDE_INT high
1478 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1479 HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1480 HOST_WIDE_INT extra = 0;
1481 int in_reg = 31;
1482
1483 /* We haven't written code to handle frames > 4GB. */
1484 #if HOST_BITS_PER_LONG_INT == 64
1485 if ((unsigned HOST_WIDE_INT) frame_size >> 32 != 0)
1486 abort ();
1487 #endif
1488
1489 if (tmp2)
1490 {
1491 extra = 0x4000;
1492 tmp1 -= 0x40000000;
1493 high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1494 }
1495
1496 if (low != 0)
1497 {
1498 fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1499 in_reg = 28;
1500 }
1501
1502 if (extra)
1503 {
1504 fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1505 in_reg = 28;
1506 }
1507
1508 fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1509
1510 fprintf (file, "\taddq $30,$28,$30\n");
1511 }
1512 else if (frame_size)
1513 fprintf (file, "\tlda $30,%d($30)\n", frame_size);
1514
1515 /* Now return to the caller. */
1516 fprintf (file, "\tret $31,($26),1\n");
1517 }
1518
1519 /* End the function. */
1520 fprintf (file, "\t.end %s\n", alpha_function_name);
1521 }