OSDN Git Service

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