OSDN Git Service

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