OSDN Git Service

(check_float_value): New function.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
3    Contributed by Richard Kenner (kenner@vlsi1.ultra.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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "recog.h"
36 #include "reload.h"
37 #include "expr.h"
38 #include "obstack.h"
39 #include "tree.h"
40
41 /* Specify how accurate floating-point traps need to be.  */
42
43 enum alpha_trap_precision alpha_tp;
44
45 /* Specify the floating-point rounding mode.  */
46
47 enum alpha_fp_rounding_mode alpha_fprm;
48
49 /* Specify which things cause traps.  */
50
51 enum alpha_fp_trap_mode alpha_fptm;
52
53 /* Strings decoded into the above options.  */
54 char *alpha_tp_string;          /* -mtrap-precision=[p|s|i] */
55 char *alpha_fprm_string;        /* -mfp-rounding-mode=[n|m|c|d] */
56 char *alpha_fptm_string;        /* -mfp-trap-mode=[n|u|su|sui] */
57
58 /* Save information from a "cmpxx" operation until the branch or scc is
59    emitted.  */
60
61 rtx alpha_compare_op0, alpha_compare_op1;
62 int alpha_compare_fp_p;
63
64 /* Save the name of the current function as used by the assembler.  This
65    is used by the epilogue.  */
66
67 char *alpha_function_name;
68
69 /* Non-zero if inside of a function, because the Alpha asm can't
70    handle .files inside of functions.  */
71
72 static int inside_function = FALSE;
73
74 /* Non-zero if an instruction that may cause a trap is pending.  */
75
76 static int trap_pending = 0;
77
78 /* Nonzero if the current function needs gp.  */
79
80 int alpha_function_needs_gp;
81
82 extern char *version_string;
83 extern int rtx_equal_function_value_matters;
84
85 /* Declarations of static functions.  */
86 static void alpha_set_memflags_1  PROTO((rtx, int, int, int));
87 static rtx alpha_emit_set_const_1 PROTO((rtx, enum machine_mode,
88                                          HOST_WIDE_INT, int));
89 static void add_long_const      PROTO((FILE *, HOST_WIDE_INT, int, int, int));
90 \f
91 /* Parse target option strings. */
92
93 void
94 override_options ()
95 {
96   alpha_tp = ALPHA_TP_PROG;
97   alpha_fprm = ALPHA_FPRM_NORM;
98   alpha_fptm = ALPHA_FPTM_N;
99
100   if (TARGET_IEEE)
101     {
102       alpha_tp_string = "i";
103       alpha_fptm_string = "su";
104       target_flags |= MASK_IEEE_CONFORMANT;
105     }
106
107   if (TARGET_IEEE_WITH_INEXACT)
108     {
109       alpha_tp_string = "i";
110       alpha_fptm_string = "sui";
111       target_flags |= MASK_IEEE_CONFORMANT;
112     }
113
114   if (alpha_tp_string)
115     switch (alpha_tp_string[0])
116       {
117       case 'p':
118         alpha_tp = ALPHA_TP_PROG;
119         break;
120
121       case 'f':
122         alpha_tp = ALPHA_TP_FUNC;
123         break;
124
125       case 'i':
126         alpha_tp = ALPHA_TP_INSN;
127         break;
128
129       default:
130         error ("bad value (%s) for -mtrap-precision switch",
131                  alpha_tp_string);
132           break;
133       }
134
135   if (alpha_fprm_string)
136     switch (alpha_fprm_string[0])
137       {
138       case 'n':
139         alpha_fprm = ALPHA_FPRM_NORM;
140         break;
141
142       case 'm':
143         alpha_fprm = ALPHA_FPRM_MINF;
144         break;
145
146       case 'c':
147         alpha_fprm = ALPHA_FPRM_CHOP;
148         break;
149
150       case 'd':
151         alpha_fprm = ALPHA_FPRM_DYN;
152         break;
153
154       default:
155         error ("bad value (%s) for -mfp-rounding-mode switch",
156                alpha_fprm_string);
157         break;
158       }
159
160   if (alpha_fptm_string)
161     if (strcmp (alpha_fptm_string, "n") == 0)
162       alpha_fptm = ALPHA_FPTM_N;
163     else if (strcmp (alpha_fptm_string, "u") == 0)
164       alpha_fptm = ALPHA_FPTM_U;
165     else if (strcmp (alpha_fptm_string, "su") == 0)
166       alpha_fptm = ALPHA_FPTM_SU;
167     else if (strcmp (alpha_fptm_string, "sui") == 0)
168       alpha_fptm = ALPHA_FPTM_SUI;
169     else
170       error ("bad value (%s) for -mfp-trap-mode switch",
171              alpha_fptm_string);
172
173   /* Do some sanity checks on the above option. */
174
175   if (alpha_fptm >= ALPHA_FPTM_SU && alpha_tp != ALPHA_TP_INSN)
176     {
177       error ("fp software completion requires -mtrap-precision=i");
178       alpha_tp = ALPHA_TP_INSN;
179     }
180 }
181 \f
182 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
183
184 int
185 zap_mask (value)
186      HOST_WIDE_INT value;
187 {
188   int i;
189
190   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
191        i++, value >>= 8)
192     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
193       return 0;
194
195   return 1;
196 }
197
198 /* Returns 1 if OP is either the constant zero or a register.  If a
199    register, it must be in the proper mode unless MODE is VOIDmode.  */
200
201 int
202 reg_or_0_operand (op, mode)
203       register rtx op;
204       enum machine_mode mode;
205 {
206   return op == const0_rtx || register_operand (op, mode);
207 }
208
209 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
210    any register.  */
211
212 int
213 reg_or_6bit_operand (op, mode)
214      register rtx op;
215      enum machine_mode mode;
216 {
217   return ((GET_CODE (op) == CONST_INT
218            && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
219           || register_operand (op, mode));
220 }
221
222
223 /* Return 1 if OP is an 8-bit constant or any register.  */
224
225 int
226 reg_or_8bit_operand (op, mode)
227      register rtx op;
228      enum machine_mode mode;
229 {
230   return ((GET_CODE (op) == CONST_INT
231            && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
232           || register_operand (op, mode));
233 }
234
235 /* Return 1 if OP is an 8-bit constant.  */
236
237 int
238 cint8_operand (op, mode)
239      register rtx op;
240      enum machine_mode mode;
241 {
242   return (GET_CODE (op) == CONST_INT
243           && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
244 }
245
246 /* Return 1 if the operand is a valid second operand to an add insn.  */
247
248 int
249 add_operand (op, mode)
250      register rtx op;
251      enum machine_mode mode;
252 {
253   if (GET_CODE (op) == CONST_INT)
254     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
255             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')
256             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
257
258   return register_operand (op, mode);
259 }
260
261 /* Return 1 if the operand is a valid second operand to a sign-extending
262    add insn.  */
263
264 int
265 sext_add_operand (op, mode)
266      register rtx op;
267      enum machine_mode mode;
268 {
269   if (GET_CODE (op) == CONST_INT)
270     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
271             || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
272
273   return register_operand (op, mode);
274 }
275
276 /* Return 1 if OP is the constant 4 or 8.  */
277
278 int
279 const48_operand (op, mode)
280      register rtx op;
281      enum machine_mode mode;
282 {
283   return (GET_CODE (op) == CONST_INT
284           && (INTVAL (op) == 4 || INTVAL (op) == 8));
285 }
286
287 /* Return 1 if OP is a valid first operand to an AND insn.  */
288
289 int
290 and_operand (op, mode)
291      register rtx op;
292      enum machine_mode mode;
293 {
294   if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
295     return (zap_mask (CONST_DOUBLE_LOW (op))
296             && zap_mask (CONST_DOUBLE_HIGH (op)));
297
298   if (GET_CODE (op) == CONST_INT)
299     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
300             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
301             || zap_mask (INTVAL (op)));
302
303   return register_operand (op, mode);
304 }
305
306 /* Return 1 if OP is a valid first operand to an IOR or XOR insn.  */
307
308 int
309 or_operand (op, mode)
310      register rtx op;
311      enum machine_mode mode;
312 {
313   if (GET_CODE (op) == CONST_INT)
314     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
315             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
316
317   return register_operand (op, mode);
318 }
319
320 /* Return 1 if OP is a constant that is the width, in bits, of an integral
321    mode smaller than DImode.  */
322
323 int
324 mode_width_operand (op, mode)
325      register rtx op;
326      enum machine_mode mode;
327 {
328   return (GET_CODE (op) == CONST_INT
329           && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
330 }
331
332 /* Return 1 if OP is a constant that is the width of an integral machine mode
333    smaller than an integer.  */
334
335 int
336 mode_mask_operand (op, mode)
337      register rtx op;
338      enum machine_mode mode;
339 {
340 #if HOST_BITS_PER_WIDE_INT == 32
341   if (GET_CODE (op) == CONST_DOUBLE)
342     return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
343 #endif
344
345   return (GET_CODE (op) == CONST_INT
346           && (INTVAL (op) == 0xff
347               || INTVAL (op) == 0xffff
348 #if HOST_BITS_PER_WIDE_INT == 64
349               || INTVAL (op) == 0xffffffff
350 #endif
351               ));
352 }
353
354 /* Return 1 if OP is a multiple of 8 less than 64.  */
355
356 int
357 mul8_operand (op, mode)
358      register rtx op;
359      enum machine_mode mode;
360 {
361   return (GET_CODE (op) == CONST_INT
362           && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
363           && (INTVAL (op) & 7) == 0);
364 }
365
366 /* Return 1 if OP is the constant zero in floating-point.  */
367
368 int
369 fp0_operand (op, mode)
370      register rtx op;
371      enum machine_mode mode;
372 {
373   return (GET_MODE (op) == mode
374           && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
375 }
376
377 /* Return 1 if OP is the floating-point constant zero or a register.  */
378
379 int
380 reg_or_fp0_operand (op, mode)
381      register rtx op;
382      enum machine_mode mode;
383 {
384   return fp0_operand (op, mode) || register_operand (op, mode);
385 }
386
387 /* Return 1 if OP is a register or a constant integer.  */
388
389
390 int
391 reg_or_cint_operand (op, mode)
392     register rtx op;
393     enum machine_mode mode;
394 {
395      return GET_CODE (op) == CONST_INT || register_operand (op, mode);
396 }
397
398 /* Return 1 if OP is something that can be reloaded into a register;
399    if it is a MEM, it need not be valid.  */
400
401 int
402 some_operand (op, mode)
403      register rtx op;
404      enum machine_mode mode;
405 {
406   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
407     return 0;
408
409   switch (GET_CODE (op))
410     {
411     case REG:  case MEM:  case CONST_DOUBLE:
412     case CONST_INT:  case LABEL_REF:  case SYMBOL_REF:  case CONST:
413       return 1;
414
415     case SUBREG:
416       return some_operand (SUBREG_REG (op), VOIDmode);
417     }
418
419   return 0;
420 }
421
422 /* Return 1 if OP is a valid operand for the source of a move insn.  */
423
424 int
425 input_operand (op, mode)
426      register rtx op;
427      enum machine_mode mode;
428 {
429   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
430     return 0;
431
432   if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
433     return 0;
434
435   switch (GET_CODE (op))
436     {
437     case LABEL_REF:
438     case SYMBOL_REF:
439     case CONST:
440         /* This handles both the Windows/NT and OSF cases.  */
441       return mode == ptr_mode || mode == DImode;
442
443     case REG:
444       return 1;
445
446     case SUBREG:
447       if (register_operand (op, mode))
448         return 1;
449       /* ... fall through ... */
450     case MEM:
451       return mode != HImode && mode != QImode && general_operand (op, mode);
452
453     case CONST_DOUBLE:
454       return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
455
456     case CONST_INT:
457       return mode == QImode || mode == HImode || add_operand (op, mode);
458     }
459
460   return 0;
461 }
462
463 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
464    file.  */
465
466 int
467 current_file_function_operand (op, mode)
468      rtx op;
469      enum machine_mode mode;
470 {
471   return (GET_CODE (op) == SYMBOL_REF
472           && ! profile_flag && ! profile_block_flag
473           && (SYMBOL_REF_FLAG (op)
474               || op == XEXP (DECL_RTL (current_function_decl), 0)));
475 }
476
477 /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
478
479 int
480 call_operand (op, mode)
481      rtx op;
482      enum machine_mode mode;
483 {
484   if (mode != Pmode)
485     return 0;
486
487   return (GET_CODE (op) == SYMBOL_REF
488           || (GET_CODE (op) == REG && REGNO (op) == 27));
489 }
490
491 /* Return 1 if OP is a valid Alpha comparison operator.  Here we know which
492    comparisons are valid in which insn.  */
493
494 int
495 alpha_comparison_operator (op, mode)
496      register rtx op;
497      enum machine_mode mode;
498 {
499   enum rtx_code code = GET_CODE (op);
500
501   if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
502     return 0;
503
504   return (code == EQ || code == LE || code == LT
505           || (mode == DImode && (code == LEU || code == LTU)));
506 }
507
508 /* Return 1 if OP is a signed comparison operation.  */
509
510 int
511 signed_comparison_operator (op, mode)
512      register rtx op;
513      enum machine_mode mode;
514 {
515   switch (GET_CODE (op))
516     {
517     case EQ:  case NE:  case LE:  case LT:  case GE:   case GT:
518       return 1;
519     }
520
521   return 0;
522 }
523
524 /* Return 1 if this is a divide or modulus operator.  */
525
526 int
527 divmod_operator (op, mode)
528      register rtx op;
529      enum machine_mode mode;
530 {
531   switch (GET_CODE (op))
532     {
533     case DIV:  case MOD:  case UDIV:  case UMOD:
534       return 1;
535     }
536
537   return 0;
538 }
539
540 /* Return 1 if this memory address is a known aligned register plus
541    a constant.  It must be a valid address.  This means that we can do
542    this as an aligned reference plus some offset.
543
544    Take into account what reload will do.
545
546    We could say that out-of-range stack slots are alignable, but that would
547    complicate get_aligned_mem and it isn't worth the trouble since few
548    functions have large stack space.  */
549
550 int
551 aligned_memory_operand (op, mode)
552      register rtx op;
553      enum machine_mode mode;
554 {
555   if (GET_CODE (op) == SUBREG)
556     {
557       if (GET_MODE (op) != mode)
558         return 0;
559       op = SUBREG_REG (op);
560       mode = GET_MODE (op);
561     }
562
563   if (reload_in_progress && GET_CODE (op) == REG
564       && REGNO (op) >= FIRST_PSEUDO_REGISTER)
565     op = reg_equiv_mem[REGNO (op)];
566
567   if (GET_CODE (op) != MEM || GET_MODE (op) != mode
568       || ! memory_address_p (mode, XEXP (op, 0)))
569     return 0;
570
571   op = XEXP (op, 0);
572
573   if (GET_CODE (op) == PLUS)
574     op = XEXP (op, 0);
575
576   return (GET_CODE (op) == REG
577           && REGNO_POINTER_ALIGN (REGNO (op)) >= 4);
578 }
579
580 /* Similar, but return 1 if OP is a MEM which is not alignable.  */
581
582 int
583 unaligned_memory_operand (op, mode)
584      register rtx op;
585      enum machine_mode mode;
586 {
587   if (GET_CODE (op) == SUBREG)
588     {
589       if (GET_MODE (op) != mode)
590         return 0;
591       op = SUBREG_REG (op);
592       mode = GET_MODE (op);
593     }
594
595   if (reload_in_progress && GET_CODE (op) == REG
596       && REGNO (op) >= FIRST_PSEUDO_REGISTER)
597     op = reg_equiv_mem[REGNO (op)];
598
599   if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
600     return 0;
601
602   op = XEXP (op, 0);
603
604   if (! memory_address_p (mode, op))
605     return 1;
606
607   if (GET_CODE (op) == PLUS)
608     op = XEXP (op, 0);
609
610   return (GET_CODE (op) != REG
611           || REGNO_POINTER_ALIGN (REGNO (op)) < 4);
612 }
613
614 /* Return 1 if OP is either a register or an unaligned memory location.  */
615
616 int
617 reg_or_unaligned_mem_operand (op, mode)
618      rtx op;
619      enum machine_mode mode;
620 {
621   return register_operand (op, mode) || unaligned_memory_operand (op, mode);
622 }
623
624 /* Return 1 if OP is any memory location.  During reload a pseudo matches.  */
625
626 int
627 any_memory_operand (op, mode)
628      register rtx op;
629      enum machine_mode mode;
630 {
631   return (GET_CODE (op) == MEM
632           || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
633           || (reload_in_progress && GET_CODE (op) == REG
634               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
635           || (reload_in_progress && GET_CODE (op) == SUBREG
636               && GET_CODE (SUBREG_REG (op)) == REG
637               && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
638 }
639
640 /* REF is an alignable memory location.  Place an aligned SImode
641    reference into *PALIGNED_MEM and the number of bits to shift into
642    *PBITNUM.  */
643
644 void
645 get_aligned_mem (ref, paligned_mem, pbitnum)
646      rtx ref;
647      rtx *paligned_mem, *pbitnum;
648 {
649   rtx base;
650   HOST_WIDE_INT offset = 0;
651
652   if (GET_CODE (ref) == SUBREG)
653     {
654       offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
655       if (BYTES_BIG_ENDIAN)
656         offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
657                    - MIN (UNITS_PER_WORD,
658                           GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
659       ref = SUBREG_REG (ref);
660     }
661
662   if (GET_CODE (ref) == REG)
663     ref = reg_equiv_mem[REGNO (ref)];
664
665   if (reload_in_progress)
666     base = find_replacement (&XEXP (ref, 0));
667   else
668     base = XEXP (ref, 0);
669
670   if (GET_CODE (base) == PLUS)
671     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
672
673   *paligned_mem = gen_rtx (MEM, SImode,
674                            plus_constant (base, offset & ~3));
675   MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
676   MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
677   RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
678
679   *pbitnum = GEN_INT ((offset & 3) * 8);
680 }
681
682 /* Similar, but just get the address.  Handle the two reload cases.  
683    Add EXTRA_OFFSET to the address we return.  */
684
685 rtx
686 get_unaligned_address (ref, extra_offset)
687      rtx ref;
688      int extra_offset;
689 {
690   rtx base;
691   HOST_WIDE_INT offset = 0;
692
693   if (GET_CODE (ref) == SUBREG)
694     {
695       offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
696       if (BYTES_BIG_ENDIAN)
697         offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
698                    - MIN (UNITS_PER_WORD,
699                           GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
700       ref = SUBREG_REG (ref);
701     }
702
703   if (GET_CODE (ref) == REG)
704     ref = reg_equiv_mem[REGNO (ref)];
705
706   if (reload_in_progress)
707     base = find_replacement (&XEXP (ref, 0));
708   else
709     base = XEXP (ref, 0);
710
711   if (GET_CODE (base) == PLUS)
712     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
713
714   return plus_constant (base, offset + extra_offset);
715 }
716 \f
717 /* Subfunction of the following function.  Update the flags of any MEM
718    found in part of X.  */
719
720 static void
721 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
722      rtx x;
723      int in_struct_p, volatile_p, unchanging_p;
724 {
725   int i;
726
727   switch (GET_CODE (x))
728     {
729     case SEQUENCE:
730     case PARALLEL:
731       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
732         alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
733                               unchanging_p);
734       break;
735
736     case INSN:
737       alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
738                             unchanging_p);
739       break;
740
741     case SET:
742       alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
743                             unchanging_p);
744       alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
745                             unchanging_p);
746       break;
747
748     case MEM:
749       MEM_IN_STRUCT_P (x) = in_struct_p;
750       MEM_VOLATILE_P (x) = volatile_p;
751       RTX_UNCHANGING_P (x) = unchanging_p;
752       break;
753     }
754 }
755
756 /* Given INSN, which is either an INSN or a SEQUENCE generated to
757    perform a memory operation, look for any MEMs in either a SET_DEST or
758    a SET_SRC and copy the in-struct, unchanging, and volatile flags from
759    REF into each of the MEMs found.  If REF is not a MEM, don't do
760    anything.  */
761
762 void
763 alpha_set_memflags (insn, ref)
764      rtx insn;
765      rtx ref;
766 {
767   /* Note that it is always safe to get these flags, though they won't
768      be what we think if REF is not a MEM.  */
769   int in_struct_p = MEM_IN_STRUCT_P (ref);
770   int volatile_p = MEM_VOLATILE_P (ref);
771   int unchanging_p = RTX_UNCHANGING_P (ref);
772
773   if (GET_CODE (ref) != MEM
774       || (! in_struct_p && ! volatile_p && ! unchanging_p))
775     return;
776
777   alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
778 }
779 \f
780 /* Try to output insns to set TARGET equal to the constant C if it can be
781    done in less than N insns.  Do all computations in MODE.  Returns the place
782    where the output has been placed if it can be done and the insns have been
783    emitted.  If it would take more than N insns, zero is returned and no
784    insns and emitted.  */
785
786 rtx
787 alpha_emit_set_const (target, mode, c, n)
788      rtx target;
789      enum machine_mode mode;
790      HOST_WIDE_INT c;
791      int n;
792 {
793   rtx pat;
794   int i;
795
796   /* Try 1 insn, then 2, then up to N. */
797   for (i = 1; i <= n; i++)
798     if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
799       return pat;
800
801   return 0;
802 }
803
804 /* Internal routine for the above to check for N or below insns.  */
805
806 static rtx
807 alpha_emit_set_const_1 (target, mode, c, n)
808      rtx target;
809      enum machine_mode mode;
810      HOST_WIDE_INT c;
811      int n;
812 {
813   HOST_WIDE_INT new = c;
814   int i, bits;
815   /* Use a pseudo if highly optimizing and still generating RTL.  */
816   rtx subtarget
817     = (flag_expensive_optimizations && rtx_equal_function_value_matters
818        ? 0 : target);
819   rtx temp;
820
821 #if HOST_BITS_PER_WIDE_INT == 64
822   /* We are only called for SImode and DImode.  If this is SImode, ensure that
823      we are sign extended to a full word.  This does not make any sense when
824      cross-compiling on a narrow machine.  */
825
826   if (mode == SImode)
827     c = (c & 0xffffffff) - 2 * (c & 0x80000000);
828 #endif
829
830   /* If this is a sign-extended 32-bit constant, we can do this in at most
831      three insns, so do it if we have enough insns left.  We always have
832      a sign-extended 32-bit constant when compiling on a narrow machine. 
833      Note that we cannot handle the constant 0x80000000.  */
834
835   if ((HOST_BITS_PER_WIDE_INT != 64
836        || c >> 31 == -1 || c >> 31 == 0)
837       && c != 0x80000000U)
838     {
839       HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
840       HOST_WIDE_INT tmp1 = c - low;
841       HOST_WIDE_INT high
842         = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
843       HOST_WIDE_INT extra = 0;
844
845       /* If HIGH will be interpreted as negative but the constant is
846          positive, we must adjust it to do two ldha insns.  */
847
848       if ((high & 0x8000) != 0 && c >= 0)
849         {
850           extra = 0x4000;
851           tmp1 -= 0x40000000;
852           high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
853         }
854
855       if (c == low || (low == 0 && extra == 0))
856         return copy_to_suggested_reg (GEN_INT (c), target, mode);
857       else if (n >= 2 + (extra != 0))
858         {
859           temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
860
861           if (extra != 0)
862             temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
863                                  subtarget, 0, OPTAB_WIDEN);
864
865           return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
866                                target, 0, OPTAB_WIDEN);
867         }
868     }
869
870   /* If we couldn't do it that way, try some other methods.  But if we have
871      no instructions left, don't bother.  Likewise, if this is SImode and
872      we can't make pseudos, we can't do anything since the expand_binop
873      and expand_unop calls will widen and try to make pseudos.  */
874
875   if (n == 1
876       || (mode == SImode && ! rtx_equal_function_value_matters))
877     return 0;
878
879 #if HOST_BITS_PER_WIDE_INT == 64
880   /* First, see if can load a value into the target that is the same as the
881      constant except that all bytes that are 0 are changed to be 0xff.  If we
882      can, then we can do a ZAPNOT to obtain the desired constant.  */
883
884   for (i = 0; i < 64; i += 8)
885     if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
886       new |= (HOST_WIDE_INT) 0xff << i;
887
888   /* We are only called for SImode and DImode.  If this is SImode, ensure that
889      we are sign extended to a full word.  */
890
891   if (mode == SImode)
892     new = (new & 0xffffffff) - 2 * (new & 0x80000000);
893
894   if (new != c
895       && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
896     return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
897                          target, 0, OPTAB_WIDEN);
898 #endif
899
900   /* Next, see if we can load a related constant and then shift and possibly
901      negate it to get the constant we want.  Try this once each increasing
902      numbers of insns.  */
903
904   for (i = 1; i < n; i++)
905     {
906       /* First try complementing.  */
907       if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
908         return expand_unop (mode, one_cmpl_optab, temp, target, 0);
909
910       /* Next try to form a constant and do a left shift.  We can do this
911          if some low-order bits are zero; the exact_log2 call below tells
912          us that information.  The bits we are shifting out could be any
913          value, but here we'll just try the 0- and sign-extended forms of
914          the constant.  To try to increase the chance of having the same
915          constant in more than one insn, start at the highest number of
916          bits to shift, but try all possibilities in case a ZAPNOT will
917          be useful.  */
918
919       if ((bits = exact_log2 (c & - c)) > 0)
920         for (; bits > 0; bits--)
921           if ((temp = (alpha_emit_set_const
922                        (subtarget, mode,
923                         (unsigned HOST_WIDE_INT) c >> bits, i))) != 0
924               || ((temp = (alpha_emit_set_const
925                           (subtarget, mode,
926                            ((unsigned HOST_WIDE_INT) c) >> bits, i)))
927                   != 0))
928             return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
929                                  target, 0, OPTAB_WIDEN);
930
931       /* Now try high-order zero bits.  Here we try the shifted-in bits as
932          all zero and all ones.  Be careful to avoid shifting outside the
933          mode and to avoid shifting outside the host wide int size.  */
934
935       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
936                    - floor_log2 (c) - 1)) > 0)
937         for (; bits > 0; bits--)
938           if ((temp = alpha_emit_set_const (subtarget, mode,
939                                             c << bits, i)) != 0
940               || ((temp = (alpha_emit_set_const
941                            (subtarget, mode,
942                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
943                             i)))
944                   != 0))
945             return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
946                                  target, 1, OPTAB_WIDEN);
947
948       /* Now try high-order 1 bits.  We get that with a sign-extension.
949          But one bit isn't enough here.  Be careful to avoid shifting outside
950          the mode and to avoid shifting outside the host wide int size. */
951       
952       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
953                    - floor_log2 (~ c) - 2)) > 0)
954         for (; bits > 0; bits--)
955           if ((temp = alpha_emit_set_const (subtarget, mode,
956                                             c << bits, i)) != 0
957               || ((temp = (alpha_emit_set_const
958                            (subtarget, mode,
959                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
960                             i)))
961                   != 0))
962             return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
963                                  target, 0, OPTAB_WIDEN);
964     }
965
966   return 0;
967 }
968 \f
969 /* Adjust the cost of a scheduling dependency.  Return the new cost of
970    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
971
972 int
973 alpha_adjust_cost (insn, link, dep_insn, cost)
974      rtx insn;
975      rtx link;
976      rtx dep_insn;
977      int cost;
978 {
979   rtx set;
980
981   /* If the dependence is an anti-dependence, there is no cost.  For an
982      output dependence, there is sometimes a cost, but it doesn't seem
983      worth handling those few cases.  */
984
985   if (REG_NOTE_KIND (link) != 0)
986     return 0;
987
988   /* If INSN is a store insn and DEP_INSN is setting the data being stored,
989      we can sometimes lower the cost.  */
990
991   if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
992       && (set = single_set (dep_insn)) != 0
993       && GET_CODE (PATTERN (insn)) == SET
994       && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
995     switch (get_attr_type (dep_insn))
996       {
997       case TYPE_LD:
998         /* No savings here.  */
999         return cost;
1000
1001       case TYPE_IMULL:
1002       case TYPE_IMULQ:
1003         /* In these cases, we save one cycle.  */
1004         return cost - 2;
1005
1006       default:
1007         /* In all other cases, we save two cycles.  */
1008         return MAX (0, cost - 4);
1009       }
1010
1011   /* Another case that needs adjustment is an arithmetic or logical
1012      operation.  It's cost is usually one cycle, but we default it to
1013      two in the MD file.  The only case that it is actually two is
1014      for the address in loads and stores.  */
1015
1016   if (recog_memoized (dep_insn) >= 0
1017       && get_attr_type (dep_insn) == TYPE_IADDLOG)
1018     switch (get_attr_type (insn))
1019       {
1020       case TYPE_LD:
1021       case TYPE_ST:
1022         return cost;
1023
1024       default:
1025         return 2;
1026       }
1027
1028   /* The final case is when a compare feeds into an integer branch.  The cost
1029      is only one cycle in that case.  */
1030
1031   if (recog_memoized (dep_insn) >= 0
1032       && get_attr_type (dep_insn) == TYPE_ICMP
1033       && recog_memoized (insn) >= 0
1034       && get_attr_type (insn) == TYPE_IBR)
1035     return 2;
1036
1037   /* Otherwise, return the default cost. */
1038
1039   return cost;
1040 }
1041 \f
1042 /* Print an operand.  Recognize special options, documented below.  */
1043
1044 void
1045 print_operand (file, x, code)
1046     FILE *file;
1047     rtx x;
1048     char code;
1049 {
1050   int i;
1051
1052   switch (code)
1053     {
1054     case '&':
1055       /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1056          chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1057          mode.  alpha_fprm controls which suffix is generated.  */
1058       switch (alpha_fprm)
1059         {
1060         case ALPHA_FPRM_NORM:
1061           break;
1062         case ALPHA_FPRM_MINF: 
1063           fputc ('m', file);
1064           break;
1065         case ALPHA_FPRM_CHOP:
1066           fputc ('c', file);
1067           break;
1068         case ALPHA_FPRM_DYN:
1069           fputc ('d', file);
1070           break;
1071         }
1072       break;
1073
1074     case '\'':
1075       /* Generates trap-mode suffix for instructions that accept the su
1076          suffix only (cmpt et al).  */
1077       if (alpha_tp == ALPHA_TP_INSN)
1078         fputs ("su", file);
1079       break;
1080
1081     case ')':
1082       /* Generates trap-mode suffix for instructions that accept the u, su,
1083          and sui suffix.  This is the bulk of the IEEE floating point
1084          instructions (addt et al).  */
1085       switch (alpha_fptm)
1086         {
1087         case ALPHA_FPTM_N:
1088           break;
1089         case ALPHA_FPTM_U:
1090           fputc ('u', file);
1091           break;
1092         case ALPHA_FPTM_SU:
1093           fputs ("su", file);
1094           break;
1095         case ALPHA_FPTM_SUI:
1096           fputs ("sui", file);
1097           break;
1098         }
1099       break;
1100
1101     case '+':
1102       /* Generates trap-mode suffix for instructions that accept the sui
1103          suffix (cvtqt and cvtqs).  */
1104       switch (alpha_fptm)
1105         {
1106         case ALPHA_FPTM_N: case ALPHA_FPTM_U:
1107         case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
1108           break;
1109         case ALPHA_FPTM_SUI:
1110           fputs ("sui", file);
1111           break;
1112         }
1113       break;
1114
1115     case 'r':
1116       /* If this operand is the constant zero, write it as "$31".  */
1117       if (GET_CODE (x) == REG)
1118         fprintf (file, "%s", reg_names[REGNO (x)]);
1119       else if (x == CONST0_RTX (GET_MODE (x)))
1120         fprintf (file, "$31");
1121       else
1122         output_operand_lossage ("invalid %%r value");
1123
1124       break;
1125
1126     case 'R':
1127       /* Similar, but for floating-point.  */
1128       if (GET_CODE (x) == REG)
1129         fprintf (file, "%s", reg_names[REGNO (x)]);
1130       else if (x == CONST0_RTX (GET_MODE (x)))
1131         fprintf (file, "$f31");
1132       else
1133         output_operand_lossage ("invalid %%R value");
1134
1135       break;
1136
1137     case 'N':
1138       /* Write the 1's complement of a constant.  */
1139       if (GET_CODE (x) != CONST_INT)
1140         output_operand_lossage ("invalid %%N value");
1141
1142       fprintf (file, "%ld", ~ INTVAL (x));
1143       break;
1144
1145     case 'P':
1146       /* Write 1 << C, for a constant C.  */
1147       if (GET_CODE (x) != CONST_INT)
1148         output_operand_lossage ("invalid %%P value");
1149
1150       fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
1151       break;
1152
1153     case 'h':
1154       /* Write the high-order 16 bits of a constant, sign-extended.  */
1155       if (GET_CODE (x) != CONST_INT)
1156         output_operand_lossage ("invalid %%h value");
1157
1158       fprintf (file, "%ld", INTVAL (x) >> 16);
1159       break;
1160
1161     case 'L':
1162       /* Write the low-order 16 bits of a constant, sign-extended.  */
1163       if (GET_CODE (x) != CONST_INT)
1164         output_operand_lossage ("invalid %%L value");
1165
1166       fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
1167       break;
1168
1169     case 'm':
1170       /* Write mask for ZAP insn.  */
1171       if (GET_CODE (x) == CONST_DOUBLE)
1172         {
1173           HOST_WIDE_INT mask = 0;
1174           HOST_WIDE_INT value;
1175
1176           value = CONST_DOUBLE_LOW (x);
1177           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1178                i++, value >>= 8)
1179             if (value & 0xff)
1180               mask |= (1 << i);
1181
1182           value = CONST_DOUBLE_HIGH (x);
1183           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1184                i++, value >>= 8)
1185             if (value & 0xff)
1186               mask |= (1 << (i + sizeof (int)));
1187
1188           fprintf (file, "%ld", mask & 0xff);
1189         }
1190
1191       else if (GET_CODE (x) == CONST_INT)
1192         {
1193           HOST_WIDE_INT mask = 0, value = INTVAL (x);
1194
1195           for (i = 0; i < 8; i++, value >>= 8)
1196             if (value & 0xff)
1197               mask |= (1 << i);
1198
1199           fprintf (file, "%ld", mask);
1200         }
1201       else
1202         output_operand_lossage ("invalid %%m value");
1203       break;
1204
1205     case 'M':
1206       /* 'b', 'w', or 'l' as the value of the constant.  */
1207       if (GET_CODE (x) != CONST_INT
1208           || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
1209         output_operand_lossage ("invalid %%M value");
1210
1211       fprintf (file, "%s",
1212                INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
1213       break;
1214
1215     case 'U':
1216       /* Similar, except do it from the mask.  */
1217       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
1218         fprintf (file, "b");
1219       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
1220         fprintf (file, "w");
1221 #if HOST_BITS_PER_WIDE_INT == 32
1222       else if (GET_CODE (x) == CONST_DOUBLE
1223                && CONST_DOUBLE_HIGH (x) == 0
1224                && CONST_DOUBLE_LOW (x) == -1)
1225         fprintf (file, "l");
1226 #else
1227       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
1228         fprintf (file, "l");
1229 #endif
1230       else
1231         output_operand_lossage ("invalid %%U value");
1232       break;
1233
1234     case 's':
1235       /* Write the constant value divided by 8.  */
1236       if (GET_CODE (x) != CONST_INT
1237           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1238           && (INTVAL (x) & 7) != 8)
1239         output_operand_lossage ("invalid %%s value");
1240
1241       fprintf (file, "%ld", INTVAL (x) / 8);
1242       break;
1243
1244     case 'S':
1245       /* Same, except compute (64 - c) / 8 */
1246
1247       if (GET_CODE (x) != CONST_INT
1248           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1249           && (INTVAL (x) & 7) != 8)
1250         output_operand_lossage ("invalid %%s value");
1251
1252       fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
1253       break;
1254
1255     case 'C':
1256       /* Write out comparison name.  */
1257       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1258         output_operand_lossage ("invalid %%C value");
1259
1260       if (GET_CODE (x) == LEU)
1261         fprintf (file, "ule");
1262       else if (GET_CODE (x) == LTU)
1263         fprintf (file, "ult");
1264       else
1265         fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
1266       break;
1267
1268     case 'D':
1269       /* Similar, but write reversed code.  We can't get an unsigned code
1270          here.  */
1271       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1272         output_operand_lossage ("invalid %%D value");
1273
1274       fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
1275       break;
1276
1277     case 'c':
1278       /* Similar to `c', but swap.  We can't get unsigned here either.  */
1279       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1280         output_operand_lossage ("invalid %%D value");
1281
1282       fprintf (file, "%s", GET_RTX_NAME (swap_condition (GET_CODE (x))));
1283       break;
1284
1285     case 'd':
1286       /* Similar, but reverse and swap.  We can't get unsigned here either.  */
1287       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1288         output_operand_lossage ("invalid %%D value");
1289
1290       fprintf (file, "%s",
1291                GET_RTX_NAME (swap_condition (reverse_condition ((GET_CODE (x))))));
1292       break;
1293
1294     case 'E':
1295       /* Write the divide or modulus operator.  */
1296       switch (GET_CODE (x))
1297         {
1298         case DIV:
1299           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
1300           break;
1301         case UDIV:
1302           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
1303           break;
1304         case MOD:
1305           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
1306           break;
1307         case UMOD:
1308           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
1309           break;
1310         default:
1311           output_operand_lossage ("invalid %%E value");
1312           break;
1313         }
1314       break;
1315
1316     case 'A':
1317       /* Write "_u" for unaligned access.  */
1318       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1319         fprintf (file, "_u");
1320       break;
1321
1322     case 0:
1323       if (GET_CODE (x) == REG)
1324         fprintf (file, "%s", reg_names[REGNO (x)]);
1325       else if (GET_CODE (x) == MEM)
1326         output_address (XEXP (x, 0));
1327       else
1328         output_addr_const (file, x);
1329       break;
1330
1331     default:
1332       output_operand_lossage ("invalid %%xn code");
1333     }
1334 }
1335 \f
1336 /* Do what is necessary for `va_start'.  The argument is ignored;
1337    We look at the current function to determine if stdarg or varargs
1338    is used and fill in an initial va_list.  A pointer to this constructor
1339    is returned.  */
1340
1341 struct rtx_def *
1342 alpha_builtin_saveregs (arglist)
1343      tree arglist;
1344 {
1345   rtx block, addr, argsize;
1346   tree fntype = TREE_TYPE (current_function_decl);
1347   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1348                 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1349                     != void_type_node));
1350
1351   /* Compute the current position into the args, taking into account
1352      both registers and memory.  Both of these are already included in
1353      current_function_args_info.  */
1354
1355   argsize = GEN_INT (current_function_args_info * UNITS_PER_WORD);
1356
1357   /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1358      storing fp arg registers in the first 48 bytes, and the integer arg
1359      registers in the next 48 bytes.  This is only done, however, if any
1360      integer registers need to be stored.
1361
1362      If no integer registers need be stored, then we must subtract 48 in
1363      order to account for the integer arg registers which are counted in
1364      argsize above, but which are not actually stored on the stack.  */
1365
1366   addr = (current_function_args_info <= 5 + stdarg
1367           ? plus_constant (virtual_incoming_args_rtx, 6 * UNITS_PER_WORD)
1368           : plus_constant (virtual_incoming_args_rtx, - (6 * UNITS_PER_WORD)));
1369
1370   addr = force_operand (addr, NULL_RTX);
1371
1372   /* Allocate the va_list constructor */
1373   block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
1374   RTX_UNCHANGING_P (block) = 1;
1375   RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1376
1377   /* Store the address of the first integer register in the __base member.  */
1378
1379 #ifdef POINTERS_EXTEND_UNSIGNED
1380   addr = convert_memory_address (ptr_mode, addr);
1381 #endif
1382
1383   emit_move_insn (change_address (block, ptr_mode, XEXP (block, 0)), addr);
1384
1385   /* Store the argsize as the __va_offset member.  */
1386   emit_move_insn (change_address (block, TYPE_MODE (integer_type_node),
1387                                   plus_constant (XEXP (block, 0),
1388                                                  POINTER_SIZE/BITS_PER_UNIT)),
1389                   argsize);
1390
1391   /* Return the address of the va_list constructor, but don't put it in a
1392      register.  Doing so would fail when not optimizing and produce worse
1393      code when optimizing.  */
1394   return XEXP (block, 0);
1395 }
1396 \f
1397 /* This page contains routines that are used to determine what the function
1398    prologue and epilogue code will do and write them out.  */
1399
1400 /* Compute the size of the save area in the stack.  */
1401
1402 int
1403 alpha_sa_size ()
1404 {
1405   int size = 0;
1406   int i;
1407
1408   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1409     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1410       size++;
1411
1412   /* If some registers were saved but not reg 26, reg 26 must also
1413      be saved, so leave space for it.  */
1414   if (size != 0 && ! regs_ever_live[26])
1415     size++;
1416
1417   /* Our size must be even (multiple of 16 bytes).  */
1418   if (size & 1)
1419     size ++;
1420
1421   return size * 8;
1422 }
1423
1424 /* Return 1 if this function can directly return via $26.  */
1425
1426 int
1427 direct_return ()
1428 {
1429   return (reload_completed && alpha_sa_size () == 0
1430           && get_frame_size () == 0
1431           && current_function_outgoing_args_size == 0
1432           && current_function_pretend_args_size == 0);
1433 }
1434
1435 /* Write a version stamp.  Don't write anything if we are running as a
1436    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
1437
1438 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__)
1439 #include <stamp.h>
1440 #endif
1441
1442 void
1443 alpha_write_verstamp (file)
1444      FILE *file;
1445 {
1446 #ifdef MS_STAMP
1447   fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
1448 #endif
1449 }
1450 \f
1451 /* Write code to add constant C to register number IN_REG (possibly 31)
1452    and put the result into OUT_REG.  Use TEMP_REG as a scratch register;
1453    usually this will be OUT_REG, but should not be if OUT_REG is 
1454    STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1455    Write the code to FILE.  */
1456
1457 static void
1458 add_long_const (file, c, in_reg, out_reg, temp_reg)
1459      FILE *file;
1460      HOST_WIDE_INT c;
1461      int in_reg, out_reg, temp_reg;
1462 {
1463   HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1464   HOST_WIDE_INT tmp1 = c - low;
1465   HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1466   HOST_WIDE_INT extra = 0;
1467
1468   /* We don't have code to write out constants larger than 32 bits.  */
1469 #if HOST_BITS_PER_LONG_INT == 64
1470   if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
1471     abort ();
1472 #endif
1473
1474   /* If HIGH will be interpreted as negative, we must adjust it to do two
1475      ldha insns.  Note that we will never be building a negative constant
1476      here.  */
1477
1478   if (high & 0x8000)
1479     {
1480       extra = 0x4000;
1481       tmp1 -= 0x40000000;
1482       high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1483     }
1484
1485   if (low != 0)
1486     {
1487       int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
1488
1489       if (low >= 0 && low < 255)
1490         fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
1491       else
1492         fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
1493
1494       in_reg = result_reg;
1495     }
1496
1497   if (extra)
1498     {
1499       int result_reg = (high == 0) ? out_reg : temp_reg;
1500
1501       fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
1502       in_reg = result_reg;
1503     }
1504
1505   if (high)
1506     fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
1507 }
1508
1509 /* Write function prologue.  */
1510
1511 void
1512 output_prolog (file, size)
1513      FILE *file;
1514      int size;
1515 {
1516   HOST_WIDE_INT out_args_size
1517     = ALPHA_ROUND (current_function_outgoing_args_size);
1518   HOST_WIDE_INT sa_size = alpha_sa_size ();
1519   HOST_WIDE_INT frame_size
1520     = (out_args_size + sa_size
1521        + ALPHA_ROUND (size + current_function_pretend_args_size));
1522   HOST_WIDE_INT reg_offset = out_args_size;
1523   HOST_WIDE_INT start_reg_offset = reg_offset;
1524   HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
1525   int int_reg_save_area_size = 0;
1526   rtx insn;
1527   unsigned reg_mask = 0;
1528   int i;
1529
1530   /* Ecoff can handle multiple .file directives, so put out file and lineno.
1531      We have to do that before the .ent directive as we cannot switch
1532      files within procedures with native ecoff because line numbers are
1533      linked to procedure descriptors.
1534      Outputting the lineno helps debugging of one line functions as they
1535      would otherwise get no line number at all. Please note that we would
1536      like to put out last_linenum from final.c, but it is not accessible.  */
1537
1538   if (write_symbols == SDB_DEBUG)
1539     {
1540       ASM_OUTPUT_SOURCE_FILENAME (file,
1541                                   DECL_SOURCE_FILE (current_function_decl));
1542       if (debug_info_level != DINFO_LEVEL_TERSE)
1543         ASM_OUTPUT_SOURCE_LINE (file,
1544                                 DECL_SOURCE_LINE (current_function_decl));
1545     }
1546
1547   /* The assembly language programmer's guide states that the second argument
1548      to the .ent directive, the lex_level, is ignored by the assembler,
1549      so we might as well omit it.  */
1550      
1551   fprintf (file, "\t.ent ");
1552   assemble_name (file, alpha_function_name);
1553   fprintf (file, "\n");
1554   ASM_OUTPUT_LABEL (file, alpha_function_name);
1555   inside_function = TRUE;
1556
1557   if (TARGET_IEEE_CONFORMANT)
1558     /* Set flags in procedure descriptor to request IEEE-conformant
1559        math-library routines.  The value we set it to is PDSC_EXC_IEEE
1560        (/usr/include/pdsc.h). */
1561     fprintf (file, "\t.eflag 48\n");
1562
1563   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
1564
1565   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
1566   alpha_arg_offset = -frame_size + 48;
1567
1568   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
1569      Even if we are a static function, we still need to do this in case
1570      our address is taken and passed to something like qsort.
1571
1572      We never need a GP for Windows/NT.  */
1573
1574   alpha_function_needs_gp = 0;
1575
1576 #ifdef TARGET_PROFILING_NEEDS_GP
1577   if (profile_flag)
1578     alpha_function_needs_gp = 1;
1579 #endif
1580
1581   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1582     if ((GET_CODE (insn) == CALL_INSN)
1583         || (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1584             && GET_CODE (PATTERN (insn)) != USE
1585             && GET_CODE (PATTERN (insn)) != CLOBBER
1586             && (get_attr_type (insn) == TYPE_LDSYM
1587                 || get_attr_type (insn) == TYPE_ISUBR)))
1588       {
1589         alpha_function_needs_gp = 1;
1590         break;
1591       }
1592
1593   if (WINDOWS_NT == 0)
1594     {
1595       if (alpha_function_needs_gp)
1596         fprintf (file, "\tldgp $29,0($27)\n");
1597
1598       /* Put a label after the GP load so we can enter the function at it.  */
1599       assemble_name (file, alpha_function_name);
1600       fprintf (file, "..ng:\n");
1601     }
1602
1603   /* Adjust the stack by the frame size.  If the frame size is > 4096
1604      bytes, we need to be sure we probe somewhere in the first and last
1605      4096 bytes (we can probably get away without the latter test) and
1606      every 8192 bytes in between.  If the frame size is > 32768, we
1607      do this in a loop.  Otherwise, we generate the explicit probe
1608      instructions. 
1609
1610      Note that we are only allowed to adjust sp once in the prologue.  */
1611
1612   if (frame_size < 32768)
1613     {
1614       if (frame_size > 4096)
1615         {
1616           int probed = 4096;
1617
1618           fprintf (file, "\tstq $31,-%d($30)\n", probed);
1619
1620           while (probed + 8192 < frame_size)
1621             fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
1622
1623           /* We only have to do this probe if we aren't saving registers.  */
1624           if (sa_size == 0 && probed + 4096 < frame_size)
1625             fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
1626         }
1627
1628       if (frame_size != 0)
1629         fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1630     }
1631   else
1632     {
1633       /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1634          number of 8192 byte blocks to probe.  We then probe each block
1635          in the loop and then set SP to the proper location.  If the
1636          amount remaining is > 4096, we have to do one more probe if we
1637          are not saving any registers.  */
1638
1639       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
1640       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
1641
1642       add_long_const (file, blocks, 31, 5, 5);
1643
1644       fprintf (file, "\tlda $4,4096($30)\n");
1645
1646       assemble_name (file, alpha_function_name);
1647       fprintf (file, "..sc:\n");
1648
1649       fprintf (file, "\tstq $31,-8192($4)\n");
1650       fprintf (file, "\tsubq $5,1,$5\n");
1651       fprintf (file, "\tlda $4,-8192($4)\n");
1652
1653       fprintf (file, "\tbne $5,");
1654       assemble_name (file, alpha_function_name);
1655       fprintf (file, "..sc\n");
1656
1657       if (leftover > 4096 && sa_size == 0)
1658         fprintf (file, "\tstq $31,-%d($4)\n", leftover);
1659
1660       fprintf (file, "\tlda $30,-%d($4)\n", leftover);
1661     }
1662
1663   /* Describe our frame.  */
1664   fprintf (file, "\t.frame $%d,%d,$26,%d\n", 
1665            (frame_pointer_needed
1666             ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
1667            frame_size, current_function_pretend_args_size);
1668     
1669   /* Save register 26 if any other register needs to be saved.  */
1670   if (sa_size != 0)
1671     {
1672       reg_mask |= 1 << 26;
1673       fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1674       reg_offset += 8;
1675       int_reg_save_area_size += 8;
1676     }
1677
1678   /* Now save any other used integer registers required to be saved.  */
1679   for (i = 0; i < 32; i++)
1680     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1681       {
1682         reg_mask |= 1 << i;
1683         fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1684         reg_offset += 8;
1685         int_reg_save_area_size += 8;
1686       }
1687
1688   /* Print the register mask and do floating-point saves.  */
1689   if (reg_mask)
1690     fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1691              actual_start_reg_offset - frame_size);
1692
1693   start_reg_offset = reg_offset;
1694   reg_mask = 0;
1695
1696   for (i = 0; i < 32; i++)
1697     if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1698         && regs_ever_live[i + 32])
1699       {
1700         reg_mask |= 1 << i;
1701         fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1702         reg_offset += 8;
1703       }
1704
1705   /* Print the floating-point mask, if we've saved any fp register.  */
1706   if (reg_mask)
1707     fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
1708              actual_start_reg_offset - frame_size + int_reg_save_area_size);
1709
1710   /* If we need a frame pointer, set it from the stack pointer.  Note that
1711      this must always be the last instruction in the prologue.  */
1712   if (frame_pointer_needed)
1713     fprintf (file, "\tbis $30,$30,$15\n");
1714
1715   /* End the prologue and say if we used gp.  */
1716   fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
1717 }
1718
1719 /* Write function epilogue.  */
1720
1721 void
1722 output_epilog (file, size)
1723      FILE *file;
1724      int size;
1725 {
1726   rtx insn = get_last_insn ();
1727   HOST_WIDE_INT out_args_size
1728     = ALPHA_ROUND (current_function_outgoing_args_size);
1729   HOST_WIDE_INT sa_size = alpha_sa_size ();
1730   HOST_WIDE_INT frame_size
1731     = (out_args_size + sa_size
1732        + ALPHA_ROUND (size + current_function_pretend_args_size));
1733   HOST_WIDE_INT reg_offset = out_args_size;
1734   HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
1735   int restore_fp
1736     = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
1737   int i;
1738
1739   /* If the last insn was a BARRIER, we don't have to write anything except
1740      the .end pseudo-op.  */
1741   if (GET_CODE (insn) == NOTE)
1742     insn = prev_nonnote_insn (insn);
1743   if (insn == 0 || GET_CODE (insn) != BARRIER)
1744     {
1745       int fp_offset = 0;
1746
1747       final_prescan_insn (NULL_RTX, NULL_PTR, 0);
1748
1749       /* If we have a frame pointer, restore SP from it.  */
1750       if (frame_pointer_needed)
1751         fprintf (file, "\tbis $15,$15,$30\n");
1752
1753       /* Restore all the registers, starting with the return address
1754          register.  */
1755       if (sa_size != 0)
1756         {
1757           fprintf (file, "\tldq $26,%d($30)\n", reg_offset);
1758           reg_offset += 8;
1759         }
1760
1761       /* Now restore any other used integer registers that that we saved,
1762          except for FP if it is being used as FP, since it must be
1763          restored last.  */
1764
1765       for (i = 0; i < 32; i++)
1766         if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1767             && i != 26)
1768           {
1769             if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1770               fp_offset = reg_offset;
1771             else
1772               fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset);
1773             reg_offset += 8;
1774           }
1775
1776       for (i = 0; i < 32; i++)
1777         if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1778             && regs_ever_live[i + 32])
1779           {
1780             fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
1781             reg_offset += 8;
1782           }
1783
1784       /* If the stack size is large and we have a frame pointer, compute the
1785          size of the stack into a register because the old FP restore, stack
1786          pointer adjust, and return are required to be consecutive
1787          instructions.   */
1788       if (frame_size > 32767 && restore_fp)
1789         add_long_const (file, frame_size, 31, 1, 1);
1790
1791       /* If we needed a frame pointer and we have to restore it, do it
1792          now.  This must be done in one instruction immediately
1793          before the SP update.  */
1794       if (restore_fp && fp_offset)
1795         fprintf (file, "\tldq $15,%d($30)\n", fp_offset);
1796
1797       /* Now update the stack pointer, if needed.  Only one instruction must
1798          modify the stack pointer.  It must be the last instruction in the
1799          sequence and must be an ADDQ or LDA instruction.  If the frame
1800          pointer was loaded above, we may only put one instruction here.  */
1801
1802       if (frame_size > 32768 && restore_fp)
1803         fprintf  (file, "\taddq $1,$30,$30\n");
1804       else
1805         add_long_const (file, frame_size, 30, 30, 1);
1806
1807       /* Finally return to the caller.  */
1808       fprintf (file, "\tret $31,($26),1\n");
1809     }
1810
1811   /* End the function.  */
1812   fprintf (file, "\t.end ");
1813   assemble_name (file, alpha_function_name);
1814   fprintf (file, "\n");
1815   inside_function = FALSE;
1816
1817   /* Show that we know this function if it is called again.  */
1818   SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
1819 }
1820 \f
1821 /* Debugging support.  */
1822
1823 #include "gstab.h"
1824
1825 /* Count the number of sdb related labels are generated (to find block
1826    start and end boundaries).  */
1827
1828 int sdb_label_count = 0;
1829
1830 /* Next label # for each statement.  */
1831
1832 static int sym_lineno = 0;
1833
1834 /* Count the number of .file directives, so that .loc is up to date.  */
1835
1836 static int num_source_filenames = 0;
1837
1838 /* Name of the file containing the current function.  */
1839
1840 static char *current_function_file = "";
1841
1842 /* Offsets to alpha virtual arg/local debugging pointers.  */
1843
1844 long alpha_arg_offset;
1845 long alpha_auto_offset;
1846 \f
1847 /* Emit a new filename to a stream.  */
1848
1849 void
1850 alpha_output_filename (stream, name)
1851      FILE *stream;
1852      char *name;
1853 {
1854   static int first_time = TRUE;
1855   char ltext_label_name[100];
1856
1857   if (first_time)
1858     {
1859       first_time = FALSE;
1860       ++num_source_filenames;
1861       current_function_file = name;
1862       fprintf (stream, "\t.file\t%d ", num_source_filenames);
1863       output_quoted_string (stream, name);
1864       fprintf (stream, "\n");
1865       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1866         fprintf (stream, "\t#@stabs\n");
1867     }
1868
1869   else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1870     {
1871       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
1872       fprintf (stream, "%s ", ASM_STABS_OP);
1873       output_quoted_string (stream, name);
1874       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
1875     }
1876
1877   else if (name != current_function_file
1878       && strcmp (name, current_function_file) != 0)
1879     {
1880       if (inside_function && ! TARGET_GAS)
1881         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
1882       else
1883         {
1884           ++num_source_filenames;
1885           current_function_file = name;
1886           fprintf (stream, "\t.file\t%d ", num_source_filenames);
1887         }
1888
1889       output_quoted_string (stream, name);
1890       fprintf (stream, "\n");
1891     }
1892 }
1893 \f
1894 /* Emit a linenumber to a stream.  */
1895
1896 void
1897 alpha_output_lineno (stream, line)
1898      FILE *stream;
1899      int line;
1900 {
1901   if (! TARGET_GAS && write_symbols == DBX_DEBUG)
1902     {
1903       /* mips-tfile doesn't understand .stabd directives.  */
1904       ++sym_lineno;
1905       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1906                sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
1907     }
1908   else
1909     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
1910 }
1911 \f
1912 /* Structure to show the current status of registers and memory.  */
1913
1914 struct shadow_summary
1915 {
1916   struct {
1917     unsigned long i     : 32;   /* Mask of int regs */
1918     unsigned long fp    : 32;   /* Mask of fp regs */
1919     unsigned long mem   :  1;   /* mem == imem | fpmem */
1920   } used, defd;
1921 };
1922
1923 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
1924    to the summary structure.  SET is nonzero if the insn is setting the
1925    object, otherwise zero.  */
1926
1927 static void
1928 summarize_insn (x, sum, set)
1929      rtx x;
1930      struct shadow_summary *sum;
1931      int set;
1932 {
1933   char *format_ptr;
1934   int i, j;
1935
1936   if (x == 0)
1937     return;
1938
1939   switch (GET_CODE (x))
1940     {
1941       /* ??? Note that this case would be incorrect if the Alpha had a
1942          ZERO_EXTRACT in SET_DEST.  */
1943     case SET:
1944       summarize_insn (SET_SRC (x), sum, 0);
1945       summarize_insn (SET_DEST (x), sum, 1);
1946       break;
1947
1948     case CLOBBER:
1949       summarize_insn (XEXP (x, 0), sum, 1);
1950       break;
1951
1952     case USE:
1953       summarize_insn (XEXP (x, 0), sum, 0);
1954       break;
1955
1956     case PARALLEL:
1957       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1958         summarize_insn (XVECEXP (x, 0, i), sum, 0);
1959       break;
1960
1961     case REG:
1962       {
1963         int regno = REGNO (x);
1964         unsigned long mask = 1UL << (regno % 32);
1965
1966         if (regno == 31 || regno == 63)
1967           break;
1968
1969         if (set)
1970           {
1971             if (regno < 32)
1972               sum->defd.i |= mask;
1973             else
1974               sum->defd.fp |= mask;
1975           }
1976         else
1977           {
1978             if (regno < 32)
1979               sum->used.i  |= mask;
1980             else
1981               sum->used.fp |= mask;
1982           }
1983         }
1984       break;
1985
1986     case MEM:
1987       if (set)
1988         sum->defd.mem = 1;
1989       else
1990         sum->used.mem = 1;
1991
1992       /* Find the regs used in memory address computation: */
1993       summarize_insn (XEXP (x, 0), sum, 0);
1994       break;
1995
1996     case SUBREG:
1997       summarize_insn (SUBREG_REG (x), sum, 0);
1998       break;
1999
2000     case CONST_INT:   case CONST_DOUBLE:
2001     case SYMBOL_REF:  case LABEL_REF:     case CONST:
2002       break;
2003
2004       /* Handle common unary and binary ops for efficiency.  */
2005     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
2006     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
2007     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
2008     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
2009     case NE:       case EQ:      case GE:      case GT:        case LE:
2010     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
2011       summarize_insn (XEXP (x, 0), sum, 0);
2012       summarize_insn (XEXP (x, 1), sum, 0);
2013       break;
2014
2015     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
2016     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
2017     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
2018     case SQRT:  case FFS: 
2019       summarize_insn (XEXP (x, 0), sum, 0);
2020       break;
2021
2022     default:
2023       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
2024       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
2025         switch (format_ptr[i])
2026           {
2027           case 'e':
2028             summarize_insn (XEXP (x, i), sum, 0);
2029             break;
2030
2031           case 'E':
2032             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2033               summarize_insn (XVECEXP (x, i, j), sum, 0);
2034             break;
2035
2036           default:
2037             abort ();
2038           }
2039     }
2040 }
2041 \f
2042 /* This function is executed just prior to the output of assembler code for
2043    INSN to modify the extracted operands so they will be output differently.
2044
2045    OPVEC is the vector containing the operands extracted from INSN, and
2046    NOPERANDS is the number of elements of the vector which contain meaningful
2047    data for this insn.  The contents of this vector are what will be used to
2048    convert the insn template into assembler code, so you can change the
2049    assembler output by changing the contents of the vector.
2050
2051    We use this function to ensure a sufficient number of `trapb' instructions
2052    are in the code when the user requests code with a trap precision of
2053    functions or instructions.
2054
2055    In naive mode, when the user requests a trap-precision of "instruction", a
2056    trapb is needed after every instruction that may generate a trap (and after
2057    jsr/bsr instructions, because called functions may import a trap from the
2058    caller).  This ensures that the code is resumption safe but it is also slow.
2059
2060    When optimizations are turned on, we delay issuing a trapb as long as
2061    possible.  In this context, a trap shadow is the sequence of instructions
2062    that starts with a (potentially) trap generating instruction and extends to
2063    the next trapb or call_pal instruction (but GCC never generates call_pal by
2064    itself).  We can delay (and therefore sometimes omit) a trapb subject to the
2065    following conditions:
2066
2067    (a) On entry to the trap shadow, if any Alpha register or memory location
2068    contains a value that is used as an operand value by some instruction in
2069    the trap shadow (live on entry), then no instruction in the trap shadow
2070    may modify the register or memory location.
2071
2072    (b) Within the trap shadow, the computation of the base register for a
2073    memory load or store instruction may not involve using the result
2074    of an instruction that might generate an UNPREDICTABLE result.
2075
2076    (c) Within the trap shadow, no register may be used more than once as a
2077    destination register.  (This is to make life easier for the trap-handler.)
2078
2079    (d) The trap shadow may not include any branch instructions.
2080
2081      */
2082
2083 void
2084 final_prescan_insn (insn, opvec, noperands)
2085      rtx insn;
2086      rtx *opvec;
2087      int noperands;
2088 {
2089   static struct shadow_summary shadow = {0, 0, 0, 0, 0};
2090
2091 #define CLOSE_SHADOW                            \
2092   do                                            \
2093     {                                           \
2094       fputs ("\ttrapb\n", asm_out_file);        \
2095       trap_pending = 0;                         \
2096       bzero ((char *) &shadow,  sizeof shadow); \
2097     }                                           \
2098   while (0)
2099
2100   if (alpha_tp == ALPHA_TP_PROG)
2101     return;
2102
2103   if (trap_pending)
2104     switch (alpha_tp)
2105       {
2106       case ALPHA_TP_FUNC:
2107         /* Generate one trapb before epilogue (indicated by INSN==0) */
2108         if (insn == 0)
2109           CLOSE_SHADOW;
2110         break;
2111
2112       case ALPHA_TP_INSN:
2113         if (optimize && insn != 0)
2114           {
2115             struct shadow_summary sum = {0, 0, 0};
2116
2117             switch (GET_CODE(insn))
2118               {
2119               case INSN:
2120                 summarize_insn (PATTERN (insn), &sum, 0);
2121
2122                 if ((sum.defd.i & shadow.defd.i)
2123                     || (sum.defd.fp & shadow.defd.fp))
2124                   {
2125                     /* (c) would be violated */
2126                     CLOSE_SHADOW;
2127                     break;
2128                   }
2129
2130                 /* Combine shadow with summary of current insn: */
2131                 shadow.used.i     |= sum.used.i;
2132                 shadow.used.fp    |= sum.used.fp;
2133                 shadow.used.mem   |= sum.used.mem;
2134                 shadow.defd.i     |= sum.defd.i;
2135                 shadow.defd.fp    |= sum.defd.fp;
2136                 shadow.defd.mem   |= sum.defd.mem;
2137
2138                 if ((sum.defd.i & shadow.used.i)
2139                     || (sum.defd.fp & shadow.used.fp)
2140                     || (sum.defd.mem & shadow.used.mem))
2141                   {
2142                     /* (a) would be violated (also takes care of (b)).  */
2143                     if (get_attr_trap (insn) == TRAP_YES
2144                         && ((sum.defd.i & sum.used.i)
2145                             || (sum.defd.fp & sum.used.fp)))
2146                       abort ();
2147
2148                     CLOSE_SHADOW;
2149                     break;
2150                   }
2151                 break;
2152
2153               case JUMP_INSN:
2154               case CALL_INSN:
2155               case CODE_LABEL:
2156                 CLOSE_SHADOW;
2157                 break;
2158
2159               default:
2160                 abort ();
2161               }
2162           }
2163         else
2164           CLOSE_SHADOW;
2165         break;
2166       }
2167
2168   if (insn != 0 && get_attr_trap (insn) == TRAP_YES)
2169     {
2170       if (optimize && !trap_pending && GET_CODE (insn) == INSN)
2171         summarize_insn (PATTERN (insn), &shadow, 0);
2172       trap_pending = 1;
2173     }
2174 }
2175
2176 /* Check a floating-point value for validity for a particular machine mode.  */
2177
2178 static char *float_strings[] =
2179 {
2180    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
2181   "-1.70141173319264430e+38",
2182    "2.93873587705571877e-39", /* 2^-128 */
2183   "-2.93873587705571877e-39"
2184 };
2185
2186 static REAL_VALUE_TYPE float_values[4];
2187 static int inited_float_values = 0;
2188
2189 int
2190 check_float_value (mode, d, overflow)
2191      enum machine_mode mode;
2192      REAL_VALUE_TYPE *d;
2193      int overflow;
2194 {
2195
2196   if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
2197     return 0;
2198
2199   if (inited_float_values == 0)
2200     {
2201       int i;
2202       for (i = 0; i < 4; i++)
2203         float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
2204
2205       inited_float_values = 1;
2206     }
2207
2208   if (mode == SFmode)
2209     {
2210       REAL_VALUE_TYPE r;
2211
2212       bcopy (d, &r, sizeof (REAL_VALUE_TYPE));
2213       if (REAL_VALUES_LESS (float_values[0], r))
2214         {
2215           bcopy (&float_values[0], d, sizeof (REAL_VALUE_TYPE));
2216           return 1;
2217         }
2218       else if (REAL_VALUES_LESS (r, float_values[1]))
2219         {
2220           bcopy (&float_values[1], d, sizeof (REAL_VALUE_TYPE));
2221           return 1;
2222         }
2223       else if (REAL_VALUES_LESS (dconst0, r)
2224                 && REAL_VALUES_LESS (r, float_values[2]))
2225         {
2226           bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));
2227           return 1;
2228         }
2229       else if (REAL_VALUES_LESS (r, dconst0)
2230                 && REAL_VALUES_LESS (float_values[3], r))
2231         {
2232           bcopy (&dconst0, d, sizeof (REAL_VALUE_TYPE));
2233           return 1;
2234         }
2235     }
2236
2237   return 0;
2238 }