OSDN Git Service

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