OSDN Git Service

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