OSDN Git Service

* alpha.c (summarize_insn): Ignore rtl slot format 'i'.
[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               branch_code = swap_condition (cmp_code);
1284               cmp_code = NIL;
1285             }
1286         }
1287       else
1288         {
1289           /* ??? We mark the the branch mode to be CCmode to prevent the
1290              compare and branch from being combined, since the compare 
1291              insn follows IEEE rules that the branch does not.  */
1292           branch_mode = CCmode;
1293         }
1294     }
1295   else
1296     {
1297       cmp_mode = DImode;
1298
1299       /* The following optimizations are only for signed compares.  */
1300       if (code != LEU && code != LTU && code != GEU && code != GTU)
1301         {
1302           /* Whee.  Compare and branch against 0 directly.  */
1303           if (op1 == const0_rtx)
1304             cmp_code = NIL, branch_code = code;
1305
1306           /* We want to use cmpcc/bcc when we can, since there is a zero delay
1307              bypass between logicals and br/cmov on EV5.  But we don't want to
1308              force valid immediate constants into registers needlessly.  */
1309           else if (GET_CODE (op1) == CONST_INT)
1310             {
1311               HOST_WIDE_INT v = INTVAL (op1), n = -v;
1312
1313               if (! CONST_OK_FOR_LETTER_P (v, 'I')
1314                   && (CONST_OK_FOR_LETTER_P (n, 'K')
1315                       || CONST_OK_FOR_LETTER_P (n, 'L')))
1316                 {
1317                   cmp_code = PLUS, branch_code = code;
1318                   op1 = GEN_INT (n);
1319                 }
1320             }
1321         }
1322     }
1323
1324   /* Force op0 into a register.  */
1325   if (GET_CODE (op0) != REG)
1326     op0 = force_reg (cmp_mode, op0);
1327
1328   /* Emit an initial compare instruction, if necessary.  */
1329   tem = op0;
1330   if (cmp_code != NIL)
1331     {
1332       tem = gen_reg_rtx (cmp_mode);
1333       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1334     }
1335
1336   /* Return the branch comparison.  */
1337   return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1338 }
1339
1340
1341 /* Rewrite a comparison against zero CMP of the form
1342    (CODE (cc0) (const_int 0)) so it can be written validly in
1343    a conditional move (if_then_else CMP ...).
1344    If both of the operands that set cc0 are non-zero we must emit
1345    an insn to perform the compare (it can't be done within
1346    the conditional move). */
1347 rtx
1348 alpha_emit_conditional_move (cmp, mode)
1349      rtx cmp;
1350      enum machine_mode mode;
1351 {
1352   enum rtx_code code = GET_CODE (cmp);
1353   enum rtx_code cmov_code = NE;
1354   rtx op0 = alpha_compare_op0;
1355   rtx op1 = alpha_compare_op1;
1356   enum machine_mode cmp_mode
1357     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1358   enum machine_mode cmp_op_mode = alpha_compare_fp_p ? DFmode : DImode;
1359   enum machine_mode cmov_mode = VOIDmode;
1360   rtx tem;
1361
1362   if (alpha_compare_fp_p != FLOAT_MODE_P (mode))
1363     return 0;
1364
1365   /* We may be able to use a conditional move directly.
1366      This avoids emitting spurious compares. */
1367   if (signed_comparison_operator (cmp, cmp_op_mode)
1368       && (!alpha_compare_fp_p || flag_fast_math)
1369       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1370     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1371
1372   /* We can't put the comparison insides a conditional move;
1373      emit a compare instruction and put that inside the
1374      conditional move.  Make sure we emit only comparisons we have;
1375      swap or reverse as necessary.  */
1376
1377   switch (code)
1378     {
1379     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1380       /* We have these compares: */
1381       break;
1382
1383     case NE:
1384       /* This must be reversed. */
1385       code = reverse_condition (code);
1386       cmov_code = EQ;
1387       break;
1388
1389     case GE:  case GT:  case GEU:  case GTU:
1390       /* These must be swapped.  Make sure the new first operand is in
1391          a register.  */
1392       code = swap_condition (code);
1393       tem = op0, op0 = op1, op1 = tem;
1394       op0 = force_reg (cmp_mode, op0);
1395       break;
1396
1397     default:
1398       abort ();
1399     }
1400
1401   /* ??? We mark the the branch mode to be CCmode to prevent the compare
1402      and cmov from being combined, since the compare insn follows IEEE
1403      rules that the cmov does not.  */
1404   if (alpha_compare_fp_p && !flag_fast_math)
1405     cmov_mode = CCmode;
1406
1407   tem = gen_reg_rtx (cmp_op_mode);
1408   emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1409   return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1410 }
1411 \f
1412 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
1413    unaligned data:
1414
1415            unsigned:                       signed:
1416    word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
1417            ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
1418            lda    r3,X(r11)                lda    r3,X+2(r11)
1419            extwl  r1,r3,r1                 extql  r1,r3,r1
1420            extwh  r2,r3,r2                 extqh  r2,r3,r2
1421            or     r1.r2.r1                 or     r1,r2,r1
1422                                            sra    r1,48,r1
1423
1424    long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
1425            ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
1426            lda    r3,X(r11)                lda    r3,X(r11)
1427            extll  r1,r3,r1                 extll  r1,r3,r1
1428            extlh  r2,r3,r2                 extlh  r2,r3,r2
1429            or     r1.r2.r1                 addl   r1,r2,r1
1430
1431    quad:   ldq_u  r1,X(r11)
1432            ldq_u  r2,X+7(r11)
1433            lda    r3,X(r11)
1434            extql  r1,r3,r1
1435            extqh  r2,r3,r2
1436            or     r1.r2.r1
1437 */
1438
1439 void
1440 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
1441      rtx tgt, mem;
1442      HOST_WIDE_INT size, ofs;
1443      int sign;
1444 {
1445   rtx meml, memh, addr, extl, exth;
1446   enum machine_mode mode;
1447
1448   meml = gen_reg_rtx (DImode);
1449   memh = gen_reg_rtx (DImode);
1450   addr = gen_reg_rtx (DImode);
1451   extl = gen_reg_rtx (DImode);
1452   exth = gen_reg_rtx (DImode);
1453
1454   emit_move_insn (meml,
1455                   change_address (mem, DImode,
1456                                   gen_rtx_AND (DImode, 
1457                                                plus_constant (XEXP (mem, 0),
1458                                                               ofs),
1459                                                GEN_INT (-8))));
1460
1461   emit_move_insn (memh,
1462                   change_address (mem, DImode,
1463                                   gen_rtx_AND (DImode, 
1464                                                plus_constant (XEXP (mem, 0),
1465                                                               ofs + size - 1),
1466                                                GEN_INT (-8))));
1467
1468   if (sign && size == 2)
1469     {
1470       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
1471
1472       emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
1473       emit_insn (gen_extqh (exth, memh, addr));
1474
1475       /* We must use tgt here for the target.  Alpha-vms port fails if we use
1476          addr for the target, because addr is marked as a pointer and combine
1477          knows that pointers are always sign-extended 32 bit values.  */
1478       addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
1479       addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), 
1480                            addr, 1, OPTAB_WIDEN);
1481     }
1482   else
1483     {
1484       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
1485       emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
1486       switch (size)
1487         {
1488         case 2:
1489           emit_insn (gen_extwh (exth, memh, addr));
1490           mode = HImode;
1491           break;
1492
1493         case 4:
1494           emit_insn (gen_extlh (exth, memh, addr));
1495           mode = SImode;
1496           break;
1497
1498         case 8:
1499           emit_insn (gen_extqh (exth, memh, addr));
1500           mode = DImode;
1501           break;
1502         }
1503
1504       addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
1505                            gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
1506                            sign, OPTAB_WIDEN);
1507     }
1508
1509   if (addr != tgt)
1510     emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
1511 }
1512
1513 /* Similarly, use ins and msk instructions to perform unaligned stores.  */
1514
1515 void
1516 alpha_expand_unaligned_store (dst, src, size, ofs)
1517      rtx dst, src;
1518      HOST_WIDE_INT size, ofs;
1519 {
1520   rtx dstl, dsth, addr, insl, insh, meml, memh;
1521   
1522   dstl = gen_reg_rtx (DImode);
1523   dsth = gen_reg_rtx (DImode);
1524   insl = gen_reg_rtx (DImode);
1525   insh = gen_reg_rtx (DImode);
1526
1527   meml = change_address (dst, DImode,
1528                          gen_rtx_AND (DImode, 
1529                                       plus_constant (XEXP (dst, 0), ofs),
1530                                       GEN_INT (-8)));
1531   memh = change_address (dst, DImode,
1532                          gen_rtx_AND (DImode, 
1533                                       plus_constant (XEXP (dst, 0),
1534                                                      ofs+size-1),
1535                                       GEN_INT (-8)));
1536
1537   emit_move_insn (dsth, memh);
1538   emit_move_insn (dstl, meml);
1539   addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
1540
1541   if (src != const0_rtx)
1542     {
1543       emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
1544                             GEN_INT (size*8), addr));
1545
1546       switch (size)
1547         {
1548         case 2:
1549           emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
1550           break;
1551         case 4:
1552           emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
1553           break;
1554         case 8:
1555           emit_insn (gen_insql (insl, src, addr));
1556           break;
1557         }
1558     }
1559
1560   emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
1561
1562   switch (size)
1563     {
1564     case 2:
1565       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
1566       break;
1567     case 4:
1568       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
1569       break;
1570     case 8:
1571       {
1572 #if HOST_BITS_PER_WIDE_INT == 32
1573         rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
1574 #else
1575         rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
1576 #endif
1577         emit_insn (gen_mskxl (dstl, dstl, msk, addr));
1578       }
1579       break;
1580     }
1581
1582   if (src != const0_rtx)
1583     {
1584       dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
1585       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
1586     }
1587   
1588   /* Must store high before low for degenerate case of aligned.  */
1589   emit_move_insn (memh, dsth);
1590   emit_move_insn (meml, dstl);
1591 }
1592
1593 /* The block move code tries to maximize speed by separating loads and
1594    stores at the expense of register pressure: we load all of the data
1595    before we store it back out.  There are two secondary effects worth
1596    mentioning, that this speeds copying to/from aligned and unaligned
1597    buffers, and that it makes the code significantly easier to write.  */
1598
1599 #define MAX_MOVE_WORDS  8
1600
1601 /* Load an integral number of consecutive unaligned quadwords.  */
1602
1603 static void
1604 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
1605      rtx *out_regs;
1606      rtx smem;
1607      HOST_WIDE_INT words, ofs;
1608 {
1609   rtx const im8 = GEN_INT (-8);
1610   rtx const i64 = GEN_INT (64);
1611   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
1612   rtx sreg, areg;
1613   HOST_WIDE_INT i;
1614
1615   /* Generate all the tmp registers we need.  */
1616   for (i = 0; i < words; ++i)
1617     {
1618       data_regs[i] = out_regs[i];
1619       ext_tmps[i] = gen_reg_rtx (DImode);
1620     }
1621   data_regs[words] = gen_reg_rtx (DImode);
1622
1623   if (ofs != 0)
1624     smem = change_address (smem, GET_MODE (smem),
1625                            plus_constant (XEXP (smem, 0), ofs));
1626   
1627   /* Load up all of the source data.  */
1628   for (i = 0; i < words; ++i)
1629     {
1630       emit_move_insn (data_regs[i],
1631                       change_address (smem, DImode,
1632                                       gen_rtx_AND (DImode,
1633                                                    plus_constant (XEXP(smem,0),
1634                                                                   8*i),
1635                                                    im8)));
1636     }
1637   emit_move_insn (data_regs[words],
1638                   change_address (smem, DImode,
1639                                   gen_rtx_AND (DImode,
1640                                                plus_constant (XEXP(smem,0),
1641                                                               8*words - 1),
1642                                                im8)));
1643
1644   /* Extract the half-word fragments.  Unfortunately DEC decided to make
1645      extxh with offset zero a noop instead of zeroing the register, so 
1646      we must take care of that edge condition ourselves with cmov.  */
1647
1648   sreg = copy_addr_to_reg (XEXP (smem, 0));
1649   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, 
1650                        1, OPTAB_WIDEN);
1651   for (i = 0; i < words; ++i)
1652     {
1653       emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
1654
1655       emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
1656       emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
1657                               gen_rtx_IF_THEN_ELSE (DImode,
1658                                                     gen_rtx_EQ (DImode, areg,
1659                                                                 const0_rtx),
1660                                                     const0_rtx, ext_tmps[i])));
1661     }
1662
1663   /* Merge the half-words into whole words.  */
1664   for (i = 0; i < words; ++i)
1665     {
1666       out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
1667                                   ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
1668     }
1669 }
1670
1671 /* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
1672    may be NULL to store zeros.  */
1673
1674 static void
1675 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
1676      rtx *data_regs;
1677      rtx dmem;
1678      HOST_WIDE_INT words, ofs;
1679 {
1680   rtx const im8 = GEN_INT (-8);
1681   rtx const i64 = GEN_INT (64);
1682 #if HOST_BITS_PER_WIDE_INT == 32
1683   rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
1684 #else
1685   rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
1686 #endif
1687   rtx ins_tmps[MAX_MOVE_WORDS];
1688   rtx st_tmp_1, st_tmp_2, dreg;
1689   rtx st_addr_1, st_addr_2;
1690   HOST_WIDE_INT i;
1691
1692   /* Generate all the tmp registers we need.  */
1693   if (data_regs != NULL)
1694     for (i = 0; i < words; ++i)
1695       ins_tmps[i] = gen_reg_rtx(DImode);
1696   st_tmp_1 = gen_reg_rtx(DImode);
1697   st_tmp_2 = gen_reg_rtx(DImode);
1698   
1699   if (ofs != 0)
1700     dmem = change_address (dmem, GET_MODE (dmem),
1701                            plus_constant (XEXP (dmem, 0), ofs));
1702   
1703
1704   st_addr_2 = change_address (dmem, DImode,
1705                               gen_rtx_AND (DImode,
1706                                            plus_constant (XEXP(dmem,0),
1707                                                           words*8 - 1),
1708                                        im8));
1709   st_addr_1 = change_address (dmem, DImode,
1710                               gen_rtx_AND (DImode, 
1711                                            XEXP (dmem, 0),
1712                                            im8));
1713
1714   /* Load up the destination end bits.  */
1715   emit_move_insn (st_tmp_2, st_addr_2);
1716   emit_move_insn (st_tmp_1, st_addr_1);
1717
1718   /* Shift the input data into place.  */
1719   dreg = copy_addr_to_reg (XEXP (dmem, 0));
1720   if (data_regs != NULL)
1721     {
1722       for (i = words-1; i >= 0; --i)
1723         {
1724           emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
1725           emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
1726         }
1727       for (i = words-1; i > 0; --i)
1728         {
1729           ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
1730                                         ins_tmps[i-1], ins_tmps[i-1], 1,
1731                                         OPTAB_WIDEN);
1732         }
1733     }
1734
1735   /* Split and merge the ends with the destination data.  */
1736   emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
1737   emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
1738
1739   if (data_regs != NULL)
1740     {
1741       st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
1742                                st_tmp_2, 1, OPTAB_WIDEN);
1743       st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
1744                                st_tmp_1, 1, OPTAB_WIDEN);
1745     }
1746
1747   /* Store it all.  */
1748   emit_move_insn (st_addr_2, st_tmp_2);
1749   for (i = words-1; i > 0; --i)
1750     {
1751       emit_move_insn (change_address (dmem, DImode,
1752                                       gen_rtx_AND (DImode,
1753                                                    plus_constant(XEXP (dmem,0),
1754                                                                  i*8),
1755                                                im8)),
1756                       data_regs ? ins_tmps[i-1] : const0_rtx);
1757     }
1758   emit_move_insn (st_addr_1, st_tmp_1);
1759 }
1760
1761
1762 /* Expand string/block move operations.
1763
1764    operands[0] is the pointer to the destination.
1765    operands[1] is the pointer to the source.
1766    operands[2] is the number of bytes to move.
1767    operands[3] is the alignment.  */
1768
1769 int
1770 alpha_expand_block_move (operands)
1771      rtx operands[];
1772 {
1773   rtx bytes_rtx = operands[2];
1774   rtx align_rtx = operands[3];
1775   HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
1776   HOST_WIDE_INT src_align = INTVAL (align_rtx);
1777   HOST_WIDE_INT dst_align = src_align;
1778   rtx orig_src  = operands[1];
1779   rtx orig_dst  = operands[0];
1780   rtx data_regs[2*MAX_MOVE_WORDS+16];
1781   rtx tmp;
1782   int i, words, ofs, nregs = 0;
1783   
1784   if (bytes <= 0)
1785     return 1;
1786   if (bytes > MAX_MOVE_WORDS*8)
1787     return 0;
1788
1789   /* Look for additional alignment information from recorded register info.  */
1790
1791   tmp = XEXP (orig_src, 0);
1792   if (GET_CODE (tmp) == REG)
1793     {
1794       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
1795         src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1796     }
1797   else if (GET_CODE (tmp) == PLUS
1798            && GET_CODE (XEXP (tmp, 0)) == REG
1799            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1800     {
1801       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1802       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1803
1804       if (a > src_align)
1805         {
1806           if (a >= 8 && c % 8 == 0)
1807             src_align = 8;
1808           else if (a >= 4 && c % 4 == 0)
1809             src_align = 4;
1810           else if (a >= 2 && c % 2 == 0)
1811             src_align = 2;
1812         }
1813     }
1814         
1815   tmp = XEXP (orig_dst, 0);
1816   if (GET_CODE (tmp) == REG)
1817     {
1818       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
1819         dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
1820     }
1821   else if (GET_CODE (tmp) == PLUS
1822            && GET_CODE (XEXP (tmp, 0)) == REG
1823            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
1824     {
1825       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
1826       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
1827
1828       if (a > dst_align)
1829         {
1830           if (a >= 8 && c % 8 == 0)
1831             dst_align = 8;
1832           else if (a >= 4 && c % 4 == 0)
1833             dst_align = 4;
1834           else if (a >= 2 && c % 2 == 0)
1835             dst_align = 2;
1836         }
1837     }
1838
1839   /*
1840    * Load the entire block into registers.
1841    */
1842
1843   if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
1844     {
1845       enum machine_mode mode;
1846       tmp = XEXP (XEXP (orig_src, 0), 0);
1847
1848       mode = mode_for_size (bytes, MODE_INT, 1);
1849       if (mode != BLKmode
1850           && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes)
1851         {
1852           /* Whee!  Optimize the load to use the existing register.  */
1853           data_regs[nregs++] = gen_lowpart (mode, tmp);
1854           goto src_done;
1855         }
1856
1857       /* ??? We could potentially be copying 3 bytes or whatnot from
1858          a wider reg.  Probably not worth worrying about.  */
1859       /* No appropriate mode; fall back on memory.  */
1860       orig_src = change_address (orig_src, GET_MODE (orig_src),
1861                                  copy_addr_to_reg (XEXP (orig_src, 0)));
1862     }
1863
1864   ofs = 0;
1865   if (src_align >= 8 && bytes >= 8)
1866     {
1867       words = bytes / 8;
1868
1869       for (i = 0; i < words; ++i)
1870         data_regs[nregs+i] = gen_reg_rtx(DImode);
1871
1872       for (i = 0; i < words; ++i)
1873         {
1874           emit_move_insn (data_regs[nregs+i],
1875                           change_address(orig_src, DImode,
1876                                          plus_constant (XEXP (orig_src, 0),
1877                                                         ofs + i*8)));
1878         }
1879
1880       nregs += words;
1881       bytes -= words * 8;
1882       ofs += words * 8;
1883     }
1884   if (src_align >= 4 && bytes >= 4)
1885     {
1886       words = bytes / 4;
1887
1888       for (i = 0; i < words; ++i)
1889         data_regs[nregs+i] = gen_reg_rtx(SImode);
1890
1891       for (i = 0; i < words; ++i)
1892         {
1893           emit_move_insn (data_regs[nregs+i],
1894                           change_address(orig_src, SImode,
1895                                          plus_constant (XEXP (orig_src, 0),
1896                                                         ofs + i*4)));
1897         }
1898
1899       nregs += words;
1900       bytes -= words * 4;
1901       ofs += words * 4;
1902     }
1903   if (bytes >= 16)
1904     {
1905       words = bytes / 8;
1906
1907       for (i = 0; i < words+1; ++i)
1908         data_regs[nregs+i] = gen_reg_rtx(DImode);
1909
1910       alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs);
1911
1912       nregs += words;
1913       bytes -= words * 8;
1914       ofs += words * 8;
1915     }
1916   if (!TARGET_BWX && bytes >= 8)
1917     {
1918       data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
1919       alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
1920       bytes -= 8;
1921       ofs += 8;
1922     }
1923   if (!TARGET_BWX && bytes >= 4)
1924     {
1925       data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
1926       alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
1927       bytes -= 4;
1928       ofs += 4;
1929     }
1930   if (bytes >= 2)
1931     {
1932       if (src_align >= 2)
1933         {
1934           do {
1935             data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1936             emit_move_insn (tmp,
1937                             change_address (orig_src, HImode,
1938                                             plus_constant (XEXP (orig_src, 0),
1939                                                            ofs)));
1940             bytes -= 2;
1941             ofs += 2;
1942           } while (bytes >= 2);
1943         }
1944       else if (!TARGET_BWX)
1945         {
1946           data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
1947           alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
1948           bytes -= 2;
1949           ofs += 2;
1950         }
1951     }
1952   while (bytes > 0)
1953     {
1954       data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
1955       emit_move_insn (tmp,
1956                       change_address (orig_src, QImode,
1957                                       plus_constant (XEXP (orig_src, 0),
1958                                                      ofs)));
1959       bytes -= 1;
1960       ofs += 1;
1961     }
1962  src_done:
1963
1964   if (nregs > sizeof(data_regs)/sizeof(*data_regs))
1965     abort();
1966
1967   /*
1968    * Now save it back out again.
1969    */
1970
1971   i = 0, ofs = 0;
1972
1973   if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
1974     {
1975       enum machine_mode mode;
1976       tmp = XEXP (XEXP (orig_dst, 0), 0);
1977
1978       mode = mode_for_size (bytes, MODE_INT, 1);
1979       if (GET_MODE (tmp) == mode && nregs == 1)
1980         {
1981           emit_move_insn (tmp, data_regs[0]);
1982           i = 1;
1983           goto dst_done;
1984         }
1985
1986       /* ??? If nregs > 1, consider reconstructing the word in regs.  */
1987       /* ??? Optimize mode < dst_mode with strict_low_part.  */
1988       /* No appropriate mode; fall back on memory.  */
1989       orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
1990                                  copy_addr_to_reg (XEXP (orig_dst, 0)));
1991     }
1992
1993   /* Write out the data in whatever chunks reading the source allowed.  */
1994   if (dst_align >= 8)
1995     {
1996       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
1997         {
1998           emit_move_insn (change_address(orig_dst, DImode,
1999                                          plus_constant (XEXP (orig_dst, 0),
2000                                                         ofs)),
2001                           data_regs[i]);
2002           ofs += 8;
2003           i++;
2004         }
2005     }
2006   if (dst_align >= 4)
2007     {
2008       /* If the source has remaining DImode regs, write them out in
2009          two pieces.  */
2010       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2011         {
2012           tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2013                               NULL_RTX, 1, OPTAB_WIDEN);
2014
2015           emit_move_insn (change_address(orig_dst, SImode,
2016                                          plus_constant (XEXP (orig_dst, 0),
2017                                                         ofs)),
2018                           gen_lowpart (SImode, data_regs[i]));
2019           emit_move_insn (change_address(orig_dst, SImode,
2020                                          plus_constant (XEXP (orig_dst, 0),
2021                                                         ofs+4)),
2022                           gen_lowpart (SImode, tmp));
2023           ofs += 8;
2024           i++;
2025         }
2026
2027       while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2028         {
2029           emit_move_insn (change_address(orig_dst, SImode,
2030                                          plus_constant (XEXP (orig_dst, 0),
2031                                                         ofs)),
2032                           data_regs[i]);
2033           ofs += 4;
2034           i++;
2035         }
2036     }
2037   if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2038     {
2039       /* Write out a remaining block of words using unaligned methods.  */
2040
2041       for (words = 1; i+words < nregs ; ++words)
2042         if (GET_MODE (data_regs[i+words]) != DImode)
2043           break;
2044
2045       if (words == 1)
2046         alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2047       else
2048         alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2049      
2050       i += words;
2051       ofs += words * 8;
2052     }
2053
2054   /* Due to the above, this won't be aligned.  */
2055   /* ??? If we have more than one of these, consider constructing full
2056      words in registers and using alpha_expand_unaligned_store_words.  */
2057   while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2058     {
2059       alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2060       ofs += 4;
2061       i++;
2062     }
2063
2064   if (dst_align >= 2)
2065     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2066       {
2067         emit_move_insn (change_address (orig_dst, HImode,
2068                                         plus_constant (XEXP (orig_dst, 0),
2069                                                        ofs)),
2070                         data_regs[i]);
2071         i++;
2072         ofs += 2;
2073       }
2074   else
2075     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2076       {
2077         alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2078         i++;
2079         ofs += 2;
2080       }
2081   while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2082     {
2083       emit_move_insn (change_address (orig_dst, QImode,
2084                                       plus_constant (XEXP (orig_dst, 0),
2085                                                      ofs)),
2086                       data_regs[i]);
2087       i++;
2088       ofs += 1;
2089     }
2090  dst_done:
2091
2092   if (i != nregs)
2093     abort();
2094
2095   return 1;
2096 }
2097
2098 int
2099 alpha_expand_block_clear (operands)
2100      rtx operands[];
2101 {
2102   rtx bytes_rtx = operands[1];
2103   rtx align_rtx = operands[2];
2104   HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2105   HOST_WIDE_INT align = INTVAL (align_rtx);
2106   rtx orig_dst  = operands[0];
2107   rtx tmp;
2108   HOST_WIDE_INT i, words, ofs = 0;
2109   
2110   if (bytes <= 0)
2111     return 1;
2112   if (bytes > MAX_MOVE_WORDS*8)
2113     return 0;
2114
2115   /* Look for stricter alignment.  */
2116
2117   tmp = XEXP (orig_dst, 0);
2118   if (GET_CODE (tmp) == REG)
2119     {
2120       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2121         align = REGNO_POINTER_ALIGN (REGNO (tmp));
2122     }
2123   else if (GET_CODE (tmp) == PLUS
2124            && GET_CODE (XEXP (tmp, 0)) == REG
2125            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2126     {
2127       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2128       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2129
2130       if (a > align)
2131         {
2132           if (a >= 8 && c % 8 == 0)
2133             align = 8;
2134           else if (a >= 4 && c % 4 == 0)
2135             align = 4;
2136           else if (a >= 2 && c % 2 == 0)
2137             align = 2;
2138         }
2139     }
2140
2141   /* Handle a block of contiguous words first.  */
2142
2143   if (align >= 8 && bytes >= 8)
2144     {
2145       words = bytes / 8;
2146
2147       for (i = 0; i < words; ++i)
2148         {
2149           emit_move_insn (change_address(orig_dst, DImode,
2150                                          plus_constant (XEXP (orig_dst, 0),
2151                                                         ofs + i*8)),
2152                           const0_rtx);
2153         }
2154
2155       bytes -= words * 8;
2156       ofs += words * 8;
2157     }
2158   if (align >= 4 && bytes >= 4)
2159     {
2160       words = bytes / 4;
2161
2162       for (i = 0; i < words; ++i)
2163         {
2164           emit_move_insn (change_address(orig_dst, SImode,
2165                                          plus_constant (XEXP (orig_dst, 0),
2166                                                         ofs + i*4)),
2167                           const0_rtx);
2168         }
2169
2170       bytes -= words * 4;
2171       ofs += words * 4;
2172     }
2173   if (bytes >= 16)
2174     {
2175       words = bytes / 8;
2176
2177       alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2178
2179       bytes -= words * 8;
2180       ofs += words * 8;
2181     }
2182
2183   /* Next clean up any trailing pieces.  We know from the contiguous
2184      block move that there are no aligned SImode or DImode hunks left.  */
2185
2186   if (!TARGET_BWX && bytes >= 8)
2187     {
2188       alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2189       bytes -= 8;
2190       ofs += 8;
2191     }
2192   if (!TARGET_BWX && bytes >= 4)
2193     {
2194       alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2195       bytes -= 4;
2196       ofs += 4;
2197     }
2198   if (bytes >= 2)
2199     {
2200       if (align >= 2)
2201         {
2202           do {
2203             emit_move_insn (change_address (orig_dst, HImode,
2204                                             plus_constant (XEXP (orig_dst, 0),
2205                                                            ofs)),
2206                             const0_rtx);
2207             bytes -= 2;
2208             ofs += 2;
2209           } while (bytes >= 2);
2210         }
2211       else if (!TARGET_BWX)
2212         {
2213           alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2214           bytes -= 2;
2215           ofs += 2;
2216         }
2217     }
2218   while (bytes > 0)
2219     {
2220       emit_move_insn (change_address (orig_dst, QImode,
2221                                       plus_constant (XEXP (orig_dst, 0),
2222                                                      ofs)),
2223                       const0_rtx);
2224       bytes -= 1;
2225       ofs += 1;
2226     }
2227
2228   return 1;
2229 }
2230
2231 \f
2232 /* Adjust the cost of a scheduling dependency.  Return the new cost of
2233    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
2234
2235 int
2236 alpha_adjust_cost (insn, link, dep_insn, cost)
2237      rtx insn;
2238      rtx link;
2239      rtx dep_insn;
2240      int cost;
2241 {
2242   rtx set, set_src;
2243   enum attr_type insn_type, dep_insn_type;
2244
2245   /* If the dependence is an anti-dependence, there is no cost.  For an
2246      output dependence, there is sometimes a cost, but it doesn't seem
2247      worth handling those few cases.  */
2248
2249   if (REG_NOTE_KIND (link) != 0)
2250     return 0;
2251
2252   /* If we can't recognize the insns, we can't really do anything.  */
2253   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
2254     return cost;
2255
2256   insn_type = get_attr_type (insn);
2257   dep_insn_type = get_attr_type (dep_insn);
2258
2259   /* Bring in the user-defined memory latency.  */
2260   if (dep_insn_type == TYPE_ILD
2261       || dep_insn_type == TYPE_FLD
2262       || dep_insn_type == TYPE_LDSYM)
2263     cost += alpha_memory_latency-1;
2264
2265   switch (alpha_cpu)
2266     {
2267     case PROCESSOR_EV4:
2268       /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
2269          being stored, we can sometimes lower the cost.  */
2270
2271       if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
2272           && (set = single_set (dep_insn)) != 0
2273           && GET_CODE (PATTERN (insn)) == SET
2274           && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
2275         {
2276           switch (dep_insn_type)
2277             {
2278             case TYPE_ILD:
2279             case TYPE_FLD:
2280               /* No savings here.  */
2281               return cost;
2282
2283             case TYPE_IMUL:
2284               /* In these cases, we save one cycle.  */
2285               return cost - 1;
2286
2287             default:
2288               /* In all other cases, we save two cycles.  */
2289               return MAX (0, cost - 2);
2290             }
2291         }
2292
2293       /* Another case that needs adjustment is an arithmetic or logical
2294          operation.  It's cost is usually one cycle, but we default it to
2295          two in the MD file.  The only case that it is actually two is
2296          for the address in loads, stores, and jumps.  */
2297
2298       if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
2299         {
2300           switch (insn_type)
2301             {
2302             case TYPE_ILD:
2303             case TYPE_IST:
2304             case TYPE_FLD:
2305             case TYPE_FST:
2306             case TYPE_JSR:
2307               return cost;
2308             default:
2309               return 1;
2310             }
2311         }
2312
2313       /* The final case is when a compare feeds into an integer branch;
2314          the cost is only one cycle in that case.  */
2315
2316       if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
2317         return 1;
2318       break;
2319
2320     case PROCESSOR_EV5:
2321       /* And the lord DEC saith:  "A special bypass provides an effective
2322          latency of 0 cycles for an ICMP or ILOG insn producing the test
2323          operand of an IBR or ICMOV insn." */
2324
2325       if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
2326           && (set = single_set (dep_insn)) != 0)
2327         {
2328           /* A branch only has one input.  This must be it.  */
2329           if (insn_type == TYPE_IBR)
2330             return 0;
2331           /* A conditional move has three, make sure it is the test.  */
2332           if (insn_type == TYPE_ICMOV
2333               && GET_CODE (set_src = PATTERN (insn)) == SET
2334               && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
2335               && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
2336             return 0;
2337         }
2338
2339       /* "The multiplier is unable to receive data from IEU bypass paths.
2340          The instruction issues at the expected time, but its latency is
2341          increased by the time it takes for the input data to become
2342          available to the multiplier" -- which happens in pipeline stage
2343          six, when results are comitted to the register file.  */
2344
2345       if (insn_type == TYPE_IMUL)
2346         {
2347           switch (dep_insn_type)
2348             {
2349             /* These insns produce their results in pipeline stage five.  */
2350             case TYPE_ILD:
2351             case TYPE_ICMOV:
2352             case TYPE_IMUL:
2353             case TYPE_MVI:
2354               return cost + 1;
2355
2356             /* Other integer insns produce results in pipeline stage four.  */
2357             default:
2358               return cost + 2;
2359             }
2360         }
2361       break;
2362
2363     case PROCESSOR_EV6:
2364       /* There is additional latency to move the result of (most) FP 
2365          operations anywhere but the FP register file.  */
2366
2367       if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
2368           && (dep_insn_type == TYPE_FADD ||
2369               dep_insn_type == TYPE_FMUL ||
2370               dep_insn_type == TYPE_FCMOV))
2371         return cost + 2;
2372
2373       break;
2374     }
2375
2376   /* Otherwise, return the default cost. */
2377   return cost;
2378 }
2379 \f
2380 /* Functions to save and restore alpha_return_addr_rtx.  */
2381
2382 struct machine_function
2383 {
2384   rtx ra_rtx;
2385 };
2386
2387 static void
2388 alpha_save_machine_status (p)
2389      struct function *p;
2390 {
2391   struct machine_function *machine =
2392     (struct machine_function *) xmalloc (sizeof (struct machine_function));
2393
2394   p->machine = machine;
2395   machine->ra_rtx = alpha_return_addr_rtx;
2396 }
2397
2398 static void
2399 alpha_restore_machine_status (p)
2400      struct function *p;
2401 {
2402   struct machine_function *machine = p->machine;
2403
2404   alpha_return_addr_rtx = machine->ra_rtx;
2405
2406   free (machine);
2407   p->machine = (struct machine_function *)0;
2408 }
2409
2410 /* Do anything needed before RTL is emitted for each function.  */
2411
2412 void
2413 alpha_init_expanders ()
2414 {
2415   alpha_return_addr_rtx = NULL_RTX;
2416
2417   /* Arrange to save and restore machine status around nested functions.  */
2418   save_machine_status = alpha_save_machine_status;
2419   restore_machine_status = alpha_restore_machine_status;
2420 }
2421
2422 /* Start the ball rolling with RETURN_ADDR_RTX.  */
2423
2424 rtx
2425 alpha_return_addr (count, frame)
2426      int count;
2427      rtx frame;
2428 {
2429   rtx init;
2430
2431   if (count != 0)
2432     return const0_rtx;
2433
2434   if (alpha_return_addr_rtx)
2435     return alpha_return_addr_rtx;
2436
2437   /* No rtx yet.  Invent one, and initialize it from $26 in the prologue.  */
2438   alpha_return_addr_rtx = gen_reg_rtx (Pmode);
2439   init = gen_rtx_SET (Pmode, alpha_return_addr_rtx,
2440                       gen_rtx_REG (Pmode, REG_RA));
2441
2442   /* Emit the insn to the prologue with the other argument copies.  */
2443   push_topmost_sequence ();
2444   emit_insn_after (init, get_insns ());
2445   pop_topmost_sequence ();
2446
2447   return alpha_return_addr_rtx;
2448 }
2449
2450 static int
2451 alpha_ra_ever_killed ()
2452 {
2453   if (!alpha_return_addr_rtx)
2454     return regs_ever_live[REG_RA];
2455
2456   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
2457                             get_insns(), NULL_RTX);
2458 }
2459
2460 \f
2461 /* Print an operand.  Recognize special options, documented below.  */
2462
2463 void
2464 print_operand (file, x, code)
2465     FILE *file;
2466     rtx x;
2467     char code;
2468 {
2469   int i;
2470
2471   switch (code)
2472     {
2473     case '&':
2474       /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
2475          chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
2476          mode.  alpha_fprm controls which suffix is generated.  */
2477       switch (alpha_fprm)
2478         {
2479         case ALPHA_FPRM_NORM:
2480           break;
2481         case ALPHA_FPRM_MINF: 
2482           fputc ('m', file);
2483           break;
2484         case ALPHA_FPRM_CHOP:
2485           fputc ('c', file);
2486           break;
2487         case ALPHA_FPRM_DYN:
2488           fputc ('d', file);
2489           break;
2490         }
2491       break;
2492
2493     case '\'':
2494       /* Generates trap-mode suffix for instructions that accept the su
2495          suffix only (cmpt et al).  */
2496       if (alpha_tp == ALPHA_TP_INSN)
2497         fputs ("su", file);
2498       break;
2499
2500     case '`':
2501       /* Generates trap-mode suffix for instructions that accept the
2502          v and sv suffix.  The only instruction that needs this is cvtql.  */
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         case ALPHA_FPTM_SUI:
2512           fputs ("sv", file);
2513           break;
2514         }
2515       break;
2516
2517     case '(':
2518       /* Generates trap-mode suffix for instructions that accept the
2519          v, sv, and svi suffix.  The only instruction that needs this
2520          is cvttq.  */
2521       switch (alpha_fptm)
2522         {
2523         case ALPHA_FPTM_N:
2524           break;
2525         case ALPHA_FPTM_U:
2526           fputs ("v", file);
2527           break;
2528         case ALPHA_FPTM_SU:
2529           fputs ("sv", file);
2530           break;
2531         case ALPHA_FPTM_SUI:
2532           fputs ("svi", file);
2533           break;
2534         }
2535       break;
2536
2537     case ')':
2538       /* Generates trap-mode suffix for instructions that accept the u, su,
2539          and sui suffix.  This is the bulk of the IEEE floating point
2540          instructions (addt et al).  */
2541       switch (alpha_fptm)
2542         {
2543         case ALPHA_FPTM_N:
2544           break;
2545         case ALPHA_FPTM_U:
2546           fputc ('u', file);
2547           break;
2548         case ALPHA_FPTM_SU:
2549           fputs ("su", file);
2550           break;
2551         case ALPHA_FPTM_SUI:
2552           fputs ("sui", file);
2553           break;
2554         }
2555       break;
2556
2557     case '+':
2558       /* Generates trap-mode suffix for instructions that accept the sui
2559          suffix (cvtqt and cvtqs).  */
2560       switch (alpha_fptm)
2561         {
2562         case ALPHA_FPTM_N:
2563         case ALPHA_FPTM_U:
2564         case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
2565           break;
2566         case ALPHA_FPTM_SUI:
2567           fputs ("sui", file);
2568           break;
2569         }
2570       break;
2571
2572     case ',':
2573       /* Generates single precision instruction suffix.  */
2574       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
2575       break;
2576
2577     case '-':
2578       /* Generates double precision instruction suffix.  */
2579       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
2580       break;
2581
2582     case 'r':
2583       /* If this operand is the constant zero, write it as "$31".  */
2584       if (GET_CODE (x) == REG)
2585         fprintf (file, "%s", reg_names[REGNO (x)]);
2586       else if (x == CONST0_RTX (GET_MODE (x)))
2587         fprintf (file, "$31");
2588       else
2589         output_operand_lossage ("invalid %%r value");
2590
2591       break;
2592
2593     case 'R':
2594       /* Similar, but for floating-point.  */
2595       if (GET_CODE (x) == REG)
2596         fprintf (file, "%s", reg_names[REGNO (x)]);
2597       else if (x == CONST0_RTX (GET_MODE (x)))
2598         fprintf (file, "$f31");
2599       else
2600         output_operand_lossage ("invalid %%R value");
2601
2602       break;
2603
2604     case 'N':
2605       /* Write the 1's complement of a constant.  */
2606       if (GET_CODE (x) != CONST_INT)
2607         output_operand_lossage ("invalid %%N value");
2608
2609       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
2610       break;
2611
2612     case 'P':
2613       /* Write 1 << C, for a constant C.  */
2614       if (GET_CODE (x) != CONST_INT)
2615         output_operand_lossage ("invalid %%P value");
2616
2617       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
2618       break;
2619
2620     case 'h':
2621       /* Write the high-order 16 bits of a constant, sign-extended.  */
2622       if (GET_CODE (x) != CONST_INT)
2623         output_operand_lossage ("invalid %%h value");
2624
2625       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
2626       break;
2627
2628     case 'L':
2629       /* Write the low-order 16 bits of a constant, sign-extended.  */
2630       if (GET_CODE (x) != CONST_INT)
2631         output_operand_lossage ("invalid %%L value");
2632
2633       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
2634                (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
2635       break;
2636
2637     case 'm':
2638       /* Write mask for ZAP insn.  */
2639       if (GET_CODE (x) == CONST_DOUBLE)
2640         {
2641           HOST_WIDE_INT mask = 0;
2642           HOST_WIDE_INT value;
2643
2644           value = CONST_DOUBLE_LOW (x);
2645           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2646                i++, value >>= 8)
2647             if (value & 0xff)
2648               mask |= (1 << i);
2649
2650           value = CONST_DOUBLE_HIGH (x);
2651           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
2652                i++, value >>= 8)
2653             if (value & 0xff)
2654               mask |= (1 << (i + sizeof (int)));
2655
2656           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
2657         }
2658
2659       else if (GET_CODE (x) == CONST_INT)
2660         {
2661           HOST_WIDE_INT mask = 0, value = INTVAL (x);
2662
2663           for (i = 0; i < 8; i++, value >>= 8)
2664             if (value & 0xff)
2665               mask |= (1 << i);
2666
2667           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
2668         }
2669       else
2670         output_operand_lossage ("invalid %%m value");
2671       break;
2672
2673     case 'M':
2674       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
2675       if (GET_CODE (x) != CONST_INT
2676           || (INTVAL (x) != 8 && INTVAL (x) != 16
2677               && INTVAL (x) != 32 && INTVAL (x) != 64))
2678         output_operand_lossage ("invalid %%M value");
2679
2680       fprintf (file, "%s",
2681                (INTVAL (x) == 8 ? "b"
2682                 : INTVAL (x) == 16 ? "w"
2683                 : INTVAL (x) == 32 ? "l"
2684                 : "q"));
2685       break;
2686
2687     case 'U':
2688       /* Similar, except do it from the mask.  */
2689       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
2690         fprintf (file, "b");
2691       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
2692         fprintf (file, "w");
2693       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
2694         fprintf (file, "l");
2695 #if HOST_BITS_PER_WIDE_INT == 32
2696       else if (GET_CODE (x) == CONST_DOUBLE
2697                && CONST_DOUBLE_HIGH (x) == 0
2698                && CONST_DOUBLE_LOW (x) == -1)
2699         fprintf (file, "l");
2700       else if (GET_CODE (x) == CONST_DOUBLE
2701                && CONST_DOUBLE_HIGH (x) == -1
2702                && CONST_DOUBLE_LOW (x) == -1)
2703         fprintf (file, "q");
2704 #else
2705       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff)
2706         fprintf (file, "q");
2707       else if (GET_CODE (x) == CONST_DOUBLE
2708                && CONST_DOUBLE_HIGH (x) == 0
2709                && CONST_DOUBLE_LOW (x) == -1)
2710         fprintf (file, "q");
2711 #endif
2712       else
2713         output_operand_lossage ("invalid %%U value");
2714       break;
2715
2716     case 's':
2717       /* Write the constant value divided by 8.  */
2718       if (GET_CODE (x) != CONST_INT
2719           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2720           && (INTVAL (x) & 7) != 8)
2721         output_operand_lossage ("invalid %%s value");
2722
2723       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
2724       break;
2725
2726     case 'S':
2727       /* Same, except compute (64 - c) / 8 */
2728
2729       if (GET_CODE (x) != CONST_INT
2730           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
2731           && (INTVAL (x) & 7) != 8)
2732         output_operand_lossage ("invalid %%s value");
2733
2734       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
2735       break;
2736
2737     case 'C': case 'D': case 'c': case 'd':
2738       /* Write out comparison name.  */
2739       {
2740         enum rtx_code c = GET_CODE (x);
2741
2742         if (GET_RTX_CLASS (c) != '<')
2743           output_operand_lossage ("invalid %%C value");
2744
2745         if (code == 'D')
2746           c = reverse_condition (c);
2747         else if (code == 'c')
2748           c = swap_condition (c);
2749         else if (code == 'd')
2750           c = swap_condition (reverse_condition (c));
2751
2752         if (c == LEU)
2753           fprintf (file, "ule");
2754         else if (c == LTU)
2755           fprintf (file, "ult");
2756         else
2757           fprintf (file, "%s", GET_RTX_NAME (c));
2758       }
2759       break;
2760
2761     case 'E':
2762       /* Write the divide or modulus operator.  */
2763       switch (GET_CODE (x))
2764         {
2765         case DIV:
2766           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
2767           break;
2768         case UDIV:
2769           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
2770           break;
2771         case MOD:
2772           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
2773           break;
2774         case UMOD:
2775           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
2776           break;
2777         default:
2778           output_operand_lossage ("invalid %%E value");
2779           break;
2780         }
2781       break;
2782
2783     case 'A':
2784       /* Write "_u" for unaligned access.  */
2785       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
2786         fprintf (file, "_u");
2787       break;
2788
2789     case 0:
2790       if (GET_CODE (x) == REG)
2791         fprintf (file, "%s", reg_names[REGNO (x)]);
2792       else if (GET_CODE (x) == MEM)
2793         output_address (XEXP (x, 0));
2794       else
2795         output_addr_const (file, x);
2796       break;
2797
2798     default:
2799       output_operand_lossage ("invalid %%xn code");
2800     }
2801 }
2802 \f
2803 /* Do what is necessary for `va_start'.  The argument is ignored;
2804    We look at the current function to determine if stdarg or varargs
2805    is used and fill in an initial va_list.  A pointer to this constructor
2806    is returned.  */
2807
2808 struct rtx_def *
2809 alpha_builtin_saveregs (arglist)
2810      tree arglist;
2811 {
2812   rtx block, addr, dest, argsize;
2813   tree fntype = TREE_TYPE (current_function_decl);
2814   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
2815                 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2816                     != void_type_node));
2817
2818   /* Compute the current position into the args, taking into account
2819      both registers and memory.  Both of these are already included in
2820      NUM_ARGS.  */
2821
2822   argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
2823
2824   /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
2825      storing fp arg registers in the first 48 bytes, and the integer arg
2826      registers in the next 48 bytes.  This is only done, however, if any
2827      integer registers need to be stored.
2828
2829      If no integer registers need be stored, then we must subtract 48 in
2830      order to account for the integer arg registers which are counted in
2831      argsize above, but which are not actually stored on the stack.  */
2832
2833   if (TARGET_OPEN_VMS)
2834     addr = plus_constant (virtual_incoming_args_rtx,
2835                           NUM_ARGS <= 5 + stdarg
2836                           ? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
2837   else
2838     addr = (NUM_ARGS <= 5 + stdarg
2839             ? plus_constant (virtual_incoming_args_rtx,
2840                              6 * UNITS_PER_WORD)
2841             : plus_constant (virtual_incoming_args_rtx,
2842                              - (6 * UNITS_PER_WORD)));
2843
2844   /* For VMS, we include the argsize, while on Unix, it's handled as
2845      a separate field.  */
2846   if (TARGET_OPEN_VMS)
2847     addr = plus_constant (addr, INTVAL (argsize));
2848
2849   addr = force_operand (addr, NULL_RTX);
2850
2851 #ifdef POINTERS_EXTEND_UNSIGNED
2852   addr = convert_memory_address (ptr_mode, addr);
2853 #endif
2854
2855   if (TARGET_OPEN_VMS)
2856     return addr;
2857   else
2858     {
2859       /* Allocate the va_list constructor */
2860       block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2861       RTX_UNCHANGING_P (block) = 1;
2862       RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
2863
2864       /* Store the address of the first integer register in the __base
2865          member.  */
2866
2867       dest = change_address (block, ptr_mode, XEXP (block, 0));
2868       emit_move_insn (dest, addr);
2869
2870       if (flag_check_memory_usage)
2871         emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2872                            dest, ptr_mode,
2873                            GEN_INT (GET_MODE_SIZE (ptr_mode)),
2874                            TYPE_MODE (sizetype),
2875                            GEN_INT (MEMORY_USE_RW), 
2876                            TYPE_MODE (integer_type_node));
2877   
2878       /* Store the argsize as the __va_offset member.  */
2879       dest = change_address (block, TYPE_MODE (integer_type_node),
2880                              plus_constant (XEXP (block, 0),
2881                                             POINTER_SIZE/BITS_PER_UNIT));
2882       emit_move_insn (dest, argsize);
2883
2884       if (flag_check_memory_usage)
2885         emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
2886                            dest, ptr_mode,
2887                            GEN_INT (GET_MODE_SIZE
2888                                     (TYPE_MODE (integer_type_node))),
2889                            TYPE_MODE (sizetype),
2890                            GEN_INT (MEMORY_USE_RW),
2891                            TYPE_MODE (integer_type_node));
2892
2893       /* Return the address of the va_list constructor, but don't put it in a
2894          register.  Doing so would fail when not optimizing and produce worse
2895          code when optimizing.  */
2896       return XEXP (block, 0);
2897     }
2898 }
2899 \f
2900 /* This page contains routines that are used to determine what the function
2901    prologue and epilogue code will do and write them out.  */
2902
2903 /* Compute the size of the save area in the stack.  */
2904
2905 #if OPEN_VMS
2906
2907 /* These variables are used for communication between the following functions.
2908    They indicate various things about the current function being compiled
2909    that are used to tell what kind of prologue, epilogue and procedure
2910    descriptior to generate. */
2911
2912 /* Nonzero if we need a stack procedure.  */
2913 static int is_stack_procedure;
2914
2915 /* Register number (either FP or SP) that is used to unwind the frame.  */
2916 static int unwind_regno;
2917
2918 /* Register number used to save FP.  We need not have one for RA since
2919    we don't modify it for register procedures.  This is only defined
2920    for register frame procedures.  */
2921 static int save_fp_regno;
2922
2923 /* Register number used to reference objects off our PV.  */
2924 static int base_regno;
2925
2926 /*  Compute register masks for saved registers.  */
2927
2928 static void
2929 alpha_sa_mask (imaskP, fmaskP)
2930     unsigned long *imaskP;
2931     unsigned long *fmaskP;
2932 {
2933   unsigned long imask = 0;
2934   unsigned long fmask = 0;
2935   int i;
2936
2937   if (is_stack_procedure)
2938     imask |= (1L << HARD_FRAME_POINTER_REGNUM);
2939
2940   /* One for every register we have to save.  */
2941
2942   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2943     if (! fixed_regs[i] && ! call_used_regs[i]
2944         && regs_ever_live[i] && i != REG_RA)
2945       {
2946         if (i < 32)
2947           imask |= (1L << i);
2948         else
2949           fmask |= (1L << (i - 32));
2950       }
2951
2952   *imaskP = imask;
2953   *fmaskP = fmask;
2954
2955   return;
2956 }
2957
2958 int
2959 alpha_sa_size ()
2960 {
2961   int sa_size = 0;
2962   HOST_WIDE_INT stack_needed;
2963   int i;
2964
2965   /* One for every register we have to save.  */
2966
2967   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2968     if (! fixed_regs[i] && ! call_used_regs[i]
2969         && regs_ever_live[i] && i != REG_RA)
2970       sa_size++;
2971
2972   /* Start by assuming we can use a register procedure if we don't make any
2973      calls (REG_RA not used) or need to save any registers and a stack
2974      procedure if we do.  */
2975   is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
2976
2977   /* Decide whether to refer to objects off our PV via FP or PV.
2978      If we need FP for something else or if we receive a nonlocal
2979      goto (which expects PV to contain the value), we must use PV.
2980      Otherwise, start by assuming we can use FP.  */
2981   base_regno = (frame_pointer_needed || current_function_has_nonlocal_label
2982                 || is_stack_procedure
2983                 || current_function_outgoing_args_size
2984                 ? REG_PV : HARD_FRAME_POINTER_REGNUM);
2985
2986   /* If we want to copy PV into FP, we need to find some register in which to
2987      save FP.  */
2988
2989   save_fp_regno = -1;
2990
2991   if (base_regno == HARD_FRAME_POINTER_REGNUM)
2992     for (i = 0; i < 32; i++)
2993       if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
2994         save_fp_regno = i;
2995
2996   if (save_fp_regno == -1)
2997     base_regno = REG_PV, is_stack_procedure = 1;
2998
2999   /* Stack unwinding should be done via FP unless we use it for PV.  */
3000   unwind_regno
3001     = base_regno == REG_PV ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
3002
3003   /* If this is a stack procedure, allow space for saving FP and RA.  */
3004   if (is_stack_procedure)
3005     sa_size += 2;
3006
3007   return sa_size * 8;
3008 }
3009
3010 int
3011 alpha_pv_save_size ()
3012 {
3013   alpha_sa_size ();
3014   return is_stack_procedure ? 8 : 0;
3015 }
3016
3017 int
3018 alpha_using_fp ()
3019 {
3020   alpha_sa_size ();
3021   return unwind_regno == HARD_FRAME_POINTER_REGNUM;
3022 }
3023
3024 #else /* ! OPEN_VMS */
3025
3026 int
3027 alpha_sa_size ()
3028 {
3029   int size = 0;
3030   int i;
3031
3032   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3033     if (! fixed_regs[i] && ! call_used_regs[i]
3034         && regs_ever_live[i] && i != REG_RA)
3035       size++;
3036
3037   /* If some registers were saved but not reg 26, reg 26 must also
3038      be saved, so leave space for it.  */
3039   if (size != 0 || alpha_ra_ever_killed ())
3040     size++;
3041
3042   /* Our size must be even (multiple of 16 bytes).  */
3043   if (size & 1)
3044     size ++;
3045
3046   return size * 8;
3047 }
3048
3049 #endif /* ! OPEN_VMS */
3050
3051 /* Return 1 if this function can directly return via $26.  */
3052
3053 int
3054 direct_return ()
3055 {
3056   return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
3057           && get_frame_size () == 0
3058           && current_function_outgoing_args_size == 0
3059           && current_function_pretend_args_size == 0);
3060 }
3061
3062 /* Write a version stamp.  Don't write anything if we are running as a
3063    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
3064
3065 #ifdef HAVE_STAMP_H
3066 #include <stamp.h>
3067 #endif
3068
3069 void
3070 alpha_write_verstamp (file)
3071      FILE *file;
3072 {
3073 #ifdef MS_STAMP
3074   fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
3075 #endif
3076 }
3077 \f
3078 /* Write code to add constant C to register number IN_REG (possibly 31)
3079    and put the result into OUT_REG.  Use TEMP_REG as a scratch register;
3080    usually this will be OUT_REG, but should not be if OUT_REG is 
3081    STACK_POINTER_REGNUM, since it must be updated in a single instruction.
3082    Write the code to FILE.  */
3083
3084 static void
3085 add_long_const (file, c, in_reg, out_reg, temp_reg)
3086      FILE *file;
3087      HOST_WIDE_INT c;
3088      int in_reg, out_reg, temp_reg;
3089 {
3090   HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
3091   HOST_WIDE_INT tmp1 = c - low;
3092   HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3093   HOST_WIDE_INT extra = 0;
3094
3095   /* We don't have code to write out constants larger than 32 bits.  */
3096 #if HOST_BITS_PER_LONG_INT == 64
3097   if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
3098     abort ();
3099 #endif
3100
3101   /* If HIGH will be interpreted as negative, we must adjust it to do two
3102      ldha insns.  Note that we will never be building a negative constant
3103      here.  */
3104
3105   if (high & 0x8000)
3106     {
3107       extra = 0x4000;
3108       tmp1 -= 0x40000000;
3109       high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
3110     }
3111
3112   if (low != 0)
3113     {
3114       int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
3115
3116       if (low >= 0 && low < 255)
3117         fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
3118       else
3119         fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
3120
3121       in_reg = result_reg;
3122     }
3123
3124   if (extra)
3125     {
3126       int result_reg = (high == 0) ? out_reg : temp_reg;
3127
3128       fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
3129       in_reg = result_reg;
3130     }
3131
3132   if (high)
3133     fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
3134 }
3135
3136 /* Write function prologue.  */
3137
3138 #if OPEN_VMS
3139
3140 /* On vms we have two kinds of functions:
3141
3142    - stack frame (PROC_STACK)
3143         these are 'normal' functions with local vars and which are
3144         calling other functions
3145    - register frame (PROC_REGISTER)
3146         keeps all data in registers, needs no stack
3147
3148    We must pass this to the assembler so it can generate the
3149    proper pdsc (procedure descriptor)
3150    This is done with the '.pdesc' command.
3151
3152    size is the stack size needed for local variables.  */
3153
3154 void
3155 output_prolog (file, size)
3156      FILE *file;
3157      HOST_WIDE_INT size;
3158 {
3159   unsigned long imask = 0;
3160   unsigned long fmask = 0;
3161   /* Stack space needed for pushing registers clobbered by us.  */
3162   HOST_WIDE_INT sa_size;
3163   /* Complete stack size needed.  */
3164   HOST_WIDE_INT frame_size;
3165   /* Offset from base reg to register save area.  */
3166   int rsa_offset = 8;
3167   /* Offset during register save.  */
3168   int reg_offset;
3169   /* Label for the procedure entry.  */
3170   char *entry_label = (char *) alloca (strlen (alpha_function_name) + 6);
3171   int i;
3172
3173   sa_size = alpha_sa_size ();
3174   frame_size
3175     = ALPHA_ROUND (sa_size 
3176                    + (is_stack_procedure ? 8 : 0)
3177                    + size + current_function_pretend_args_size);
3178
3179   /* Issue function start and label.  */
3180   fprintf (file, "\t.ent ");
3181   assemble_name (file, alpha_function_name);
3182   fprintf (file, "\n");
3183   sprintf (entry_label, "%s..en", alpha_function_name);
3184   ASM_OUTPUT_LABEL (file, entry_label);
3185   inside_function = TRUE;
3186
3187   fprintf (file, "\t.base $%d\n", base_regno);
3188
3189   /* Calculate register masks for clobbered registers.  */
3190
3191   if (is_stack_procedure)
3192     alpha_sa_mask (&imask, &fmask);
3193
3194   /* Adjust the stack by the frame size.  If the frame size is > 4096
3195      bytes, we need to be sure we probe somewhere in the first and last
3196      4096 bytes (we can probably get away without the latter test) and
3197      every 8192 bytes in between.  If the frame size is > 32768, we
3198      do this in a loop.  Otherwise, we generate the explicit probe
3199      instructions. 
3200
3201      Note that we are only allowed to adjust sp once in the prologue.  */
3202
3203   if (frame_size < 32768)
3204     {
3205       if (frame_size > 4096)
3206         {
3207           int probed = 4096;
3208
3209           fprintf (file, "\tstq $31,-%d($30)\n", probed);
3210
3211           while (probed + 8192 < frame_size)
3212             fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3213
3214           /* We only have to do this probe if we aren't saving registers.  */
3215           if (sa_size == 0 && probed + 4096 < frame_size)
3216             fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3217         }
3218
3219       if (frame_size != 0)
3220           fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3221     }
3222   else
3223     {
3224       /* Here we generate code to set R4 to SP + 4096 and set R23 to the
3225          number of 8192 byte blocks to probe.  We then probe each block
3226          in the loop and then set SP to the proper location.  If the
3227          amount remaining is > 4096, we have to do one more probe if we
3228          are not saving any registers.  */
3229
3230       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3231       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3232
3233       add_long_const (file, blocks, 31, 23, 23);
3234
3235       fprintf (file, "\tlda $22,4096($30)\n");
3236
3237       fputc ('$', file);
3238       assemble_name (file, alpha_function_name);
3239       fprintf (file, "..sc:\n");
3240
3241       fprintf (file, "\tstq $31,-8192($22)\n");
3242       fprintf (file, "\tsubq $23,1,$23\n");
3243       fprintf (file, "\tlda $22,-8192($22)\n");
3244
3245       fprintf (file, "\tbne $23,$");
3246       assemble_name (file, alpha_function_name);
3247       fprintf (file, "..sc\n");
3248
3249       if (leftover > 4096 && sa_size == 0)
3250         fprintf (file, "\tstq $31,-%d($22)\n", leftover);
3251
3252       fprintf (file, "\tlda $30,-%d($22)\n", leftover);
3253     }
3254
3255   if (is_stack_procedure)
3256     {
3257       int reg_offset = rsa_offset;
3258
3259       /* Store R26 (RA) first.  */
3260       fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
3261       reg_offset += 8;
3262
3263       /* Store integer regs. according to mask.  */
3264       for (i = 0; i < 32; i++)
3265         if (imask & (1L<<i))
3266           {
3267             fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
3268             reg_offset += 8;
3269           }
3270
3271       /* Print the register mask and do floating-point saves.  */
3272
3273       if (imask)
3274         fprintf (file, "\t.mask 0x%x,0\n", imask);
3275
3276       for (i = 0; i < 32; i++)
3277         {
3278           if (fmask & (1L << i))
3279             {
3280               fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
3281               reg_offset += 8;
3282             }
3283         }
3284
3285       /* Print the floating-point mask, if we've saved any fp register.  */
3286       if (fmask)
3287         fprintf (file, "\t.fmask 0x%x,0\n", fmask);
3288
3289       fprintf (file, "\tstq $27,0($30)\n");
3290     }
3291   else 
3292     {
3293       fprintf (file, "\t.fp_save $%d\n", save_fp_regno);
3294       fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3295                HARD_FRAME_POINTER_REGNUM, save_fp_regno);
3296     }
3297
3298   if (base_regno != REG_PV)
3299     fprintf (file, "\tbis $%d,$%d,$%d\n", REG_PV, REG_PV, base_regno);
3300
3301   if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3302     fprintf (file, "\tbis $%d,$%d,$%d\n", STACK_POINTER_REGNUM,
3303              STACK_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM);
3304
3305   /* Describe our frame.  */
3306   fprintf (file, "\t.frame $%d,", unwind_regno);
3307
3308   /* If the frame size is larger than an integer, print it as zero to
3309      avoid an assembler error.  We won't be properly describing such a
3310      frame, but that's the best we can do.  */
3311   fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3312 #if HOST_BITS_PER_WIDE_INT == 64
3313            frame_size >= (1l << 31) ? 0:
3314 #endif
3315            frame_size
3316            );
3317   fprintf (file, ",$26,%d\n", rsa_offset);
3318
3319   /* If we have to allocate space for outgoing args, do it now.  */
3320   if (current_function_outgoing_args_size != 0)
3321     fprintf (file, "\tlda $%d,%d($%d)\n", STACK_POINTER_REGNUM,
3322              - ALPHA_ROUND (current_function_outgoing_args_size),
3323              HARD_FRAME_POINTER_REGNUM);
3324
3325   fprintf (file, "\t.prologue\n");
3326
3327   readonly_section ();
3328   fprintf (file, "\t.align 3\n");
3329   assemble_name (file, alpha_function_name); fputs ("..na:\n", file);
3330   fputs ("\t.ascii \"", file);
3331   assemble_name (file, alpha_function_name);
3332   fputs ("\\0\"\n", file);
3333       
3334   link_section ();
3335   fprintf (file, "\t.align 3\n");
3336   fputs ("\t.name ", file);
3337   assemble_name (file, alpha_function_name);
3338   fputs ("..na\n", file);
3339   ASM_OUTPUT_LABEL (file, alpha_function_name);
3340   fprintf (file, "\t.pdesc ");
3341   assemble_name (file, alpha_function_name);
3342   fprintf (file, "..en,%s\n", is_stack_procedure ? "stack" : "reg");
3343   alpha_need_linkage (alpha_function_name, 1);
3344   text_section ();
3345
3346   return;
3347 }
3348
3349 /* Write function epilogue.  */
3350
3351 void
3352 output_epilog (file, size)
3353      FILE *file;
3354      int size;
3355 {
3356   unsigned long imask = 0;
3357   unsigned long fmask = 0;
3358   /* Stack space needed for pushing registers clobbered by us.  */
3359   HOST_WIDE_INT sa_size = alpha_sa_size ();
3360   /* Complete stack size needed.  */
3361   HOST_WIDE_INT frame_size
3362     = ALPHA_ROUND (sa_size
3363                    + (is_stack_procedure ? 8 : 0)
3364                    + size + current_function_pretend_args_size);
3365   int i;
3366   rtx insn = get_last_insn ();
3367
3368   /* If the last insn was a BARRIER, we don't have to write anything except
3369      the .end pseudo-op.  */
3370
3371   if (GET_CODE (insn) == NOTE)
3372     insn = prev_nonnote_insn (insn);
3373
3374   if (insn == 0 || GET_CODE (insn) != BARRIER)
3375     {
3376       /* Restore clobbered registers, load FP last.  */
3377
3378       if (is_stack_procedure)
3379         {
3380           int rsa_offset = 8;
3381           int reg_offset;
3382           int fp_offset;
3383
3384           if (unwind_regno == HARD_FRAME_POINTER_REGNUM)
3385             fprintf (file, "\tbis $%d,$%d,$%d\n", HARD_FRAME_POINTER_REGNUM,
3386                      HARD_FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
3387
3388           alpha_sa_mask (&imask, &fmask);
3389
3390           /* Start reloading registers after RA.  */
3391           reg_offset = rsa_offset + 8;
3392
3393           for (i = 0; i < 32; i++)
3394             if (imask & (1L<<i))
3395               {
3396                 if (i == HARD_FRAME_POINTER_REGNUM)
3397                   fp_offset = reg_offset;
3398                 else
3399                   fprintf (file, "\tldq $%d,%d($30)\n",
3400                                   i, reg_offset);
3401                 reg_offset += 8;
3402               }
3403
3404           for (i = 0; i < 32; i++)
3405             if (fmask & (1L << i))
3406               {
3407                 fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
3408                 reg_offset += 8;
3409               }
3410
3411           /* Restore R26 (RA).  */
3412           fprintf (file, "\tldq $26,%d($30)\n", rsa_offset);
3413
3414           /* Restore R29 (FP).  */
3415           fprintf (file, "\tldq $29,%d($30)\n", fp_offset);
3416         }
3417       else
3418         fprintf (file, "\tbis $%d,$%d,$%d\n", save_fp_regno, save_fp_regno,
3419                  HARD_FRAME_POINTER_REGNUM);
3420
3421       if (frame_size != 0)
3422         {
3423           if (frame_size < 32768)
3424             fprintf (file, "\tlda $30,%d($30)\n", frame_size);
3425           else
3426             {
3427               long high = frame_size >> 16;
3428               long low = frame_size & 0xffff;
3429               if (low & 0x8000)
3430                 {
3431                   high++;
3432                   low = -32768 + (low & 0x7fff);
3433                 }
3434               fprintf (file, "\tldah $2,%ld($31)\n", high);
3435               fprintf (file, "\tlda $2,%ld($2)\n", low);
3436               fprintf (file, "\taddq $30,$2,$30\n");
3437             }
3438         }
3439
3440       /* Finally return to the caller.  */
3441       fprintf (file, "\tret $31,($26),1\n");
3442     }
3443
3444   /* End the function.  */
3445   fprintf (file, "\t.end ");
3446   assemble_name (file,  alpha_function_name);
3447   fprintf (file, "\n");
3448   inside_function = FALSE;
3449
3450   /* Show that we know this function if it is called again.  */
3451   SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3452 }
3453
3454 int
3455 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3456      tree decl;
3457      tree attributes;
3458      tree identifier;
3459      tree args;
3460 {
3461   if (is_attribute_p ("overlaid", identifier))
3462     return (args == NULL_TREE);
3463   return 0;
3464 }
3465
3466 #else /* !OPEN_VMS */
3467
3468 static int
3469 alpha_does_function_need_gp ()
3470 {
3471   rtx insn;
3472
3473   /* We never need a GP for Windows/NT.  */
3474   if (TARGET_WINDOWS_NT)
3475     return 0;
3476
3477 #ifdef TARGET_PROFILING_NEEDS_GP
3478   if (profile_flag)
3479     return 1;
3480 #endif
3481
3482   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
3483      Even if we are a static function, we still need to do this in case
3484      our address is taken and passed to something like qsort.  */
3485
3486   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3487     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
3488         && GET_CODE (PATTERN (insn)) != USE
3489         && GET_CODE (PATTERN (insn)) != CLOBBER)
3490       {
3491         enum attr_type type = get_attr_type (insn);
3492         if (type == TYPE_LDSYM || type == TYPE_JSR)
3493           return 1;
3494       }
3495
3496   return 0;
3497 }
3498
3499 void
3500 output_prolog (file, size)
3501      FILE *file;
3502      HOST_WIDE_INT size;
3503 {
3504   HOST_WIDE_INT out_args_size
3505     = ALPHA_ROUND (current_function_outgoing_args_size);
3506   HOST_WIDE_INT sa_size = alpha_sa_size ();
3507   HOST_WIDE_INT frame_size
3508     = (out_args_size + sa_size
3509        + ALPHA_ROUND (size + current_function_pretend_args_size));
3510   HOST_WIDE_INT reg_offset = out_args_size;
3511   HOST_WIDE_INT start_reg_offset = reg_offset;
3512   HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
3513   int int_reg_save_area_size = 0;
3514   unsigned reg_mask = 0;
3515   int i, sa_reg;
3516
3517   /* Ecoff can handle multiple .file directives, so put out file and lineno.
3518      We have to do that before the .ent directive as we cannot switch
3519      files within procedures with native ecoff because line numbers are
3520      linked to procedure descriptors.
3521      Outputting the lineno helps debugging of one line functions as they
3522      would otherwise get no line number at all. Please note that we would
3523      like to put out last_linenum from final.c, but it is not accessible.  */
3524
3525   if (write_symbols == SDB_DEBUG)
3526     {
3527       ASM_OUTPUT_SOURCE_FILENAME (file,
3528                                   DECL_SOURCE_FILE (current_function_decl));
3529       if (debug_info_level != DINFO_LEVEL_TERSE)
3530         ASM_OUTPUT_SOURCE_LINE (file,
3531                                 DECL_SOURCE_LINE (current_function_decl));
3532     }
3533
3534   /* The assembly language programmer's guide states that the second argument
3535      to the .ent directive, the lex_level, is ignored by the assembler,
3536      so we might as well omit it.  */
3537      
3538   if (!flag_inhibit_size_directive)
3539     {
3540       fprintf (file, "\t.ent ");
3541       assemble_name (file, alpha_function_name);
3542       fprintf (file, "\n");
3543     }
3544   ASM_OUTPUT_LABEL (file, alpha_function_name);
3545   inside_function = TRUE;
3546
3547   if (TARGET_IEEE_CONFORMANT && !flag_inhibit_size_directive)
3548     /* Set flags in procedure descriptor to request IEEE-conformant
3549        math-library routines.  The value we set it to is PDSC_EXC_IEEE
3550        (/usr/include/pdsc.h). */
3551     fprintf (file, "\t.eflag 48\n");
3552
3553   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
3554
3555   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
3556   alpha_arg_offset = -frame_size + 48;
3557
3558   alpha_function_needs_gp = alpha_does_function_need_gp ();
3559
3560   if (TARGET_WINDOWS_NT == 0)
3561     {
3562       if (alpha_function_needs_gp)
3563         fprintf (file, "\tldgp $29,0($27)\n");
3564
3565       /* Put a label after the GP load so we can enter the function at it.  */
3566       fputc ('$', file);
3567       assemble_name (file, alpha_function_name);
3568       fprintf (file, "..ng:\n");
3569     }
3570
3571   /* Adjust the stack by the frame size.  If the frame size is > 4096
3572      bytes, we need to be sure we probe somewhere in the first and last
3573      4096 bytes (we can probably get away without the latter test) and
3574      every 8192 bytes in between.  If the frame size is > 32768, we
3575      do this in a loop.  Otherwise, we generate the explicit probe
3576      instructions. 
3577
3578      Note that we are only allowed to adjust sp once in the prologue.  */
3579
3580   if (frame_size < 32768)
3581     {
3582       if (frame_size > 4096)
3583         {
3584           int probed = 4096;
3585
3586           fprintf (file, "\tstq $31,-%d($30)\n", probed);
3587
3588           while (probed + 8192 < frame_size)
3589             fprintf (file, "\tstq $31,-%d($30)\n", probed += 8192);
3590
3591           /* We only have to do this probe if we aren't saving registers.  */
3592           if (sa_size == 0 && probed + 4096 < frame_size)
3593             fprintf (file, "\tstq $31,-%d($30)\n", frame_size);
3594         }
3595
3596       if (frame_size != 0)
3597         fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
3598     }
3599   else
3600     {
3601       /* Here we generate code to set R4 to SP + 4096 and set R5 to the
3602          number of 8192 byte blocks to probe.  We then probe each block
3603          in the loop and then set SP to the proper location.  If the
3604          amount remaining is > 4096, we have to do one more probe if we
3605          are not saving any registers.  */
3606
3607       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
3608       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
3609
3610       add_long_const (file, blocks, 31, 5, 5);
3611
3612       fprintf (file, "\tlda $4,4096($30)\n");
3613
3614       fputc ('$', file);
3615       assemble_name (file, alpha_function_name);
3616       fprintf (file, "..sc:\n");
3617
3618       fprintf (file, "\tstq $31,-8192($4)\n");
3619       fprintf (file, "\tsubq $5,1,$5\n");
3620       fprintf (file, "\tlda $4,-8192($4)\n");
3621
3622       fprintf (file, "\tbne $5,$");
3623       assemble_name (file, alpha_function_name);
3624       fprintf (file, "..sc\n");
3625
3626       if (leftover > 4096 && sa_size == 0)
3627         fprintf (file, "\tstq $31,-%d($4)\n", leftover);
3628
3629       fprintf (file, "\tlda $30,-%d($4)\n", leftover);
3630     }
3631
3632   /* Describe our frame.  */
3633   if (!flag_inhibit_size_directive)
3634     {
3635       fprintf (file, "\t.frame $%d,",
3636                (frame_pointer_needed
3637                 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
3638
3639       /* If the frame size is larger than an integer, print it as zero to
3640          avoid an assembler error.  We won't be properly describing such a
3641          frame, but that's the best we can do.  */
3642       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3643 #if HOST_BITS_PER_WIDE_INT == 64
3644                frame_size >= (1l << 31) ? 0 :
3645 #endif
3646                frame_size
3647                );
3648       fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
3649     }
3650
3651   /* Cope with very large offsets to the register save area.  */
3652   sa_reg = 30;
3653   if (reg_offset + sa_size > 0x8000)
3654     {
3655       int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3656       if (low + sa_size <= 0x8000)
3657         {
3658           add_long_const (file, reg_offset - low, 30, 24, 24);
3659           reg_offset = low;
3660         }
3661       else
3662         {
3663           add_long_const (file, reg_offset, 30, 24, 24);
3664           reg_offset = 0;
3665         }
3666       sa_reg = 24;
3667     }
3668     
3669   /* Save register RA if any other register needs to be saved.  */
3670   if (sa_size != 0)
3671     {
3672       reg_mask |= 1 << REG_RA;
3673       fprintf (file, "\tstq $26,%d($%d)\n", reg_offset, sa_reg);
3674       reg_offset += 8;
3675       int_reg_save_area_size += 8;
3676     }
3677
3678   /* Now save any other used integer registers required to be saved.  */
3679   for (i = 0; i < 32; i++)
3680     if (! fixed_regs[i] && ! call_used_regs[i]
3681         && regs_ever_live[i] && i != REG_RA)
3682       {
3683         reg_mask |= 1 << i;
3684         fprintf (file, "\tstq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3685         reg_offset += 8;
3686         int_reg_save_area_size += 8;
3687       }
3688
3689   /* Print the register mask and do floating-point saves.  */
3690   if (reg_mask && !flag_inhibit_size_directive)
3691     {
3692       fprintf (file, "\t.mask 0x%x,", reg_mask);
3693       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3694 #if HOST_BITS_PER_WIDE_INT == 64
3695                frame_size >= (1l << 31) ? 0 :
3696 #endif
3697                actual_start_reg_offset - frame_size);
3698       fprintf (file, "\n");
3699     }
3700
3701   start_reg_offset = reg_offset;
3702   reg_mask = 0;
3703
3704   for (i = 0; i < 32; i++)
3705     if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3706         && regs_ever_live[i + 32])
3707       {
3708         reg_mask |= 1 << i;
3709         fprintf (file, "\tstt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3710         reg_offset += 8;
3711       }
3712
3713   /* Print the floating-point mask, if we've saved any fp register.  */
3714   if (reg_mask && !flag_inhibit_size_directive)
3715     fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
3716              actual_start_reg_offset - frame_size + int_reg_save_area_size);
3717
3718   /* If we need a frame pointer, set it from the stack pointer.  Note that
3719      this must always be the last instruction in the prologue.  */
3720   if (frame_pointer_needed)
3721     fprintf (file, "\tbis $30,$30,$15\n");
3722
3723   /* End the prologue and say if we used gp.  */
3724   if (!flag_inhibit_size_directive)
3725     fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
3726 }
3727
3728 /* Write function epilogue.  */
3729
3730 void
3731 output_epilog (file, size)
3732      FILE *file;
3733      int size;
3734 {
3735   rtx insn = get_last_insn ();
3736   HOST_WIDE_INT out_args_size
3737     = ALPHA_ROUND (current_function_outgoing_args_size);
3738   HOST_WIDE_INT sa_size = alpha_sa_size ();
3739   HOST_WIDE_INT frame_size
3740     = (out_args_size + sa_size
3741        + ALPHA_ROUND (size + current_function_pretend_args_size));
3742   HOST_WIDE_INT reg_offset = out_args_size;
3743   int restore_fp
3744     = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
3745   int i;
3746
3747   /* If the last insn was a BARRIER, we don't have to write anything except
3748      the .end pseudo-op.  */
3749   if (GET_CODE (insn) == NOTE)
3750     insn = prev_nonnote_insn (insn);
3751   if (insn == 0 || GET_CODE (insn) != BARRIER)
3752     {
3753       int fp_offset = 0;
3754       int sa_reg;
3755
3756       /* If we have a frame pointer, restore SP from it.  */
3757       if (frame_pointer_needed)
3758         fprintf (file, "\tbis $15,$15,$30\n");
3759
3760       /* Cope with large offsets to the register save area.  */
3761       sa_reg = 30;
3762       if (reg_offset + sa_size > 0x8000)
3763         {
3764           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
3765           if (low + sa_size <= 0x8000)
3766             {
3767               add_long_const (file, reg_offset - low, 30, 24, 24);
3768               reg_offset = low;
3769             }
3770           else
3771             {
3772               add_long_const (file, reg_offset, 30, 24, 24);
3773               reg_offset = 0;
3774             }
3775           sa_reg = 24;
3776         }
3777
3778       /* Restore all the registers, starting with the return address
3779          register.  */
3780       if (sa_size != 0)
3781         {
3782           fprintf (file, "\tldq $26,%d($%d)\n", reg_offset, sa_reg);
3783           reg_offset += 8;
3784         }
3785
3786       /* Now restore any other used integer registers that we saved,
3787          except for FP if it is being used as FP, since it must be
3788          restored last.  */
3789
3790       for (i = 0; i < 32; i++)
3791         if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
3792             && i != 26)
3793           {
3794             if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
3795               fp_offset = reg_offset;
3796             else
3797               fprintf (file, "\tldq $%d,%d($%d)\n", i, reg_offset, sa_reg);
3798             reg_offset += 8;
3799           }
3800
3801       for (i = 0; i < 32; i++)
3802         if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
3803             && regs_ever_live[i + 32])
3804           {
3805             fprintf (file, "\tldt $f%d,%d($%d)\n", i, reg_offset, sa_reg);
3806             reg_offset += 8;
3807           }
3808
3809       /* If the stack size is large and we have a frame pointer, compute the
3810          size of the stack into a register because the old FP restore, stack
3811          pointer adjust, and return are required to be consecutive
3812          instructions.   */
3813       if (frame_size > 32767 && restore_fp)
3814         add_long_const (file, frame_size, 31, 1, 1);
3815
3816       /* If we needed a frame pointer and we have to restore it, do it
3817          now.  This must be done in one instruction immediately
3818          before the SP update.  */
3819       if (restore_fp && fp_offset)
3820         fprintf (file, "\tldq $15,%d($%d)\n", fp_offset, sa_reg);
3821
3822       /* Now update the stack pointer, if needed.  Only one instruction must
3823          modify the stack pointer.  It must be the last instruction in the
3824          sequence and must be an ADDQ or LDA instruction.  If the frame
3825          pointer was loaded above, we may only put one instruction here.  */
3826
3827       if (frame_size > 32768 && restore_fp)
3828         fprintf  (file, "\taddq $1,$30,$30\n");
3829       else
3830         add_long_const (file, frame_size, 30, 30, 1);
3831
3832       /* Finally return to the caller.  */
3833       fprintf (file, "\tret $31,($26),1\n");
3834     }
3835
3836   /* End the function.  */
3837   if (!flag_inhibit_size_directive)
3838     {
3839       fprintf (file, "\t.end ");
3840       assemble_name (file, alpha_function_name);
3841       fprintf (file, "\n");
3842     }
3843   inside_function = FALSE;
3844
3845   /* Show that we know this function if it is called again. 
3846
3847      Don't do this for global functions in object files destined for a
3848      shared library because the function may be overridden by the application
3849      or other libraries.
3850      ??? Is this just ELF?  */
3851
3852   if (!flag_pic || !TREE_PUBLIC (current_function_decl))
3853     SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
3854 }
3855 #endif /* !OPEN_VMS */
3856 \f
3857 /* Debugging support.  */
3858
3859 #include "gstab.h"
3860
3861 /* Count the number of sdb related labels are generated (to find block
3862    start and end boundaries).  */
3863
3864 int sdb_label_count = 0;
3865
3866 /* Next label # for each statement.  */
3867
3868 static int sym_lineno = 0;
3869
3870 /* Count the number of .file directives, so that .loc is up to date.  */
3871
3872 static int num_source_filenames = 0;
3873
3874 /* Name of the file containing the current function.  */
3875
3876 static char *current_function_file = "";
3877
3878 /* Offsets to alpha virtual arg/local debugging pointers.  */
3879
3880 long alpha_arg_offset;
3881 long alpha_auto_offset;
3882 \f
3883 /* Emit a new filename to a stream.  */
3884
3885 void
3886 alpha_output_filename (stream, name)
3887      FILE *stream;
3888      char *name;
3889 {
3890   static int first_time = TRUE;
3891   char ltext_label_name[100];
3892
3893   if (first_time)
3894     {
3895       first_time = FALSE;
3896       ++num_source_filenames;
3897       current_function_file = name;
3898       fprintf (stream, "\t.file\t%d ", num_source_filenames);
3899       output_quoted_string (stream, name);
3900       fprintf (stream, "\n");
3901       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3902         fprintf (stream, "\t#@stabs\n");
3903     }
3904
3905   else if (write_symbols == DBX_DEBUG)
3906     {
3907       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3908       fprintf (stream, "%s ", ASM_STABS_OP);
3909       output_quoted_string (stream, name);
3910       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
3911     }
3912
3913   else if (name != current_function_file
3914            && strcmp (name, current_function_file) != 0)
3915     {
3916       if (inside_function && ! TARGET_GAS)
3917         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
3918       else
3919         {
3920           ++num_source_filenames;
3921           current_function_file = name;
3922           fprintf (stream, "\t.file\t%d ", num_source_filenames);
3923         }
3924
3925       output_quoted_string (stream, name);
3926       fprintf (stream, "\n");
3927     }
3928 }
3929 \f
3930 /* Emit a linenumber to a stream.  */
3931
3932 void
3933 alpha_output_lineno (stream, line)
3934      FILE *stream;
3935      int line;
3936 {
3937   if (write_symbols == DBX_DEBUG)
3938     {
3939       /* mips-tfile doesn't understand .stabd directives.  */
3940       ++sym_lineno;
3941       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3942                sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3943     }
3944   else
3945     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
3946 }
3947 \f
3948 /* Structure to show the current status of registers and memory.  */
3949
3950 struct shadow_summary
3951 {
3952   struct {
3953     unsigned long i     : 31;   /* Mask of int regs */
3954     unsigned long fp    : 31;   /* Mask of fp regs */
3955     unsigned long mem   :  1;   /* mem == imem | fpmem */
3956   } used, defd;
3957 };
3958
3959 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
3960    to the summary structure.  SET is nonzero if the insn is setting the
3961    object, otherwise zero.  */
3962
3963 static void
3964 summarize_insn (x, sum, set)
3965      rtx x;
3966      struct shadow_summary *sum;
3967      int set;
3968 {
3969   char *format_ptr;
3970   int i, j;
3971
3972   if (x == 0)
3973     return;
3974
3975   switch (GET_CODE (x))
3976     {
3977       /* ??? Note that this case would be incorrect if the Alpha had a
3978          ZERO_EXTRACT in SET_DEST.  */
3979     case SET:
3980       summarize_insn (SET_SRC (x), sum, 0);
3981       summarize_insn (SET_DEST (x), sum, 1);
3982       break;
3983
3984     case CLOBBER:
3985       summarize_insn (XEXP (x, 0), sum, 1);
3986       break;
3987
3988     case USE:
3989       summarize_insn (XEXP (x, 0), sum, 0);
3990       break;
3991
3992     case ASM_OPERANDS:
3993       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
3994         summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
3995       break;
3996
3997     case PARALLEL:
3998       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
3999         summarize_insn (XVECEXP (x, 0, i), sum, 0);
4000       break;
4001
4002     case SUBREG:
4003       x = SUBREG_REG (x);
4004       /* FALLTHRU */
4005
4006     case REG:
4007       {
4008         int regno = REGNO (x);
4009         unsigned long mask = 1UL << (regno % 32);
4010
4011         if (regno == 31 || regno == 63)
4012           break;
4013
4014         if (set)
4015           {
4016             if (regno < 32)
4017               sum->defd.i |= mask;
4018             else
4019               sum->defd.fp |= mask;
4020           }
4021         else
4022           {
4023             if (regno < 32)
4024               sum->used.i  |= mask;
4025             else
4026               sum->used.fp |= mask;
4027           }
4028         }
4029       break;
4030
4031     case MEM:
4032       if (set)
4033         sum->defd.mem = 1;
4034       else
4035         sum->used.mem = 1;
4036
4037       /* Find the regs used in memory address computation: */
4038       summarize_insn (XEXP (x, 0), sum, 0);
4039       break;
4040
4041     case CONST_INT:   case CONST_DOUBLE:
4042     case SYMBOL_REF:  case LABEL_REF:     case CONST:
4043       break;
4044
4045       /* Handle common unary and binary ops for efficiency.  */
4046     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
4047     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
4048     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
4049     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
4050     case NE:       case EQ:      case GE:      case GT:        case LE:
4051     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
4052       summarize_insn (XEXP (x, 0), sum, 0);
4053       summarize_insn (XEXP (x, 1), sum, 0);
4054       break;
4055
4056     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
4057     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
4058     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
4059     case SQRT:  case FFS: 
4060       summarize_insn (XEXP (x, 0), sum, 0);
4061       break;
4062
4063     default:
4064       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4065       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4066         switch (format_ptr[i])
4067           {
4068           case 'e':
4069             summarize_insn (XEXP (x, i), sum, 0);
4070             break;
4071
4072           case 'E':
4073             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4074               summarize_insn (XVECEXP (x, i, j), sum, 0);
4075             break;
4076
4077           case 'i':
4078             break;
4079
4080           default:
4081             abort ();
4082           }
4083     }
4084 }
4085
4086 /* Ensure a sufficient number of `trapb' insns are in the code when the user
4087    requests code with a trap precision of functions or instructions.
4088
4089    In naive mode, when the user requests a trap-precision of "instruction", a
4090    trapb is needed after every instruction that may generate a trap (and after
4091    jsr/bsr instructions, because called functions may import a trap from the
4092    caller).  This ensures that the code is resumption safe but it is also slow.
4093
4094    When optimizations are turned on, we delay issuing a trapb as long as
4095    possible.  In this context, a trap shadow is the sequence of instructions
4096    that starts with a (potentially) trap generating instruction and extends to
4097    the next trapb or call_pal instruction (but GCC never generates call_pal by
4098    itself).  We can delay (and therefore sometimes omit) a trapb subject to the
4099    following conditions:
4100
4101    (a) On entry to the trap shadow, if any Alpha register or memory location
4102    contains a value that is used as an operand value by some instruction in
4103    the trap shadow (live on entry), then no instruction in the trap shadow
4104    may modify the register or memory location.
4105
4106    (b) Within the trap shadow, the computation of the base register for a
4107    memory load or store instruction may not involve using the result
4108    of an instruction that might generate an UNPREDICTABLE result.
4109
4110    (c) Within the trap shadow, no register may be used more than once as a
4111    destination register.  (This is to make life easier for the trap-handler.)
4112
4113    (d) The trap shadow may not include any branch instructions.  */
4114
4115 static void
4116 alpha_handle_trap_shadows (insns)
4117      rtx insns;
4118 {
4119   struct shadow_summary shadow;
4120   int trap_pending, exception_nesting;
4121   rtx i;
4122
4123   if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
4124     return;
4125
4126   trap_pending = 0;
4127   exception_nesting = 0;
4128   shadow.used.i = 0;
4129   shadow.used.fp = 0;
4130   shadow.used.mem = 0;
4131   shadow.defd = shadow.used;
4132   
4133   for (i = insns; i ; i = NEXT_INSN (i))
4134     {
4135       if (GET_CODE (i) == NOTE)
4136         {
4137           switch (NOTE_LINE_NUMBER (i))
4138             {
4139             case NOTE_INSN_EH_REGION_BEG:
4140               exception_nesting++;
4141               if (trap_pending)
4142                 goto close_shadow;
4143               break;
4144
4145             case NOTE_INSN_EH_REGION_END:
4146               exception_nesting--;
4147               if (trap_pending)
4148                 goto close_shadow;
4149               break;
4150
4151             case NOTE_INSN_EPILOGUE_BEG:
4152               if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
4153                 goto close_shadow;
4154               break;
4155             }
4156         }
4157       else if (trap_pending)
4158         {
4159           if (alpha_tp == ALPHA_TP_FUNC)
4160             {
4161               if (GET_CODE (i) == JUMP_INSN
4162                   && GET_CODE (PATTERN (i)) == RETURN)
4163                 goto close_shadow;
4164             }
4165           else if (alpha_tp == ALPHA_TP_INSN)
4166             {
4167               if (optimize > 0)
4168                 {
4169                   struct shadow_summary sum;
4170
4171                   sum.used.i = 0;
4172                   sum.used.fp = 0;
4173                   sum.used.mem = 0;
4174                   sum.defd = sum.used;
4175
4176                   switch (GET_CODE (i))
4177                     {
4178                     case INSN:
4179                       /* Annoyingly, get_attr_trap will abort on these.  */
4180                       if (GET_CODE (PATTERN (i)) == USE
4181                           || GET_CODE (PATTERN (i)) == CLOBBER)
4182                         break;
4183
4184                       summarize_insn (PATTERN (i), &sum, 0);
4185
4186                       if ((sum.defd.i & shadow.defd.i)
4187                           || (sum.defd.fp & shadow.defd.fp))
4188                         {
4189                           /* (c) would be violated */
4190                           goto close_shadow;
4191                         }
4192
4193                       /* Combine shadow with summary of current insn: */
4194                       shadow.used.i   |= sum.used.i;
4195                       shadow.used.fp  |= sum.used.fp;
4196                       shadow.used.mem |= sum.used.mem;
4197                       shadow.defd.i   |= sum.defd.i;
4198                       shadow.defd.fp  |= sum.defd.fp;
4199                       shadow.defd.mem |= sum.defd.mem;
4200
4201                       if ((sum.defd.i & shadow.used.i)
4202                           || (sum.defd.fp & shadow.used.fp)
4203                           || (sum.defd.mem & shadow.used.mem))
4204                         {
4205                           /* (a) would be violated (also takes care of (b))  */
4206                           if (get_attr_trap (i) == TRAP_YES
4207                               && ((sum.defd.i & sum.used.i)
4208                                   || (sum.defd.fp & sum.used.fp)))
4209                             abort ();
4210
4211                           goto close_shadow;
4212                         }
4213                       break;
4214
4215                     case JUMP_INSN:
4216                     case CALL_INSN:
4217                     case CODE_LABEL:
4218                       goto close_shadow;
4219
4220                     default:
4221                       abort ();
4222                     }
4223                 }
4224               else
4225                 {
4226                 close_shadow:
4227                   emit_insn_before (gen_trapb (), i);
4228                   trap_pending = 0;
4229                   shadow.used.i = 0;
4230                   shadow.used.fp = 0;
4231                   shadow.used.mem = 0;
4232                   shadow.defd = shadow.used;
4233                 }
4234             }
4235         }
4236
4237       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
4238           && GET_CODE (i) == INSN
4239           && GET_CODE (PATTERN (i)) != USE
4240           && GET_CODE (PATTERN (i)) != CLOBBER
4241           && get_attr_trap (i) == TRAP_YES)
4242         {
4243           if (optimize && !trap_pending)
4244             summarize_insn (PATTERN (i), &shadow, 0);
4245           trap_pending = 1;
4246         }
4247     }
4248 }
4249
4250 /* Machine dependant reorg pass.  */
4251
4252 void
4253 alpha_reorg (insns)
4254      rtx insns;
4255 {
4256   alpha_handle_trap_shadows (insns);
4257 }
4258
4259 \f
4260 /* Check a floating-point value for validity for a particular machine mode.  */
4261
4262 static char *float_strings[] =
4263 {
4264   /* These are for FLOAT_VAX.  */
4265    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
4266   "-1.70141173319264430e+38",
4267    "2.93873587705571877e-39", /* 2^-128 */
4268   "-2.93873587705571877e-39",
4269   /* These are for the default broken IEEE mode, which traps
4270      on infinity or denormal numbers.  */
4271    "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
4272   "-3.402823466385288598117e+38",
4273    "1.1754943508222875079687e-38", /* 2^-126 */
4274   "-1.1754943508222875079687e-38",
4275 };
4276
4277 static REAL_VALUE_TYPE float_values[8];
4278 static int inited_float_values = 0;
4279
4280 int
4281 check_float_value (mode, d, overflow)
4282      enum machine_mode mode;
4283      REAL_VALUE_TYPE *d;
4284      int overflow;
4285 {
4286
4287   if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
4288     return 0;
4289
4290   if (inited_float_values == 0)
4291     {
4292       int i;
4293       for (i = 0; i < 8; i++)
4294         float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
4295
4296       inited_float_values = 1;
4297     }
4298
4299   if (mode == SFmode)
4300     {
4301       REAL_VALUE_TYPE r;
4302       REAL_VALUE_TYPE *fvptr;
4303
4304       if (TARGET_FLOAT_VAX)
4305         fvptr = &float_values[0];
4306       else
4307         fvptr = &float_values[4];
4308
4309       bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
4310       if (REAL_VALUES_LESS (fvptr[0], r))
4311         {
4312           bcopy ((char *) &fvptr[0], (char *) d,
4313                  sizeof (REAL_VALUE_TYPE));
4314           return 1;
4315         }
4316       else if (REAL_VALUES_LESS (r, fvptr[1]))
4317         {
4318           bcopy ((char *) &fvptr[1], (char *) d,
4319                  sizeof (REAL_VALUE_TYPE));
4320           return 1;
4321         }
4322       else if (REAL_VALUES_LESS (dconst0, r)
4323                 && REAL_VALUES_LESS (r, fvptr[2]))
4324         {
4325           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4326           return 1;
4327         }
4328       else if (REAL_VALUES_LESS (r, dconst0)
4329                 && REAL_VALUES_LESS (fvptr[3], r))
4330         {
4331           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
4332           return 1;
4333         }
4334     }
4335
4336   return 0;
4337 }
4338
4339 #if OPEN_VMS
4340
4341 /* Return the VMS argument type corresponding to MODE.  */
4342
4343 enum avms_arg_type
4344 alpha_arg_type (mode)
4345      enum machine_mode mode;
4346 {
4347   switch (mode)
4348     {
4349     case SFmode:
4350       return TARGET_FLOAT_VAX ? FF : FS;
4351     case DFmode:
4352       return TARGET_FLOAT_VAX ? FD : FT;
4353     default:
4354       return I64;
4355     }
4356 }
4357
4358 /* Return an rtx for an integer representing the VMS Argument Information
4359    register value.  */
4360
4361 struct rtx_def *
4362 alpha_arg_info_reg_val (cum)
4363      CUMULATIVE_ARGS cum;
4364 {
4365   unsigned HOST_WIDE_INT regval = cum.num_args;
4366   int i;
4367
4368   for (i = 0; i < 6; i++)
4369     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
4370
4371   return GEN_INT (regval);
4372 }
4373 \f
4374 /* Structure to collect function names for final output
4375    in link section.  */
4376
4377 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
4378
4379
4380 struct alpha_links {
4381   struct alpha_links *next;
4382   char *name;
4383   enum links_kind kind;
4384 };
4385
4386 static struct alpha_links *alpha_links_base = 0;
4387
4388 /* Make (or fake) .linkage entry for function call.
4389
4390    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.  */
4391
4392 void
4393 alpha_need_linkage (name, is_local)
4394     char *name;
4395     int is_local;
4396 {
4397   rtx x;
4398   struct alpha_links *lptr, *nptr;
4399
4400   if (name[0] == '*')
4401     name++;
4402
4403   /* Is this name already defined ?  */
4404
4405   for (lptr = alpha_links_base; lptr; lptr = lptr->next)
4406     if (strcmp (lptr->name, name) == 0)
4407       {
4408         if (is_local)
4409           {
4410             /* Defined here but external assumed.  */
4411             if (lptr->kind == KIND_EXTERN)
4412               lptr->kind = KIND_LOCAL;
4413           }
4414         else
4415           {
4416             /* Used here but unused assumed.  */
4417             if (lptr->kind == KIND_UNUSED)
4418               lptr->kind = KIND_LOCAL;
4419           }
4420         return;
4421       }
4422
4423   nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
4424   nptr->next = alpha_links_base;
4425   nptr->name = xstrdup (name);
4426
4427   /* Assume external if no definition.  */
4428   nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
4429
4430   /* Ensure we have an IDENTIFIER so assemble_name can mark is used.  */
4431   get_identifier (name);
4432
4433   alpha_links_base = nptr;
4434
4435   return;
4436 }
4437
4438
4439 void
4440 alpha_write_linkage (stream)
4441     FILE *stream;
4442 {
4443   struct alpha_links *lptr, *nptr;
4444
4445   readonly_section ();
4446
4447   fprintf (stream, "\t.align 3\n");
4448
4449   for (lptr = alpha_links_base; lptr; lptr = nptr)
4450     {
4451       nptr = lptr->next;
4452
4453       if (lptr->kind == KIND_UNUSED
4454           || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
4455         continue;
4456
4457       fprintf (stream, "$%s..lk:\n", lptr->name);
4458       if (lptr->kind == KIND_LOCAL)   
4459         {
4460           /*  Local and used, build linkage pair.  */
4461           fprintf (stream, "\t.quad %s..en\n", lptr->name);
4462           fprintf (stream, "\t.quad %s\n", lptr->name);
4463         }
4464       else
4465         /* External and used, request linkage pair.  */
4466         fprintf (stream, "\t.linkage %s\n", lptr->name);
4467     }
4468 }
4469
4470 #else
4471
4472 void
4473 alpha_need_linkage (name, is_local)
4474      char *name;
4475      int is_local;
4476 {
4477 }
4478
4479 #endif /* OPEN_VMS */
4480