OSDN Git Service

(check_float_value): Cast args of bcopy to avoid warnings.
[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
969 /* Rewrite a comparison against zero CMP of the form
970    (CODE (cc0) (const_int 0)) so it can be written validly in
971    a conditional move (if_then_else CMP ...).
972    If both of the operands that set cc0 are non-zero we must emit
973    an insn to perform the compare (it can't be done within
974    the conditional move). */
975 rtx
976 alpha_emit_conditional_move (cmp, mode)
977      rtx cmp;
978      enum machine_mode mode;
979 {
980   enum rtx_code code = GET_CODE (cmp);
981   rtx op0 = alpha_compare_op0;
982   rtx op1 = alpha_compare_op1;
983   enum machine_mode cmp_mode
984     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
985   enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
986   rtx tem;
987
988   if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
989     return 0;
990
991   /* We may be able to use a conditional move directly.
992      This avoids emitting spurious compares. */
993   if (signed_comparison_operator (cmp, cmp_op_mode)
994       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
995     return gen_rtx (code, VOIDmode, op0, op1);
996
997   /* We can't put the comparison insides a conditional move;
998      emit a compare instruction and put that inside the
999      conditional move.  Make sure we emit only comparisons we have;
1000      swap or reverse as necessary.  */
1001
1002   switch (code)
1003     {
1004     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1005       /* We have these compares: */
1006       break;
1007
1008     case NE:
1009       /* This must be reversed. */
1010       code = reverse_condition (code);
1011       break;
1012
1013     case GE:  case GT:  case GEU:  case GTU:
1014       /* These must be swapped.  Make sure the new first operand is in
1015          a register.  */
1016       code = swap_condition (code);
1017       tem = op0, op0 = op1, op1 = tem;
1018       op0 = force_reg (cmp_mode, op0);
1019       break;
1020
1021     default:
1022       abort ();
1023     }
1024
1025   tem = gen_reg_rtx (cmp_op_mode);
1026   emit_move_insn (tem, gen_rtx (code, cmp_op_mode, op0, op1));
1027   return gen_rtx (code == NE ? EQ : NE, VOIDmode, tem, CONST0_RTX (mode));
1028 }
1029 \f
1030 /* Adjust the cost of a scheduling dependency.  Return the new cost of
1031    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
1032
1033 int
1034 alpha_adjust_cost (insn, link, dep_insn, cost)
1035      rtx insn;
1036      rtx link;
1037      rtx dep_insn;
1038      int cost;
1039 {
1040   rtx set;
1041
1042   /* If the dependence is an anti-dependence, there is no cost.  For an
1043      output dependence, there is sometimes a cost, but it doesn't seem
1044      worth handling those few cases.  */
1045
1046   if (REG_NOTE_KIND (link) != 0)
1047     return 0;
1048
1049   /* If INSN is a store insn and DEP_INSN is setting the data being stored,
1050      we can sometimes lower the cost.  */
1051
1052   if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
1053       && (set = single_set (dep_insn)) != 0
1054       && GET_CODE (PATTERN (insn)) == SET
1055       && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
1056     switch (get_attr_type (dep_insn))
1057       {
1058       case TYPE_LD:
1059         /* No savings here.  */
1060         return cost;
1061
1062       case TYPE_IMULL:
1063       case TYPE_IMULQ:
1064         /* In these cases, we save one cycle.  */
1065         return cost - 2;
1066
1067       default:
1068         /* In all other cases, we save two cycles.  */
1069         return MAX (0, cost - 4);
1070       }
1071
1072   /* Another case that needs adjustment is an arithmetic or logical
1073      operation.  It's cost is usually one cycle, but we default it to
1074      two in the MD file.  The only case that it is actually two is
1075      for the address in loads and stores.  */
1076
1077   if (recog_memoized (dep_insn) >= 0
1078       && get_attr_type (dep_insn) == TYPE_IADDLOG)
1079     switch (get_attr_type (insn))
1080       {
1081       case TYPE_LD:
1082       case TYPE_ST:
1083         return cost;
1084
1085       default:
1086         return 2;
1087       }
1088
1089   /* The final case is when a compare feeds into an integer branch.  The cost
1090      is only one cycle in that case.  */
1091
1092   if (recog_memoized (dep_insn) >= 0
1093       && get_attr_type (dep_insn) == TYPE_ICMP
1094       && recog_memoized (insn) >= 0
1095       && get_attr_type (insn) == TYPE_IBR)
1096     return 2;
1097
1098   /* Otherwise, return the default cost. */
1099
1100   return cost;
1101 }
1102 \f
1103 /* Print an operand.  Recognize special options, documented below.  */
1104
1105 void
1106 print_operand (file, x, code)
1107     FILE *file;
1108     rtx x;
1109     char code;
1110 {
1111   int i;
1112
1113   switch (code)
1114     {
1115     case '&':
1116       /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
1117          chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
1118          mode.  alpha_fprm controls which suffix is generated.  */
1119       switch (alpha_fprm)
1120         {
1121         case ALPHA_FPRM_NORM:
1122           break;
1123         case ALPHA_FPRM_MINF: 
1124           fputc ('m', file);
1125           break;
1126         case ALPHA_FPRM_CHOP:
1127           fputc ('c', file);
1128           break;
1129         case ALPHA_FPRM_DYN:
1130           fputc ('d', file);
1131           break;
1132         }
1133       break;
1134
1135     case '\'':
1136       /* Generates trap-mode suffix for instructions that accept the su
1137          suffix only (cmpt et al).  */
1138       if (alpha_tp == ALPHA_TP_INSN)
1139         fputs ("su", file);
1140       break;
1141
1142     case ')':
1143       /* Generates trap-mode suffix for instructions that accept the u, su,
1144          and sui suffix.  This is the bulk of the IEEE floating point
1145          instructions (addt et al).  */
1146       switch (alpha_fptm)
1147         {
1148         case ALPHA_FPTM_N:
1149           break;
1150         case ALPHA_FPTM_U:
1151           fputc ('u', file);
1152           break;
1153         case ALPHA_FPTM_SU:
1154           fputs ("su", file);
1155           break;
1156         case ALPHA_FPTM_SUI:
1157           fputs ("sui", file);
1158           break;
1159         }
1160       break;
1161
1162     case '+':
1163       /* Generates trap-mode suffix for instructions that accept the sui
1164          suffix (cvtqt and cvtqs).  */
1165       switch (alpha_fptm)
1166         {
1167         case ALPHA_FPTM_N: case ALPHA_FPTM_U:
1168         case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
1169           break;
1170         case ALPHA_FPTM_SUI:
1171           fputs ("sui", file);
1172           break;
1173         }
1174       break;
1175
1176     case 'r':
1177       /* If this operand is the constant zero, write it as "$31".  */
1178       if (GET_CODE (x) == REG)
1179         fprintf (file, "%s", reg_names[REGNO (x)]);
1180       else if (x == CONST0_RTX (GET_MODE (x)))
1181         fprintf (file, "$31");
1182       else
1183         output_operand_lossage ("invalid %%r value");
1184
1185       break;
1186
1187     case 'R':
1188       /* Similar, but for floating-point.  */
1189       if (GET_CODE (x) == REG)
1190         fprintf (file, "%s", reg_names[REGNO (x)]);
1191       else if (x == CONST0_RTX (GET_MODE (x)))
1192         fprintf (file, "$f31");
1193       else
1194         output_operand_lossage ("invalid %%R value");
1195
1196       break;
1197
1198     case 'N':
1199       /* Write the 1's complement of a constant.  */
1200       if (GET_CODE (x) != CONST_INT)
1201         output_operand_lossage ("invalid %%N value");
1202
1203       fprintf (file, "%ld", ~ INTVAL (x));
1204       break;
1205
1206     case 'P':
1207       /* Write 1 << C, for a constant C.  */
1208       if (GET_CODE (x) != CONST_INT)
1209         output_operand_lossage ("invalid %%P value");
1210
1211       fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
1212       break;
1213
1214     case 'h':
1215       /* Write the high-order 16 bits of a constant, sign-extended.  */
1216       if (GET_CODE (x) != CONST_INT)
1217         output_operand_lossage ("invalid %%h value");
1218
1219       fprintf (file, "%ld", INTVAL (x) >> 16);
1220       break;
1221
1222     case 'L':
1223       /* Write the low-order 16 bits of a constant, sign-extended.  */
1224       if (GET_CODE (x) != CONST_INT)
1225         output_operand_lossage ("invalid %%L value");
1226
1227       fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
1228       break;
1229
1230     case 'm':
1231       /* Write mask for ZAP insn.  */
1232       if (GET_CODE (x) == CONST_DOUBLE)
1233         {
1234           HOST_WIDE_INT mask = 0;
1235           HOST_WIDE_INT value;
1236
1237           value = CONST_DOUBLE_LOW (x);
1238           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1239                i++, value >>= 8)
1240             if (value & 0xff)
1241               mask |= (1 << i);
1242
1243           value = CONST_DOUBLE_HIGH (x);
1244           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
1245                i++, value >>= 8)
1246             if (value & 0xff)
1247               mask |= (1 << (i + sizeof (int)));
1248
1249           fprintf (file, "%ld", mask & 0xff);
1250         }
1251
1252       else if (GET_CODE (x) == CONST_INT)
1253         {
1254           HOST_WIDE_INT mask = 0, value = INTVAL (x);
1255
1256           for (i = 0; i < 8; i++, value >>= 8)
1257             if (value & 0xff)
1258               mask |= (1 << i);
1259
1260           fprintf (file, "%ld", mask);
1261         }
1262       else
1263         output_operand_lossage ("invalid %%m value");
1264       break;
1265
1266     case 'M':
1267       /* 'b', 'w', or 'l' as the value of the constant.  */
1268       if (GET_CODE (x) != CONST_INT
1269           || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
1270         output_operand_lossage ("invalid %%M value");
1271
1272       fprintf (file, "%s",
1273                INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
1274       break;
1275
1276     case 'U':
1277       /* Similar, except do it from the mask.  */
1278       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
1279         fprintf (file, "b");
1280       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
1281         fprintf (file, "w");
1282 #if HOST_BITS_PER_WIDE_INT == 32
1283       else if (GET_CODE (x) == CONST_DOUBLE
1284                && CONST_DOUBLE_HIGH (x) == 0
1285                && CONST_DOUBLE_LOW (x) == -1)
1286         fprintf (file, "l");
1287 #else
1288       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
1289         fprintf (file, "l");
1290 #endif
1291       else
1292         output_operand_lossage ("invalid %%U value");
1293       break;
1294
1295     case 's':
1296       /* Write the constant value divided by 8.  */
1297       if (GET_CODE (x) != CONST_INT
1298           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1299           && (INTVAL (x) & 7) != 8)
1300         output_operand_lossage ("invalid %%s value");
1301
1302       fprintf (file, "%ld", INTVAL (x) / 8);
1303       break;
1304
1305     case 'S':
1306       /* Same, except compute (64 - c) / 8 */
1307
1308       if (GET_CODE (x) != CONST_INT
1309           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
1310           && (INTVAL (x) & 7) != 8)
1311         output_operand_lossage ("invalid %%s value");
1312
1313       fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
1314       break;
1315
1316     case 'C':
1317       /* Write out comparison name.  */
1318       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1319         output_operand_lossage ("invalid %%C value");
1320
1321       if (GET_CODE (x) == LEU)
1322         fprintf (file, "ule");
1323       else if (GET_CODE (x) == LTU)
1324         fprintf (file, "ult");
1325       else
1326         fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
1327       break;
1328
1329     case 'D':
1330       /* Similar, but write reversed code.  We can't get an unsigned code
1331          here.  */
1332       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1333         output_operand_lossage ("invalid %%D value");
1334
1335       fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
1336       break;
1337
1338     case 'c':
1339       /* Similar to `c', but swap.  We can't get unsigned here either.  */
1340       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1341         output_operand_lossage ("invalid %%D value");
1342
1343       fprintf (file, "%s", GET_RTX_NAME (swap_condition (GET_CODE (x))));
1344       break;
1345
1346     case 'd':
1347       /* Similar, but reverse and swap.  We can't get unsigned here either.  */
1348       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
1349         output_operand_lossage ("invalid %%D value");
1350
1351       fprintf (file, "%s",
1352                GET_RTX_NAME (swap_condition (reverse_condition ((GET_CODE (x))))));
1353       break;
1354
1355     case 'E':
1356       /* Write the divide or modulus operator.  */
1357       switch (GET_CODE (x))
1358         {
1359         case DIV:
1360           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
1361           break;
1362         case UDIV:
1363           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
1364           break;
1365         case MOD:
1366           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
1367           break;
1368         case UMOD:
1369           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
1370           break;
1371         default:
1372           output_operand_lossage ("invalid %%E value");
1373           break;
1374         }
1375       break;
1376
1377     case 'A':
1378       /* Write "_u" for unaligned access.  */
1379       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1380         fprintf (file, "_u");
1381       break;
1382
1383     case 0:
1384       if (GET_CODE (x) == REG)
1385         fprintf (file, "%s", reg_names[REGNO (x)]);
1386       else if (GET_CODE (x) == MEM)
1387         output_address (XEXP (x, 0));
1388       else
1389         output_addr_const (file, x);
1390       break;
1391
1392     default:
1393       output_operand_lossage ("invalid %%xn code");
1394     }
1395 }
1396 \f
1397 /* Do what is necessary for `va_start'.  The argument is ignored;
1398    We look at the current function to determine if stdarg or varargs
1399    is used and fill in an initial va_list.  A pointer to this constructor
1400    is returned.  */
1401
1402 struct rtx_def *
1403 alpha_builtin_saveregs (arglist)
1404      tree arglist;
1405 {
1406   rtx block, addr, argsize;
1407   tree fntype = TREE_TYPE (current_function_decl);
1408   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1409                 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1410                     != void_type_node));
1411
1412   /* Compute the current position into the args, taking into account
1413      both registers and memory.  Both of these are already included in
1414      current_function_args_info.  */
1415
1416   argsize = GEN_INT (current_function_args_info * UNITS_PER_WORD);
1417
1418   /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
1419      storing fp arg registers in the first 48 bytes, and the integer arg
1420      registers in the next 48 bytes.  This is only done, however, if any
1421      integer registers need to be stored.
1422
1423      If no integer registers need be stored, then we must subtract 48 in
1424      order to account for the integer arg registers which are counted in
1425      argsize above, but which are not actually stored on the stack.  */
1426
1427   addr = (current_function_args_info <= 5 + stdarg
1428           ? plus_constant (virtual_incoming_args_rtx, 6 * UNITS_PER_WORD)
1429           : plus_constant (virtual_incoming_args_rtx, - (6 * UNITS_PER_WORD)));
1430
1431   addr = force_operand (addr, NULL_RTX);
1432
1433   /* Allocate the va_list constructor */
1434   block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
1435   RTX_UNCHANGING_P (block) = 1;
1436   RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
1437
1438   /* Store the address of the first integer register in the __base member.  */
1439
1440 #ifdef POINTERS_EXTEND_UNSIGNED
1441   addr = convert_memory_address (ptr_mode, addr);
1442 #endif
1443
1444   emit_move_insn (change_address (block, ptr_mode, XEXP (block, 0)), addr);
1445
1446   /* Store the argsize as the __va_offset member.  */
1447   emit_move_insn (change_address (block, TYPE_MODE (integer_type_node),
1448                                   plus_constant (XEXP (block, 0),
1449                                                  POINTER_SIZE/BITS_PER_UNIT)),
1450                   argsize);
1451
1452   /* Return the address of the va_list constructor, but don't put it in a
1453      register.  Doing so would fail when not optimizing and produce worse
1454      code when optimizing.  */
1455   return XEXP (block, 0);
1456 }
1457 \f
1458 /* This page contains routines that are used to determine what the function
1459    prologue and epilogue code will do and write them out.  */
1460
1461 /* Compute the size of the save area in the stack.  */
1462
1463 int
1464 alpha_sa_size ()
1465 {
1466   int size = 0;
1467   int i;
1468
1469   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1470     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
1471       size++;
1472
1473   /* If some registers were saved but not reg 26, reg 26 must also
1474      be saved, so leave space for it.  */
1475   if (size != 0 && ! regs_ever_live[26])
1476     size++;
1477
1478   /* Our size must be even (multiple of 16 bytes).  */
1479   if (size & 1)
1480     size ++;
1481
1482   return size * 8;
1483 }
1484
1485 /* Return 1 if this function can directly return via $26.  */
1486
1487 int
1488 direct_return ()
1489 {
1490   return (reload_completed && alpha_sa_size () == 0
1491           && get_frame_size () == 0
1492           && current_function_outgoing_args_size == 0
1493           && current_function_pretend_args_size == 0);
1494 }
1495
1496 /* Write a version stamp.  Don't write anything if we are running as a
1497    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
1498
1499 #if !defined(CROSS_COMPILE) && !defined(_WIN32) && !defined(__linux__)
1500 #include <stamp.h>
1501 #endif
1502
1503 void
1504 alpha_write_verstamp (file)
1505      FILE *file;
1506 {
1507 #ifdef MS_STAMP
1508   fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
1509 #endif
1510 }
1511 \f
1512 /* Write code to add constant C to register number IN_REG (possibly 31)
1513    and put the result into OUT_REG.  Use TEMP_REG as a scratch register;
1514    usually this will be OUT_REG, but should not be if OUT_REG is 
1515    STACK_POINTER_REGNUM, since it must be updated in a single instruction.
1516    Write the code to FILE.  */
1517
1518 static void
1519 add_long_const (file, c, in_reg, out_reg, temp_reg)
1520      FILE *file;
1521      HOST_WIDE_INT c;
1522      int in_reg, out_reg, temp_reg;
1523 {
1524   HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1525   HOST_WIDE_INT tmp1 = c - low;
1526   HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1527   HOST_WIDE_INT extra = 0;
1528
1529   /* We don't have code to write out constants larger than 32 bits.  */
1530 #if HOST_BITS_PER_LONG_INT == 64
1531   if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
1532     abort ();
1533 #endif
1534
1535   /* If HIGH will be interpreted as negative, we must adjust it to do two
1536      ldha insns.  Note that we will never be building a negative constant
1537      here.  */
1538
1539   if (high & 0x8000)
1540     {
1541       extra = 0x4000;
1542       tmp1 -= 0x40000000;
1543       high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1544     }
1545
1546   if (low != 0)
1547     {
1548       int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
1549
1550       if (low >= 0 && low < 255)
1551         fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
1552       else
1553         fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
1554
1555       in_reg = result_reg;
1556     }
1557
1558   if (extra)
1559     {
1560       int result_reg = (high == 0) ? out_reg : temp_reg;
1561
1562       fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
1563       in_reg = result_reg;
1564     }
1565
1566   if (high)
1567     fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
1568 }
1569
1570 /* Write function prologue.  */
1571
1572 void
1573 output_prolog (file, size)
1574      FILE *file;
1575      int size;
1576 {
1577   HOST_WIDE_INT out_args_size
1578     = ALPHA_ROUND (current_function_outgoing_args_size);
1579   HOST_WIDE_INT sa_size = alpha_sa_size ();
1580   HOST_WIDE_INT frame_size
1581     = (out_args_size + sa_size
1582        + ALPHA_ROUND (size + current_function_pretend_args_size));
1583   HOST_WIDE_INT reg_offset = out_args_size;
1584   HOST_WIDE_INT start_reg_offset = reg_offset;
1585   HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
1586   int int_reg_save_area_size = 0;
1587   rtx insn;
1588   unsigned reg_mask = 0;
1589   int i;
1590
1591   /* Ecoff can handle multiple .file directives, so put out file and lineno.
1592      We have to do that before the .ent directive as we cannot switch
1593      files within procedures with native ecoff because line numbers are
1594      linked to procedure descriptors.
1595      Outputting the lineno helps debugging of one line functions as they
1596      would otherwise get no line number at all. Please note that we would
1597      like to put out last_linenum from final.c, but it is not accessible.  */
1598
1599   if (write_symbols == SDB_DEBUG)
1600     {
1601       ASM_OUTPUT_SOURCE_FILENAME (file,
1602                                   DECL_SOURCE_FILE (current_function_decl));
1603       if (debug_info_level != DINFO_LEVEL_TERSE)
1604         ASM_OUTPUT_SOURCE_LINE (file,
1605                                 DECL_SOURCE_LINE (current_function_decl));
1606     }
1607
1608   /* The assembly language programmer's guide states that the second argument
1609      to the .ent directive, the lex_level, is ignored by the assembler,
1610      so we might as well omit it.  */
1611      
1612   fprintf (file, "\t.ent ");
1613   assemble_name (file, alpha_function_name);
1614   fprintf (file, "\n");
1615   ASM_OUTPUT_LABEL (file, alpha_function_name);
1616   inside_function = TRUE;
1617
1618   if (TARGET_IEEE_CONFORMANT)
1619     /* Set flags in procedure descriptor to request IEEE-conformant
1620        math-library routines.  The value we set it to is PDSC_EXC_IEEE
1621        (/usr/include/pdsc.h). */
1622     fprintf (file, "\t.eflag 48\n");
1623
1624   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
1625
1626   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
1627   alpha_arg_offset = -frame_size + 48;
1628
1629   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
1630      Even if we are a static function, we still need to do this in case
1631      our address is taken and passed to something like qsort.
1632
1633      We never need a GP for Windows/NT.  */
1634
1635   alpha_function_needs_gp = 0;
1636
1637 #ifdef TARGET_PROFILING_NEEDS_GP
1638   if (profile_flag)
1639     alpha_function_needs_gp = 1;
1640 #endif
1641
1642   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1643     if ((GET_CODE (insn) == CALL_INSN)
1644         || (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1645             && GET_CODE (PATTERN (insn)) != USE
1646             && GET_CODE (PATTERN (insn)) != CLOBBER
1647             && (get_attr_type (insn) == TYPE_LDSYM
1648                 || get_attr_type (insn) == TYPE_ISUBR)))
1649       {
1650         alpha_function_needs_gp = 1;
1651         break;
1652       }
1653
1654   if (WINDOWS_NT == 0)
1655     {
1656       if (alpha_function_needs_gp)
1657         fprintf (file, "\tldgp $29,0($27)\n");
1658
1659       /* Put a label after the GP load so we can enter the function at it.  */
1660       assemble_name (file, alpha_function_name);
1661       fprintf (file, "..ng:\n");
1662     }
1663
1664   /* Adjust the stack by the frame size.  If the frame size is > 4096
1665      bytes, we need to be sure we probe somewhere in the first and last
1666      4096 bytes (we can probably get away without the latter test) and
1667      every 8192 bytes in between.  If the frame size is > 32768, we
1668      do this in a loop.  Otherwise, we generate the explicit probe
1669      instructions. 
1670
1671      Note that we are only allowed to adjust sp once in the prologue.  */
1672
1673   if (frame_size < 32768)
1674     {
1675       if (frame_size > 4096)
1676         {
1677           int probed = 4096;
1678
1679           fprintf (file, "\tstq $31,-%d($30)\n", probed);
1680
1681           while (probed + 8192 < frame_size)
1682             fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
1683
1684           /* We only have to do this probe if we aren't saving registers.  */
1685           if (sa_size == 0 && probed + 4096 < frame_size)
1686             fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
1687         }
1688
1689       if (frame_size != 0)
1690         fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
1691     }
1692   else
1693     {
1694       /* Here we generate code to set R4 to SP + 4096 and set R5 to the
1695          number of 8192 byte blocks to probe.  We then probe each block
1696          in the loop and then set SP to the proper location.  If the
1697          amount remaining is > 4096, we have to do one more probe if we
1698          are not saving any registers.  */
1699
1700       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
1701       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
1702
1703       add_long_const (file, blocks, 31, 5, 5);
1704
1705       fprintf (file, "\tlda $4,4096($30)\n");
1706
1707       assemble_name (file, alpha_function_name);
1708       fprintf (file, "..sc:\n");
1709
1710       fprintf (file, "\tstq $31,-8192($4)\n");
1711       fprintf (file, "\tsubq $5,1,$5\n");
1712       fprintf (file, "\tlda $4,-8192($4)\n");
1713
1714       fprintf (file, "\tbne $5,");
1715       assemble_name (file, alpha_function_name);
1716       fprintf (file, "..sc\n");
1717
1718       if (leftover > 4096 && sa_size == 0)
1719         fprintf (file, "\tstq $31,-%d($4)\n", leftover);
1720
1721       fprintf (file, "\tlda $30,-%d($4)\n", leftover);
1722     }
1723
1724   /* Describe our frame.  */
1725   fprintf (file, "\t.frame $%d,%d,$26,%d\n", 
1726            (frame_pointer_needed
1727             ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
1728            frame_size, current_function_pretend_args_size);
1729     
1730   /* Save register 26 if any other register needs to be saved.  */
1731   if (sa_size != 0)
1732     {
1733       reg_mask |= 1 << 26;
1734       fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1735       reg_offset += 8;
1736       int_reg_save_area_size += 8;
1737     }
1738
1739   /* Now save any other used integer registers required to be saved.  */
1740   for (i = 0; i < 32; i++)
1741     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
1742       {
1743         reg_mask |= 1 << i;
1744         fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1745         reg_offset += 8;
1746         int_reg_save_area_size += 8;
1747       }
1748
1749   /* Print the register mask and do floating-point saves.  */
1750   if (reg_mask)
1751     fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1752              actual_start_reg_offset - frame_size);
1753
1754   start_reg_offset = reg_offset;
1755   reg_mask = 0;
1756
1757   for (i = 0; i < 32; i++)
1758     if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1759         && regs_ever_live[i + 32])
1760       {
1761         reg_mask |= 1 << i;
1762         fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1763         reg_offset += 8;
1764       }
1765
1766   /* Print the floating-point mask, if we've saved any fp register.  */
1767   if (reg_mask)
1768     fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
1769              actual_start_reg_offset - frame_size + int_reg_save_area_size);
1770
1771   /* If we need a frame pointer, set it from the stack pointer.  Note that
1772      this must always be the last instruction in the prologue.  */
1773   if (frame_pointer_needed)
1774     fprintf (file, "\tbis $30,$30,$15\n");
1775
1776   /* End the prologue and say if we used gp.  */
1777   fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
1778 }
1779
1780 /* Write function epilogue.  */
1781
1782 void
1783 output_epilog (file, size)
1784      FILE *file;
1785      int size;
1786 {
1787   rtx insn = get_last_insn ();
1788   HOST_WIDE_INT out_args_size
1789     = ALPHA_ROUND (current_function_outgoing_args_size);
1790   HOST_WIDE_INT sa_size = alpha_sa_size ();
1791   HOST_WIDE_INT frame_size
1792     = (out_args_size + sa_size
1793        + ALPHA_ROUND (size + current_function_pretend_args_size));
1794   HOST_WIDE_INT reg_offset = out_args_size;
1795   HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
1796   int restore_fp
1797     = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
1798   int i;
1799
1800   /* If the last insn was a BARRIER, we don't have to write anything except
1801      the .end pseudo-op.  */
1802   if (GET_CODE (insn) == NOTE)
1803     insn = prev_nonnote_insn (insn);
1804   if (insn == 0 || GET_CODE (insn) != BARRIER)
1805     {
1806       int fp_offset = 0;
1807
1808       final_prescan_insn (NULL_RTX, NULL_PTR, 0);
1809
1810       /* If we have a frame pointer, restore SP from it.  */
1811       if (frame_pointer_needed)
1812         fprintf (file, "\tbis $15,$15,$30\n");
1813
1814       /* Restore all the registers, starting with the return address
1815          register.  */
1816       if (sa_size != 0)
1817         {
1818           fprintf (file, "\tldq $26,%d($30)\n", reg_offset);
1819           reg_offset += 8;
1820         }
1821
1822       /* Now restore any other used integer registers that that we saved,
1823          except for FP if it is being used as FP, since it must be
1824          restored last.  */
1825
1826       for (i = 0; i < 32; i++)
1827         if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
1828             && i != 26)
1829           {
1830             if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1831               fp_offset = reg_offset;
1832             else
1833               fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset);
1834             reg_offset += 8;
1835           }
1836
1837       for (i = 0; i < 32; i++)
1838         if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
1839             && regs_ever_live[i + 32])
1840           {
1841             fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
1842             reg_offset += 8;
1843           }
1844
1845       /* If the stack size is large and we have a frame pointer, compute the
1846          size of the stack into a register because the old FP restore, stack
1847          pointer adjust, and return are required to be consecutive
1848          instructions.   */
1849       if (frame_size > 32767 && restore_fp)
1850         add_long_const (file, frame_size, 31, 1, 1);
1851
1852       /* If we needed a frame pointer and we have to restore it, do it
1853          now.  This must be done in one instruction immediately
1854          before the SP update.  */
1855       if (restore_fp && fp_offset)
1856         fprintf (file, "\tldq $15,%d($30)\n", fp_offset);
1857
1858       /* Now update the stack pointer, if needed.  Only one instruction must
1859          modify the stack pointer.  It must be the last instruction in the
1860          sequence and must be an ADDQ or LDA instruction.  If the frame
1861          pointer was loaded above, we may only put one instruction here.  */
1862
1863       if (frame_size > 32768 && restore_fp)
1864         fprintf  (file, "\taddq $1,$30,$30\n");
1865       else
1866         add_long_const (file, frame_size, 30, 30, 1);
1867
1868       /* Finally return to the caller.  */
1869       fprintf (file, "\tret $31,($26),1\n");
1870     }
1871
1872   /* End the function.  */
1873   fprintf (file, "\t.end ");
1874   assemble_name (file, alpha_function_name);
1875   fprintf (file, "\n");
1876   inside_function = FALSE;
1877
1878   /* Show that we know this function if it is called again.  */
1879   SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
1880 }
1881 \f
1882 /* Debugging support.  */
1883
1884 #include "gstab.h"
1885
1886 /* Count the number of sdb related labels are generated (to find block
1887    start and end boundaries).  */
1888
1889 int sdb_label_count = 0;
1890
1891 /* Next label # for each statement.  */
1892
1893 static int sym_lineno = 0;
1894
1895 /* Count the number of .file directives, so that .loc is up to date.  */
1896
1897 static int num_source_filenames = 0;
1898
1899 /* Name of the file containing the current function.  */
1900
1901 static char *current_function_file = "";
1902
1903 /* Offsets to alpha virtual arg/local debugging pointers.  */
1904
1905 long alpha_arg_offset;
1906 long alpha_auto_offset;
1907 \f
1908 /* Emit a new filename to a stream.  */
1909
1910 void
1911 alpha_output_filename (stream, name)
1912      FILE *stream;
1913      char *name;
1914 {
1915   static int first_time = TRUE;
1916   char ltext_label_name[100];
1917
1918   if (first_time)
1919     {
1920       first_time = FALSE;
1921       ++num_source_filenames;
1922       current_function_file = name;
1923       fprintf (stream, "\t.file\t%d ", num_source_filenames);
1924       output_quoted_string (stream, name);
1925       fprintf (stream, "\n");
1926       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1927         fprintf (stream, "\t#@stabs\n");
1928     }
1929
1930   else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
1931     {
1932       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
1933       fprintf (stream, "%s ", ASM_STABS_OP);
1934       output_quoted_string (stream, name);
1935       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
1936     }
1937
1938   else if (name != current_function_file
1939       && strcmp (name, current_function_file) != 0)
1940     {
1941       if (inside_function && ! TARGET_GAS)
1942         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
1943       else
1944         {
1945           ++num_source_filenames;
1946           current_function_file = name;
1947           fprintf (stream, "\t.file\t%d ", num_source_filenames);
1948         }
1949
1950       output_quoted_string (stream, name);
1951       fprintf (stream, "\n");
1952     }
1953 }
1954 \f
1955 /* Emit a linenumber to a stream.  */
1956
1957 void
1958 alpha_output_lineno (stream, line)
1959      FILE *stream;
1960      int line;
1961 {
1962   if (! TARGET_GAS && write_symbols == DBX_DEBUG)
1963     {
1964       /* mips-tfile doesn't understand .stabd directives.  */
1965       ++sym_lineno;
1966       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
1967                sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
1968     }
1969   else
1970     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
1971 }
1972 \f
1973 /* Structure to show the current status of registers and memory.  */
1974
1975 struct shadow_summary
1976 {
1977   struct {
1978     unsigned long i     : 32;   /* Mask of int regs */
1979     unsigned long fp    : 32;   /* Mask of fp regs */
1980     unsigned long mem   :  1;   /* mem == imem | fpmem */
1981   } used, defd;
1982 };
1983
1984 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
1985    to the summary structure.  SET is nonzero if the insn is setting the
1986    object, otherwise zero.  */
1987
1988 static void
1989 summarize_insn (x, sum, set)
1990      rtx x;
1991      struct shadow_summary *sum;
1992      int set;
1993 {
1994   char *format_ptr;
1995   int i, j;
1996
1997   if (x == 0)
1998     return;
1999
2000   switch (GET_CODE (x))
2001     {
2002       /* ??? Note that this case would be incorrect if the Alpha had a
2003          ZERO_EXTRACT in SET_DEST.  */
2004     case SET:
2005       summarize_insn (SET_SRC (x), sum, 0);
2006       summarize_insn (SET_DEST (x), sum, 1);
2007       break;
2008
2009     case CLOBBER:
2010       summarize_insn (XEXP (x, 0), sum, 1);
2011       break;
2012
2013     case USE:
2014       summarize_insn (XEXP (x, 0), sum, 0);
2015       break;
2016
2017     case PARALLEL:
2018       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
2019         summarize_insn (XVECEXP (x, 0, i), sum, 0);
2020       break;
2021
2022     case REG:
2023       {
2024         int regno = REGNO (x);
2025         unsigned long mask = 1UL << (regno % 32);
2026
2027         if (regno == 31 || regno == 63)
2028           break;
2029
2030         if (set)
2031           {
2032             if (regno < 32)
2033               sum->defd.i |= mask;
2034             else
2035               sum->defd.fp |= mask;
2036           }
2037         else
2038           {
2039             if (regno < 32)
2040               sum->used.i  |= mask;
2041             else
2042               sum->used.fp |= mask;
2043           }
2044         }
2045       break;
2046
2047     case MEM:
2048       if (set)
2049         sum->defd.mem = 1;
2050       else
2051         sum->used.mem = 1;
2052
2053       /* Find the regs used in memory address computation: */
2054       summarize_insn (XEXP (x, 0), sum, 0);
2055       break;
2056
2057     case SUBREG:
2058       summarize_insn (SUBREG_REG (x), sum, 0);
2059       break;
2060
2061     case CONST_INT:   case CONST_DOUBLE:
2062     case SYMBOL_REF:  case LABEL_REF:     case CONST:
2063       break;
2064
2065       /* Handle common unary and binary ops for efficiency.  */
2066     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
2067     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
2068     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
2069     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
2070     case NE:       case EQ:      case GE:      case GT:        case LE:
2071     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
2072       summarize_insn (XEXP (x, 0), sum, 0);
2073       summarize_insn (XEXP (x, 1), sum, 0);
2074       break;
2075
2076     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
2077     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
2078     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
2079     case SQRT:  case FFS: 
2080       summarize_insn (XEXP (x, 0), sum, 0);
2081       break;
2082
2083     default:
2084       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
2085       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
2086         switch (format_ptr[i])
2087           {
2088           case 'e':
2089             summarize_insn (XEXP (x, i), sum, 0);
2090             break;
2091
2092           case 'E':
2093             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2094               summarize_insn (XVECEXP (x, i, j), sum, 0);
2095             break;
2096
2097           default:
2098             abort ();
2099           }
2100     }
2101 }
2102 \f
2103 /* This function is executed just prior to the output of assembler code for
2104    INSN to modify the extracted operands so they will be output differently.
2105
2106    OPVEC is the vector containing the operands extracted from INSN, and
2107    NOPERANDS is the number of elements of the vector which contain meaningful
2108    data for this insn.  The contents of this vector are what will be used to
2109    convert the insn template into assembler code, so you can change the
2110    assembler output by changing the contents of the vector.
2111
2112    We use this function to ensure a sufficient number of `trapb' instructions
2113    are in the code when the user requests code with a trap precision of
2114    functions or instructions.
2115
2116    In naive mode, when the user requests a trap-precision of "instruction", a
2117    trapb is needed after every instruction that may generate a trap (and after
2118    jsr/bsr instructions, because called functions may import a trap from the
2119    caller).  This ensures that the code is resumption safe but it is also slow.
2120
2121    When optimizations are turned on, we delay issuing a trapb as long as
2122    possible.  In this context, a trap shadow is the sequence of instructions
2123    that starts with a (potentially) trap generating instruction and extends to
2124    the next trapb or call_pal instruction (but GCC never generates call_pal by
2125    itself).  We can delay (and therefore sometimes omit) a trapb subject to the
2126    following conditions:
2127
2128    (a) On entry to the trap shadow, if any Alpha register or memory location
2129    contains a value that is used as an operand value by some instruction in
2130    the trap shadow (live on entry), then no instruction in the trap shadow
2131    may modify the register or memory location.
2132
2133    (b) Within the trap shadow, the computation of the base register for a
2134    memory load or store instruction may not involve using the result
2135    of an instruction that might generate an UNPREDICTABLE result.
2136
2137    (c) Within the trap shadow, no register may be used more than once as a
2138    destination register.  (This is to make life easier for the trap-handler.)
2139
2140    (d) The trap shadow may not include any branch instructions.
2141
2142      */
2143
2144 void
2145 final_prescan_insn (insn, opvec, noperands)
2146      rtx insn;
2147      rtx *opvec;
2148      int noperands;
2149 {
2150   static struct shadow_summary shadow = {0, 0, 0, 0, 0};
2151
2152 #define CLOSE_SHADOW                            \
2153   do                                            \
2154     {                                           \
2155       fputs ("\ttrapb\n", asm_out_file);        \
2156       trap_pending = 0;                         \
2157       bzero ((char *) &shadow,  sizeof shadow); \
2158     }                                           \
2159   while (0)
2160
2161   if (alpha_tp == ALPHA_TP_PROG)
2162     return;
2163
2164   if (trap_pending)
2165     switch (alpha_tp)
2166       {
2167       case ALPHA_TP_FUNC:
2168         /* Generate one trapb before epilogue (indicated by INSN==0) */
2169         if (insn == 0)
2170           CLOSE_SHADOW;
2171         break;
2172
2173       case ALPHA_TP_INSN:
2174         if (optimize && insn != 0)
2175           {
2176             struct shadow_summary sum = {0, 0, 0};
2177
2178             switch (GET_CODE(insn))
2179               {
2180               case INSN:
2181                 summarize_insn (PATTERN (insn), &sum, 0);
2182
2183                 if ((sum.defd.i & shadow.defd.i)
2184                     || (sum.defd.fp & shadow.defd.fp))
2185                   {
2186                     /* (c) would be violated */
2187                     CLOSE_SHADOW;
2188                     break;
2189                   }
2190
2191                 /* Combine shadow with summary of current insn: */
2192                 shadow.used.i     |= sum.used.i;
2193                 shadow.used.fp    |= sum.used.fp;
2194                 shadow.used.mem   |= sum.used.mem;
2195                 shadow.defd.i     |= sum.defd.i;
2196                 shadow.defd.fp    |= sum.defd.fp;
2197                 shadow.defd.mem   |= sum.defd.mem;
2198
2199                 if ((sum.defd.i & shadow.used.i)
2200                     || (sum.defd.fp & shadow.used.fp)
2201                     || (sum.defd.mem & shadow.used.mem))
2202                   {
2203                     /* (a) would be violated (also takes care of (b)).  */
2204                     if (get_attr_trap (insn) == TRAP_YES
2205                         && ((sum.defd.i & sum.used.i)
2206                             || (sum.defd.fp & sum.used.fp)))
2207                       abort ();
2208
2209                     CLOSE_SHADOW;
2210                     break;
2211                   }
2212                 break;
2213
2214               case JUMP_INSN:
2215               case CALL_INSN:
2216               case CODE_LABEL:
2217                 CLOSE_SHADOW;
2218                 break;
2219
2220               default:
2221                 abort ();
2222               }
2223           }
2224         else
2225           CLOSE_SHADOW;
2226         break;
2227       }
2228
2229   if (insn != 0 && get_attr_trap (insn) == TRAP_YES)
2230     {
2231       if (optimize && !trap_pending && GET_CODE (insn) == INSN)
2232         summarize_insn (PATTERN (insn), &shadow, 0);
2233       trap_pending = 1;
2234     }
2235 }
2236
2237 /* Check a floating-point value for validity for a particular machine mode.  */
2238
2239 static char *float_strings[] =
2240 {
2241    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
2242   "-1.70141173319264430e+38",
2243    "2.93873587705571877e-39", /* 2^-128 */
2244   "-2.93873587705571877e-39"
2245 };
2246
2247 static REAL_VALUE_TYPE float_values[4];
2248 static int inited_float_values = 0;
2249
2250 int
2251 check_float_value (mode, d, overflow)
2252      enum machine_mode mode;
2253      REAL_VALUE_TYPE *d;
2254      int overflow;
2255 {
2256
2257   if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
2258     return 0;
2259
2260   if (inited_float_values == 0)
2261     {
2262       int i;
2263       for (i = 0; i < 4; i++)
2264         float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
2265
2266       inited_float_values = 1;
2267     }
2268
2269   if (mode == SFmode)
2270     {
2271       REAL_VALUE_TYPE r;
2272
2273       bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
2274       if (REAL_VALUES_LESS (float_values[0], r))
2275         {
2276           bcopy ((char *) &float_values[0], (char *) d,
2277                  sizeof (REAL_VALUE_TYPE));
2278           return 1;
2279         }
2280       else if (REAL_VALUES_LESS (r, float_values[1]))
2281         {
2282           bcopy ((char *) &float_values[1], (char *) d,
2283                  sizeof (REAL_VALUE_TYPE));
2284           return 1;
2285         }
2286       else if (REAL_VALUES_LESS (dconst0, r)
2287                 && REAL_VALUES_LESS (r, float_values[2]))
2288         {
2289           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
2290           return 1;
2291         }
2292       else if (REAL_VALUES_LESS (r, dconst0)
2293                 && REAL_VALUES_LESS (float_values[3], r))
2294         {
2295           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
2296           return 1;
2297         }
2298     }
2299
2300   return 0;
2301 }