OSDN Git Service

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