OSDN Git Service

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