OSDN Git Service

ca027ec4da4cea8ef3c1088ab5e0d13501101546
[pf3gnuchains/gcc-fork.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 stdarg 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 stdarg = (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 * UNITS_PER_WORD + UNITS_PER_WORD - 1));
1038       argsize = expand_shift (RSHIFT_EXPR, Pmode, argsize,
1039                               build_int_2 (3, 0), argsize, 0);
1040     }
1041   else
1042     {
1043       /* Compute the number of args in memory and number of arguments already
1044          processed.  Then adjust the number of registers if this is stdarg.  */
1045       int memargs = ((INTVAL (current_function_arg_offset_rtx)
1046                       + UNITS_PER_WORD - 1)
1047                      / UNITS_PER_WORD);
1048
1049       argsize = GEN_INT (MIN (nregs, 6) + memargs);
1050
1051       if (nregs <= 6)
1052         nregs -= stdarg;
1053     }
1054
1055   /* Allocate the va_list constructor */
1056   block = assign_stack_local (BLKmode, 4 * UNITS_PER_WORD, BITS_PER_WORD);
1057   RTX_UNCHANGING_P (block) = 1;
1058   RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1059
1060   /* Store the argsize as the __va_arg member.  */
1061   emit_move_insn (change_address (block, DImode, XEXP (block, 0)),
1062                   argsize);
1063
1064   /* Store the arg pointer in the __va_stack member.  */
1065   emit_move_insn (change_address (block, Pmode,
1066                                   plus_constant (XEXP (block, 0),
1067                                                  UNITS_PER_WORD)),
1068                   virtual_incoming_args_rtx);
1069
1070   /* Allocate the integer register space, and store it as the
1071      __va_ireg member.  */
1072   addr = assign_stack_local (BLKmode, 6 * UNITS_PER_WORD, -1);
1073   MEM_IN_STRUCT_P (addr) = 1;
1074   RTX_UNCHANGING_P (addr) = 1;
1075   RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
1076
1077   emit_move_insn (change_address (block, Pmode,
1078                                   plus_constant (XEXP (block, 0),
1079                                                  2 * UNITS_PER_WORD)),
1080                   copy_to_reg (XEXP (addr, 0)));
1081
1082   /* Now store the incoming integer registers.  */
1083   if (nregs < 6)
1084       move_block_from_reg
1085         (16 + nregs,
1086          change_address (addr, Pmode,
1087                          plus_constant (XEXP (addr, 0),
1088                                         nregs * UNITS_PER_WORD)),
1089          6 - nregs);
1090
1091   /* Allocate the FP register space, and store it as the
1092      __va_freg member.  */
1093   addr = assign_stack_local (BLKmode, 6 * UNITS_PER_WORD, -1);
1094   MEM_IN_STRUCT_P (addr) = 1;
1095   RTX_UNCHANGING_P (addr) = 1;
1096   RTX_UNCHANGING_P (XEXP (addr, 0)) = 1;
1097
1098   emit_move_insn (change_address (block, Pmode,
1099                                   plus_constant (XEXP (block, 0),
1100                                                  3 * UNITS_PER_WORD)),
1101                   copy_to_reg (XEXP (addr, 0)));
1102
1103   /* Now store the incoming floating-point registers.   If we are not
1104      to use the floating-point registers, store the integer registers
1105      in those locations too.  */
1106   if (nregs < 6)
1107       move_block_from_reg
1108         (16 + 32 * (TARGET_FPREGS != 0) + nregs,
1109          change_address (addr, Pmode,
1110                          plus_constant (XEXP (addr, 0),
1111                                         nregs * UNITS_PER_WORD)),
1112          6 - nregs);
1113
1114   /* Return the address of the va_list constructor, but don't put it in a
1115      register.  This fails when not optimizing and produces worse code when
1116      optimizing.  */
1117   return XEXP (block, 0);
1118 }
1119 \f
1120 /* This page contains routines that are used to determine what the function
1121    prologue and epilogue code will do and write them out.  */
1122
1123 /* Compute the size of the save area in the stack.  */
1124
1125 int
1126 alpha_sa_size ()
1127 {
1128   int size = 0;
1129   int i;
1130
1131   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1132     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1133       size++;
1134
1135   return size * 8;
1136 }
1137
1138 /* Return non-zero if this function needs gp.  It does if it has
1139    an LDSYM insn.  */
1140
1141 int
1142 alpha_need_gp ()
1143 {
1144   rtx insn;
1145
1146   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1147     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1148         && GET_CODE (PATTERN (insn)) != USE
1149         && GET_CODE (PATTERN (insn)) != CLOBBER
1150         && get_attr_type (insn) == TYPE_LDSYM)
1151       return 1;
1152
1153   return 0;
1154 }
1155
1156 /* Return 1 if GP is dead at after INSN.  */
1157
1158 int
1159 alpha_gp_dead_after (insn)
1160      rtx insn;
1161 {
1162   int jump_count = 0;
1163   int found = 0;
1164   rtx p;
1165
1166   /* If we aren't optimizing, don't do this optimization.  More importantly,
1167      JUMP_LABEL isn't properly set when not optimizing.  */
1168
1169   if (optimize == 0)
1170     return 0;
1171
1172   /* If we are followed by a BARRIER, we don't return.  */
1173   if (NEXT_INSN (insn) && GET_CODE (NEXT_INSN (insn)) == BARRIER)
1174     return 1;
1175
1176   /* Otherwise search for a use of GP before a return.  */
1177
1178   for (p = next_active_insn (insn); p; p = next_active_insn (p))
1179     {
1180       if (get_attr_type (p) == TYPE_LDSYM
1181           || get_attr_type (p) == TYPE_JSR)
1182         {
1183           found = 1;
1184           break;
1185         }
1186
1187       if (GET_CODE (p) == JUMP_INSN)
1188         {
1189           if (GET_CODE (PATTERN (p)) == RETURN)
1190             break;
1191
1192           if (! simplejump_p (p) || jump_count++ > 10)
1193             {
1194               found = 1;
1195               break;
1196             }
1197
1198           p = JUMP_LABEL (p);
1199         }
1200     }
1201
1202   /* Restore any operands destroyed by the attribute calls above.  */
1203   insn_extract (insn);
1204
1205   return ! found;
1206 }
1207
1208 /* Return 1 if this function can directly return via $26.  */
1209
1210 int
1211 direct_return ()
1212 {
1213   return (reload_completed && alpha_sa_size () == 0
1214           && get_frame_size () == 0
1215           && current_function_pretend_args_size == 0);
1216 }
1217
1218 /* Write function prologue.  */
1219
1220 void
1221 output_prolog (file, size)
1222      FILE *file;
1223      int size;
1224 {
1225   HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1226                                + current_function_pretend_args_size
1227                                + alpha_sa_size () + 15) & ~15);
1228   int reg_offset = current_function_outgoing_args_size;
1229   int start_reg_offset = reg_offset;
1230   unsigned reg_mask = 0;
1231   int i;
1232
1233   /* If we need a GP, load it first.  */
1234   alpha_function_needs_gp = alpha_need_gp ();
1235
1236   if (alpha_function_needs_gp)
1237     {
1238       rtx insn;
1239
1240       fprintf (file, "\tldgp $29,0($27)\n");
1241
1242       /* If we have a recursive call, put a special label here.  */
1243       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1244         if (GET_CODE (insn) == CALL_INSN
1245             && get_attr_type (insn) != TYPE_JSR)
1246           {
1247             fprintf (file, "%s..ng:\n", current_function_name);
1248             break;
1249           }
1250     }
1251
1252   /* Adjust the stack by the frame size.  If the frame size is > 32768
1253      bytes, we have to load it into a register first and then subtract
1254      from sp.  Note that we are only allowed to adjust sp once in the
1255      prologue.  */
1256
1257   if (frame_size > 32768)
1258     {
1259       HOST_WIDE_INT low = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1260       HOST_WIDE_INT tmp1 = frame_size - low;
1261       HOST_WIDE_INT high
1262         = ((tmp1 >> 16) & 0xfff) - 2 * ((tmp1 >> 16) & 0x8000);
1263       HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1264       HOST_WIDE_INT extra = 0;
1265       int in_reg = 31;
1266
1267       /* We haven't written code to handle frames > 4GB.  */
1268 #if HOST_BITS_PER_LONG_INT == 64
1269       if ((unsigned HOST_WIDE_INT) frame_size >> 32 != 0)
1270         abort ();
1271 #endif
1272
1273       if (tmp2)
1274         {
1275           extra = 0x4000;
1276           tmp1 -= 0x40000000;
1277           high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1278         }
1279
1280       if (low != 0)
1281         {
1282           fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1283           in_reg = 28;
1284         }
1285
1286       if (extra)
1287         {
1288           fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1289           in_reg = 28;
1290         }
1291
1292       fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1293
1294       fprintf (file, "\tsubq $30,$28,$30\n");
1295     }
1296   else if (frame_size)
1297     fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1298
1299   /* Write out the .frame line.  If we need a frame pointer, we use
1300      an offset of zero.  */
1301
1302   if (frame_pointer_needed)
1303     fprintf (file, "\t.frame $15,0,$26\n");
1304   else
1305     fprintf (file, "\t.frame $30,%d,$26\n", frame_size);
1306
1307     
1308   /* Save register 26 if it is used.  */
1309   if (regs_ever_live[26])
1310     {
1311       reg_mask |= 1 << 26;
1312       fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1313       reg_offset += 8;
1314     }
1315
1316   /* Now save any other used register that are required to be saved.  */
1317   for (i = 0; i < 32; i++)
1318     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1319       {
1320         reg_mask |= 1 << i;
1321         fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1322         reg_offset += 8;
1323       }
1324
1325   /* Print the register mask and do floating-point saves.  */
1326   if (reg_mask)
1327     fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1328              start_reg_offset - frame_size);
1329
1330   start_reg_offset = reg_offset;
1331   reg_mask = 0;
1332
1333   for (i = 0; i < 32; i++)
1334     if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1335         && regs_ever_live[i + 32])
1336       {
1337         reg_mask |= 1 << i;
1338         fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1339         reg_offset += 8;
1340       }
1341
1342   /* Print the floating-point mask, if we've saved any fp register.  */
1343   if (reg_mask)
1344     fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask, start_reg_offset);
1345
1346   /* If we need a frame pointer, set it to the value of incoming stack
1347      which we compute by adding back the frame size pointer.  Because we
1348      can subtract one more than we can add, we have to special-case
1349      frame sizes of 32K.  Note that there is no restriction that the frame
1350      pointer be updated in one instruction.  */
1351
1352   if (frame_pointer_needed)
1353     {
1354       if (frame_size == 32768)
1355         fprintf (file, "\tlda $15,16384($30)\n\tlda $15,16384($15)\n");
1356       else if (frame_size > 32768)
1357         fprintf (file, "\taddq $30,$28,$15\n");
1358       else
1359         fprintf (file, "\tlda $15,%d($30)\n", frame_size);
1360     }
1361 }
1362
1363 /* Write function epilogue.  */
1364
1365 void
1366 output_epilog (file, size)
1367      FILE *file;
1368      int size;
1369 {
1370   rtx insn = get_last_insn ();
1371   HOST_WIDE_INT frame_size = ((size + current_function_outgoing_args_size
1372                                + current_function_pretend_args_size
1373                                + alpha_sa_size () + 15) & ~15);
1374   int reg_offset = current_function_outgoing_args_size;
1375   int reg_offset_from = STACK_POINTER_REGNUM;
1376   int i;
1377
1378   /* If the last insn was a BARRIER, we don't have to write anything except
1379      the .end pseudo-op.  */
1380   if (GET_CODE (insn) == NOTE)
1381     insn = prev_nonnote_insn (insn);
1382   if (insn == 0 || GET_CODE (insn) != BARRIER)
1383     {
1384       /* If we have a frame pointer, we restore the registers from an
1385          offset from it, assuming that we can reach the offset.  If not,
1386          we have to compute the address using a scratch register.  This is
1387          messy, but should not be common.  We have to copy the frame
1388          pointer elsewhere here since we will be restoring it before we can
1389          use it to restore the stack pointer.  We use $25.  */
1390
1391       if (frame_pointer_needed)
1392         {
1393           fprintf (file, "\tbis $15,$15,$25\n");
1394
1395           if (frame_size < 32768)
1396             reg_offset -= frame_size, reg_offset_from = 25;
1397           else
1398             {
1399               HOST_WIDE_INT low
1400                 = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1401               HOST_WIDE_INT tmp1 = frame_size - low;
1402               HOST_WIDE_INT high
1403                 = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1404               HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1405               int extra = 0;
1406               int in_reg = 31;
1407
1408               if (tmp2)
1409                 {
1410                   extra = 0x4000;
1411                   tmp1 -= 0x40000000;   
1412                   high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1413                 }
1414
1415               if (low != 0)
1416                 {
1417                   fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1418                   in_reg = 28;
1419                 }
1420
1421               if (extra)
1422                 {
1423                   fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1424                   in_reg = 28;
1425                 }
1426
1427               fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1428
1429               fprintf (file, "\tsubq $25,$28,$28\n");
1430
1431               reg_offset_from = 28;
1432             }
1433         }
1434
1435       /* Restore all the registers, starting with the return address
1436          register.  */
1437       if (regs_ever_live[26])
1438         {
1439           fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, reg_offset_from);
1440           reg_offset += 8;
1441         }
1442
1443       /* Now restore any other used register that that we saved.  */
1444       for (i = 0; i < 32; i++)
1445         if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1446             && i != 26)
1447           {
1448             fprintf (file, "\tldq $%d,%d($%d)\n",
1449                      i, reg_offset, reg_offset_from);
1450             reg_offset += 8;
1451           }
1452
1453       for (i = 0; i < 32; i++)
1454         if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1455             && regs_ever_live[i + 32])
1456           {
1457             fprintf (file, "\tldt $f%d,%d($%d)\n",
1458                      i, reg_offset, reg_offset_from);
1459             reg_offset += 8;
1460           }
1461
1462       /* Restore the stack.  If we have a frame pointer, use it.  Otherwise,
1463          add the size back into the stack, handling the large frame size.  */
1464
1465       if (frame_pointer_needed)
1466         fprintf (file, "\tbis $25,$25,$30\n");
1467       else if (frame_size > 32767)
1468         {
1469           HOST_WIDE_INT low
1470             = (frame_size & 0xffff) - 2 * (frame_size & 0x8000);
1471           HOST_WIDE_INT tmp1 = frame_size - low;
1472           HOST_WIDE_INT high
1473             = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1474           HOST_WIDE_INT tmp2 = frame_size - (high << 16) - low;
1475           HOST_WIDE_INT extra = 0;
1476           int in_reg = 31;
1477
1478           /* We haven't written code to handle frames > 4GB.  */
1479 #if HOST_BITS_PER_LONG_INT == 64
1480           if ((unsigned HOST_WIDE_INT) frame_size >> 32 != 0)
1481             abort ();
1482 #endif
1483
1484           if (tmp2)
1485             {
1486               extra = 0x4000;
1487               tmp1 -= 0x40000000;
1488               high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1489             }
1490
1491           if (low != 0)
1492             {
1493               fprintf (file, "\tlda $28,%d($%d)\n", low, in_reg);
1494               in_reg = 28;
1495             }
1496
1497           if (extra)
1498             {
1499               fprintf (file, "\tldah $28,%d($%d)\n", extra, in_reg);
1500               in_reg = 28;
1501             }
1502
1503           fprintf (file, "\tldah $28,%d($%d)\n", high, in_reg);
1504
1505           fprintf (file, "\taddq $30,$28,$30\n");
1506         }
1507       else if (frame_size)
1508         fprintf (file, "\tlda $30,%d($30)\n", frame_size);
1509
1510       /* Now return to the caller.  */
1511       fprintf (file, "\tret $31,($26),1\n");
1512     }
1513
1514   /* End the function.  */
1515   fprintf (file, "\t.end %s\n", alpha_function_name);
1516 }