OSDN Git Service

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