OSDN Git Service

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