OSDN Git Service

* alpha.c (print_operand_address): Account for the subreg word.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2    Copyright (C) 1992, 93-98, 1999 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 "config.h"
24 #include "system.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 "tree.h"
38 #include "expr.h"
39 #include "obstack.h"
40 #include "except.h"
41 #include "function.h"
42 #include "toplev.h"
43
44 /* External data.  */
45 extern char *version_string;
46 extern int rtx_equal_function_value_matters;
47
48 /* Specify which cpu to schedule for. */
49
50 enum processor_type alpha_cpu;
51 static const char * const alpha_cpu_name[] = 
52 {
53   "ev4", "ev5", "ev6"
54 };
55
56 /* Specify how accurate floating-point traps need to be.  */
57
58 enum alpha_trap_precision alpha_tp;
59
60 /* Specify the floating-point rounding mode.  */
61
62 enum alpha_fp_rounding_mode alpha_fprm;
63
64 /* Specify which things cause traps.  */
65
66 enum alpha_fp_trap_mode alpha_fptm;
67
68 /* Strings decoded into the above options.  */
69
70 const char *alpha_cpu_string;   /* -mcpu= */
71 const char *alpha_tp_string;    /* -mtrap-precision=[p|s|i] */
72 const char *alpha_fprm_string;  /* -mfp-rounding-mode=[n|m|c|d] */
73 const char *alpha_fptm_string;  /* -mfp-trap-mode=[n|u|su|sui] */
74 const char *alpha_mlat_string;  /* -mmemory-latency= */
75
76 /* Save information from a "cmpxx" operation until the branch or scc is
77    emitted.  */
78
79 rtx alpha_compare_op0, alpha_compare_op1;
80 int alpha_compare_fp_p;
81
82 /* Define the information needed to modify the epilogue for EH.  */
83
84 rtx alpha_eh_epilogue_sp_ofs;
85
86 /* Non-zero if inside of a function, because the Alpha asm can't
87    handle .files inside of functions.  */
88
89 static int inside_function = FALSE;
90
91 /* If non-null, this rtx holds the return address for the function.  */
92
93 static rtx alpha_return_addr_rtx;
94
95 /* The number of cycles of latency we should assume on memory reads.  */
96
97 int alpha_memory_latency = 3;
98
99 /* Whether the function needs the GP.  */
100
101 static int alpha_function_needs_gp;
102
103 /* The alias set for prologue/epilogue register save/restore.  */
104
105 static int alpha_sr_alias_set;
106
107 /* Declarations of static functions.  */
108 static void alpha_set_memflags_1
109   PROTO((rtx, int, int, int));
110 static rtx alpha_emit_set_const_1
111   PROTO((rtx, enum machine_mode, HOST_WIDE_INT, int));
112 static void alpha_expand_unaligned_load_words
113   PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
114 static void alpha_expand_unaligned_store_words
115   PROTO((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
116 static void alpha_sa_mask
117   PROTO((unsigned long *imaskP, unsigned long *fmaskP));
118 static int alpha_does_function_need_gp
119   PROTO((void));
120
121
122 /* Get the number of args of a function in one of two ways.  */
123 #ifdef OPEN_VMS
124 #define NUM_ARGS current_function_args_info.num_args
125 #else
126 #define NUM_ARGS current_function_args_info
127 #endif
128
129 #define REG_PV 27
130 #define REG_RA 26
131 \f
132 /* Parse target option strings. */
133
134 void
135 override_options ()
136 {
137   alpha_cpu
138     = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
139       : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
140
141   if (alpha_cpu_string)
142     {
143       if (! strcmp (alpha_cpu_string, "ev4")
144           || ! strcmp (alpha_cpu_string, "21064"))
145         {
146           alpha_cpu = PROCESSOR_EV4;
147           target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
148         }
149       else if (! strcmp (alpha_cpu_string, "ev5")
150                || ! strcmp (alpha_cpu_string, "21164"))
151         {
152           alpha_cpu = PROCESSOR_EV5;
153           target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
154         }
155       else if (! strcmp (alpha_cpu_string, "ev56")
156                || ! strcmp (alpha_cpu_string, "21164a"))
157         {
158           alpha_cpu = PROCESSOR_EV5;
159           target_flags |= MASK_BWX;
160           target_flags &= ~ (MASK_CIX | MASK_MAX);
161         }
162       else if (! strcmp (alpha_cpu_string, "pca56")
163                || ! strcmp (alpha_cpu_string, "21164PC")
164                || ! strcmp (alpha_cpu_string, "21164pc"))
165         {
166           alpha_cpu = PROCESSOR_EV5;
167           target_flags |= MASK_BWX | MASK_MAX;
168           target_flags &= ~ MASK_CIX;
169         }
170       else if (! strcmp (alpha_cpu_string, "ev6")
171                || ! strcmp (alpha_cpu_string, "21264"))
172         {
173           alpha_cpu = PROCESSOR_EV6;
174           target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
175         }
176       else
177         error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
178     }
179
180   alpha_tp = ALPHA_TP_PROG;
181   alpha_fprm = ALPHA_FPRM_NORM;
182   alpha_fptm = ALPHA_FPTM_N;
183
184   if (TARGET_IEEE)
185     {
186       alpha_tp = ALPHA_TP_INSN;
187       alpha_fptm = ALPHA_FPTM_SU;
188     }
189
190   if (TARGET_IEEE_WITH_INEXACT)
191     {
192       alpha_tp = ALPHA_TP_INSN;
193       alpha_fptm = ALPHA_FPTM_SUI;
194     }
195
196   if (alpha_tp_string)
197     {
198       if (! strcmp (alpha_tp_string, "p"))
199         alpha_tp = ALPHA_TP_PROG;
200       else if (! strcmp (alpha_tp_string, "f"))
201         alpha_tp = ALPHA_TP_FUNC;
202       else if (! strcmp (alpha_tp_string, "i"))
203         alpha_tp = ALPHA_TP_INSN;
204       else
205         error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
206     }
207
208   if (alpha_fprm_string)
209     {
210       if (! strcmp (alpha_fprm_string, "n"))
211         alpha_fprm = ALPHA_FPRM_NORM;
212       else if (! strcmp (alpha_fprm_string, "m"))
213         alpha_fprm = ALPHA_FPRM_MINF;
214       else if (! strcmp (alpha_fprm_string, "c"))
215         alpha_fprm = ALPHA_FPRM_CHOP;
216       else if (! strcmp (alpha_fprm_string,"d"))
217         alpha_fprm = ALPHA_FPRM_DYN;
218       else
219         error ("bad value `%s' for -mfp-rounding-mode switch",
220                alpha_fprm_string);
221     }
222
223   if (alpha_fptm_string)
224     {
225       if (strcmp (alpha_fptm_string, "n") == 0)
226         alpha_fptm = ALPHA_FPTM_N;
227       else if (strcmp (alpha_fptm_string, "u") == 0)
228         alpha_fptm = ALPHA_FPTM_U;
229       else if (strcmp (alpha_fptm_string, "su") == 0)
230         alpha_fptm = ALPHA_FPTM_SU;
231       else if (strcmp (alpha_fptm_string, "sui") == 0)
232         alpha_fptm = ALPHA_FPTM_SUI;
233       else
234         error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
235     }
236
237   /* Do some sanity checks on the above option. */
238
239   if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
240       && alpha_tp != ALPHA_TP_INSN)
241     {
242       warning ("fp software completion requires -mtrap-precision=i");
243       alpha_tp = ALPHA_TP_INSN;
244     }
245
246   if (TARGET_FLOAT_VAX)
247     {
248       if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
249         {
250           warning ("rounding mode not supported for VAX floats");
251           alpha_fprm = ALPHA_FPRM_NORM;
252         }
253       if (alpha_fptm == ALPHA_FPTM_SUI)
254         {
255           warning ("trap mode not supported for VAX floats");
256           alpha_fptm = ALPHA_FPTM_SU;
257         }
258     }
259
260   {
261     char *end;
262     int lat;
263
264     if (!alpha_mlat_string)
265       alpha_mlat_string = "L1";
266
267     if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
268         && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
269       ;
270     else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
271              && ISDIGIT ((unsigned char)alpha_mlat_string[1])
272              && alpha_mlat_string[2] == '\0')
273       {
274         static int const cache_latency[][4] = 
275         {
276           { 3, 30, -1 },        /* ev4 -- Bcache is a guess */
277           { 2, 12, 38 },        /* ev5 -- Bcache from PC164 LMbench numbers */
278           { 3, 13, -1 },        /* ev6 -- Ho hum, doesn't exist yet */
279         };
280
281         lat = alpha_mlat_string[1] - '0';
282         if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
283           {
284             warning ("L%d cache latency unknown for %s",
285                      lat, alpha_cpu_name[alpha_cpu]);
286             lat = 3;
287           }
288         else
289           lat = cache_latency[alpha_cpu][lat-1];
290       }
291     else if (! strcmp (alpha_mlat_string, "main"))
292       {
293         /* Most current memories have about 370ns latency.  This is
294            a reasonable guess for a fast cpu.  */
295         lat = 150;
296       }
297     else
298       {
299         warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
300         lat = 3;
301       }
302
303     alpha_memory_latency = lat;
304   }
305
306   /* Default the definition of "small data" to 8 bytes.  */
307   if (!g_switch_set)
308     g_switch_value = 8;
309
310   /* Acquire a unique set number for our register saves and restores.  */
311   alpha_sr_alias_set = new_alias_set ();
312 }
313 \f
314 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
315
316 int
317 zap_mask (value)
318      HOST_WIDE_INT value;
319 {
320   int i;
321
322   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
323        i++, value >>= 8)
324     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
325       return 0;
326
327   return 1;
328 }
329
330 /* Returns 1 if OP is either the constant zero or a register.  If a
331    register, it must be in the proper mode unless MODE is VOIDmode.  */
332
333 int
334 reg_or_0_operand (op, mode)
335       register rtx op;
336       enum machine_mode mode;
337 {
338   return op == const0_rtx || register_operand (op, mode);
339 }
340
341 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
342    any register.  */
343
344 int
345 reg_or_6bit_operand (op, mode)
346      register rtx op;
347      enum machine_mode mode;
348 {
349   return ((GET_CODE (op) == CONST_INT
350            && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
351           || register_operand (op, mode));
352 }
353
354
355 /* Return 1 if OP is an 8-bit constant or any register.  */
356
357 int
358 reg_or_8bit_operand (op, mode)
359      register rtx op;
360      enum machine_mode mode;
361 {
362   return ((GET_CODE (op) == CONST_INT
363            && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
364           || register_operand (op, mode));
365 }
366
367 /* Return 1 if OP is an 8-bit constant.  */
368
369 int
370 cint8_operand (op, mode)
371      register rtx op;
372      enum machine_mode mode ATTRIBUTE_UNUSED;
373 {
374   return ((GET_CODE (op) == CONST_INT
375            && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
376 }
377
378 /* Return 1 if the operand is a valid second operand to an add insn.  */
379
380 int
381 add_operand (op, mode)
382      register rtx op;
383      enum machine_mode mode;
384 {
385   if (GET_CODE (op) == CONST_INT)
386     /* Constraints I, J, O and P are covered by K.  */
387     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
388             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
389
390   return register_operand (op, mode);
391 }
392
393 /* Return 1 if the operand is a valid second operand to a sign-extending
394    add insn.  */
395
396 int
397 sext_add_operand (op, mode)
398      register rtx op;
399      enum machine_mode mode;
400 {
401   if (GET_CODE (op) == CONST_INT)
402     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
403             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
404
405   return register_operand (op, mode);
406 }
407
408 /* Return 1 if OP is the constant 4 or 8.  */
409
410 int
411 const48_operand (op, mode)
412      register rtx op;
413      enum machine_mode mode ATTRIBUTE_UNUSED;
414 {
415   return (GET_CODE (op) == CONST_INT
416           && (INTVAL (op) == 4 || INTVAL (op) == 8));
417 }
418
419 /* Return 1 if OP is a valid first operand to an AND insn.  */
420
421 int
422 and_operand (op, mode)
423      register rtx op;
424      enum machine_mode mode;
425 {
426   if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
427     return (zap_mask (CONST_DOUBLE_LOW (op))
428             && zap_mask (CONST_DOUBLE_HIGH (op)));
429
430   if (GET_CODE (op) == CONST_INT)
431     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
432             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
433             || zap_mask (INTVAL (op)));
434
435   return register_operand (op, mode);
436 }
437
438 /* Return 1 if OP is a valid first operand to an IOR or XOR insn.  */
439
440 int
441 or_operand (op, mode)
442      register rtx op;
443      enum machine_mode mode;
444 {
445   if (GET_CODE (op) == CONST_INT)
446     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
447             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
448
449   return register_operand (op, mode);
450 }
451
452 /* Return 1 if OP is a constant that is the width, in bits, of an integral
453    mode smaller than DImode.  */
454
455 int
456 mode_width_operand (op, mode)
457      register rtx op;
458      enum machine_mode mode ATTRIBUTE_UNUSED;
459 {
460   return (GET_CODE (op) == CONST_INT
461           && (INTVAL (op) == 8 || INTVAL (op) == 16
462               || INTVAL (op) == 32 || INTVAL (op) == 64));
463 }
464
465 /* Return 1 if OP is a constant that is the width of an integral machine mode
466    smaller than an integer.  */
467
468 int
469 mode_mask_operand (op, mode)
470      register rtx op;
471      enum machine_mode mode ATTRIBUTE_UNUSED;
472 {
473 #if HOST_BITS_PER_WIDE_INT == 32
474   if (GET_CODE (op) == CONST_DOUBLE)
475     return (CONST_DOUBLE_LOW (op) == -1
476             && (CONST_DOUBLE_HIGH (op) == -1
477                 || CONST_DOUBLE_HIGH (op) == 0));
478 #else
479   if (GET_CODE (op) == CONST_DOUBLE)
480     return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
481 #endif
482
483   return (GET_CODE (op) == CONST_INT
484           && (INTVAL (op) == 0xff
485               || INTVAL (op) == 0xffff
486               || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
487 #if HOST_BITS_PER_WIDE_INT == 64
488               || INTVAL (op) == -1
489 #endif
490               ));
491 }
492
493 /* Return 1 if OP is a multiple of 8 less than 64.  */
494
495 int
496 mul8_operand (op, mode)
497      register rtx op;
498      enum machine_mode mode ATTRIBUTE_UNUSED;
499 {
500   return (GET_CODE (op) == CONST_INT
501           && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
502           && (INTVAL (op) & 7) == 0);
503 }
504
505 /* Return 1 if OP is the constant zero in floating-point.  */
506
507 int
508 fp0_operand (op, mode)
509      register rtx op;
510      enum machine_mode mode;
511 {
512   return (GET_MODE (op) == mode
513           && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
514 }
515
516 /* Return 1 if OP is the floating-point constant zero or a register.  */
517
518 int
519 reg_or_fp0_operand (op, mode)
520      register rtx op;
521      enum machine_mode mode;
522 {
523   return fp0_operand (op, mode) || register_operand (op, mode);
524 }
525
526 /* Return 1 if OP is a hard floating-point register.  */
527
528 int
529 hard_fp_register_operand (op, mode)
530      register rtx op;
531      enum machine_mode mode;
532 {
533   return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
534           || (GET_CODE (op) == SUBREG
535               && hard_fp_register_operand (SUBREG_REG (op), mode)));
536 }
537
538 /* Return 1 if OP is a register or a constant integer.  */
539
540
541 int
542 reg_or_cint_operand (op, mode)
543     register rtx op;
544     enum machine_mode mode;
545 {
546      return (GET_CODE (op) == CONST_INT
547              || register_operand (op, mode));
548 }
549
550 /* Return 1 if OP is something that can be reloaded into a register;
551    if it is a MEM, it need not be valid.  */
552
553 int
554 some_operand (op, mode)
555      register rtx op;
556      enum machine_mode mode;
557 {
558   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
559     return 0;
560
561   switch (GET_CODE (op))
562     {
563     case REG:  case MEM:  case CONST_DOUBLE:  case CONST_INT:  case LABEL_REF:
564     case SYMBOL_REF:  case CONST:
565       return 1;
566
567     case SUBREG:
568       return some_operand (SUBREG_REG (op), VOIDmode);
569
570     default:
571       break;
572     }
573
574   return 0;
575 }
576
577 /* Return 1 if OP is a valid operand for the source of a move insn.  */
578
579 int
580 input_operand (op, mode)
581      register rtx op;
582      enum machine_mode mode;
583 {
584   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
585     return 0;
586
587   if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
588     return 0;
589
590   switch (GET_CODE (op))
591     {
592     case LABEL_REF:
593     case SYMBOL_REF:
594     case CONST:
595       /* This handles both the Windows/NT and OSF cases.  */
596       return mode == ptr_mode || mode == DImode;
597
598     case REG:
599       return 1;
600
601     case SUBREG:
602       if (register_operand (op, mode))
603         return 1;
604       /* ... fall through ... */
605     case MEM:
606       return ((TARGET_BWX || (mode != HImode && mode != QImode))
607               && general_operand (op, mode));
608
609     case CONST_DOUBLE:
610       return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
611
612     case CONST_INT:
613       return mode == QImode || mode == HImode || add_operand (op, mode);
614
615     case CONSTANT_P_RTX:
616       return 1;
617
618     default:
619       break;
620     }
621
622   return 0;
623 }
624
625 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
626    file.  */
627
628 int
629 current_file_function_operand (op, mode)
630      rtx op;
631      enum machine_mode mode ATTRIBUTE_UNUSED;
632 {
633   return (GET_CODE (op) == SYMBOL_REF
634           && ! profile_flag && ! profile_block_flag
635           && (SYMBOL_REF_FLAG (op)
636               || op == XEXP (DECL_RTL (current_function_decl), 0)));
637 }
638
639 /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
640
641 int
642 call_operand (op, mode)
643      rtx op;
644      enum machine_mode mode;
645 {
646   if (mode != Pmode)
647     return 0;
648
649   return (GET_CODE (op) == SYMBOL_REF
650           || (GET_CODE (op) == REG
651               && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
652 }
653
654 /* Return 1 if OP is a valid Alpha comparison operator.  Here we know which
655    comparisons are valid in which insn.  */
656
657 int
658 alpha_comparison_operator (op, mode)
659      register rtx op;
660      enum machine_mode mode;
661 {
662   enum rtx_code code = GET_CODE (op);
663
664   if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
665     return 0;
666
667   return (code == EQ || code == LE || code == LT
668           || (mode == DImode && (code == LEU || code == LTU)));
669 }
670
671 /* Return 1 if OP is a valid Alpha swapped comparison operator.  */
672
673 int
674 alpha_swapped_comparison_operator (op, mode)
675      register rtx op;
676      enum machine_mode mode;
677 {
678   enum rtx_code code = GET_CODE (op);
679
680   if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
681     return 0;
682
683   code = swap_condition (code);
684   return (code == EQ || code == LE || code == LT
685           || (mode == DImode && (code == LEU || code == LTU)));
686 }
687
688 /* Return 1 if OP is a signed comparison operation.  */
689
690 int
691 signed_comparison_operator (op, mode)
692      register rtx op;
693      enum machine_mode mode ATTRIBUTE_UNUSED;
694 {
695   switch (GET_CODE (op))
696     {
697     case EQ:  case NE:  case LE:  case LT:  case GE:   case GT:
698       return 1;
699
700     default:
701       break;
702     }
703
704   return 0;
705 }
706
707 /* Return 1 if this is a divide or modulus operator.  */
708
709 int
710 divmod_operator (op, mode)
711      register rtx op;
712      enum machine_mode mode ATTRIBUTE_UNUSED;
713 {
714   switch (GET_CODE (op))
715     {
716     case DIV:  case MOD:  case UDIV:  case UMOD:
717       return 1;
718
719     default:
720       break;
721     }
722
723   return 0;
724 }
725
726 /* Return 1 if this memory address is a known aligned register plus
727    a constant.  It must be a valid address.  This means that we can do
728    this as an aligned reference plus some offset.
729
730    Take into account what reload will do.  */
731
732 int
733 aligned_memory_operand (op, mode)
734      register rtx op;
735      enum machine_mode mode;
736 {
737   rtx base;
738
739   if (reload_in_progress)
740     {
741       rtx tmp = op;
742       if (GET_CODE (tmp) == SUBREG)
743         tmp = SUBREG_REG (tmp);
744       if (GET_CODE (tmp) == REG
745           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
746         {
747           op = reg_equiv_memory_loc[REGNO (tmp)];
748           if (op == 0)
749             return 0;
750         }
751     }
752
753   if (GET_CODE (op) != MEM
754       || GET_MODE (op) != mode)
755     return 0;
756   op = XEXP (op, 0);
757
758   /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
759      sorts of constructs.  Dig for the real base register.  */
760   if (reload_in_progress
761       && GET_CODE (op) == PLUS
762       && GET_CODE (XEXP (op, 0)) == PLUS)
763     base = XEXP (XEXP (op, 0), 0);
764   else
765     {
766       if (! memory_address_p (mode, op))
767         return 0;
768       base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
769     }
770
771   return (GET_CODE (base) == REG
772           && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
773 }
774
775 /* Similar, but return 1 if OP is a MEM which is not alignable.  */
776
777 int
778 unaligned_memory_operand (op, mode)
779      register rtx op;
780      enum machine_mode mode;
781 {
782   rtx base;
783
784   if (reload_in_progress)
785     {
786       rtx tmp = op;
787       if (GET_CODE (tmp) == SUBREG)
788         tmp = SUBREG_REG (tmp);
789       if (GET_CODE (tmp) == REG
790           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
791         {
792           op = reg_equiv_memory_loc[REGNO (tmp)];
793           if (op == 0)
794             return 0;
795         }
796     }
797
798   if (GET_CODE (op) != MEM
799       || GET_MODE (op) != mode)
800     return 0;
801   op = XEXP (op, 0);
802
803   /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
804      sorts of constructs.  Dig for the real base register.  */
805   if (reload_in_progress
806       && GET_CODE (op) == PLUS
807       && GET_CODE (XEXP (op, 0)) == PLUS)
808     base = XEXP (XEXP (op, 0), 0);
809   else
810     {
811       if (! memory_address_p (mode, op))
812         return 0;
813       base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
814     }
815
816   return (GET_CODE (base) == REG
817           && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
818 }
819
820 /* Return 1 if OP is either a register or an unaligned memory location.  */
821
822 int
823 reg_or_unaligned_mem_operand (op, mode)
824      rtx op;
825      enum machine_mode mode;
826 {
827   return register_operand (op, mode) || unaligned_memory_operand (op, mode);
828 }
829
830 /* Return 1 if OP is any memory location.  During reload a pseudo matches.  */
831
832 int
833 any_memory_operand (op, mode)
834      register rtx op;
835      enum machine_mode mode ATTRIBUTE_UNUSED;
836 {
837   return (GET_CODE (op) == MEM
838           || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
839           || (reload_in_progress && GET_CODE (op) == REG
840               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
841           || (reload_in_progress && GET_CODE (op) == SUBREG
842               && GET_CODE (SUBREG_REG (op)) == REG
843               && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
844 }
845
846 /* Returns 1 if OP is not an eliminable register.
847
848    This exists to cure a pathological abort in the s8addq (et al) patterns,
849
850         long foo () { long t; bar(); return (long) &t * 26107; }
851
852    which run afoul of a hack in reload to cure a (presumably) similar
853    problem with lea-type instructions on other targets.  But there is
854    one of us and many of them, so work around the problem by selectively
855    preventing combine from making the optimization.  */
856
857 int
858 reg_not_elim_operand (op, mode)
859       register rtx op;
860       enum machine_mode mode;
861 {
862   rtx inner = op;
863   if (GET_CODE (op) == SUBREG)
864     inner = SUBREG_REG (op);
865   if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
866     return 0;
867
868   return register_operand (op, mode);
869 }
870
871 /* Return 1 is OP is a memory location that is not a reference (using
872    an AND) to an unaligned location.  Take into account what reload
873    will do.  */
874
875 int
876 normal_memory_operand (op, mode)
877      register rtx op;
878      enum machine_mode mode ATTRIBUTE_UNUSED;
879 {
880   if (reload_in_progress)
881     {
882       rtx tmp = op;
883       if (GET_CODE (tmp) == SUBREG)
884         tmp = SUBREG_REG (tmp);
885       if (GET_CODE (tmp) == REG
886           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
887         {
888           op = reg_equiv_memory_loc[REGNO (tmp)];
889
890           /* This may not have been assigned an equivalent address if it will
891              be eliminated.  In that case, it doesn't matter what we do.  */
892           if (op == 0)
893             return 1;
894         }
895     }
896
897   return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
898 }
899
900 /* Accept a register, but not a subreg of any kind.  This allows us to
901    avoid pathological cases in reload wrt data movement common in 
902    int->fp conversion.  */
903
904 int
905 reg_no_subreg_operand (op, mode)
906      register rtx op;
907      enum machine_mode mode;
908 {
909   if (GET_CODE (op) == SUBREG)
910     return 0;
911   return register_operand (op, mode);
912 }
913 \f
914 /* Return 1 if this function can directly return via $26.  */
915
916 int
917 direct_return ()
918 {
919   return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
920           && get_frame_size () == 0
921           && current_function_outgoing_args_size == 0
922           && current_function_pretend_args_size == 0);
923 }
924
925 /* REF is an alignable memory location.  Place an aligned SImode
926    reference into *PALIGNED_MEM and the number of bits to shift into
927    *PBITNUM.  SCRATCH is a free register for use in reloading out
928    of range stack slots.  */
929
930 void
931 get_aligned_mem (ref, paligned_mem, pbitnum)
932      rtx ref;
933      rtx *paligned_mem, *pbitnum;
934 {
935   rtx base;
936   HOST_WIDE_INT offset = 0;
937
938   if (GET_CODE (ref) != MEM)
939     abort ();
940
941   if (reload_in_progress
942       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
943     {
944       base = find_replacement (&XEXP (ref, 0));
945
946       if (! memory_address_p (GET_MODE (ref), base))
947         abort ();
948     }
949   else
950     {
951       base = XEXP (ref, 0);
952     }
953
954   if (GET_CODE (base) == PLUS)
955     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
956
957   *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
958   MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
959   RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
960
961   /* Sadly, we cannot use alias sets here because we may overlap other
962      data in a different alias set.  */
963   /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
964
965   *pbitnum = GEN_INT ((offset & 3) * 8);
966 }
967
968 /* Similar, but just get the address.  Handle the two reload cases.  
969    Add EXTRA_OFFSET to the address we return.  */
970
971 rtx
972 get_unaligned_address (ref, extra_offset)
973      rtx ref;
974      int extra_offset;
975 {
976   rtx base;
977   HOST_WIDE_INT offset = 0;
978
979   if (GET_CODE (ref) != MEM)
980     abort ();
981
982   if (reload_in_progress
983       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
984     {
985       base = find_replacement (&XEXP (ref, 0));
986
987       if (! memory_address_p (GET_MODE (ref), base))
988         abort ();
989     }
990   else
991     {
992       base = XEXP (ref, 0);
993     }
994
995   if (GET_CODE (base) == PLUS)
996     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
997
998   return plus_constant (base, offset + extra_offset);
999 }
1000 \f
1001 /* Subfunction of the following function.  Update the flags of any MEM
1002    found in part of X.  */
1003
1004 static void
1005 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1006      rtx x;
1007      int in_struct_p, volatile_p, unchanging_p;
1008 {
1009   int i;
1010
1011   switch (GET_CODE (x))
1012     {
1013     case SEQUENCE:
1014     case PARALLEL:
1015       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1016         alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1017                               unchanging_p);
1018       break;
1019
1020     case INSN:
1021       alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1022                             unchanging_p);
1023       break;
1024
1025     case SET:
1026       alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1027                             unchanging_p);
1028       alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1029                             unchanging_p);
1030       break;
1031
1032     case MEM:
1033       MEM_IN_STRUCT_P (x) = in_struct_p;
1034       MEM_VOLATILE_P (x) = volatile_p;
1035       RTX_UNCHANGING_P (x) = unchanging_p;
1036       /* Sadly, we cannot use alias sets because the extra aliasing
1037          produced by the AND interferes.  Given that two-byte quantities
1038          are the only thing we would be able to differentiate anyway,
1039          there does not seem to be any point in convoluting the early
1040          out of the alias check.  */
1041       /* MEM_ALIAS_SET (x) = alias_set; */
1042       break;
1043
1044     default:
1045       break;
1046     }
1047 }
1048
1049 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1050    perform a memory operation, look for any MEMs in either a SET_DEST or
1051    a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1052    REF into each of the MEMs found.  If REF is not a MEM, don't do
1053    anything.  */
1054
1055 void
1056 alpha_set_memflags (insn, ref)
1057      rtx insn;
1058      rtx ref;
1059 {
1060   int in_struct_p, volatile_p, unchanging_p;
1061
1062   if (GET_CODE (ref) != MEM)
1063     return;
1064
1065   in_struct_p = MEM_IN_STRUCT_P (ref);
1066   volatile_p = MEM_VOLATILE_P (ref);
1067   unchanging_p = RTX_UNCHANGING_P (ref);
1068
1069   /* This is only called from alpha.md, after having had something 
1070      generated from one of the insn patterns.  So if everything is
1071      zero, the pattern is already up-to-date.  */
1072   if (! in_struct_p && ! volatile_p && ! unchanging_p)
1073     return;
1074
1075   alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1076 }
1077 \f
1078 /* Try to output insns to set TARGET equal to the constant C if it can be
1079    done in less than N insns.  Do all computations in MODE.  Returns the place
1080    where the output has been placed if it can be done and the insns have been
1081    emitted.  If it would take more than N insns, zero is returned and no
1082    insns and emitted.  */
1083
1084 rtx
1085 alpha_emit_set_const (target, mode, c, n)
1086      rtx target;
1087      enum machine_mode mode;
1088      HOST_WIDE_INT c;
1089      int n;
1090 {
1091   rtx pat;
1092   int i;
1093
1094   /* Try 1 insn, then 2, then up to N. */
1095   for (i = 1; i <= n; i++)
1096     if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1097       return pat;
1098
1099   return 0;
1100 }
1101
1102 /* Internal routine for the above to check for N or below insns.  */
1103
1104 static rtx
1105 alpha_emit_set_const_1 (target, mode, c, n)
1106      rtx target;
1107      enum machine_mode mode;
1108      HOST_WIDE_INT c;
1109      int n;
1110 {
1111   HOST_WIDE_INT new = c;
1112   int i, bits;
1113   /* Use a pseudo if highly optimizing and still generating RTL.  */
1114   rtx subtarget
1115     = (flag_expensive_optimizations && rtx_equal_function_value_matters
1116        ? 0 : target);
1117   rtx temp;
1118
1119 #if HOST_BITS_PER_WIDE_INT == 64
1120   /* We are only called for SImode and DImode.  If this is SImode, ensure that
1121      we are sign extended to a full word.  This does not make any sense when
1122      cross-compiling on a narrow machine.  */
1123
1124   if (mode == SImode)
1125     c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1126 #endif
1127
1128   /* If this is a sign-extended 32-bit constant, we can do this in at most
1129      three insns, so do it if we have enough insns left.  We always have
1130      a sign-extended 32-bit constant when compiling on a narrow machine.   */
1131
1132   if (HOST_BITS_PER_WIDE_INT != 64
1133       || c >> 31 == -1 || c >> 31 == 0)
1134     {
1135       HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1136       HOST_WIDE_INT tmp1 = c - low;
1137       HOST_WIDE_INT high
1138         = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1139       HOST_WIDE_INT extra = 0;
1140
1141       /* If HIGH will be interpreted as negative but the constant is
1142          positive, we must adjust it to do two ldha insns.  */
1143
1144       if ((high & 0x8000) != 0 && c >= 0)
1145         {
1146           extra = 0x4000;
1147           tmp1 -= 0x40000000;
1148           high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1149         }
1150
1151       if (c == low || (low == 0 && extra == 0))
1152         {
1153           /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1154              but that meant that we can't handle INT_MIN on 32-bit machines
1155              (like NT/Alpha), because we recurse indefinitely through 
1156              emit_move_insn to gen_movdi.  So instead, since we know exactly
1157              what we want, create it explicitly.  */
1158
1159           if (target == NULL)
1160             target = gen_reg_rtx (mode);
1161           emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1162           return target;
1163         }
1164       else if (n >= 2 + (extra != 0))
1165         {
1166           temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1167
1168           if (extra != 0)
1169             temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1170                                  subtarget, 0, OPTAB_WIDEN);
1171
1172           return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1173                                target, 0, OPTAB_WIDEN);
1174         }
1175     }
1176
1177   /* If we couldn't do it that way, try some other methods.  But if we have
1178      no instructions left, don't bother.  Likewise, if this is SImode and
1179      we can't make pseudos, we can't do anything since the expand_binop
1180      and expand_unop calls will widen and try to make pseudos.  */
1181
1182   if (n == 1
1183       || (mode == SImode && ! rtx_equal_function_value_matters))
1184     return 0;
1185
1186 #if HOST_BITS_PER_WIDE_INT == 64
1187   /* First, see if can load a value into the target that is the same as the
1188      constant except that all bytes that are 0 are changed to be 0xff.  If we
1189      can, then we can do a ZAPNOT to obtain the desired constant.  */
1190
1191   for (i = 0; i < 64; i += 8)
1192     if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1193       new |= (HOST_WIDE_INT) 0xff << i;
1194
1195   /* We are only called for SImode and DImode.  If this is SImode, ensure that
1196      we are sign extended to a full word.  */
1197
1198   if (mode == SImode)
1199     new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1200
1201   if (new != c
1202       && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1203     return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1204                          target, 0, OPTAB_WIDEN);
1205 #endif
1206
1207   /* Next, see if we can load a related constant and then shift and possibly
1208      negate it to get the constant we want.  Try this once each increasing
1209      numbers of insns.  */
1210
1211   for (i = 1; i < n; i++)
1212     {
1213       /* First try complementing.  */
1214       if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1215         return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1216
1217       /* Next try to form a constant and do a left shift.  We can do this
1218          if some low-order bits are zero; the exact_log2 call below tells
1219          us that information.  The bits we are shifting out could be any
1220          value, but here we'll just try the 0- and sign-extended forms of
1221          the constant.  To try to increase the chance of having the same
1222          constant in more than one insn, start at the highest number of
1223          bits to shift, but try all possibilities in case a ZAPNOT will
1224          be useful.  */
1225
1226       if ((bits = exact_log2 (c & - c)) > 0)
1227         for (; bits > 0; bits--)
1228           if ((temp = (alpha_emit_set_const
1229                        (subtarget, mode,
1230                         (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1231               || ((temp = (alpha_emit_set_const
1232                           (subtarget, mode,
1233                            ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1234                   != 0))
1235             return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1236                                  target, 0, OPTAB_WIDEN);
1237
1238       /* Now try high-order zero bits.  Here we try the shifted-in bits as
1239          all zero and all ones.  Be careful to avoid shifting outside the
1240          mode and to avoid shifting outside the host wide int size.  */
1241       /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1242          confuse the recursive call and set all of the high 32 bits.  */
1243
1244       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1245                    - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1246         for (; bits > 0; bits--)
1247           if ((temp = alpha_emit_set_const (subtarget, mode,
1248                                             c << bits, i)) != 0
1249               || ((temp = (alpha_emit_set_const
1250                            (subtarget, mode,
1251                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1252                             i)))
1253                   != 0))
1254             return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1255                                  target, 1, OPTAB_WIDEN);
1256
1257       /* Now try high-order 1 bits.  We get that with a sign-extension.
1258          But one bit isn't enough here.  Be careful to avoid shifting outside
1259          the mode and to avoid shifting outside the host wide int size. */
1260       
1261       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1262                    - floor_log2 (~ c) - 2)) > 0)
1263         for (; bits > 0; bits--)
1264           if ((temp = alpha_emit_set_const (subtarget, mode,
1265                                             c << bits, i)) != 0
1266               || ((temp = (alpha_emit_set_const
1267                            (subtarget, mode,
1268                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1269                             i)))
1270                   != 0))
1271             return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1272                                  target, 0, OPTAB_WIDEN);
1273     }
1274
1275   return 0;
1276 }
1277
1278 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1279    fall back to a straight forward decomposition.  We do this to avoid
1280    exponential run times encountered when looking for longer sequences
1281    with alpha_emit_set_const.  */
1282
1283 rtx
1284 alpha_emit_set_long_const (target, c1, c2)
1285      rtx target;
1286      HOST_WIDE_INT c1, c2;
1287 {
1288   HOST_WIDE_INT d1, d2, d3, d4;
1289
1290   /* Decompose the entire word */
1291 #if HOST_BITS_PER_WIDE_INT >= 64
1292   if (c2 != -(c1 < 0))
1293     abort ();
1294   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1295   c1 -= d1;
1296   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1297   c1 = (c1 - d2) >> 32;
1298   d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1299   c1 -= d3;
1300   d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1301   if (c1 != d4)
1302     abort ();
1303 #else
1304   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1305   c1 -= d1;
1306   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1307   if (c1 != d2)
1308     abort ();
1309   c2 += (d2 < 0);
1310   d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1311   c2 -= d3;
1312   d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1313   if (c2 != d4)
1314     abort ();
1315 #endif
1316
1317   /* Construct the high word */
1318   if (d4)
1319     {
1320       emit_move_insn (target, GEN_INT (d4));
1321       if (d3)
1322         emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1323     }
1324   else
1325     emit_move_insn (target, GEN_INT (d3));
1326
1327   /* Shift it into place */
1328   emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1329
1330   /* Add in the low bits.  */
1331   if (d2)
1332     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1333   if (d1)
1334     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1335
1336   return target;
1337 }
1338
1339 /* Generate the comparison for a conditional branch.  */
1340
1341 rtx
1342 alpha_emit_conditional_branch (code)
1343      enum rtx_code code;
1344 {
1345   enum rtx_code cmp_code, branch_code;
1346   enum machine_mode cmp_mode, branch_mode = VOIDmode;
1347   rtx op0 = alpha_compare_op0, op1 = alpha_compare_op1;
1348   rtx tem;
1349
1350   /* The general case: fold the comparison code to the types of compares
1351      that we have, choosing the branch as necessary.  */
1352   switch (code)
1353     {
1354     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1355       /* We have these compares: */
1356       cmp_code = code, branch_code = NE;
1357       break;
1358
1359     case NE:
1360       /* This must be reversed. */
1361       cmp_code = EQ, branch_code = EQ;
1362       break;
1363
1364     case GE:  case GT: case GEU:  case GTU:
1365       /* For FP, we swap them, for INT, we reverse them.  */
1366       if (alpha_compare_fp_p)
1367         {
1368           cmp_code = swap_condition (code);
1369           branch_code = NE;
1370           tem = op0, op0 = op1, op1 = tem;
1371         }
1372       else
1373         {
1374           cmp_code = reverse_condition (code);
1375           branch_code = EQ;
1376         }
1377       break;
1378
1379     default:
1380       abort ();
1381     }
1382
1383   if (alpha_compare_fp_p)
1384     {
1385       cmp_mode = DFmode;
1386       if (flag_fast_math)
1387         {
1388           /* When we are not as concerned about non-finite values, and we
1389              are comparing against zero, we can branch directly.  */
1390           if (op1 == CONST0_RTX (DFmode))
1391             cmp_code = NIL, branch_code = code;
1392           else if (op0 == CONST0_RTX (DFmode))
1393             {
1394               /* Undo the swap we probably did just above.  */
1395               tem = op0, op0 = op1, op1 = tem;
1396               branch_code = swap_condition (cmp_code);
1397               cmp_code = NIL;
1398             }
1399         }
1400       else
1401         {
1402           /* ??? We mark the the branch mode to be CCmode to prevent the
1403              compare and branch from being combined, since the compare 
1404              insn follows IEEE rules that the branch does not.  */
1405           branch_mode = CCmode;
1406         }
1407     }
1408   else
1409     {
1410       cmp_mode = DImode;
1411
1412       /* The following optimizations are only for signed compares.  */
1413       if (code != LEU && code != LTU && code != GEU && code != GTU)
1414         {
1415           /* Whee.  Compare and branch against 0 directly.  */
1416           if (op1 == const0_rtx)
1417             cmp_code = NIL, branch_code = code;
1418
1419           /* We want to use cmpcc/bcc when we can, since there is a zero delay
1420              bypass between logicals and br/cmov on EV5.  But we don't want to
1421              force valid immediate constants into registers needlessly.  */
1422           else if (GET_CODE (op1) == CONST_INT)
1423             {
1424               HOST_WIDE_INT v = INTVAL (op1), n = -v;
1425
1426               if (! CONST_OK_FOR_LETTER_P (v, 'I')
1427                   && (CONST_OK_FOR_LETTER_P (n, 'K')
1428                       || CONST_OK_FOR_LETTER_P (n, 'L')))
1429                 {
1430                   cmp_code = PLUS, branch_code = code;
1431                   op1 = GEN_INT (n);
1432                 }
1433             }
1434         }
1435     }
1436
1437   /* Force op0 into a register.  */
1438   if (GET_CODE (op0) != REG)
1439     op0 = force_reg (cmp_mode, op0);
1440
1441   /* Emit an initial compare instruction, if necessary.  */
1442   tem = op0;
1443   if (cmp_code != NIL)
1444     {
1445       tem = gen_reg_rtx (cmp_mode);
1446       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1447     }
1448
1449   /* Return the branch comparison.  */
1450   return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1451 }
1452
1453
1454 /* Rewrite a comparison against zero CMP of the form
1455    (CODE (cc0) (const_int 0)) so it can be written validly in
1456    a conditional move (if_then_else CMP ...).
1457    If both of the operands that set cc0 are non-zero we must emit
1458    an insn to perform the compare (it can't be done within
1459    the conditional move). */
1460 rtx
1461 alpha_emit_conditional_move (cmp, mode)
1462      rtx cmp;
1463      enum machine_mode mode;
1464 {
1465   enum rtx_code code = GET_CODE (cmp);
1466   enum rtx_code cmov_code = NE;
1467   rtx op0 = alpha_compare_op0;
1468   rtx op1 = alpha_compare_op1;
1469   enum machine_mode cmp_mode
1470     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1471   enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1472   enum machine_mode cmov_mode = VOIDmode;
1473   rtx tem;
1474
1475   if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1476     return 0;
1477
1478   /* We may be able to use a conditional move directly.
1479      This avoids emitting spurious compares. */
1480   if (signed_comparison_operator (cmp, cmp_op_mode)
1481       && (!alpha_compare_fp_p || flag_fast_math)
1482       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1483     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1484
1485   /* We can't put the comparison insides a conditional move;
1486      emit a compare instruction and put that inside the
1487      conditional move.  Make sure we emit only comparisons we have;
1488      swap or reverse as necessary.  */
1489
1490   switch (code)
1491     {
1492     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1493       /* We have these compares: */
1494       break;
1495
1496     case NE:
1497       /* This must be reversed. */
1498       code = reverse_condition (code);
1499       cmov_code = EQ;
1500       break;
1501
1502     case GE:  case GT:  case GEU:  case GTU:
1503       /* These must be swapped.  Make sure the new first operand is in
1504          a register.  */
1505       code = swap_condition (code);
1506       tem = op0, op0 = op1, op1 = tem;
1507       op0 = force_reg (cmp_mode, op0);
1508       break;
1509
1510     default:
1511       abort ();
1512     }
1513
1514   /* ??? We mark the branch mode to be CCmode to prevent the compare
1515      and cmov from being combined, since the compare insn follows IEEE
1516      rules that the cmov does not.  */
1517   if (alpha_compare_fp_p && !flag_fast_math)
1518     cmov_mode = CCmode;
1519
1520   tem = gen_reg_rtx (cmp_op_mode);
1521   emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1522   return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1523 }
1524 \f
1525 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1526    unaligned data:
1527
1528            unsigned:                       signed:
1529    word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
1530            ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
1531            lda    r3,X(r11)                lda    r3,X+2(r11)
1532            extwl  r1,r3,r1                 extql  r1,r3,r1
1533            extwh  r2,r3,r2                 extqh  r2,r3,r2
1534            or     r1.r2.r1                 or     r1,r2,r1
1535                                            sra    r1,48,r1
1536
1537    long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
1538            ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
1539            lda    r3,X(r11)                lda    r3,X(r11)
1540            extll  r1,r3,r1                 extll  r1,r3,r1
1541            extlh  r2,r3,r2                 extlh  r2,r3,r2
1542            or     r1.r2.r1                 addl   r1,r2,r1
1543
1544    quad:   ldq_u  r1,X(r11)
1545            ldq_u  r2,X+7(r11)
1546            lda    r3,X(r11)
1547            extql  r1,r3,r1
1548            extqh  r2,r3,r2
1549            or     r1.r2.r1
1550 */
1551
1552 void
1553 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1554      rtx tgt, mem;
1555      HOST_WIDE_INT size, ofs;
1556      int sign;
1557 {
1558   rtx meml, memh, addr, extl, exth;
1559   enum machine_mode mode;
1560
1561   meml = gen_reg_rtx (DImode);
1562   memh = gen_reg_rtx (DImode);
1563   addr = gen_reg_rtx (DImode);
1564   extl = gen_reg_rtx (DImode);
1565   exth = gen_reg_rtx (DImode);
1566
1567   emit_move_insn (meml,
1568                   change_address (mem, DImode,
1569                                   gen_rtx_AND (DImode, 
1570                                                plus_constant (XEXP (mem, 0),
1571                                                               ofs),
1572                                                GEN_INT (-8))));
1573
1574   emit_move_insn (memh,
1575                   change_address (mem, DImode,
1576                                   gen_rtx_AND (DImode, 
1577                                                plus_constant (XEXP (mem, 0),
1578                                                               ofs + size - 1),
1579                                                GEN_INT (-8))));
1580
1581   if (sign && size == 2)
1582     {
1583       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1584
1585       emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1586       emit_insn (gen_extqh (exth, memh, addr));
1587
1588       /* We must use tgt here for the target.  Alpha-vms port fails if we use
1589          addr for the target, because addr is marked as a pointer and combine
1590          knows that pointers are always sign-extended 32 bit values.  */
1591       addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1592       addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), 
1593                            addr, 1, OPTAB_WIDEN);
1594     }
1595   else
1596     {
1597       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1598       emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1599       switch (size)
1600         {
1601         case 2:
1602           emit_insn (gen_extwh (exth, memh, addr));
1603           mode = HImode;
1604           break;
1605
1606         case 4:
1607           emit_insn (gen_extlh (exth, memh, addr));
1608           mode = SImode;
1609           break;
1610
1611         case 8:
1612           emit_insn (gen_extqh (exth, memh, addr));
1613           mode = DImode;
1614           break;
1615         default:
1616           abort();
1617         }
1618
1619       addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1620                            gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1621                            sign, OPTAB_WIDEN);
1622     }
1623
1624   if (addr != tgt)
1625     emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1626 }
1627
1628 /* Similarly, use ins and msk instructions to perform unaligned stores.  */
1629
1630 void
1631 alpha_expand_unaligned_store (dst, src, size, ofs)
1632      rtx dst, src;
1633      HOST_WIDE_INT size, ofs;
1634 {
1635   rtx dstl, dsth, addr, insl, insh, meml, memh;
1636   
1637   dstl = gen_reg_rtx (DImode);
1638   dsth = gen_reg_rtx (DImode);
1639   insl = gen_reg_rtx (DImode);
1640   insh = gen_reg_rtx (DImode);
1641
1642   meml = change_address (dst, DImode,
1643                          gen_rtx_AND (DImode, 
1644                                       plus_constant (XEXP (dst, 0), ofs),
1645                                       GEN_INT (-8)));
1646   memh = change_address (dst, DImode,
1647                          gen_rtx_AND (DImode, 
1648                                       plus_constant (XEXP (dst, 0),
1649                                                      ofs+size-1),
1650                                       GEN_INT (-8)));
1651
1652   emit_move_insn (dsth, memh);
1653   emit_move_insn (dstl, meml);
1654   addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1655
1656   if (src != const0_rtx)
1657     {
1658       emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1659                             GEN_INT (size*8), addr));
1660
1661       switch (size)
1662         {
1663         case 2:
1664           emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1665           break;
1666         case 4:
1667           emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1668           break;
1669         case 8:
1670           emit_insn (gen_insql (insl, src, addr));
1671           break;
1672         }
1673     }
1674
1675   emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1676
1677   switch (size)
1678     {
1679     case 2:
1680       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1681       break;
1682     case 4:
1683       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1684       break;
1685     case 8:
1686       {
1687 #if HOST_BITS_PER_WIDE_INT == 32
1688         rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1689 #else
1690         rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1691 #endif
1692         emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1693       }
1694       break;
1695     }
1696
1697   if (src != const0_rtx)
1698     {
1699       dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1700       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1701     }
1702   
1703   /* Must store high before low for degenerate case of aligned.  */
1704   emit_move_insn (memh, dsth);
1705   emit_move_insn (meml, dstl);
1706 }
1707
1708 /* The block move code tries to maximize speed by separating loads and
1709    stores at the expense of register pressure: we load all of the data
1710    before we store it back out.  There are two secondary effects worth
1711    mentioning, that this speeds copying to/from aligned and unaligned
1712    buffers, and that it makes the code significantly easier to write.  */
1713
1714 #define MAX_MOVE_WORDS  8
1715
1716 /* Load an integral number of consecutive unaligned quadwords.  */
1717
1718 static void
1719 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1720      rtx *out_regs;
1721      rtx smem;
1722      HOST_WIDE_INT words, ofs;
1723 {
1724   rtx const im8 = GEN_INT (-8);
1725   rtx const i64 = GEN_INT (64);
1726   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1727   rtx sreg, areg;
1728   HOST_WIDE_INT i;
1729
1730   /* Generate all the tmp registers we need.  */
1731   for (i = 0; i < words; ++i)
1732     {
1733       data_regs[i] = out_regs[i];
1734       ext_tmps[i] = gen_reg_rtx (DImode);
1735     }
1736   data_regs[words] = gen_reg_rtx (DImode);
1737
1738   if (ofs != 0)
1739     smem = change_address (smem, GET_MODE (smem),
1740                            plus_constant (XEXP (smem, 0), ofs));
1741   
1742   /* Load up all of the source data.  */
1743   for (i = 0; i < words; ++i)
1744     {
1745       emit_move_insn (data_regs[i],
1746                       change_address (smem, DImode,
1747                                       gen_rtx_AND (DImode,
1748                                                    plus_constant (XEXP(smem,0),
1749                                                                   8*i),
1750                                                    im8)));
1751     }
1752   emit_move_insn (data_regs[words],
1753                   change_address (smem, DImode,
1754                                   gen_rtx_AND (DImode,
1755                                                plus_constant (XEXP(smem,0),
1756                                                               8*words - 1),
1757                                                im8)));
1758
1759   /* Extract the half-word fragments.  Unfortunately DEC decided to make
1760      extxh with offset zero a noop instead of zeroing the register, so 
1761      we must take care of that edge condition ourselves with cmov.  */
1762
1763   sreg = copy_addr_to_reg (XEXP (smem, 0));
1764   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, 
1765                        1, OPTAB_WIDEN);
1766   for (i = 0; i < words; ++i)
1767     {
1768       emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1769
1770       emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1771       emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1772                               gen_rtx_IF_THEN_ELSE (DImode,
1773                                                     gen_rtx_EQ (DImode, areg,
1774                                                                 const0_rtx),
1775                                                     const0_rtx, ext_tmps[i])));
1776     }
1777
1778   /* Merge the half-words into whole words.  */
1779   for (i = 0; i < words; ++i)
1780     {
1781       out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1782                                   ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1783     }
1784 }
1785
1786 /* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
1787    may be NULL to store zeros.  */
1788
1789 static void
1790 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1791      rtx *data_regs;
1792      rtx dmem;
1793      HOST_WIDE_INT words, ofs;
1794 {
1795   rtx const im8 = GEN_INT (-8);
1796   rtx const i64 = GEN_INT (64);
1797 #if HOST_BITS_PER_WIDE_INT == 32
1798   rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1799 #else
1800   rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1801 #endif
1802   rtx ins_tmps[MAX_MOVE_WORDS];
1803   rtx st_tmp_1, st_tmp_2, dreg;
1804   rtx st_addr_1, st_addr_2;
1805   HOST_WIDE_INT i;
1806
1807   /* Generate all the tmp registers we need.  */
1808   if (data_regs != NULL)
1809     for (i = 0; i < words; ++i)
1810       ins_tmps[i] = gen_reg_rtx(DImode);
1811   st_tmp_1 = gen_reg_rtx(DImode);
1812   st_tmp_2 = gen_reg_rtx(DImode);
1813   
1814   if (ofs != 0)
1815     dmem = change_address (dmem, GET_MODE (dmem),
1816                            plus_constant (XEXP (dmem, 0), ofs));
1817   
1818
1819   st_addr_2 = change_address (dmem, DImode,
1820                               gen_rtx_AND (DImode,
1821                                            plus_constant (XEXP(dmem,0),
1822                                                           words*8 - 1),
1823                                        im8));
1824   st_addr_1 = change_address (dmem, DImode,
1825                               gen_rtx_AND (DImode, 
1826                                            XEXP (dmem, 0),
1827                                            im8));
1828
1829   /* Load up the destination end bits.  */
1830   emit_move_insn (st_tmp_2, st_addr_2);
1831   emit_move_insn (st_tmp_1, st_addr_1);
1832
1833   /* Shift the input data into place.  */
1834   dreg = copy_addr_to_reg (XEXP (dmem, 0));
1835   if (data_regs != NULL)
1836     {
1837       for (i = words-1; i >= 0; --i)
1838         {
1839           emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1840           emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1841         }
1842       for (i = words-1; i > 0; --i)
1843         {
1844           ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1845                                         ins_tmps[i-1], ins_tmps[i-1], 1,
1846                                         OPTAB_WIDEN);
1847         }
1848     }
1849
1850   /* Split and merge the ends with the destination data.  */
1851   emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1852   emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1853
1854   if (data_regs != NULL)
1855     {
1856       st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1857                                st_tmp_2, 1, OPTAB_WIDEN);
1858       st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1859                                st_tmp_1, 1, OPTAB_WIDEN);
1860     }
1861
1862   /* Store it all.  */
1863   emit_move_insn (st_addr_2, st_tmp_2);
1864   for (i = words-1; i > 0; --i)
1865     {
1866       emit_move_insn (change_address (dmem, DImode,
1867                                       gen_rtx_AND (DImode,
1868                                                    plus_constant(XEXP (dmem,0),
1869                                                                  i*8),
1870                                                im8)),
1871                       data_regs ? ins_tmps[i-1] : const0_rtx);
1872     }
1873   emit_move_insn (st_addr_1, st_tmp_1);
1874 }
1875
1876
1877 /* Expand string/block move operations.
1878
1879    operands[0] is the pointer to the destination.
1880    operands[1] is the pointer to the source.
1881    operands[2] is the number of bytes to move.
1882    operands[3] is the alignment.  */
1883
1884 int
1885 alpha_expand_block_move (operands)
1886      rtx operands[];
1887 {
1888   rtx bytes_rtx = operands[2];
1889   rtx align_rtx = operands[3];
1890   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
1891   HOST_WIDE_INT bytes = orig_bytes;
1892   HOST_WIDE_INT src_align = INTVAL (align_rtx);
1893   HOST_WIDE_INT dst_align = src_align;
1894   rtx orig_src  = operands[1];
1895   rtx orig_dst  = operands[0];
1896   rtx data_regs[2*MAX_MOVE_WORDS+16];
1897   rtx tmp;
1898   int i, words, ofs, nregs = 0;
1899   
1900   if (bytes <= 0)
1901     return 1;
1902   if (bytes > MAX_MOVE_WORDS*8)
1903     return 0;
1904
1905   /* Look for additional alignment information from recorded register info.  */
1906
1907   tmp = XEXP (orig_src, 0);
1908   if (GET_CODE (tmp) == REG)
1909     {
1910       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1911         src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1912     }
1913   else if (GET_CODE (tmp) == PLUS
1914            && GET_CODE (XEXP (tmp, 0)) == REG
1915            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1916     {
1917       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1918       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1919
1920       if (a > src_align)
1921         {
1922           if (a >= 8 && c % 8 == 0)
1923             src_align = 8;
1924           else if (a >= 4 && c % 4 == 0)
1925             src_align = 4;
1926           else if (a >= 2 && c % 2 == 0)
1927             src_align = 2;
1928         }
1929     }
1930         
1931   tmp = XEXP (orig_dst, 0);
1932   if (GET_CODE (tmp) == REG)
1933     {
1934       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1935         dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1936     }
1937   else if (GET_CODE (tmp) == PLUS
1938            && GET_CODE (XEXP (tmp, 0)) == REG
1939            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1940     {
1941       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1942       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1943
1944       if (a > dst_align)
1945         {
1946           if (a >= 8 && c % 8 == 0)
1947             dst_align = 8;
1948           else if (a >= 4 && c % 4 == 0)
1949             dst_align = 4;
1950           else if (a >= 2 && c % 2 == 0)
1951             dst_align = 2;
1952         }
1953     }
1954
1955   /*
1956    * Load the entire block into registers.
1957    */
1958
1959   if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1960     {
1961       enum machine_mode mode;
1962       tmp = XEXP (XEXP (orig_src, 0), 0);
1963
1964       mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
1965       if (mode != BLKmode
1966           && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1967         {
1968           /* Whee!  Optimize the load to use the existing register.  */
1969           data_regs[nregs++] = gen_lowpart (mode, tmp);
1970           goto src_done;
1971         }
1972
1973       /* ??? We could potentially be copying 3 bytes or whatnot from
1974          a wider reg.  Probably not worth worrying about.  */
1975       /* No appropriate mode; fall back on memory.  */
1976       orig_src = change_address (orig_src, GET_MODE (orig_src),
1977                                  copy_addr_to_reg (XEXP (orig_src, 0)));
1978     }
1979
1980   ofs = 0;
1981   if (src_align >= 8 && bytes >= 8)
1982     {
1983       words = bytes / 8;
1984
1985       for (i = 0; i < words; ++i)
1986         data_regs[nregs+i] = gen_reg_rtx(DImode);
1987
1988       for (i = 0; i < words; ++i)
1989         {
1990           emit_move_insn (data_regs[nregs+i],
1991                           change_address(orig_src, DImode,
1992                                          plus_constant (XEXP (orig_src, 0),
1993                                                         ofs + i*8)));
1994         }
1995
1996       nregs += words;
1997       bytes -= words * 8;
1998       ofs += words * 8;
1999     }
2000   if (src_align >= 4 && bytes >= 4)
2001     {
2002       words = bytes / 4;
2003
2004       for (i = 0; i < words; ++i)
2005         data_regs[nregs+i] = gen_reg_rtx(SImode);
2006
2007       for (i = 0; i < words; ++i)
2008         {
2009           emit_move_insn (data_regs[nregs+i],
2010                           change_address(orig_src, SImode,
2011                                          plus_constant (XEXP (orig_src, 0),
2012                                                         ofs + i*4)));
2013         }
2014
2015       nregs += words;
2016       bytes -= words * 4;
2017       ofs += words * 4;
2018     }
2019   if (bytes >= 16)
2020     {
2021       words = bytes / 8;
2022
2023       for (i = 0; i < words+1; ++i)
2024         data_regs[nregs+i] = gen_reg_rtx(DImode);
2025
2026       alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
2027
2028       nregs += words;
2029       bytes -= words * 8;
2030       ofs += words * 8;
2031     }
2032   if (!TARGET_BWX && bytes >= 8)
2033     {
2034       data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2035       alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2036       bytes -= 8;
2037       ofs += 8;
2038     }
2039   if (!TARGET_BWX && bytes >= 4)
2040     {
2041       data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2042       alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2043       bytes -= 4;
2044       ofs += 4;
2045     }
2046   if (bytes >= 2)
2047     {
2048       if (src_align >= 2)
2049         {
2050           do {
2051             data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2052             emit_move_insn (tmp,
2053                             change_address (orig_src, HImode,
2054                                             plus_constant (XEXP (orig_src, 0),
2055                                                            ofs)));
2056             bytes -= 2;
2057             ofs += 2;
2058           } while (bytes >= 2);
2059         }
2060       else if (!TARGET_BWX)
2061         {
2062           data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2063           alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2064           bytes -= 2;
2065           ofs += 2;
2066         }
2067     }
2068   while (bytes > 0)
2069     {
2070       data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2071       emit_move_insn (tmp,
2072                       change_address (orig_src, QImode,
2073                                       plus_constant (XEXP (orig_src, 0),
2074                                                      ofs)));
2075       bytes -= 1;
2076       ofs += 1;
2077     }
2078  src_done:
2079
2080   if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2081     abort();
2082
2083   /*
2084    * Now save it back out again.
2085    */
2086
2087   i = 0, ofs = 0;
2088
2089   if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2090     {
2091       enum machine_mode mode;
2092       tmp = XEXP (XEXP (orig_dst, 0), 0);
2093
2094       mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2095       if (GET_MODE (tmp) == mode && nregs == 1)
2096         {
2097           emit_move_insn (tmp, data_regs[0]);
2098           i = 1;
2099           goto dst_done;
2100         }
2101
2102       /* ??? If nregs > 1, consider reconstructing the word in regs.  */
2103       /* ??? Optimize mode < dst_mode with strict_low_part.  */
2104
2105       /* No appropriate mode; fall back on memory.  We can speed things
2106          up by recognizing extra alignment information.  */
2107       orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2108                                  copy_addr_to_reg (XEXP (orig_dst, 0)));
2109       dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2110     }
2111
2112   /* Write out the data in whatever chunks reading the source allowed.  */
2113   if (dst_align >= 8)
2114     {
2115       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2116         {
2117           emit_move_insn (change_address(orig_dst, DImode,
2118                                          plus_constant (XEXP (orig_dst, 0),
2119                                                         ofs)),
2120                           data_regs[i]);
2121           ofs += 8;
2122           i++;
2123         }
2124     }
2125   if (dst_align >= 4)
2126     {
2127       /* If the source has remaining DImode regs, write them out in
2128          two pieces.  */
2129       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2130         {
2131           tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2132                               NULL_RTX, 1, OPTAB_WIDEN);
2133
2134           emit_move_insn (change_address(orig_dst, SImode,
2135                                          plus_constant (XEXP (orig_dst, 0),
2136                                                         ofs)),
2137                           gen_lowpart (SImode, data_regs[i]));
2138           emit_move_insn (change_address(orig_dst, SImode,
2139                                          plus_constant (XEXP (orig_dst, 0),
2140                                                         ofs+4)),
2141                           gen_lowpart (SImode, tmp));
2142           ofs += 8;
2143           i++;
2144         }
2145
2146       while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2147         {
2148           emit_move_insn (change_address(orig_dst, SImode,
2149                                          plus_constant (XEXP (orig_dst, 0),
2150                                                         ofs)),
2151                           data_regs[i]);
2152           ofs += 4;
2153           i++;
2154         }
2155     }
2156   if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2157     {
2158       /* Write out a remaining block of words using unaligned methods.  */
2159
2160       for (words = 1; i+words < nregs ; ++words)
2161         if (GET_MODE (data_regs[i+words]) != DImode)
2162           break;
2163
2164       if (words == 1)
2165         alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2166       else
2167         alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2168      
2169       i += words;
2170       ofs += words * 8;
2171     }
2172
2173   /* Due to the above, this won't be aligned.  */
2174   /* ??? If we have more than one of these, consider constructing full
2175      words in registers and using alpha_expand_unaligned_store_words.  */
2176   while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2177     {
2178       alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2179       ofs += 4;
2180       i++;
2181     }
2182
2183   if (dst_align >= 2)
2184     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2185       {
2186         emit_move_insn (change_address (orig_dst, HImode,
2187                                         plus_constant (XEXP (orig_dst, 0),
2188                                                        ofs)),
2189                         data_regs[i]);
2190         i++;
2191         ofs += 2;
2192       }
2193   else
2194     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2195       {
2196         alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2197         i++;
2198         ofs += 2;
2199       }
2200   while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2201     {
2202       emit_move_insn (change_address (orig_dst, QImode,
2203                                       plus_constant (XEXP (orig_dst, 0),
2204                                                      ofs)),
2205                       data_regs[i]);
2206       i++;
2207       ofs += 1;
2208     }
2209  dst_done:
2210
2211   if (i != nregs)
2212     abort();
2213
2214   return 1;
2215 }
2216
2217 int
2218 alpha_expand_block_clear (operands)
2219      rtx operands[];
2220 {
2221   rtx bytes_rtx = operands[1];
2222   rtx align_rtx = operands[2];
2223   HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2224   HOST_WIDE_INT align = INTVAL (align_rtx);
2225   rtx orig_dst  = operands[0];
2226   rtx tmp;
2227   HOST_WIDE_INT i, words, ofs = 0;
2228   
2229   if (bytes <= 0)
2230     return 1;
2231   if (bytes > MAX_MOVE_WORDS*8)
2232     return 0;
2233
2234   /* Look for stricter alignment.  */
2235
2236   tmp = XEXP (orig_dst, 0);
2237   if (GET_CODE (tmp) == REG)
2238     {
2239       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2240         align = REGNO_POINTER_ALIGN (REGNO (tmp));
2241     }
2242   else if (GET_CODE (tmp) == PLUS
2243            && GET_CODE (XEXP (tmp, 0)) == REG
2244            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2245     {
2246       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2247       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2248
2249       if (a > align)
2250         {
2251           if (a >= 8 && c % 8 == 0)
2252             align = 8;
2253           else if (a >= 4 && c % 4 == 0)
2254             align = 4;
2255           else if (a >= 2 && c % 2 == 0)
2256             align = 2;
2257         }
2258     }
2259
2260   /* Handle a block of contiguous words first.  */
2261
2262   if (align >= 8 && bytes >= 8)
2263     {
2264       words = bytes / 8;
2265
2266       for (i = 0; i < words; ++i)
2267         {
2268           emit_move_insn (change_address(orig_dst, DImode,
2269                                          plus_constant (XEXP (orig_dst, 0),
2270                                                         ofs + i*8)),
2271                           const0_rtx);
2272         }
2273
2274       bytes -= words * 8;
2275       ofs += words * 8;
2276     }
2277   if (align >= 4 && bytes >= 4)
2278     {
2279       words = bytes / 4;
2280
2281       for (i = 0; i < words; ++i)
2282         {
2283           emit_move_insn (change_address(orig_dst, SImode,
2284                                          plus_constant (XEXP (orig_dst, 0),
2285                                                         ofs + i*4)),
2286                           const0_rtx);
2287         }
2288
2289       bytes -= words * 4;
2290       ofs += words * 4;
2291     }
2292   if (bytes >= 16)
2293     {
2294       words = bytes / 8;
2295
2296       alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2297
2298       bytes -= words * 8;
2299       ofs += words * 8;
2300     }
2301
2302   /* Next clean up any trailing pieces.  We know from the contiguous
2303      block move that there are no aligned SImode or DImode hunks left.  */
2304
2305   if (!TARGET_BWX && bytes >= 8)
2306     {
2307       alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2308       bytes -= 8;
2309       ofs += 8;
2310     }
2311   if (!TARGET_BWX && bytes >= 4)
2312     {
2313       alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2314       bytes -= 4;
2315       ofs += 4;
2316     }
2317   if (bytes >= 2)
2318     {
2319       if (align >= 2)
2320         {
2321           do {
2322             emit_move_insn (change_address (orig_dst, HImode,
2323                                             plus_constant (XEXP (orig_dst, 0),
2324                                                            ofs)),
2325                             const0_rtx);
2326             bytes -= 2;
2327             ofs += 2;
2328           } while (bytes >= 2);
2329         }
2330       else if (!TARGET_BWX)
2331         {
2332           alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2333           bytes -= 2;
2334           ofs += 2;
2335         }
2336     }
2337   while (bytes > 0)
2338     {
2339       emit_move_insn (change_address (orig_dst, QImode,
2340                                       plus_constant (XEXP (orig_dst, 0),
2341                                                      ofs)),
2342                       const0_rtx);
2343       bytes -= 1;
2344       ofs += 1;
2345     }
2346
2347   return 1;
2348 }
2349
2350 \f
2351 /* Adjust the cost of a scheduling dependency.  Return the new cost of
2352    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
2353
2354 int
2355 alpha_adjust_cost (insn, link, dep_insn, cost)
2356      rtx insn;
2357      rtx link;
2358      rtx dep_insn;
2359      int cost;
2360 {
2361   rtx set, set_src;
2362   enum attr_type insn_type, dep_insn_type;
2363
2364   /* If the dependence is an anti-dependence, there is no cost.  For an
2365      output dependence, there is sometimes a cost, but it doesn't seem
2366      worth handling those few cases.  */
2367
2368   if (REG_NOTE_KIND (link) != 0)
2369     return 0;
2370
2371   /* If we can't recognize the insns, we can't really do anything.  */
2372   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2373     return cost;
2374
2375   insn_type = get_attr_type (insn);
2376   dep_insn_type = get_attr_type (dep_insn);
2377
2378   /* Bring in the user-defined memory latency.  */
2379   if (dep_insn_type == TYPE_ILD
2380       || dep_insn_type == TYPE_FLD
2381       || dep_insn_type == TYPE_LDSYM)
2382     cost += alpha_memory_latency-1;
2383
2384   switch (alpha_cpu)
2385     {
2386     case PROCESSOR_EV4:
2387       /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2388          being stored, we can sometimes lower the cost.  */
2389
2390       if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2391           && (set = single_set (dep_insn)) != 0
2392           && GET_CODE (PATTERN (insn)) == SET
2393           && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2394         {
2395           switch (dep_insn_type)
2396             {
2397             case TYPE_ILD:
2398             case TYPE_FLD:
2399               /* No savings here.  */
2400               return cost;
2401
2402             case TYPE_IMUL:
2403               /* In these cases, we save one cycle.  */
2404               return cost - 1;
2405
2406             default:
2407               /* In all other cases, we save two cycles.  */
2408               return MAX (0, cost - 2);
2409             }
2410         }
2411
2412       /* Another case that needs adjustment is an arithmetic or logical
2413          operation.  It's cost is usually one cycle, but we default it to
2414          two in the MD file.  The only case that it is actually two is
2415          for the address in loads, stores, and jumps.  */
2416
2417       if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2418         {
2419           switch (insn_type)
2420             {
2421             case TYPE_ILD:
2422             case TYPE_IST:
2423             case TYPE_FLD:
2424             case TYPE_FST:
2425             case TYPE_JSR:
2426               return cost;
2427             default:
2428               return 1;
2429             }
2430         }
2431
2432       /* The final case is when a compare feeds into an integer branch;
2433          the cost is only one cycle in that case.  */
2434
2435       if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2436         return 1;
2437       break;
2438
2439     case PROCESSOR_EV5:
2440       /* And the lord DEC saith:  "A special bypass provides an effective
2441          latency of 0 cycles for an ICMP or ILOG insn producing the test
2442          operand of an IBR or ICMOV insn." */
2443
2444       if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2445           && (set = single_set (dep_insn)) != 0)
2446         {
2447           /* A branch only has one input.  This must be it.  */
2448           if (insn_type == TYPE_IBR)
2449             return 0;
2450           /* A conditional move has three, make sure it is the test.  */
2451           if (insn_type == TYPE_ICMOV
2452               && GET_CODE (set_src = PATTERN (insn)) == SET
2453               && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2454               && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2455             return 0;
2456         }
2457
2458       /* "The multiplier is unable to receive data from IEU bypass paths.
2459          The instruction issues at the expected time, but its latency is
2460          increased by the time it takes for the input data to become
2461          available to the multiplier" -- which happens in pipeline stage
2462          six, when results are comitted to the register file.  */
2463
2464       if (insn_type == TYPE_IMUL)
2465         {
2466           switch (dep_insn_type)
2467             {
2468             /* These insns produce their results in pipeline stage five.  */
2469             case TYPE_ILD:
2470             case TYPE_ICMOV:
2471             case TYPE_IMUL:
2472             case TYPE_MVI:
2473               return cost + 1;
2474
2475             /* Other integer insns produce results in pipeline stage four.  */
2476             default:
2477               return cost + 2;
2478             }
2479         }
2480       break;
2481
2482     case PROCESSOR_EV6:
2483       /* There is additional latency to move the result of (most) FP 
2484          operations anywhere but the FP register file.  */
2485
2486       if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2487           && (dep_insn_type == TYPE_FADD ||
2488               dep_insn_type == TYPE_FMUL ||
2489               dep_insn_type == TYPE_FCMOV))
2490         return cost + 2;
2491
2492       break;
2493     }
2494
2495   /* Otherwise, return the default cost. */
2496   return cost;
2497 }
2498 \f
2499 /* Functions to save and restore alpha_return_addr_rtx.  */
2500
2501 struct machine_function
2502 {
2503   rtx ra_rtx;
2504 };
2505
2506 static void
2507 alpha_save_machine_status (p)
2508      struct function *p;
2509 {
2510   struct machine_function *machine =
2511     (struct machine_function *) xmalloc (sizeof (struct machine_function));
2512
2513   p->machine = machine;
2514   machine->ra_rtx = alpha_return_addr_rtx;
2515 }
2516
2517 static void
2518 alpha_restore_machine_status (p)
2519      struct function *p;
2520 {
2521   struct machine_function *machine = p->machine;
2522
2523   alpha_return_addr_rtx = machine->ra_rtx;
2524
2525   free (machine);
2526   p->machine = (struct machine_function *)0;
2527 }
2528
2529 /* Do anything needed before RTL is emitted for each function.  */
2530
2531 void
2532 alpha_init_expanders ()
2533 {
2534   alpha_return_addr_rtx = NULL_RTX;
2535   alpha_eh_epilogue_sp_ofs = NULL_RTX;
2536
2537   /* Arrange to save and restore machine status around nested functions.  */
2538   save_machine_status = alpha_save_machine_status;
2539   restore_machine_status = alpha_restore_machine_status;
2540 }
2541
2542 /* Start the ball rolling with RETURN_ADDR_RTX.  */
2543
2544 rtx
2545 alpha_return_addr (count, frame)
2546      int count;
2547      rtx frame ATTRIBUTE_UNUSED;
2548 {
2549   rtx init;
2550
2551   if (count != 0)
2552     return const0_rtx;
2553
2554   if (alpha_return_addr_rtx)
2555     return alpha_return_addr_rtx;
2556
2557   /* No rtx yet.  Invent one, and initialize it from $26 in the prologue.  */
2558   alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2559   init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx,
2560                       gen_rtx_REG (Pmode, REG_RA));
2561
2562   /* Emit the insn to the prologue with the other argument copies.  */
2563   push_topmost_sequence ();
2564   emit_insn_after (init, get_insns ());
2565   pop_topmost_sequence ();
2566
2567   return alpha_return_addr_rtx;
2568 }
2569
2570 static int
2571 alpha_ra_ever_killed ()
2572 {
2573   rtx top;
2574
2575 #ifdef ASM_OUTPUT_MI_THUNK
2576   if (current_function_is_thunk)
2577     return 0;
2578 #endif
2579   if (!alpha_return_addr_rtx)
2580     return regs_ever_live[REG_RA];
2581
2582   push_topmost_sequence ();
2583   top = get_insns ();
2584   pop_topmost_sequence ();
2585
2586   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
2587 }
2588
2589 \f
2590 /* Print an operand.  Recognize special options, documented below.  */
2591
2592 void
2593 print_operand (file, x, code)
2594     FILE *file;
2595     rtx x;
2596     char code;
2597 {
2598   int i;
2599
2600   switch (code)
2601     {
2602     case '&':
2603       /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2604          chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2605          mode.  alpha_fprm controls which suffix is generated.  */
2606       switch (alpha_fprm)
2607         {
2608         case ALPHA_FPRM_NORM:
2609           break;
2610         case ALPHA_FPRM_MINF: 
2611           fputc ('m', file);
2612           break;
2613         case ALPHA_FPRM_CHOP:
2614           fputc ('c', file);
2615           break;
2616         case ALPHA_FPRM_DYN:
2617           fputc ('d', file);
2618           break;
2619         }
2620       break;
2621
2622     case '\'':
2623       /* Generates trap-mode suffix for instructions that accept the su
2624          suffix only (cmpt et al).  */
2625       if (alpha_tp == ALPHA_TP_INSN)
2626         fputs ("su", file);
2627       break;
2628
2629     case '`':
2630       /* Generates trap-mode suffix for instructions that accept the
2631          v and sv suffix.  The only instruction that needs this is cvtql.  */
2632       switch (alpha_fptm)
2633         {
2634         case ALPHA_FPTM_N:
2635           break;
2636         case ALPHA_FPTM_U:
2637           fputs ("v", file);
2638           break;
2639         case ALPHA_FPTM_SU:
2640         case ALPHA_FPTM_SUI:
2641           fputs ("sv", file);
2642           break;
2643         }
2644       break;
2645
2646     case '(':
2647       /* Generates trap-mode suffix for instructions that accept the
2648          v, sv, and svi suffix.  The only instruction that needs this
2649          is cvttq.  */
2650       switch (alpha_fptm)
2651         {
2652         case ALPHA_FPTM_N:
2653           break;
2654         case ALPHA_FPTM_U:
2655           fputs ("v", file);
2656           break;
2657         case ALPHA_FPTM_SU:
2658           fputs ("sv", file);
2659           break;
2660         case ALPHA_FPTM_SUI:
2661           fputs ("svi", file);
2662           break;
2663         }
2664       break;
2665
2666     case ')':
2667       /* Generates trap-mode suffix for instructions that accept the u, su,
2668          and sui suffix.  This is the bulk of the IEEE floating point
2669          instructions (addt et al).  */
2670       switch (alpha_fptm)
2671         {
2672         case ALPHA_FPTM_N:
2673           break;
2674         case ALPHA_FPTM_U:
2675           fputc ('u', file);
2676           break;
2677         case ALPHA_FPTM_SU:
2678           fputs ("su", file);
2679           break;
2680         case ALPHA_FPTM_SUI:
2681           fputs ("sui", file);
2682           break;
2683         }
2684       break;
2685
2686     case '+':
2687       /* Generates trap-mode suffix for instructions that accept the sui
2688          suffix (cvtqt and cvtqs).  */
2689       switch (alpha_fptm)
2690         {
2691         case ALPHA_FPTM_N:
2692         case ALPHA_FPTM_U:
2693         case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
2694           break;
2695         case ALPHA_FPTM_SUI:
2696           fputs ("sui", file);
2697           break;
2698         }
2699       break;
2700
2701     case ',':
2702       /* Generates single precision instruction suffix.  */
2703       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2704       break;
2705
2706     case '-':
2707       /* Generates double precision instruction suffix.  */
2708       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2709       break;
2710
2711     case 'r':
2712       /* If this operand is the constant zero, write it as "$31".  */
2713       if (GET_CODE (x) == REG)
2714         fprintf (file, "%s", reg_names[REGNO (x)]);
2715       else if (x == CONST0_RTX (GET_MODE (x)))
2716         fprintf (file, "$31");
2717       else
2718         output_operand_lossage ("invalid %%r value");
2719
2720       break;
2721
2722     case 'R':
2723       /* Similar, but for floating-point.  */
2724       if (GET_CODE (x) == REG)
2725         fprintf (file, "%s", reg_names[REGNO (x)]);
2726       else if (x == CONST0_RTX (GET_MODE (x)))
2727         fprintf (file, "$f31");
2728       else
2729         output_operand_lossage ("invalid %%R value");
2730
2731       break;
2732
2733     case 'N':
2734       /* Write the 1's complement of a constant.  */
2735       if (GET_CODE (x) != CONST_INT)
2736         output_operand_lossage ("invalid %%N value");
2737
2738       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2739       break;
2740
2741     case 'P':
2742       /* Write 1 << C, for a constant C.  */
2743       if (GET_CODE (x) != CONST_INT)
2744         output_operand_lossage ("invalid %%P value");
2745
2746       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2747       break;
2748
2749     case 'h':
2750       /* Write the high-order 16 bits of a constant, sign-extended.  */
2751       if (GET_CODE (x) != CONST_INT)
2752         output_operand_lossage ("invalid %%h value");
2753
2754       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2755       break;
2756
2757     case 'L':
2758       /* Write the low-order 16 bits of a constant, sign-extended.  */
2759       if (GET_CODE (x) != CONST_INT)
2760         output_operand_lossage ("invalid %%L value");
2761
2762       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2763                (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2764       break;
2765
2766     case 'm':
2767       /* Write mask for ZAP insn.  */
2768       if (GET_CODE (x) == CONST_DOUBLE)
2769         {
2770           HOST_WIDE_INT mask = 0;
2771           HOST_WIDE_INT value;
2772
2773           value = CONST_DOUBLE_LOW (x);
2774           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2775                i++, value >>= 8)
2776             if (value & 0xff)
2777               mask |= (1 << i);
2778
2779           value = CONST_DOUBLE_HIGH (x);
2780           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2781                i++, value >>= 8)
2782             if (value & 0xff)
2783               mask |= (1 << (i + sizeof (int)));
2784
2785           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2786         }
2787
2788       else if (GET_CODE (x) == CONST_INT)
2789         {
2790           HOST_WIDE_INT mask = 0, value = INTVAL (x);
2791
2792           for (i = 0; i < 8; i++, value >>= 8)
2793             if (value & 0xff)
2794               mask |= (1 << i);
2795
2796           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2797         }
2798       else
2799         output_operand_lossage ("invalid %%m value");
2800       break;
2801
2802     case 'M':
2803       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
2804       if (GET_CODE (x) != CONST_INT
2805           || (INTVAL (x) != 8 && INTVAL (x) != 16
2806               && INTVAL (x) != 32 && INTVAL (x) != 64))
2807         output_operand_lossage ("invalid %%M value");
2808
2809       fprintf (file, "%s",
2810                (INTVAL (x) == 8 ? "b"
2811                 : INTVAL (x) == 16 ? "w"
2812                 : INTVAL (x) == 32 ? "l"
2813                 : "q"));
2814       break;
2815
2816     case 'U':
2817       /* Similar, except do it from the mask.  */
2818       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2819         fprintf (file, "b");
2820       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2821         fprintf (file, "w");
2822       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2823         fprintf (file, "l");
2824 #if HOST_BITS_PER_WIDE_INT == 32
2825       else if (GET_CODE (x) == CONST_DOUBLE
2826                && CONST_DOUBLE_HIGH (x) == 0
2827                && CONST_DOUBLE_LOW (x) == -1)
2828         fprintf (file, "l");
2829       else if (GET_CODE (x) == CONST_DOUBLE
2830                && CONST_DOUBLE_HIGH (x) == -1
2831                && CONST_DOUBLE_LOW (x) == -1)
2832         fprintf (file, "q");
2833 #else
2834       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
2835         fprintf (file, "q");
2836       else if (GET_CODE (x) == CONST_DOUBLE
2837                && CONST_DOUBLE_HIGH (x) == 0
2838                && CONST_DOUBLE_LOW (x) == -1)
2839         fprintf (file, "q");
2840 #endif
2841       else
2842         output_operand_lossage ("invalid %%U value");
2843       break;
2844
2845     case 's':
2846       /* Write the constant value divided by 8.  */
2847       if (GET_CODE (x) != CONST_INT
2848           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2849           && (INTVAL (x) & 7) != 8)
2850         output_operand_lossage ("invalid %%s value");
2851
2852       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2853       break;
2854
2855     case 'S':
2856       /* Same, except compute (64 - c) / 8 */
2857
2858       if (GET_CODE (x) != CONST_INT
2859           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2860           && (INTVAL (x) & 7) != 8)
2861         output_operand_lossage ("invalid %%s value");
2862
2863       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2864       break;
2865
2866     case 'C': case 'D': case 'c': case 'd':
2867       /* Write out comparison name.  */
2868       {
2869         enum rtx_code c = GET_CODE (x);
2870
2871         if (GET_RTX_CLASS (c) != '<')
2872           output_operand_lossage ("invalid %%C value");
2873
2874         if (code == 'D')
2875           c = reverse_condition (c);
2876         else if (code == 'c')
2877           c = swap_condition (c);
2878         else if (code == 'd')
2879           c = swap_condition (reverse_condition (c));
2880
2881         if (c == LEU)
2882           fprintf (file, "ule");
2883         else if (c == LTU)
2884           fprintf (file, "ult");
2885         else
2886           fprintf (file, "%s", GET_RTX_NAME (c));
2887       }
2888       break;
2889
2890     case 'E':
2891       /* Write the divide or modulus operator.  */
2892       switch (GET_CODE (x))
2893         {
2894         case DIV:
2895           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2896           break;
2897         case UDIV:
2898           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2899           break;
2900         case MOD:
2901           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2902           break;
2903         case UMOD:
2904           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2905           break;
2906         default:
2907           output_operand_lossage ("invalid %%E value");
2908           break;
2909         }
2910       break;
2911
2912     case 'A':
2913       /* Write "_u" for unaligned access.  */
2914       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2915         fprintf (file, "_u");
2916       break;
2917
2918     case 0:
2919       if (GET_CODE (x) == REG)
2920         fprintf (file, "%s", reg_names[REGNO (x)]);
2921       else if (GET_CODE (x) == MEM)
2922         output_address (XEXP (x, 0));
2923       else
2924         output_addr_const (file, x);
2925       break;
2926
2927     default:
2928       output_operand_lossage ("invalid %%xn code");
2929     }
2930 }
2931
2932 void
2933 print_operand_address (file, addr)
2934     FILE *file;
2935      rtx addr;
2936 {
2937   int basereg = 31;
2938   HOST_WIDE_INT offset = 0;
2939
2940   if (GET_CODE (addr) == AND)
2941     addr = XEXP (addr, 0);
2942
2943   if (GET_CODE (addr) == PLUS
2944       && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2945     {
2946       offset = INTVAL (XEXP (addr, 1));
2947       addr = XEXP (addr, 0);
2948     }
2949   if (GET_CODE (addr) == REG)
2950     basereg = REGNO (addr);
2951   else if (GET_CODE (addr) == SUBREG
2952            && GET_CODE (SUBREG_REG (addr)) == REG)
2953     basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
2954   else if (GET_CODE (addr) == CONST_INT)
2955     offset = INTVAL (addr);
2956   else
2957     abort ();
2958
2959   fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
2960   fprintf (file, "($%d)", basereg);
2961 }
2962 \f
2963 /* Emit RTL insns to initialize the variable parts of a trampoline at
2964    TRAMP. FNADDR is an RTX for the address of the function's pure
2965    code.  CXT is an RTX for the static chain value for the function.
2966
2967    The three offset parameters are for the individual template's
2968    layout.  A JMPOFS < 0 indicates that the trampoline does not 
2969    contain instructions at all.
2970
2971    We assume here that a function will be called many more times than
2972    its address is taken (e.g., it might be passed to qsort), so we
2973    take the trouble to initialize the "hint" field in the JMP insn.
2974    Note that the hint field is PC (new) + 4 * bits 13:0.  */
2975
2976 void
2977 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
2978      rtx tramp, fnaddr, cxt;
2979      int fnofs, cxtofs, jmpofs;
2980 {
2981   rtx temp, temp1, addr;
2982   /* VMS really uses DImode pointers in memory at this point.  */
2983   enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
2984
2985 #ifdef POINTERS_EXTEND_UNSIGNED
2986   fnaddr = convert_memory_address (mode, fnaddr);
2987   cxt = convert_memory_address (mode, cxt);
2988 #endif
2989
2990   /* Store function address and CXT.  */
2991   addr = memory_address (mode, plus_constant (tramp, fnofs));
2992   emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr);
2993   addr = memory_address (mode, plus_constant (tramp, cxtofs));
2994   emit_move_insn (gen_rtx (MEM, mode, addr), cxt);
2995
2996   /* This has been disabled since the hint only has a 32k range, and in
2997      no existing OS is the stack within 32k of the text segment. */
2998   if (0 && jmpofs >= 0)
2999     {
3000       /* Compute hint value.  */
3001       temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3002       temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3003                            OPTAB_WIDEN);
3004       temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3005                            build_int_2 (2, 0), NULL_RTX, 1);
3006       temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3007
3008       /* Merge in the hint.  */
3009       addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3010       temp1 = force_reg (SImode, gen_rtx (MEM, SImode, addr));
3011       temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3012       temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3013                             OPTAB_WIDEN);
3014       emit_move_insn (gen_rtx (MEM, SImode, addr), temp1);
3015     }
3016
3017 #ifdef TRANSFER_FROM_TRAMPOLINE
3018   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
3019                      0, VOIDmode, 1, addr, Pmode);
3020 #endif
3021
3022   if (jmpofs >= 0)
3023     emit_insn (gen_imb ());
3024 }
3025 \f
3026 /* Do what is necessary for `va_start'.  The argument is ignored;
3027    We look at the current function to determine if stdarg or varargs
3028    is used and fill in an initial va_list.  A pointer to this constructor
3029    is returned.  */
3030
3031 struct rtx_def *
3032 alpha_builtin_saveregs (arglist)
3033      tree arglist ATTRIBUTE_UNUSED;
3034 {
3035   rtx block, addr, dest, argsize;
3036   tree fntype = TREE_TYPE (current_function_decl);
3037   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
3038                 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3039                     != void_type_node));
3040
3041   /* Compute the current position into the args, taking into account
3042      both registers and memory.  Both of these are already included in
3043      NUM_ARGS.  */
3044
3045   argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
3046
3047   /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
3048      storing fp arg registers in the first 48 bytes, and the integer arg
3049      registers in the next 48 bytes.  This is only done, however, if any
3050      integer registers need to be stored.
3051
3052      If no integer registers need be stored, then we must subtract 48 in
3053      order to account for the integer arg registers which are counted in
3054      argsize above, but which are not actually stored on the stack.  */
3055
3056   if (TARGET_OPEN_VMS)
3057     addr = plus_constant (virtual_incoming_args_rtx,
3058                           NUM_ARGS <= 5 + stdarg
3059                           ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
3060   else
3061     addr = (NUM_ARGS <= 5 + stdarg
3062             ? plus_constant (virtual_incoming_args_rtx,
3063                              6 * UNITS_PER_WORD)
3064             : plus_constant (virtual_incoming_args_rtx,
3065                              - (6 * UNITS_PER_WORD)));
3066
3067   /* For VMS, we include the argsize, while on Unix, it's handled as
3068      a separate field.  */
3069   if (TARGET_OPEN_VMS)
3070     addr = plus_constant (addr, INTVAL (argsize));
3071
3072   addr = force_operand (addr, NULL_RTX);
3073
3074 #ifdef POINTERS_EXTEND_UNSIGNED
3075   addr = convert_memory_address (ptr_mode, addr);
3076 #endif
3077
3078   if (TARGET_OPEN_VMS)
3079     return addr;
3080   else
3081     {
3082       /* Allocate the va_list constructor */
3083       block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
3084       RTX_UNCHANGING_P (block) = 1;
3085       RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
3086
3087       /* Store the address of the first integer register in the __base
3088          member.  */
3089
3090       dest = change_address (block, ptr_mode, XEXP (block, 0));
3091       emit_move_insn (dest, addr);
3092
3093       if (current_function_check_memory_usage)
3094         emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3095                            dest, ptr_mode,
3096                            GEN_INT (GET_MODE_SIZE (ptr_mode)),
3097                            TYPE_MODE (sizetype),
3098                            GEN_INT (MEMORY_USE_RW), 
3099                            TYPE_MODE (integer_type_node));
3100   
3101       /* Store the argsize as the __va_offset member.  */
3102       dest = change_address (block, TYPE_MODE (integer_type_node),
3103                              plus_constant (XEXP (block, 0),
3104                                             POINTER_SIZE/BITS_PER_UNIT));
3105       emit_move_insn (dest, argsize);
3106
3107       if (current_function_check_memory_usage)
3108         emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
3109                            dest, ptr_mode,
3110                            GEN_INT (GET_MODE_SIZE
3111                                     (TYPE_MODE (integer_type_node))),
3112                            TYPE_MODE (sizetype),
3113                            GEN_INT (MEMORY_USE_RW),
3114                            TYPE_MODE (integer_type_node));
3115
3116       /* Return the address of the va_list constructor, but don't put it in a
3117          register.  Doing so would fail when not optimizing and produce worse
3118          code when optimizing.  */
3119       return XEXP (block, 0);
3120     }
3121 }
3122 \f
3123 /* This page contains routines that are used to determine what the function
3124    prologue and epilogue code will do and write them out.  */
3125
3126 /* Compute the size of the save area in the stack.  */
3127
3128 /* These variables are used for communication between the following functions.
3129    They indicate various things about the current function being compiled
3130    that are used to tell what kind of prologue, epilogue and procedure
3131    descriptior to generate. */
3132
3133 /* Nonzero if we need a stack procedure.  */
3134 static int vms_is_stack_procedure;
3135
3136 /* Register number (either FP or SP) that is used to unwind the frame.  */
3137 static int vms_unwind_regno;
3138
3139 /* Register number used to save FP.  We need not have one for RA since
3140    we don't modify it for register procedures.  This is only defined
3141    for register frame procedures.  */
3142 static int vms_save_fp_regno;
3143
3144 /* Register number used to reference objects off our PV.  */
3145 static int vms_base_regno;
3146
3147 /* Compute register masks for saved registers.  */
3148
3149 static void
3150 alpha_sa_mask (imaskP, fmaskP)
3151     unsigned long *imaskP;
3152     unsigned long *fmaskP;
3153 {
3154   unsigned long imask = 0;
3155   unsigned long fmask = 0;
3156   int i;
3157
3158 #ifdef ASM_OUTPUT_MI_THUNK
3159   if (!current_function_is_thunk)
3160 #endif
3161     {
3162       if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3163         imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3164
3165       /* One for every register we have to save.  */
3166       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3167         if (! fixed_regs[i] && ! call_used_regs[i]
3168             && regs_ever_live[i] && i != REG_RA)
3169           {
3170             if (i < 32)
3171               imask |= (1L << i);
3172             else
3173               fmask |= (1L << (i - 32));
3174           }
3175
3176       if (imask || fmask || alpha_ra_ever_killed ())
3177         imask |= (1L << REG_RA);
3178     }
3179
3180   *imaskP = imask;
3181   *fmaskP = fmask;
3182 }
3183
3184 int
3185 alpha_sa_size ()
3186 {
3187   int sa_size = 0;
3188   int i;
3189
3190 #ifdef ASM_OUTPUT_MI_THUNK
3191   if (current_function_is_thunk)
3192     sa_size = 0;
3193   else
3194 #endif
3195     {
3196       /* One for every register we have to save.  */
3197       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3198         if (! fixed_regs[i] && ! call_used_regs[i]
3199             && regs_ever_live[i] && i != REG_RA)
3200           sa_size++;
3201     }
3202
3203   if (TARGET_OPEN_VMS)
3204     {
3205       /* Start by assuming we can use a register procedure if we don't
3206          make any calls (REG_RA not used) or need to save any
3207          registers and a stack procedure if we do.  */
3208       vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3209
3210       /* Decide whether to refer to objects off our PV via FP or PV.
3211          If we need FP for something else or if we receive a nonlocal
3212          goto (which expects PV to contain the value), we must use PV.
3213          Otherwise, start by assuming we can use FP.  */
3214       vms_base_regno = (frame_pointer_needed
3215                         || current_function_has_nonlocal_label
3216                         || vms_is_stack_procedure
3217                         || current_function_outgoing_args_size
3218                         ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3219
3220       /* If we want to copy PV into FP, we need to find some register
3221          in which to save FP.  */
3222
3223       vms_save_fp_regno = -1;
3224       if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3225         for (i = 0; i < 32; i++)
3226           if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3227             vms_save_fp_regno = i;
3228
3229       if (vms_save_fp_regno == -1)
3230         vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3231
3232       /* Stack unwinding should be done via FP unless we use it for PV.  */
3233       vms_unwind_regno = (vms_base_regno == REG_PV
3234                           ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3235
3236       /* If this is a stack procedure, allow space for saving FP and RA.  */
3237       if (vms_is_stack_procedure)
3238         sa_size += 2;
3239     }
3240   else
3241     {
3242       /* If some registers were saved but not RA, RA must also be saved,
3243          so leave space for it.  */
3244       if (sa_size != 0 || alpha_ra_ever_killed ())
3245         sa_size++;
3246
3247       /* Our size must be even (multiple of 16 bytes).  */
3248       if (sa_size & 1)
3249         sa_size++;
3250     }
3251
3252   return sa_size * 8;
3253 }
3254
3255 int
3256 alpha_pv_save_size ()
3257 {
3258   alpha_sa_size ();
3259   return vms_is_stack_procedure ? 8 : 0;
3260 }
3261
3262 int
3263 alpha_using_fp ()
3264 {
3265   alpha_sa_size ();
3266   return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3267 }
3268
3269 int
3270 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3271      tree decl ATTRIBUTE_UNUSED;
3272      tree attributes ATTRIBUTE_UNUSED;
3273      tree identifier;
3274      tree args;
3275 {
3276   if (is_attribute_p ("overlaid", identifier))
3277     return (args == NULL_TREE);
3278   return 0;
3279 }
3280
3281 static int
3282 alpha_does_function_need_gp ()
3283 {
3284   rtx insn;
3285
3286   /* We never need a GP for Windows/NT or VMS.  */
3287   if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3288     return 0;
3289
3290 #ifdef TARGET_PROFILING_NEEDS_GP
3291   if (profile_flag)
3292     return 1;
3293 #endif
3294
3295 #ifdef ASM_OUTPUT_MI_THUNK
3296   if (current_function_is_thunk)
3297     return 1;
3298 #endif
3299
3300   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
3301      Even if we are a static function, we still need to do this in case
3302      our address is taken and passed to something like qsort.  */
3303
3304   push_topmost_sequence ();
3305   insn = get_insns ();
3306   pop_topmost_sequence ();
3307
3308   for (; insn; insn = NEXT_INSN (insn))
3309     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3310         && GET_CODE (PATTERN (insn)) != USE
3311         && GET_CODE (PATTERN (insn)) != CLOBBER)
3312       {
3313         enum attr_type type = get_attr_type (insn);
3314         if (type == TYPE_LDSYM || type == TYPE_JSR)
3315           return 1;
3316       }
3317
3318   return 0;
3319 }
3320
3321 /* Write a version stamp.  Don't write anything if we are running as a
3322    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
3323
3324 #ifdef HAVE_STAMP_H
3325 #include <stamp.h>
3326 #endif
3327
3328 void
3329 alpha_write_verstamp (file)
3330      FILE *file ATTRIBUTE_UNUSED;
3331 {
3332 #ifdef MS_STAMP
3333   fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3334 #endif
3335 }
3336 \f
3337 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
3338    sequences.  */
3339
3340 static rtx
3341 set_frame_related_p ()
3342 {
3343   rtx seq = gen_sequence ();
3344   end_sequence ();
3345
3346   if (GET_CODE (seq) == SEQUENCE)
3347     {
3348       int i = XVECLEN (seq, 0);
3349       while (--i >= 0)
3350         RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
3351      return emit_insn (seq);
3352     }
3353   else
3354     {
3355       seq = emit_insn (seq);
3356       RTX_FRAME_RELATED_P (seq) = 1;
3357       return seq;
3358     }
3359 }
3360
3361 #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
3362
3363 /* Write function prologue.  */
3364
3365 /* On vms we have two kinds of functions:
3366
3367    - stack frame (PROC_STACK)
3368         these are 'normal' functions with local vars and which are
3369         calling other functions
3370    - register frame (PROC_REGISTER)
3371         keeps all data in registers, needs no stack
3372
3373    We must pass this to the assembler so it can generate the
3374    proper pdsc (procedure descriptor)
3375    This is done with the '.pdesc' command.
3376
3377    On not-vms, we don't really differentiate between the two, as we can
3378    simply allocate stack without saving registers.  */
3379
3380 void
3381 alpha_expand_prologue ()
3382 {
3383   /* Registers to save.  */
3384   unsigned long imask = 0;
3385   unsigned long fmask = 0;
3386   /* Stack space needed for pushing registers clobbered by us.  */
3387   HOST_WIDE_INT sa_size;
3388   /* Complete stack size needed.  */
3389   HOST_WIDE_INT frame_size;
3390   /* Offset from base reg to register save area.  */
3391   HOST_WIDE_INT reg_offset;
3392   rtx sa_reg, mem;
3393   int i;
3394
3395   sa_size = alpha_sa_size ();
3396
3397   frame_size = get_frame_size ();
3398   if (TARGET_OPEN_VMS)
3399     frame_size = ALPHA_ROUND (sa_size 
3400                               + (vms_is_stack_procedure ? 8 : 0)
3401                               + frame_size
3402                               + current_function_pretend_args_size);
3403   else
3404     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3405                   + sa_size
3406                   + ALPHA_ROUND (frame_size
3407                                  + current_function_pretend_args_size));
3408
3409   if (TARGET_OPEN_VMS)
3410     reg_offset = 8;
3411   else
3412     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3413
3414   alpha_sa_mask (&imask, &fmask);
3415
3416   /* Adjust the stack by the frame size.  If the frame size is > 4096
3417      bytes, we need to be sure we probe somewhere in the first and last
3418      4096 bytes (we can probably get away without the latter test) and
3419      every 8192 bytes in between.  If the frame size is > 32768, we
3420      do this in a loop.  Otherwise, we generate the explicit probe
3421      instructions. 
3422
3423      Note that we are only allowed to adjust sp once in the prologue.  */
3424
3425   if (frame_size <= 32768)
3426     {
3427       if (frame_size > 4096)
3428         {
3429           int probed = 4096;
3430
3431           do
3432             emit_insn (gen_probe_stack (GEN_INT (-probed)));
3433           while ((probed += 8192) < frame_size);
3434
3435           /* We only have to do this probe if we aren't saving registers.  */
3436           if (sa_size == 0 && probed + 4096 < frame_size)
3437             emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
3438         }
3439
3440       if (frame_size != 0)
3441         {
3442           FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
3443                                       GEN_INT (-frame_size))));
3444         }
3445     }
3446   else
3447     {
3448       /* Here we generate code to set R22 to SP + 4096 and set R23 to the
3449          number of 8192 byte blocks to probe.  We then probe each block
3450          in the loop and then set SP to the proper location.  If the
3451          amount remaining is > 4096, we have to do one more probe if we
3452          are not saving any registers.  */
3453
3454       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3455       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3456       rtx ptr = gen_rtx_REG (DImode, 22);
3457       rtx count = gen_rtx_REG (DImode, 23);
3458       rtx seq;
3459
3460       emit_move_insn (count, GEN_INT (blocks));
3461       emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
3462
3463       /* Because of the difficulty in emitting a new basic block this
3464          late in the compilation, generate the loop as a single insn.  */
3465       emit_insn (gen_prologue_stack_probe_loop (count, ptr));
3466
3467       if (leftover > 4096 && sa_size == 0)
3468         {
3469           rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
3470           MEM_VOLATILE_P (last) = 1;
3471           emit_move_insn (last, const0_rtx);
3472         }
3473
3474       if (TARGET_WINDOWS_NT)
3475         {
3476           /* For NT stack unwind (done by 'reverse execution'), it's
3477              not OK to take the result of a loop, even though the value
3478              is already in ptr, so we reload it via a single operation
3479              and subtract it to sp. 
3480
3481              Yes, that's correct -- we have to reload the whole constant
3482              into a temporary via ldah+lda then subtract from sp.  To
3483              ensure we get ldah+lda, we use a special pattern.  */
3484
3485           HOST_WIDE_INT lo, hi;
3486           lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3487           hi = frame_size - lo;
3488
3489           emit_move_insn (ptr, GEN_INT (hi));
3490           emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
3491           seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3492                                        ptr));
3493         }
3494       else
3495         {
3496           seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
3497                                        GEN_INT (-leftover)));
3498         }
3499
3500       /* This alternative is special, because the DWARF code cannot
3501          possibly intuit through the loop above.  So we invent this
3502          note it looks at instead.  */
3503       RTX_FRAME_RELATED_P (seq) = 1;
3504       REG_NOTES (seq)
3505         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3506                              gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3507                                gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3508                                              GEN_INT (-frame_size))),
3509                              REG_NOTES (seq));
3510     }
3511
3512   /* Cope with very large offsets to the register save area.  */
3513   sa_reg = stack_pointer_rtx;
3514   if (reg_offset + sa_size > 0x8000)
3515     {
3516       int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3517       HOST_WIDE_INT bias;
3518
3519       if (low + sa_size <= 0x8000)
3520         bias = reg_offset - low, reg_offset = low;
3521       else 
3522         bias = reg_offset, reg_offset = 0;
3523
3524       sa_reg = gen_rtx_REG (DImode, 24);
3525       FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
3526     }
3527     
3528   /* Save regs in stack order.  Beginning with VMS PV.  */
3529   if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3530     {
3531       mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
3532       MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3533       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
3534     }
3535
3536   /* Save register RA next.  */
3537   if (imask & (1L << REG_RA))
3538     {
3539       mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3540       MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3541       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
3542       imask &= ~(1L << REG_RA);
3543       reg_offset += 8;
3544     }
3545
3546   /* Now save any other registers required to be saved.  */
3547   for (i = 0; i < 32; i++)
3548     if (imask & (1L << i))
3549       {
3550         mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
3551         MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3552         FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
3553         reg_offset += 8;
3554       }
3555
3556   for (i = 0; i < 32; i++)
3557     if (fmask & (1L << i))
3558       {
3559         mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
3560         MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3561         FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
3562         reg_offset += 8;
3563       }
3564
3565   if (TARGET_OPEN_VMS)
3566     {
3567       if (!vms_is_stack_procedure)
3568         {
3569           /* Register frame procedures fave the fp.  */
3570           FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
3571                                hard_frame_pointer_rtx));
3572         }
3573
3574       if (vms_base_regno != REG_PV)
3575         FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
3576                              gen_rtx_REG (DImode, REG_PV)));
3577
3578       if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3579         {
3580           FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3581         }
3582
3583       /* If we have to allocate space for outgoing args, do it now.  */
3584       if (current_function_outgoing_args_size != 0)
3585         {
3586           FRP (emit_move_insn (stack_pointer_rtx, 
3587                 plus_constant (hard_frame_pointer_rtx,
3588                  - ALPHA_ROUND (current_function_outgoing_args_size))));
3589         }
3590     }
3591   else
3592     {
3593       /* If we need a frame pointer, set it from the stack pointer.  */
3594       if (frame_pointer_needed)
3595         {
3596           if (TARGET_CAN_FAULT_IN_PROLOGUE)
3597             FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
3598           else
3599             {
3600               /* This must always be the last instruction in the
3601                  prologue, thus we emit a special move + clobber.  */
3602               FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
3603                                            stack_pointer_rtx, sa_reg)));
3604             }
3605         }
3606     }
3607
3608   /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
3609      the prologue, for exception handling reasons, we cannot do this for
3610      any insn that might fault.  We could prevent this for mems with a
3611      (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
3612      have to prevent all such scheduling with a blockage.
3613
3614      Linux, on the other hand, never bothered to implement OSF/1's 
3615      exception handling, and so doesn't care about such things.  Anyone
3616      planning to use dwarf2 frame-unwind info can also omit the blockage.  */
3617
3618   if (! TARGET_CAN_FAULT_IN_PROLOGUE)
3619     emit_insn (gen_blockage ());
3620 }
3621
3622 /* Output the textual info surrounding the prologue.  */
3623
3624 void
3625 alpha_start_function (file, fnname, decl)
3626      FILE *file;
3627      char *fnname;
3628      tree decl ATTRIBUTE_UNUSED;
3629 {
3630   unsigned long imask = 0;
3631   unsigned long fmask = 0;
3632   /* Stack space needed for pushing registers clobbered by us.  */
3633   HOST_WIDE_INT sa_size;
3634   /* Complete stack size needed.  */
3635   HOST_WIDE_INT frame_size;
3636   /* Offset from base reg to register save area.  */
3637   HOST_WIDE_INT reg_offset;
3638   char *entry_label = (char *) alloca (strlen (fnname) + 6);
3639   int i;
3640
3641   sa_size = alpha_sa_size ();
3642
3643   frame_size = get_frame_size ();
3644   if (TARGET_OPEN_VMS)
3645     frame_size = ALPHA_ROUND (sa_size 
3646                               + (vms_is_stack_procedure ? 8 : 0)
3647                               + frame_size
3648                               + current_function_pretend_args_size);
3649   else
3650     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3651                   + sa_size
3652                   + ALPHA_ROUND (frame_size
3653                                  + current_function_pretend_args_size));
3654
3655   if (TARGET_OPEN_VMS)
3656     reg_offset = 8;
3657   else
3658     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3659
3660   alpha_sa_mask (&imask, &fmask);
3661
3662   /* Ecoff can handle multiple .file directives, so put out file and lineno.
3663      We have to do that before the .ent directive as we cannot switch
3664      files within procedures with native ecoff because line numbers are
3665      linked to procedure descriptors.
3666      Outputting the lineno helps debugging of one line functions as they
3667      would otherwise get no line number at all. Please note that we would
3668      like to put out last_linenum from final.c, but it is not accessible.  */
3669
3670   if (write_symbols == SDB_DEBUG)
3671     {
3672       ASM_OUTPUT_SOURCE_FILENAME (file,
3673                                   DECL_SOURCE_FILE (current_function_decl));
3674       if (debug_info_level != DINFO_LEVEL_TERSE)
3675         ASM_OUTPUT_SOURCE_LINE (file,
3676                                 DECL_SOURCE_LINE (current_function_decl));
3677     }
3678
3679   /* Issue function start and label.  */
3680   if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
3681     {
3682       fputs ("\t.ent ", file);
3683       assemble_name (file, fnname);
3684       putc ('\n', file);
3685     }
3686
3687   strcpy (entry_label, fnname);
3688   if (TARGET_OPEN_VMS)
3689     strcat (entry_label, "..en");
3690   ASM_OUTPUT_LABEL (file, entry_label);
3691   inside_function = TRUE;
3692
3693   if (TARGET_OPEN_VMS)
3694     fprintf (file, "\t.base $%d\n", vms_base_regno);
3695
3696   if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
3697       && !flag_inhibit_size_directive)
3698     {
3699       /* Set flags in procedure descriptor to request IEEE-conformant
3700          math-library routines.  The value we set it to is PDSC_EXC_IEEE
3701          (/usr/include/pdsc.h). */
3702       fputs ("\t.eflag 48\n", file);
3703     }
3704
3705   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
3706   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3707   alpha_arg_offset = -frame_size + 48;
3708
3709   /* Describe our frame.  If the frame size is larger than an integer,
3710      print it as zero to avoid an assembler error.  We won't be
3711      properly describing such a frame, but that's the best we can do.  */
3712   if (TARGET_OPEN_VMS)
3713     {
3714       fprintf (file, "\t.frame $%d,", vms_unwind_regno);
3715       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3716                frame_size >= (1l << 31) ? 0 : frame_size);
3717       fputs (",$26,", file);
3718       fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
3719       fputs ("\n", file);
3720     }
3721   else if (!flag_inhibit_size_directive)
3722     {
3723       fprintf (file, "\t.frame $%d,",
3724                (frame_pointer_needed
3725                 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3726       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3727                frame_size >= (1l << 31) ? 0 : frame_size);
3728       fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3729     }
3730
3731   /* Describe which registers were spilled.  */
3732   if (TARGET_OPEN_VMS)
3733     {
3734       if (imask)
3735         /* ??? Does VMS care if mask contains ra?  The old code did'nt
3736            set it, so I don't here.  */
3737         fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
3738       if (fmask)
3739         fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
3740       if (!vms_is_stack_procedure)
3741         fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
3742     }
3743   else if (!flag_inhibit_size_directive)
3744     {
3745       if (imask)
3746         {
3747           fprintf (file, "\t.mask 0x%lx,", imask);
3748           fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3749                    frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3750           putc ('\n', file);
3751
3752           for (i = 0; i < 32; ++i)
3753             if (imask & (1L << i))
3754               reg_offset += 8;
3755         }
3756
3757       if (fmask)
3758         {
3759           fprintf (file, "\t.fmask 0x%lx,", fmask);
3760           fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3761                    frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
3762           putc ('\n', file);
3763         }
3764     }
3765
3766   /* Emit GP related things.  It is rather unfortunate about the alignment
3767      issues surrounding a CODE_LABEL that forces us to do the label in 
3768      plain text.  */
3769   if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
3770     {
3771       alpha_function_needs_gp = alpha_does_function_need_gp ();
3772       if (alpha_function_needs_gp)
3773         fputs ("\tldgp $29,0($27)\n", file);
3774
3775       putc ('$', file);
3776       assemble_name (file, fnname);
3777       fputs ("..ng:\n", file);
3778     }
3779
3780 #ifdef OPEN_VMS
3781   /* Ifdef'ed cause readonly_section and link_section are only
3782      available then.  */
3783   readonly_section ();
3784   fprintf (file, "\t.align 3\n");
3785   assemble_name (file, fnname); fputs ("..na:\n", file);
3786   fputs ("\t.ascii \"", file);
3787   assemble_name (file, fnname);
3788   fputs ("\\0\"\n", file);
3789       
3790   link_section ();
3791   fprintf (file, "\t.align 3\n");
3792   fputs ("\t.name ", file);
3793   assemble_name (file, fnname);
3794   fputs ("..na\n", file);
3795   ASM_OUTPUT_LABEL (file, fnname);
3796   fprintf (file, "\t.pdesc ");
3797   assemble_name (file, fnname);
3798   fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
3799   alpha_need_linkage (fnname, 1);
3800   text_section ();
3801 #endif
3802 }
3803
3804 /* Emit the .prologue note at the scheduled end of the prologue.  */
3805
3806 void
3807 output_end_prologue (file)
3808      FILE *file;
3809 {
3810   if (TARGET_OPEN_VMS)
3811     fputs ("\t.prologue\n", file);
3812   else if (TARGET_WINDOWS_NT)
3813     fputs ("\t.prologue 0\n", file);
3814   else if (!flag_inhibit_size_directive)
3815     fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3816 }
3817
3818 /* Write function epilogue.  */
3819
3820 /* ??? At some point we will want to support full unwind, and so will 
3821    need to mark the epilogue as well.  At the moment, we just confuse
3822    dwarf2out.  */
3823 #undef FRP
3824 #define FRP(exp) exp
3825
3826 void
3827 alpha_expand_epilogue ()
3828 {
3829   /* Registers to save.  */
3830   unsigned long imask = 0;
3831   unsigned long fmask = 0;
3832   /* Stack space needed for pushing registers clobbered by us.  */
3833   HOST_WIDE_INT sa_size;
3834   /* Complete stack size needed.  */
3835   HOST_WIDE_INT frame_size;
3836   /* Offset from base reg to register save area.  */
3837   HOST_WIDE_INT reg_offset;
3838   int fp_is_frame_pointer, fp_offset;
3839   rtx sa_reg, sa_reg_exp = NULL;
3840   rtx sp_adj1, sp_adj2, mem;
3841   int i;
3842
3843   sa_size = alpha_sa_size ();
3844
3845   frame_size = get_frame_size ();
3846   if (TARGET_OPEN_VMS)
3847     frame_size = ALPHA_ROUND (sa_size 
3848                               + (vms_is_stack_procedure ? 8 : 0)
3849                               + frame_size
3850                               + current_function_pretend_args_size);
3851   else
3852     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
3853                   + sa_size
3854                   + ALPHA_ROUND (frame_size
3855                                  + current_function_pretend_args_size));
3856
3857   if (TARGET_OPEN_VMS)
3858     reg_offset = 8;
3859   else
3860     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
3861
3862   alpha_sa_mask (&imask, &fmask);
3863
3864   fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
3865                          || (!TARGET_OPEN_VMS && frame_pointer_needed));
3866
3867   if (sa_size)
3868     {
3869       /* If we have a frame pointer, restore SP from it.  */
3870       if ((TARGET_OPEN_VMS
3871            && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
3872           || (!TARGET_OPEN_VMS && frame_pointer_needed))
3873         {
3874           FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
3875         }
3876
3877       /* Cope with very large offsets to the register save area.  */
3878       sa_reg = stack_pointer_rtx;
3879       if (reg_offset + sa_size > 0x8000)
3880         {
3881           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3882           HOST_WIDE_INT bias;
3883
3884           if (low + sa_size <= 0x8000)
3885             bias = reg_offset - low, reg_offset = low;
3886           else 
3887             bias = reg_offset, reg_offset = 0;
3888
3889           sa_reg = gen_rtx_REG (DImode, 22);
3890           sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
3891
3892           FRP (emit_move_insn (sa_reg, sa_reg_exp));
3893         }
3894           
3895       /* Restore registers in order, excepting a true frame pointer. */
3896
3897       if (! alpha_eh_epilogue_sp_ofs)
3898         {
3899           mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3900           MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3901           FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
3902         }
3903       reg_offset += 8;
3904       imask &= ~(1L << REG_RA);
3905
3906       for (i = 0; i < 32; ++i)
3907         if (imask & (1L << i))
3908           {
3909             if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
3910               fp_offset = reg_offset;
3911             else
3912               {
3913                 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
3914                 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3915                 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
3916               }
3917             reg_offset += 8;
3918           }
3919
3920       for (i = 0; i < 32; ++i)
3921         if (fmask & (1L << i))
3922           {
3923             mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
3924             MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3925             FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
3926             reg_offset += 8;
3927           }
3928     }
3929
3930   if (frame_size || alpha_eh_epilogue_sp_ofs)
3931     {
3932       sp_adj1 = stack_pointer_rtx;
3933
3934       if (alpha_eh_epilogue_sp_ofs)
3935         {
3936           sp_adj1 = gen_rtx_REG (DImode, 23);
3937           emit_move_insn (sp_adj1,
3938                           gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3939                                         alpha_eh_epilogue_sp_ofs));
3940         }
3941
3942       /* If the stack size is large, begin computation into a temporary
3943          register so as not to interfere with a potential fp restore,
3944          which must be consecutive with an SP restore.  */
3945       if (frame_size < 32768)
3946         sp_adj2 = GEN_INT (frame_size);
3947       else if (frame_size < 0x40007fffL)
3948         {
3949           int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
3950
3951           sp_adj2 = plus_constant (sp_adj1, frame_size - low);
3952           if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
3953             sp_adj1 = sa_reg;
3954           else
3955             {
3956               sp_adj1 = gen_rtx_REG (DImode, 23);
3957               FRP (emit_move_insn (sp_adj1, sp_adj2));
3958             }
3959           sp_adj2 = GEN_INT (low);
3960         }
3961       else
3962         {
3963           rtx tmp = gen_rtx_REG (DImode, 23);
3964           FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
3965           if (!sp_adj2)
3966             {
3967               /* We can't drop new things to memory this late, afaik,
3968                  so build it up by pieces.  */
3969               FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
3970                                                         -(frame_size < 0)));
3971               if (!sp_adj2)
3972                 abort ();
3973             }
3974         }
3975
3976       /* From now on, things must be in order.  So emit blockages.  */
3977
3978       /* Restore the frame pointer.  */
3979       if (fp_is_frame_pointer)
3980         {
3981           emit_insn (gen_blockage ());
3982           mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
3983           MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
3984           FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
3985         }
3986       else if (TARGET_OPEN_VMS)
3987         {
3988           emit_insn (gen_blockage ());
3989           FRP (emit_move_insn (hard_frame_pointer_rtx,
3990                                gen_rtx_REG (DImode, vms_save_fp_regno)));
3991         }
3992
3993       /* Restore the stack pointer.  */
3994       emit_insn (gen_blockage ());
3995       FRP (emit_move_insn (stack_pointer_rtx,
3996                            gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
3997     }
3998   else 
3999     {
4000       if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4001         {
4002           emit_insn (gen_blockage ());
4003           FRP (emit_move_insn (hard_frame_pointer_rtx,
4004                                gen_rtx_REG (DImode, vms_save_fp_regno)));
4005         }
4006     }
4007
4008   /* Return.  */
4009   emit_jump_insn (gen_return_internal ());
4010 }
4011
4012 /* Output the rest of the textual info surrounding the epilogue.  */
4013
4014 void
4015 alpha_end_function (file, fnname, decl)
4016      FILE *file;
4017      char *fnname;
4018      tree decl ATTRIBUTE_UNUSED;
4019 {
4020   /* End the function.  */
4021   if (!flag_inhibit_size_directive)
4022     {
4023       fputs ("\t.end ", file);
4024       assemble_name (file, fnname);
4025       putc ('\n', file);
4026     }
4027   inside_function = FALSE;
4028
4029   /* Show that we know this function if it is called again. 
4030
4031      Don't do this for global functions in object files destined for a
4032      shared library because the function may be overridden by the application
4033      or other libraries.  Similarly, don't do this for weak functions.  */
4034
4035   if (!DECL_WEAK (current_function_decl)
4036       && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4037     SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4038 }
4039 \f
4040 /* Debugging support.  */
4041
4042 #include "gstab.h"
4043
4044 /* Count the number of sdb related labels are generated (to find block
4045    start and end boundaries).  */
4046
4047 int sdb_label_count = 0;
4048
4049 /* Next label # for each statement.  */
4050
4051 static int sym_lineno = 0;
4052
4053 /* Count the number of .file directives, so that .loc is up to date.  */
4054
4055 static int num_source_filenames = 0;
4056
4057 /* Name of the file containing the current function.  */
4058
4059 static const char *current_function_file = "";
4060
4061 /* Offsets to alpha virtual arg/local debugging pointers.  */
4062
4063 long alpha_arg_offset;
4064 long alpha_auto_offset;
4065 \f
4066 /* Emit a new filename to a stream.  */
4067
4068 void
4069 alpha_output_filename (stream, name)
4070      FILE *stream;
4071      char *name;
4072 {
4073   static int first_time = TRUE;
4074   char ltext_label_name[100];
4075
4076   if (first_time)
4077     {
4078       first_time = FALSE;
4079       ++num_source_filenames;
4080       current_function_file = name;
4081       fprintf (stream, "\t.file\t%d ", num_source_filenames);
4082       output_quoted_string (stream, name);
4083       fprintf (stream, "\n");
4084       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4085         fprintf (stream, "\t#@stabs\n");
4086     }
4087
4088   else if (write_symbols == DBX_DEBUG)
4089     {
4090       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4091       fprintf (stream, "%s ", ASM_STABS_OP);
4092       output_quoted_string (stream, name);
4093       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
4094     }
4095
4096   else if (name != current_function_file
4097            && strcmp (name, current_function_file) != 0)
4098     {
4099       if (inside_function && ! TARGET_GAS)
4100         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4101       else
4102         {
4103           ++num_source_filenames;
4104           current_function_file = name;
4105           fprintf (stream, "\t.file\t%d ", num_source_filenames);
4106         }
4107
4108       output_quoted_string (stream, name);
4109       fprintf (stream, "\n");
4110     }
4111 }
4112 \f
4113 /* Emit a linenumber to a stream.  */
4114
4115 void
4116 alpha_output_lineno (stream, line)
4117      FILE *stream;
4118      int line;
4119 {
4120   if (write_symbols == DBX_DEBUG)
4121     {
4122       /* mips-tfile doesn't understand .stabd directives.  */
4123       ++sym_lineno;
4124       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4125                sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4126     }
4127   else
4128     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4129 }
4130 \f
4131 /* Structure to show the current status of registers and memory.  */
4132
4133 struct shadow_summary
4134 {
4135   struct {
4136     unsigned long i     : 31;   /* Mask of int regs */
4137     unsigned long fp    : 31;   /* Mask of fp regs */
4138     unsigned long mem   :  1;   /* mem == imem | fpmem */
4139   } used, defd;
4140 };
4141
4142 static void summarize_insn PROTO((rtx, struct shadow_summary *, int));
4143 static void alpha_handle_trap_shadows PROTO((rtx));
4144
4145 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
4146    to the summary structure.  SET is nonzero if the insn is setting the
4147    object, otherwise zero.  */
4148
4149 static void
4150 summarize_insn (x, sum, set)
4151      rtx x;
4152      struct shadow_summary *sum;
4153      int set;
4154 {
4155   char *format_ptr;
4156   int i, j;
4157
4158   if (x == 0)
4159     return;
4160
4161   switch (GET_CODE (x))
4162     {
4163       /* ??? Note that this case would be incorrect if the Alpha had a
4164          ZERO_EXTRACT in SET_DEST.  */
4165     case SET:
4166       summarize_insn (SET_SRC (x), sum, 0);
4167       summarize_insn (SET_DEST (x), sum, 1);
4168       break;
4169
4170     case CLOBBER:
4171       summarize_insn (XEXP (x, 0), sum, 1);
4172       break;
4173
4174     case USE:
4175       summarize_insn (XEXP (x, 0), sum, 0);
4176       break;
4177
4178     case ASM_OPERANDS:
4179       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4180         summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4181       break;
4182
4183     case PARALLEL:
4184       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4185         summarize_insn (XVECEXP (x, 0, i), sum, 0);
4186       break;
4187
4188     case SUBREG:
4189       summarize_insn (SUBREG_REG (x), sum, 0);
4190       break;
4191
4192     case REG:
4193       {
4194         int regno = REGNO (x);
4195         unsigned long mask = 1UL << (regno % 32);
4196
4197         if (regno == 31 || regno == 63)
4198           break;
4199
4200         if (set)
4201           {
4202             if (regno < 32)
4203               sum->defd.i |= mask;
4204             else
4205               sum->defd.fp |= mask;
4206           }
4207         else
4208           {
4209             if (regno < 32)
4210               sum->used.i  |= mask;
4211             else
4212               sum->used.fp |= mask;
4213           }
4214         }
4215       break;
4216
4217     case MEM:
4218       if (set)
4219         sum->defd.mem = 1;
4220       else
4221         sum->used.mem = 1;
4222
4223       /* Find the regs used in memory address computation: */
4224       summarize_insn (XEXP (x, 0), sum, 0);
4225       break;
4226
4227     case CONST_INT:   case CONST_DOUBLE:
4228     case SYMBOL_REF:  case LABEL_REF:     case CONST:
4229       break;
4230
4231       /* Handle common unary and binary ops for efficiency.  */
4232     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
4233     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
4234     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
4235     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
4236     case NE:       case EQ:      case GE:      case GT:        case LE:
4237     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
4238       summarize_insn (XEXP (x, 0), sum, 0);
4239       summarize_insn (XEXP (x, 1), sum, 0);
4240       break;
4241
4242     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
4243     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
4244     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
4245     case SQRT:  case FFS: 
4246       summarize_insn (XEXP (x, 0), sum, 0);
4247       break;
4248
4249     default:
4250       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4251       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4252         switch (format_ptr[i])
4253           {
4254           case 'e':
4255             summarize_insn (XEXP (x, i), sum, 0);
4256             break;
4257
4258           case 'E':
4259             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4260               summarize_insn (XVECEXP (x, i, j), sum, 0);
4261             break;
4262
4263           case 'i':
4264             break;
4265
4266           default:
4267             abort ();
4268           }
4269     }
4270 }
4271
4272 /* Ensure a sufficient number of `trapb' insns are in the code when
4273    the user requests code with a trap precision of functions or
4274    instructions.
4275
4276    In naive mode, when the user requests a trap-precision of
4277    "instruction", a trapb is needed after every instruction that may
4278    generate a trap.  This ensures that the code is resumption safe but
4279    it is also slow.
4280
4281    When optimizations are turned on, we delay issuing a trapb as long
4282    as possible.  In this context, a trap shadow is the sequence of
4283    instructions that starts with a (potentially) trap generating
4284    instruction and extends to the next trapb or call_pal instruction
4285    (but GCC never generates call_pal by itself).  We can delay (and
4286    therefore sometimes omit) a trapb subject to the following
4287    conditions:
4288
4289    (a) On entry to the trap shadow, if any Alpha register or memory
4290    location contains a value that is used as an operand value by some
4291    instruction in the trap shadow (live on entry), then no instruction
4292    in the trap shadow may modify the register or memory location.
4293
4294    (b) Within the trap shadow, the computation of the base register
4295    for a memory load or store instruction may not involve using the
4296    result of an instruction that might generate an UNPREDICTABLE
4297    result.
4298
4299    (c) Within the trap shadow, no register may be used more than once
4300    as a destination register.  (This is to make life easier for the
4301    trap-handler.)
4302
4303    (d) The trap shadow may not include any branch instructions.  */
4304
4305 static void
4306 alpha_handle_trap_shadows (insns)
4307      rtx insns;
4308 {
4309   struct shadow_summary shadow;
4310   int trap_pending, exception_nesting;
4311   rtx i, n;
4312
4313   trap_pending = 0;
4314   exception_nesting = 0;
4315   shadow.used.i = 0;
4316   shadow.used.fp = 0;
4317   shadow.used.mem = 0;
4318   shadow.defd = shadow.used;
4319   
4320   for (i = insns; i ; i = NEXT_INSN (i))
4321     {
4322       if (GET_CODE (i) == NOTE)
4323         {
4324           switch (NOTE_LINE_NUMBER (i))
4325             {
4326             case NOTE_INSN_EH_REGION_BEG:
4327               exception_nesting++;
4328               if (trap_pending)
4329                 goto close_shadow;
4330               break;
4331
4332             case NOTE_INSN_EH_REGION_END:
4333               exception_nesting--;
4334               if (trap_pending)
4335                 goto close_shadow;
4336               break;
4337
4338             case NOTE_INSN_EPILOGUE_BEG:
4339               if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4340                 goto close_shadow;
4341               break;
4342             }
4343         }
4344       else if (trap_pending)
4345         {
4346           if (alpha_tp == ALPHA_TP_FUNC)
4347             {
4348               if (GET_CODE (i) == JUMP_INSN
4349                   && GET_CODE (PATTERN (i)) == RETURN)
4350                 goto close_shadow;
4351             }
4352           else if (alpha_tp == ALPHA_TP_INSN)
4353             {
4354               if (optimize > 0)
4355                 {
4356                   struct shadow_summary sum;
4357
4358                   sum.used.i = 0;
4359                   sum.used.fp = 0;
4360                   sum.used.mem = 0;
4361                   sum.defd = sum.used;
4362
4363                   switch (GET_CODE (i))
4364                     {
4365                     case INSN:
4366                       /* Annoyingly, get_attr_trap will abort on these.  */
4367                       if (GET_CODE (PATTERN (i)) == USE
4368                           || GET_CODE (PATTERN (i)) == CLOBBER)
4369                         break;
4370
4371                       summarize_insn (PATTERN (i), &sum, 0);
4372
4373                       if ((sum.defd.i & shadow.defd.i)
4374                           || (sum.defd.fp & shadow.defd.fp))
4375                         {
4376                           /* (c) would be violated */
4377                           goto close_shadow;
4378                         }
4379
4380                       /* Combine shadow with summary of current insn: */
4381                       shadow.used.i   |= sum.used.i;
4382                       shadow.used.fp  |= sum.used.fp;
4383                       shadow.used.mem |= sum.used.mem;
4384                       shadow.defd.i   |= sum.defd.i;
4385                       shadow.defd.fp  |= sum.defd.fp;
4386                       shadow.defd.mem |= sum.defd.mem;
4387
4388                       if ((sum.defd.i & shadow.used.i)
4389                           || (sum.defd.fp & shadow.used.fp)
4390                           || (sum.defd.mem & shadow.used.mem))
4391                         {
4392                           /* (a) would be violated (also takes care of (b))  */
4393                           if (get_attr_trap (i) == TRAP_YES
4394                               && ((sum.defd.i & sum.used.i)
4395                                   || (sum.defd.fp & sum.used.fp)))
4396                             abort ();
4397
4398                           goto close_shadow;
4399                         }
4400                       break;
4401
4402                     case JUMP_INSN:
4403                     case CALL_INSN:
4404                     case CODE_LABEL:
4405                       goto close_shadow;
4406
4407                     default:
4408                       abort ();
4409                     }
4410                 }
4411               else
4412                 {
4413                 close_shadow:
4414                   n = emit_insn_before (gen_trapb (), i);
4415                   PUT_MODE (n, TImode);
4416                   PUT_MODE (i, TImode);
4417                   trap_pending = 0;
4418                   shadow.used.i = 0;
4419                   shadow.used.fp = 0;
4420                   shadow.used.mem = 0;
4421                   shadow.defd = shadow.used;
4422                 }
4423             }
4424         }
4425
4426       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4427           && GET_CODE (i) == INSN
4428           && GET_CODE (PATTERN (i)) != USE
4429           && GET_CODE (PATTERN (i)) != CLOBBER
4430           && get_attr_trap (i) == TRAP_YES)
4431         {
4432           if (optimize && !trap_pending)
4433             summarize_insn (PATTERN (i), &shadow, 0);
4434           trap_pending = 1;
4435         }
4436     }
4437 }
4438 \f
4439 #ifdef HAIFA
4440 /* Alpha can only issue instruction groups simultaneously if they are
4441    suitibly aligned.  This is very processor-specific.  */
4442
4443 enum alphaev4_pipe {
4444   EV4_STOP = 0,
4445   EV4_IB0 = 1,
4446   EV4_IB1 = 2,
4447   EV4_IBX = 4
4448 };
4449
4450 enum alphaev5_pipe {
4451   EV5_STOP = 0,
4452   EV5_NONE = 1,
4453   EV5_E01 = 2,
4454   EV5_E0 = 4,
4455   EV5_E1 = 8,
4456   EV5_FAM = 16,
4457   EV5_FA = 32,
4458   EV5_FM = 64
4459 };
4460
4461 static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx));
4462 static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx));
4463 static rtx alphaev4_next_group PROTO((rtx, int*, int*));
4464 static rtx alphaev5_next_group PROTO((rtx, int*, int*));
4465 static rtx alphaev4_next_nop PROTO((int*));
4466 static rtx alphaev5_next_nop PROTO((int*));
4467
4468 static void alpha_align_insns
4469   PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
4470
4471 static enum alphaev4_pipe
4472 alphaev4_insn_pipe (insn)
4473      rtx insn;
4474 {
4475   if (recog_memoized (insn) < 0)
4476     return EV4_STOP;
4477   if (get_attr_length (insn) != 4)
4478     return EV4_STOP;
4479
4480   switch (get_attr_type (insn))
4481     {
4482     case TYPE_ILD:
4483     case TYPE_FLD:
4484       return EV4_IBX;
4485
4486     case TYPE_LDSYM:
4487     case TYPE_IADD:
4488     case TYPE_ILOG:
4489     case TYPE_ICMOV:
4490     case TYPE_ICMP:
4491     case TYPE_IST:
4492     case TYPE_FST:
4493     case TYPE_SHIFT:
4494     case TYPE_IMUL:
4495     case TYPE_FBR:
4496       return EV4_IB0;
4497
4498     case TYPE_MISC:
4499     case TYPE_IBR:
4500     case TYPE_JSR:
4501     case TYPE_FCPYS:
4502     case TYPE_FCMOV:
4503     case TYPE_FADD:
4504     case TYPE_FDIV:
4505     case TYPE_FMUL:
4506       return EV4_IB1;
4507
4508     default:
4509       abort();
4510     }
4511 }
4512
4513 static enum alphaev5_pipe
4514 alphaev5_insn_pipe (insn)
4515      rtx insn;
4516 {
4517   if (recog_memoized (insn) < 0)
4518     return EV5_STOP;
4519   if (get_attr_length (insn) != 4)
4520     return EV5_STOP;
4521
4522   switch (get_attr_type (insn))
4523     {
4524     case TYPE_ILD:
4525     case TYPE_FLD:
4526     case TYPE_LDSYM:
4527     case TYPE_IADD:
4528     case TYPE_ILOG:
4529     case TYPE_ICMOV:
4530     case TYPE_ICMP:
4531       return EV5_E01;
4532
4533     case TYPE_IST:
4534     case TYPE_FST:
4535     case TYPE_SHIFT:
4536     case TYPE_IMUL:
4537     case TYPE_MISC:
4538     case TYPE_MVI:
4539       return EV5_E0;
4540
4541     case TYPE_IBR:
4542     case TYPE_JSR:
4543       return EV5_E1;
4544
4545     case TYPE_FCPYS:
4546       return EV5_FAM;
4547
4548     case TYPE_FBR:
4549     case TYPE_FCMOV:
4550     case TYPE_FADD:
4551     case TYPE_FDIV:
4552       return EV5_FA;
4553
4554     case TYPE_FMUL:
4555       return EV5_FM;
4556
4557     default:
4558       abort();
4559     }
4560 }
4561
4562 /* IN_USE is a mask of the slots currently filled within the insn group. 
4563    The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
4564    the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1. 
4565
4566    LEN is, of course, the length of the group in bytes.  */
4567
4568 static rtx
4569 alphaev4_next_group (insn, pin_use, plen)
4570      rtx insn;
4571      int *pin_use, *plen;
4572 {
4573   int len, in_use;
4574
4575   len = in_use = 0;
4576
4577   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4578       || GET_CODE (PATTERN (insn)) == CLOBBER
4579       || GET_CODE (PATTERN (insn)) == USE)
4580     goto next_and_done;
4581
4582   while (1)
4583     {
4584       enum alphaev4_pipe pipe;
4585
4586       pipe = alphaev4_insn_pipe (insn);
4587       switch (pipe)
4588         {
4589         case EV4_STOP:
4590           /* Force complex instructions to start new groups.  */
4591           if (in_use)
4592             goto done;
4593
4594           /* If this is a completely unrecognized insn, its an asm.
4595              We don't know how long it is, so record length as -1 to
4596              signal a needed realignment.  */
4597           if (recog_memoized (insn) < 0)
4598             len = -1;
4599           else
4600             len = get_attr_length (insn);
4601           goto next_and_done;
4602
4603         case EV4_IBX:
4604           if (in_use & EV4_IB0)
4605             {
4606               if (in_use & EV4_IB1)
4607                 goto done;
4608               in_use |= EV4_IB1;
4609             }
4610           else
4611             in_use |= EV4_IB0 | EV4_IBX;
4612           break;
4613
4614         case EV4_IB0:
4615           if (in_use & EV4_IB0)
4616             {
4617               if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
4618                 goto done;
4619               in_use |= EV4_IB1;
4620             }
4621           in_use |= EV4_IB0;
4622           break;
4623
4624         case EV4_IB1:
4625           if (in_use & EV4_IB1)
4626             goto done;
4627           in_use |= EV4_IB1;
4628           break;
4629
4630         default:
4631           abort();
4632         }
4633       len += 4;
4634       
4635       /* Haifa doesn't do well scheduling branches.  */
4636       if (GET_CODE (insn) == JUMP_INSN)
4637         goto next_and_done;
4638
4639     next:
4640       insn = next_nonnote_insn (insn);
4641
4642       if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4643         goto done;
4644
4645       /* Let Haifa tell us where it thinks insn group boundaries are.  */
4646       if (GET_MODE (insn) == TImode)
4647         goto done;
4648
4649       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4650         goto next;
4651     }
4652
4653  next_and_done:
4654   insn = next_nonnote_insn (insn);
4655
4656  done:
4657   *plen = len;
4658   *pin_use = in_use;
4659   return insn;
4660 }
4661
4662 /* IN_USE is a mask of the slots currently filled within the insn group. 
4663    The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
4664    the insn in EV5_E0 can be swapped by the hardware into EV5_E1. 
4665
4666    LEN is, of course, the length of the group in bytes.  */
4667
4668 static rtx
4669 alphaev5_next_group (insn, pin_use, plen)
4670      rtx insn;
4671      int *pin_use, *plen;
4672 {
4673   int len, in_use;
4674
4675   len = in_use = 0;
4676
4677   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
4678       || GET_CODE (PATTERN (insn)) == CLOBBER
4679       || GET_CODE (PATTERN (insn)) == USE)
4680     goto next_and_done;
4681
4682   while (1)
4683     {
4684       enum alphaev5_pipe pipe;
4685
4686       pipe = alphaev5_insn_pipe (insn);
4687       switch (pipe)
4688         {
4689         case EV5_STOP:
4690           /* Force complex instructions to start new groups.  */
4691           if (in_use)
4692             goto done;
4693
4694           /* If this is a completely unrecognized insn, its an asm.
4695              We don't know how long it is, so record length as -1 to
4696              signal a needed realignment.  */
4697           if (recog_memoized (insn) < 0)
4698             len = -1;
4699           else
4700             len = get_attr_length (insn);
4701           goto next_and_done;
4702
4703         /* ??? Most of the places below, we would like to abort, as 
4704            it would indicate an error either in Haifa, or in the 
4705            scheduling description.  Unfortunately, Haifa never 
4706            schedules the last instruction of the BB, so we don't
4707            have an accurate TI bit to go off.  */
4708         case EV5_E01:
4709           if (in_use & EV5_E0)
4710             {
4711               if (in_use & EV5_E1)
4712                 goto done;
4713               in_use |= EV5_E1;
4714             }
4715           else
4716             in_use |= EV5_E0 | EV5_E01;
4717           break;
4718
4719         case EV5_E0:
4720           if (in_use & EV5_E0)
4721             {
4722               if (!(in_use & EV5_E01) || (in_use & EV5_E1))
4723                 goto done;
4724               in_use |= EV5_E1;
4725             }
4726           in_use |= EV5_E0;
4727           break;
4728
4729         case EV5_E1:
4730           if (in_use & EV5_E1)
4731             goto done;
4732           in_use |= EV5_E1;
4733           break;
4734
4735         case EV5_FAM:
4736           if (in_use & EV5_FA)
4737             {
4738               if (in_use & EV5_FM)
4739                 goto done;
4740               in_use |= EV5_FM;
4741             }
4742           else
4743             in_use |= EV5_FA | EV5_FAM;
4744           break;
4745
4746         case EV5_FA:
4747           if (in_use & EV5_FA)
4748             goto done;
4749           in_use |= EV5_FA;
4750           break;
4751
4752         case EV5_FM:
4753           if (in_use & EV5_FM)
4754             goto done;
4755           in_use |= EV5_FM;
4756           break;
4757
4758         case EV5_NONE:
4759           break;
4760
4761         default:
4762           abort();
4763         }
4764       len += 4;
4765       
4766       /* Haifa doesn't do well scheduling branches.  */
4767       /* ??? If this is predicted not-taken, slotting continues, except
4768          that no more IBR, FBR, or JSR insns may be slotted.  */
4769       if (GET_CODE (insn) == JUMP_INSN)
4770         goto next_and_done;
4771
4772     next:
4773       insn = next_nonnote_insn (insn);
4774
4775       if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
4776         goto done;
4777
4778       /* Let Haifa tell us where it thinks insn group boundaries are.  */
4779       if (GET_MODE (insn) == TImode)
4780         goto done;
4781
4782       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
4783         goto next;
4784     }
4785
4786  next_and_done:
4787   insn = next_nonnote_insn (insn);
4788
4789  done:
4790   *plen = len;
4791   *pin_use = in_use;
4792   return insn;
4793 }
4794
4795 static rtx
4796 alphaev4_next_nop (pin_use)
4797      int *pin_use;
4798 {
4799   int in_use = *pin_use;
4800   rtx nop;
4801
4802   if (!(in_use & EV4_IB0))
4803     {
4804       in_use |= EV4_IB0;
4805       nop = gen_nop ();
4806     }
4807   else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
4808     {
4809       in_use |= EV4_IB1;
4810       nop = gen_nop ();
4811     }
4812   else if (TARGET_FP && !(in_use & EV4_IB1))
4813     {
4814       in_use |= EV4_IB1;
4815       nop = gen_fnop ();
4816     }
4817   else
4818     nop = gen_unop ();
4819
4820   *pin_use = in_use;
4821   return nop;
4822 }
4823
4824 static rtx
4825 alphaev5_next_nop (pin_use)
4826      int *pin_use;
4827 {
4828   int in_use = *pin_use;
4829   rtx nop;
4830
4831   if (!(in_use & EV5_E1))
4832     {
4833       in_use |= EV5_E1;
4834       nop = gen_nop ();
4835     }
4836   else if (TARGET_FP && !(in_use & EV5_FA))
4837     {
4838       in_use |= EV5_FA;
4839       nop = gen_fnop ();
4840     }
4841   else if (TARGET_FP && !(in_use & EV5_FM))
4842     {
4843       in_use |= EV5_FM;
4844       nop = gen_fnop ();
4845     }
4846   else
4847     nop = gen_unop ();
4848
4849   *pin_use = in_use;
4850   return nop;
4851 }
4852
4853 /* The instruction group alignment main loop.  */
4854
4855 static void
4856 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
4857      rtx insns;
4858      int max_align;
4859      rtx (*next_group) PROTO((rtx, int*, int*));
4860      rtx (*next_nop) PROTO((int*));
4861      int gp_in_use;
4862 {
4863   /* ALIGN is the known alignment for the insn group.  */
4864   int align;
4865   /* OFS is the offset of the current insn in the insn group.  */
4866   int ofs;
4867   int prev_in_use, in_use, len;
4868   rtx i, next;
4869
4870   /* Let shorten branches care for assigning alignments to code labels.  */
4871   shorten_branches (insns);
4872
4873   align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
4874            ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
4875
4876   /* Account for the initial GP load, which happens before the scheduled
4877      prologue we emitted as RTL.  */
4878   ofs = prev_in_use = 0;
4879   if (alpha_does_function_need_gp())
4880     {
4881       ofs = 8 & (align - 1);
4882       prev_in_use = gp_in_use;
4883     }
4884
4885   i = insns;
4886   if (GET_CODE (i) == NOTE)
4887     i = next_nonnote_insn (i);
4888
4889   while (i)
4890     {
4891       next = (*next_group)(i, &in_use, &len);
4892
4893       /* When we see a label, resync alignment etc.  */
4894       if (GET_CODE (i) == CODE_LABEL)
4895         {
4896           int new_align = 1 << label_to_alignment (i);
4897           if (new_align >= align)
4898             {
4899               align = new_align < max_align ? new_align : max_align;
4900               ofs = 0;
4901             }
4902           else if (ofs & (new_align-1))
4903             ofs = (ofs | (new_align-1)) + 1;
4904           if (len != 0)
4905             abort();
4906         }
4907
4908       /* Handle complex instructions special.  */
4909       else if (in_use == 0)
4910         {
4911           /* Asms will have length < 0.  This is a signal that we have
4912              lost alignment knowledge.  Assume, however, that the asm
4913              will not mis-align instructions.  */
4914           if (len < 0)
4915             {
4916               ofs = 0;
4917               align = 4;
4918               len = 0;
4919             }
4920         }
4921
4922       /* If the known alignment is smaller than the recognized insn group,
4923          realign the output.  */
4924       else if (align < len)
4925         {
4926           int new_log_align = len > 8 ? 4 : 3;
4927           rtx where;
4928
4929           where = prev_nonnote_insn (i);
4930           if (!where || GET_CODE (where) != CODE_LABEL)
4931             where = i;
4932
4933           emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
4934           align = 1 << new_log_align;
4935           ofs = 0;
4936         }
4937
4938       /* If the group won't fit in the same INT16 as the previous,
4939          we need to add padding to keep the group together.  Rather
4940          than simply leaving the insn filling to the assembler, we
4941          can make use of the knowledge of what sorts of instructions
4942          were issued in the previous group to make sure that all of
4943          the added nops are really free.  */
4944       else if (ofs + len > align)
4945         {
4946           int nop_count = (align - ofs) / 4;
4947           rtx where;
4948
4949           /* Insert nops before labels and branches to truely merge the
4950              execution of the nops with the previous instruction group.  */
4951           where = prev_nonnote_insn (i);
4952           if (where)
4953             {
4954               if (GET_CODE (where) == CODE_LABEL)
4955                 {
4956                   rtx where2 = prev_nonnote_insn (where);
4957                   if (where2 && GET_CODE (where2) == JUMP_INSN)
4958                     where = where2;
4959                 }
4960               else if (GET_CODE (where) != JUMP_INSN)
4961                 where = i;
4962             }
4963           else
4964             where = i;
4965
4966           do 
4967             emit_insn_before ((*next_nop)(&prev_in_use), where);
4968           while (--nop_count);
4969           ofs = 0;
4970         }
4971
4972       ofs = (ofs + len) & (align - 1);
4973       prev_in_use = in_use;
4974       i = next;
4975     }
4976 }
4977 #endif /* HAIFA */
4978 \f
4979 /* Machine dependant reorg pass.  */
4980
4981 void
4982 alpha_reorg (insns)
4983      rtx insns;
4984 {
4985   if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
4986     alpha_handle_trap_shadows (insns);
4987
4988 #ifdef HAIFA
4989   /* Due to the number of extra trapb insns, don't bother fixing up
4990      alignment when trap precision is instruction.  Moreover, we can
4991      only do our job when sched2 is run and Haifa is our scheduler.  */
4992   if (optimize && !optimize_size
4993       && alpha_tp != ALPHA_TP_INSN
4994       && flag_schedule_insns_after_reload)
4995     {
4996       if (alpha_cpu == PROCESSOR_EV4)
4997         alpha_align_insns (insns, 8, alphaev4_next_group,
4998                            alphaev4_next_nop, EV4_IB0);
4999       else if (alpha_cpu == PROCESSOR_EV5)
5000         alpha_align_insns (insns, 16, alphaev5_next_group,
5001                            alphaev5_next_nop, EV5_E01 | EV5_E0);
5002     }
5003 #endif
5004 }
5005
5006 \f
5007 /* Check a floating-point value for validity for a particular machine mode.  */
5008
5009 static char * const float_strings[] =
5010 {
5011   /* These are for FLOAT_VAX.  */
5012    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5013   "-1.70141173319264430e+38",
5014    "2.93873587705571877e-39", /* 2^-128 */
5015   "-2.93873587705571877e-39",
5016   /* These are for the default broken IEEE mode, which traps
5017      on infinity or denormal numbers.  */
5018    "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5019   "-3.402823466385288598117e+38",
5020    "1.1754943508222875079687e-38", /* 2^-126 */
5021   "-1.1754943508222875079687e-38",
5022 };
5023
5024 static REAL_VALUE_TYPE float_values[8];
5025 static int inited_float_values = 0;
5026
5027 int
5028 check_float_value (mode, d, overflow)
5029      enum machine_mode mode;
5030      REAL_VALUE_TYPE *d;
5031      int overflow ATTRIBUTE_UNUSED;
5032 {
5033
5034   if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5035     return 0;
5036
5037   if (inited_float_values == 0)
5038     {
5039       int i;
5040       for (i = 0; i < 8; i++)
5041         float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5042
5043       inited_float_values = 1;
5044     }
5045
5046   if (mode == SFmode)
5047     {
5048       REAL_VALUE_TYPE r;
5049       REAL_VALUE_TYPE *fvptr;
5050
5051       if (TARGET_FLOAT_VAX)
5052         fvptr = &float_values[0];
5053       else
5054         fvptr = &float_values[4];
5055
5056       bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5057       if (REAL_VALUES_LESS (fvptr[0], r))
5058         {
5059           bcopy ((char *) &fvptr[0], (char *) d,
5060                  sizeof (REAL_VALUE_TYPE));
5061           return 1;
5062         }
5063       else if (REAL_VALUES_LESS (r, fvptr[1]))
5064         {
5065           bcopy ((char *) &fvptr[1], (char *) d,
5066                  sizeof (REAL_VALUE_TYPE));
5067           return 1;
5068         }
5069       else if (REAL_VALUES_LESS (dconst0, r)
5070                 && REAL_VALUES_LESS (r, fvptr[2]))
5071         {
5072           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5073           return 1;
5074         }
5075       else if (REAL_VALUES_LESS (r, dconst0)
5076                 && REAL_VALUES_LESS (fvptr[3], r))
5077         {
5078           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5079           return 1;
5080         }
5081     }
5082
5083   return 0;
5084 }
5085
5086 #if OPEN_VMS
5087
5088 /* Return the VMS argument type corresponding to MODE.  */
5089
5090 enum avms_arg_type
5091 alpha_arg_type (mode)
5092      enum machine_mode mode;
5093 {
5094   switch (mode)
5095     {
5096     case SFmode:
5097       return TARGET_FLOAT_VAX ? FF : FS;
5098     case DFmode:
5099       return TARGET_FLOAT_VAX ? FD : FT;
5100     default:
5101       return I64;
5102     }
5103 }
5104
5105 /* Return an rtx for an integer representing the VMS Argument Information
5106    register value.  */
5107
5108 struct rtx_def *
5109 alpha_arg_info_reg_val (cum)
5110      CUMULATIVE_ARGS cum;
5111 {
5112   unsigned HOST_WIDE_INT regval = cum.num_args;
5113   int i;
5114
5115   for (i = 0; i < 6; i++)
5116     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5117
5118   return GEN_INT (regval);
5119 }
5120 \f
5121 /* Structure to collect function names for final output
5122    in link section.  */
5123
5124 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5125
5126
5127 struct alpha_links {
5128   struct alpha_links *next;
5129   char *name;
5130   enum links_kind kind;
5131 };
5132
5133 static struct alpha_links *alpha_links_base = 0;
5134
5135 /* Make (or fake) .linkage entry for function call.
5136
5137    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.  */
5138
5139 void
5140 alpha_need_linkage (name, is_local)
5141     char *name;
5142     int is_local;
5143 {
5144   rtx x;
5145   struct alpha_links *lptr, *nptr;
5146
5147   if (name[0] == '*')
5148     name++;
5149
5150   /* Is this name already defined ?  */
5151
5152   for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5153     if (strcmp (lptr->name, name) == 0)
5154       {
5155         if (is_local)
5156           {
5157             /* Defined here but external assumed.  */
5158             if (lptr->kind == KIND_EXTERN)
5159               lptr->kind = KIND_LOCAL;
5160           }
5161         else
5162           {
5163             /* Used here but unused assumed.  */
5164             if (lptr->kind == KIND_UNUSED)
5165               lptr->kind = KIND_LOCAL;
5166           }
5167         return;
5168       }
5169
5170   nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5171   nptr->next = alpha_links_base;
5172   nptr->name = xstrdup (name);
5173
5174   /* Assume external if no definition.  */
5175   nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5176
5177   /* Ensure we have an IDENTIFIER so assemble_name can mark is used.  */
5178   get_identifier (name);
5179
5180   alpha_links_base = nptr;
5181
5182   return;
5183 }
5184
5185
5186 void
5187 alpha_write_linkage (stream)
5188     FILE *stream;
5189 {
5190   struct alpha_links *lptr, *nptr;
5191
5192   readonly_section ();
5193
5194   fprintf (stream, "\t.align 3\n");
5195
5196   for (lptr = alpha_links_base; lptr; lptr = nptr)
5197     {
5198       nptr = lptr->next;
5199
5200       if (lptr->kind == KIND_UNUSED
5201           || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5202         continue;
5203
5204       fprintf (stream, "$%s..lk:\n", lptr->name);
5205       if (lptr->kind == KIND_LOCAL)   
5206         {
5207           /*  Local and used, build linkage pair.  */
5208           fprintf (stream, "\t.quad %s..en\n", lptr->name);
5209           fprintf (stream, "\t.quad %s\n", lptr->name);
5210         }
5211       else
5212         /* External and used, request linkage pair.  */
5213         fprintf (stream, "\t.linkage %s\n", lptr->name);
5214     }
5215 }
5216
5217 #else
5218
5219 void
5220 alpha_need_linkage (name, is_local)
5221      char *name ATTRIBUTE_UNUSED;
5222      int is_local ATTRIBUTE_UNUSED;
5223 {
5224 }
5225
5226 #endif /* OPEN_VMS */