OSDN Git Service

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