OSDN Git Service

* alpha.c (alpha_emit_set_const_1): Also try c + small constant.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.c
1 /* Subroutines used for code generation on the DEC Alpha.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000 Free Software Foundation, Inc. 
4    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING.  If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23
24 #include "config.h"
25 #include "system.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 "tree.h"
39 #include "expr.h"
40 #include "obstack.h"
41 #include "except.h"
42 #include "function.h"
43 #include "toplev.h"
44 #include "ggc.h"
45 #include "tm_p.h"
46
47 /* External data.  */
48 extern int rtx_equal_function_value_matters;
49
50 /* Specify which cpu to schedule for. */
51
52 enum processor_type alpha_cpu;
53 static const char * const alpha_cpu_name[] = 
54 {
55   "ev4", "ev5", "ev6"
56 };
57
58 /* Specify how accurate floating-point traps need to be.  */
59
60 enum alpha_trap_precision alpha_tp;
61
62 /* Specify the floating-point rounding mode.  */
63
64 enum alpha_fp_rounding_mode alpha_fprm;
65
66 /* Specify which things cause traps.  */
67
68 enum alpha_fp_trap_mode alpha_fptm;
69
70 /* Strings decoded into the above options.  */
71
72 const char *alpha_cpu_string;   /* -mcpu= */
73 const char *alpha_tp_string;    /* -mtrap-precision=[p|s|i] */
74 const char *alpha_fprm_string;  /* -mfp-rounding-mode=[n|m|c|d] */
75 const char *alpha_fptm_string;  /* -mfp-trap-mode=[n|u|su|sui] */
76 const char *alpha_mlat_string;  /* -mmemory-latency= */
77
78 /* Save information from a "cmpxx" operation until the branch or scc is
79    emitted.  */
80
81 struct alpha_compare alpha_compare;
82
83 /* Non-zero if inside of a function, because the Alpha asm can't
84    handle .files inside of functions.  */
85
86 static int inside_function = FALSE;
87
88 /* The number of cycles of latency we should assume on memory reads.  */
89
90 int alpha_memory_latency = 3;
91
92 /* Whether the function needs the GP.  */
93
94 static int alpha_function_needs_gp;
95
96 /* The alias set for prologue/epilogue register save/restore.  */
97
98 static int alpha_sr_alias_set;
99
100 /* Declarations of static functions.  */
101 static void alpha_set_memflags_1
102   PARAMS ((rtx, int, int, int));
103 static rtx alpha_emit_set_const_1
104   PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
105 static void alpha_expand_unaligned_load_words
106   PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
107 static void alpha_expand_unaligned_store_words
108   PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
109 static void alpha_sa_mask
110   PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
111 static int alpha_does_function_need_gp
112   PARAMS ((void));
113 static void alpha_init_machine_status
114   PARAMS ((struct function *p));
115 static void alpha_mark_machine_status
116   PARAMS ((struct function *p));
117 static int alpha_ra_ever_killed
118   PARAMS ((void));
119 static rtx set_frame_related_p
120   PARAMS ((void));
121 static const char *alpha_lookup_xfloating_lib_func
122   PARAMS ((enum rtx_code));
123 static int alpha_compute_xfloating_mode_arg
124   PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
125 static void alpha_emit_xfloating_libcall
126   PARAMS ((const char *, rtx, rtx[], int, rtx));
127 static rtx alpha_emit_xfloating_compare
128   PARAMS ((enum rtx_code, rtx, rtx));
129
130 /* Get the number of args of a function in one of two ways.  */
131 #ifdef OPEN_VMS
132 #define NUM_ARGS current_function_args_info.num_args
133 #else
134 #define NUM_ARGS current_function_args_info
135 #endif
136
137 #define REG_PV 27
138 #define REG_RA 26
139 \f
140 /* Parse target option strings. */
141
142 void
143 override_options ()
144 {
145   alpha_tp = ALPHA_TP_PROG;
146   alpha_fprm = ALPHA_FPRM_NORM;
147   alpha_fptm = ALPHA_FPTM_N;
148
149   if (TARGET_IEEE)
150     {
151       alpha_tp = ALPHA_TP_INSN;
152       alpha_fptm = ALPHA_FPTM_SU;
153     }
154
155   if (TARGET_IEEE_WITH_INEXACT)
156     {
157       alpha_tp = ALPHA_TP_INSN;
158       alpha_fptm = ALPHA_FPTM_SUI;
159     }
160
161   if (alpha_tp_string)
162     {
163       if (! strcmp (alpha_tp_string, "p"))
164         alpha_tp = ALPHA_TP_PROG;
165       else if (! strcmp (alpha_tp_string, "f"))
166         alpha_tp = ALPHA_TP_FUNC;
167       else if (! strcmp (alpha_tp_string, "i"))
168         alpha_tp = ALPHA_TP_INSN;
169       else
170         error ("bad value `%s' for -mtrap-precision switch", alpha_tp_string);
171     }
172
173   if (alpha_fprm_string)
174     {
175       if (! strcmp (alpha_fprm_string, "n"))
176         alpha_fprm = ALPHA_FPRM_NORM;
177       else if (! strcmp (alpha_fprm_string, "m"))
178         alpha_fprm = ALPHA_FPRM_MINF;
179       else if (! strcmp (alpha_fprm_string, "c"))
180         alpha_fprm = ALPHA_FPRM_CHOP;
181       else if (! strcmp (alpha_fprm_string,"d"))
182         alpha_fprm = ALPHA_FPRM_DYN;
183       else
184         error ("bad value `%s' for -mfp-rounding-mode switch",
185                alpha_fprm_string);
186     }
187
188   if (alpha_fptm_string)
189     {
190       if (strcmp (alpha_fptm_string, "n") == 0)
191         alpha_fptm = ALPHA_FPTM_N;
192       else if (strcmp (alpha_fptm_string, "u") == 0)
193         alpha_fptm = ALPHA_FPTM_U;
194       else if (strcmp (alpha_fptm_string, "su") == 0)
195         alpha_fptm = ALPHA_FPTM_SU;
196       else if (strcmp (alpha_fptm_string, "sui") == 0)
197         alpha_fptm = ALPHA_FPTM_SUI;
198       else
199         error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
200     }
201
202   alpha_cpu
203     = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
204       : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
205
206   if (alpha_cpu_string)
207     {
208       if (! strcmp (alpha_cpu_string, "ev4")
209           || ! strcmp (alpha_cpu_string, "ev45")
210           || ! strcmp (alpha_cpu_string, "21064"))
211         {
212           alpha_cpu = PROCESSOR_EV4;
213           target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
214         }
215       else if (! strcmp (alpha_cpu_string, "ev5")
216                || ! strcmp (alpha_cpu_string, "21164"))
217         {
218           alpha_cpu = PROCESSOR_EV5;
219           target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
220         }
221       else if (! strcmp (alpha_cpu_string, "ev56")
222                || ! strcmp (alpha_cpu_string, "21164a"))
223         {
224           alpha_cpu = PROCESSOR_EV5;
225           target_flags |= MASK_BWX;
226           target_flags &= ~ (MASK_MAX | MASK_FIX | MASK_CIX);
227         }
228       else if (! strcmp (alpha_cpu_string, "pca56")
229                || ! strcmp (alpha_cpu_string, "21164PC")
230                || ! strcmp (alpha_cpu_string, "21164pc"))
231         {
232           alpha_cpu = PROCESSOR_EV5;
233           target_flags |= MASK_BWX | MASK_MAX;
234           target_flags &= ~ (MASK_FIX | MASK_CIX);
235         }
236       else if (! strcmp (alpha_cpu_string, "ev6")
237                || ! strcmp (alpha_cpu_string, "21264"))
238         {
239           alpha_cpu = PROCESSOR_EV6;
240           target_flags |= MASK_BWX | MASK_MAX | MASK_FIX;
241           target_flags &= ~ (MASK_CIX);
242         }
243       else if (! strcmp (alpha_cpu_string, "ev67")
244                || ! strcmp (alpha_cpu_string, "21264a"))
245         {
246           alpha_cpu = PROCESSOR_EV6;
247           target_flags |= MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX;
248         }
249       else
250         error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
251     }
252
253   /* Do some sanity checks on the above options. */
254
255   if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
256       && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
257     {
258       warning ("fp software completion requires -mtrap-precision=i");
259       alpha_tp = ALPHA_TP_INSN;
260     }
261
262   if (alpha_cpu == PROCESSOR_EV6)
263     {
264       /* Except for EV6 pass 1 (not released), we always have precise
265          arithmetic traps.  Which means we can do software completion
266          without minding trap shadows.  */
267       alpha_tp = ALPHA_TP_PROG;
268     }
269
270   if (TARGET_FLOAT_VAX)
271     {
272       if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
273         {
274           warning ("rounding mode not supported for VAX floats");
275           alpha_fprm = ALPHA_FPRM_NORM;
276         }
277       if (alpha_fptm == ALPHA_FPTM_SUI)
278         {
279           warning ("trap mode not supported for VAX floats");
280           alpha_fptm = ALPHA_FPTM_SU;
281         }
282     }
283
284   {
285     char *end;
286     int lat;
287
288     if (!alpha_mlat_string)
289       alpha_mlat_string = "L1";
290
291     if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
292         && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
293       ;
294     else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
295              && ISDIGIT ((unsigned char)alpha_mlat_string[1])
296              && alpha_mlat_string[2] == '\0')
297       {
298         static int const cache_latency[][4] = 
299         {
300           { 3, 30, -1 },        /* ev4 -- Bcache is a guess */
301           { 2, 12, 38 },        /* ev5 -- Bcache from PC164 LMbench numbers */
302           { 3, 13, -1 },        /* ev6 -- Ho hum, doesn't exist yet */
303         };
304
305         lat = alpha_mlat_string[1] - '0';
306         if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
307           {
308             warning ("L%d cache latency unknown for %s",
309                      lat, alpha_cpu_name[alpha_cpu]);
310             lat = 3;
311           }
312         else
313           lat = cache_latency[alpha_cpu][lat-1];
314       }
315     else if (! strcmp (alpha_mlat_string, "main"))
316       {
317         /* Most current memories have about 370ns latency.  This is
318            a reasonable guess for a fast cpu.  */
319         lat = 150;
320       }
321     else
322       {
323         warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
324         lat = 3;
325       }
326
327     alpha_memory_latency = lat;
328   }
329
330   /* Default the definition of "small data" to 8 bytes.  */
331   if (!g_switch_set)
332     g_switch_value = 8;
333
334   /* Acquire a unique set number for our register saves and restores.  */
335   alpha_sr_alias_set = new_alias_set ();
336
337   /* Set up function hooks.  */
338   init_machine_status = alpha_init_machine_status;
339   mark_machine_status = alpha_mark_machine_status;
340 }
341 \f
342 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
343
344 int
345 zap_mask (value)
346      HOST_WIDE_INT value;
347 {
348   int i;
349
350   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
351        i++, value >>= 8)
352     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
353       return 0;
354
355   return 1;
356 }
357
358 /* Returns 1 if OP is either the constant zero or a register.  If a
359    register, it must be in the proper mode unless MODE is VOIDmode.  */
360
361 int
362 reg_or_0_operand (op, mode)
363       register rtx op;
364       enum machine_mode mode;
365 {
366   return op == const0_rtx || register_operand (op, mode);
367 }
368
369 /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
370    any register.  */
371
372 int
373 reg_or_6bit_operand (op, mode)
374      register rtx op;
375      enum machine_mode mode;
376 {
377   return ((GET_CODE (op) == CONST_INT
378            && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
379           || register_operand (op, mode));
380 }
381
382
383 /* Return 1 if OP is an 8-bit constant or any register.  */
384
385 int
386 reg_or_8bit_operand (op, mode)
387      register rtx op;
388      enum machine_mode mode;
389 {
390   return ((GET_CODE (op) == CONST_INT
391            && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
392           || register_operand (op, mode));
393 }
394
395 /* Return 1 if OP is an 8-bit constant.  */
396
397 int
398 cint8_operand (op, mode)
399      register rtx op;
400      enum machine_mode mode ATTRIBUTE_UNUSED;
401 {
402   return ((GET_CODE (op) == CONST_INT
403            && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
404 }
405
406 /* Return 1 if the operand is a valid second operand to an add insn.  */
407
408 int
409 add_operand (op, mode)
410      register rtx op;
411      enum machine_mode mode;
412 {
413   if (GET_CODE (op) == CONST_INT)
414     /* Constraints I, J, O and P are covered by K.  */
415     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K')
416             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
417
418   return register_operand (op, mode);
419 }
420
421 /* Return 1 if the operand is a valid second operand to a sign-extending
422    add insn.  */
423
424 int
425 sext_add_operand (op, mode)
426      register rtx op;
427      enum machine_mode mode;
428 {
429   if (GET_CODE (op) == CONST_INT)
430     return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
431             || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'));
432
433   return reg_not_elim_operand (op, mode);
434 }
435
436 /* Return 1 if OP is the constant 4 or 8.  */
437
438 int
439 const48_operand (op, mode)
440      register rtx op;
441      enum machine_mode mode ATTRIBUTE_UNUSED;
442 {
443   return (GET_CODE (op) == CONST_INT
444           && (INTVAL (op) == 4 || INTVAL (op) == 8));
445 }
446
447 /* Return 1 if OP is a valid first operand to an AND insn.  */
448
449 int
450 and_operand (op, mode)
451      register rtx op;
452      enum machine_mode mode;
453 {
454   if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
455     return (zap_mask (CONST_DOUBLE_LOW (op))
456             && zap_mask (CONST_DOUBLE_HIGH (op)));
457
458   if (GET_CODE (op) == CONST_INT)
459     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
460             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
461             || zap_mask (INTVAL (op)));
462
463   return register_operand (op, mode);
464 }
465
466 /* Return 1 if OP is a valid first operand to an IOR or XOR insn.  */
467
468 int
469 or_operand (op, mode)
470      register rtx op;
471      enum machine_mode mode;
472 {
473   if (GET_CODE (op) == CONST_INT)
474     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
475             || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
476
477   return register_operand (op, mode);
478 }
479
480 /* Return 1 if OP is a constant that is the width, in bits, of an integral
481    mode smaller than DImode.  */
482
483 int
484 mode_width_operand (op, mode)
485      register rtx op;
486      enum machine_mode mode ATTRIBUTE_UNUSED;
487 {
488   return (GET_CODE (op) == CONST_INT
489           && (INTVAL (op) == 8 || INTVAL (op) == 16
490               || INTVAL (op) == 32 || INTVAL (op) == 64));
491 }
492
493 /* Return 1 if OP is a constant that is the width of an integral machine mode
494    smaller than an integer.  */
495
496 int
497 mode_mask_operand (op, mode)
498      register rtx op;
499      enum machine_mode mode ATTRIBUTE_UNUSED;
500 {
501 #if HOST_BITS_PER_WIDE_INT == 32
502   if (GET_CODE (op) == CONST_DOUBLE)
503     return (CONST_DOUBLE_LOW (op) == -1
504             && (CONST_DOUBLE_HIGH (op) == -1
505                 || CONST_DOUBLE_HIGH (op) == 0));
506 #else
507   if (GET_CODE (op) == CONST_DOUBLE)
508     return (CONST_DOUBLE_LOW (op) == -1 && CONST_DOUBLE_HIGH (op) == 0);
509 #endif
510
511   return (GET_CODE (op) == CONST_INT
512           && (INTVAL (op) == 0xff
513               || INTVAL (op) == 0xffff
514               || INTVAL (op) == (HOST_WIDE_INT)0xffffffff
515 #if HOST_BITS_PER_WIDE_INT == 64
516               || INTVAL (op) == -1
517 #endif
518               ));
519 }
520
521 /* Return 1 if OP is a multiple of 8 less than 64.  */
522
523 int
524 mul8_operand (op, mode)
525      register rtx op;
526      enum machine_mode mode ATTRIBUTE_UNUSED;
527 {
528   return (GET_CODE (op) == CONST_INT
529           && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
530           && (INTVAL (op) & 7) == 0);
531 }
532
533 /* Return 1 if OP is the constant zero in floating-point.  */
534
535 int
536 fp0_operand (op, mode)
537      register rtx op;
538      enum machine_mode mode;
539 {
540   return (GET_MODE (op) == mode
541           && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
542 }
543
544 /* Return 1 if OP is the floating-point constant zero or a register.  */
545
546 int
547 reg_or_fp0_operand (op, mode)
548      register rtx op;
549      enum machine_mode mode;
550 {
551   return fp0_operand (op, mode) || register_operand (op, mode);
552 }
553
554 /* Return 1 if OP is a hard floating-point register.  */
555
556 int
557 hard_fp_register_operand (op, mode)
558      register rtx op;
559      enum machine_mode mode;
560 {
561   return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS)
562           || (GET_CODE (op) == SUBREG
563               && hard_fp_register_operand (SUBREG_REG (op), mode)));
564 }
565
566 /* Return 1 if OP is a register or a constant integer.  */
567
568
569 int
570 reg_or_cint_operand (op, mode)
571     register rtx op;
572     enum machine_mode mode;
573 {
574      return (GET_CODE (op) == CONST_INT
575              || register_operand (op, mode));
576 }
577
578 /* Return 1 if OP is something that can be reloaded into a register;
579    if it is a MEM, it need not be valid.  */
580
581 int
582 some_operand (op, mode)
583      register rtx op;
584      enum machine_mode mode;
585 {
586   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
587     return 0;
588
589   switch (GET_CODE (op))
590     {
591     case REG:  case MEM:  case CONST_DOUBLE:  case CONST_INT:  case LABEL_REF:
592     case SYMBOL_REF:  case CONST:
593       return 1;
594
595     case SUBREG:
596       return some_operand (SUBREG_REG (op), VOIDmode);
597
598     default:
599       break;
600     }
601
602   return 0;
603 }
604
605 /* Likewise, but don't accept constants.  */
606
607 int
608 some_ni_operand (op, mode)
609      register rtx op;
610      enum machine_mode mode;
611 {
612   if (GET_MODE (op) != mode && mode != VOIDmode)
613     return 0;
614
615   if (GET_CODE (op) == SUBREG)
616     op = SUBREG_REG (op);
617
618   return (GET_CODE (op) == REG || GET_CODE (op) == MEM);
619 }
620
621 /* Return 1 if OP is a valid operand for the source of a move insn.  */
622
623 int
624 input_operand (op, mode)
625      register rtx op;
626      enum machine_mode mode;
627 {
628   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
629     return 0;
630
631   if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
632     return 0;
633
634   switch (GET_CODE (op))
635     {
636     case LABEL_REF:
637     case SYMBOL_REF:
638     case CONST:
639       /* This handles both the Windows/NT and OSF cases.  */
640       return mode == ptr_mode || mode == DImode;
641
642     case REG:
643     case ADDRESSOF:
644       return 1;
645
646     case SUBREG:
647       if (register_operand (op, mode))
648         return 1;
649       /* ... fall through ... */
650     case MEM:
651       return ((TARGET_BWX || (mode != HImode && mode != QImode))
652               && general_operand (op, mode));
653
654     case CONST_DOUBLE:
655       return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
656
657     case CONST_INT:
658       return mode == QImode || mode == HImode || add_operand (op, mode);
659
660     case CONSTANT_P_RTX:
661       return 1;
662
663     default:
664       break;
665     }
666
667   return 0;
668 }
669
670 /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
671    file.  */
672
673 int
674 current_file_function_operand (op, mode)
675      rtx op;
676      enum machine_mode mode ATTRIBUTE_UNUSED;
677 {
678   return (GET_CODE (op) == SYMBOL_REF
679           && ! profile_flag && ! profile_block_flag
680           && (SYMBOL_REF_FLAG (op)
681               || op == XEXP (DECL_RTL (current_function_decl), 0)));
682 }
683
684 /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
685
686 int
687 call_operand (op, mode)
688      rtx op;
689      enum machine_mode mode;
690 {
691   if (mode != Pmode)
692     return 0;
693
694   return (GET_CODE (op) == SYMBOL_REF
695           || (GET_CODE (op) == REG
696               && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27)));
697 }
698
699 /* Return 1 if OP is a valid Alpha comparison operator.  Here we know which
700    comparisons are valid in which insn.  */
701
702 int
703 alpha_comparison_operator (op, mode)
704      register rtx op;
705      enum machine_mode mode;
706 {
707   enum rtx_code code = GET_CODE (op);
708
709   if (mode != GET_MODE (op) && mode != VOIDmode)
710     return 0;
711
712   return (code == EQ || code == LE || code == LT
713           || (mode == DImode && (code == LEU || code == LTU)));
714 }
715
716 /* Return 1 if OP is a valid Alpha swapped comparison operator.  */
717
718 int
719 alpha_swapped_comparison_operator (op, mode)
720      register rtx op;
721      enum machine_mode mode;
722 {
723   enum rtx_code code = GET_CODE (op);
724
725   if ((mode != GET_MODE (op) && mode != VOIDmode)
726       || GET_RTX_CLASS (code) != '<')
727     return 0;
728
729   code = swap_condition (code);
730   return (code == EQ || code == LE || code == LT
731           || (mode == DImode && (code == LEU || code == LTU)));
732 }
733
734 /* Return 1 if OP is a signed comparison operation.  */
735
736 int
737 signed_comparison_operator (op, mode)
738      register rtx op;
739      enum machine_mode mode ATTRIBUTE_UNUSED;
740 {
741   enum rtx_code code = GET_CODE (op);
742
743   if (mode != GET_MODE (op) && mode != VOIDmode)
744     return 0;
745
746   return (code == EQ || code == NE
747           || code == LE || code == LT
748           || code == GE || code == GT);
749 }
750
751 /* Return 1 if OP is a valid Alpha floating point comparison operator.
752    Here we know which comparisons are valid in which insn.  */
753
754 int
755 alpha_fp_comparison_operator (op, mode)
756      register rtx op;
757      enum machine_mode mode;
758 {
759   enum rtx_code code = GET_CODE (op);
760
761   if (mode != GET_MODE (op) && mode != VOIDmode)
762     return 0;
763
764   return (code == EQ || code == LE || code == LT || code == UNORDERED);
765 }
766
767 /* Return 1 if this is a divide or modulus operator.  */
768
769 int
770 divmod_operator (op, mode)
771      register rtx op;
772      enum machine_mode mode ATTRIBUTE_UNUSED;
773 {
774   switch (GET_CODE (op))
775     {
776     case DIV:  case MOD:  case UDIV:  case UMOD:
777       return 1;
778
779     default:
780       break;
781     }
782
783   return 0;
784 }
785
786 /* Return 1 if this memory address is a known aligned register plus
787    a constant.  It must be a valid address.  This means that we can do
788    this as an aligned reference plus some offset.
789
790    Take into account what reload will do.  */
791
792 int
793 aligned_memory_operand (op, mode)
794      register rtx op;
795      enum machine_mode mode;
796 {
797   rtx base;
798
799   if (reload_in_progress)
800     {
801       rtx tmp = op;
802       if (GET_CODE (tmp) == SUBREG)
803         tmp = SUBREG_REG (tmp);
804       if (GET_CODE (tmp) == REG
805           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
806         {
807           op = reg_equiv_memory_loc[REGNO (tmp)];
808           if (op == 0)
809             return 0;
810         }
811     }
812
813   if (GET_CODE (op) != MEM
814       || GET_MODE (op) != mode)
815     return 0;
816   op = XEXP (op, 0);
817
818   /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
819      sorts of constructs.  Dig for the real base register.  */
820   if (reload_in_progress
821       && GET_CODE (op) == PLUS
822       && GET_CODE (XEXP (op, 0)) == PLUS)
823     base = XEXP (XEXP (op, 0), 0);
824   else
825     {
826       if (! memory_address_p (mode, op))
827         return 0;
828       base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
829     }
830
831   return (GET_CODE (base) == REG
832           && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
833 }
834
835 /* Similar, but return 1 if OP is a MEM which is not alignable.  */
836
837 int
838 unaligned_memory_operand (op, mode)
839      register rtx op;
840      enum machine_mode mode;
841 {
842   rtx base;
843
844   if (reload_in_progress)
845     {
846       rtx tmp = op;
847       if (GET_CODE (tmp) == SUBREG)
848         tmp = SUBREG_REG (tmp);
849       if (GET_CODE (tmp) == REG
850           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
851         {
852           op = reg_equiv_memory_loc[REGNO (tmp)];
853           if (op == 0)
854             return 0;
855         }
856     }
857
858   if (GET_CODE (op) != MEM
859       || GET_MODE (op) != mode)
860     return 0;
861   op = XEXP (op, 0);
862
863   /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
864      sorts of constructs.  Dig for the real base register.  */
865   if (reload_in_progress
866       && GET_CODE (op) == PLUS
867       && GET_CODE (XEXP (op, 0)) == PLUS)
868     base = XEXP (XEXP (op, 0), 0);
869   else
870     {
871       if (! memory_address_p (mode, op))
872         return 0;
873       base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
874     }
875
876   return (GET_CODE (base) == REG
877           && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
878 }
879
880 /* Return 1 if OP is either a register or an unaligned memory location.  */
881
882 int
883 reg_or_unaligned_mem_operand (op, mode)
884      rtx op;
885      enum machine_mode mode;
886 {
887   return register_operand (op, mode) || unaligned_memory_operand (op, mode);
888 }
889
890 /* Return 1 if OP is any memory location.  During reload a pseudo matches.  */
891
892 int
893 any_memory_operand (op, mode)
894      register rtx op;
895      enum machine_mode mode ATTRIBUTE_UNUSED;
896 {
897   return (GET_CODE (op) == MEM
898           || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
899           || (reload_in_progress && GET_CODE (op) == REG
900               && REGNO (op) >= FIRST_PSEUDO_REGISTER)
901           || (reload_in_progress && GET_CODE (op) == SUBREG
902               && GET_CODE (SUBREG_REG (op)) == REG
903               && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
904 }
905
906 /* Returns 1 if OP is not an eliminable register.
907
908    This exists to cure a pathological abort in the s8addq (et al) patterns,
909
910         long foo () { long t; bar(); return (long) &t * 26107; }
911
912    which run afoul of a hack in reload to cure a (presumably) similar
913    problem with lea-type instructions on other targets.  But there is
914    one of us and many of them, so work around the problem by selectively
915    preventing combine from making the optimization.  */
916
917 int
918 reg_not_elim_operand (op, mode)
919       register rtx op;
920       enum machine_mode mode;
921 {
922   rtx inner = op;
923   if (GET_CODE (op) == SUBREG)
924     inner = SUBREG_REG (op);
925   if (inner == frame_pointer_rtx || inner == arg_pointer_rtx)
926     return 0;
927
928   return register_operand (op, mode);
929 }
930
931 /* Return 1 is OP is a memory location that is not a reference (using
932    an AND) to an unaligned location.  Take into account what reload
933    will do.  */
934
935 int
936 normal_memory_operand (op, mode)
937      register rtx op;
938      enum machine_mode mode ATTRIBUTE_UNUSED;
939 {
940   if (reload_in_progress)
941     {
942       rtx tmp = op;
943       if (GET_CODE (tmp) == SUBREG)
944         tmp = SUBREG_REG (tmp);
945       if (GET_CODE (tmp) == REG
946           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
947         {
948           op = reg_equiv_memory_loc[REGNO (tmp)];
949
950           /* This may not have been assigned an equivalent address if it will
951              be eliminated.  In that case, it doesn't matter what we do.  */
952           if (op == 0)
953             return 1;
954         }
955     }
956
957   return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND;
958 }
959
960 /* Accept a register, but not a subreg of any kind.  This allows us to
961    avoid pathological cases in reload wrt data movement common in 
962    int->fp conversion.  */
963
964 int
965 reg_no_subreg_operand (op, mode)
966      register rtx op;
967      enum machine_mode mode;
968 {
969   if (GET_CODE (op) == SUBREG)
970     return 0;
971   return register_operand (op, mode);
972 }
973
974 /* Recognize a addition operation that includes a constant.  Used to
975    convince reload to canonize (plus (plus reg c1) c2) during register
976    elimination.  */
977
978 int
979 addition_operation (op, mode)
980      register rtx op;
981      enum machine_mode mode;
982 {
983   if (GET_MODE (op) != mode && mode != VOIDmode)
984     return 0;
985   if (GET_CODE (op) == PLUS
986       && register_operand (XEXP (op, 0), mode)
987       && GET_CODE (XEXP (op, 1)) == CONST_INT
988       && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op, 1)), 'K'))
989     return 1;
990   return 0;
991 }
992
993 /* Return 1 if this function can directly return via $26.  */
994
995 int
996 direct_return ()
997 {
998   return (! TARGET_OPEN_VMS && reload_completed && alpha_sa_size () == 0
999           && get_frame_size () == 0
1000           && current_function_outgoing_args_size == 0
1001           && current_function_pretend_args_size == 0);
1002 }
1003 \f
1004 /* REF is an alignable memory location.  Place an aligned SImode
1005    reference into *PALIGNED_MEM and the number of bits to shift into
1006    *PBITNUM.  SCRATCH is a free register for use in reloading out
1007    of range stack slots.  */
1008
1009 void
1010 get_aligned_mem (ref, paligned_mem, pbitnum)
1011      rtx ref;
1012      rtx *paligned_mem, *pbitnum;
1013 {
1014   rtx base;
1015   HOST_WIDE_INT offset = 0;
1016
1017   if (GET_CODE (ref) != MEM)
1018     abort ();
1019
1020   if (reload_in_progress
1021       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1022     {
1023       base = find_replacement (&XEXP (ref, 0));
1024
1025       if (! memory_address_p (GET_MODE (ref), base))
1026         abort ();
1027     }
1028   else
1029     {
1030       base = XEXP (ref, 0);
1031     }
1032
1033   if (GET_CODE (base) == PLUS)
1034     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1035
1036   *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3));
1037   MEM_COPY_ATTRIBUTES (*paligned_mem, ref);
1038   RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
1039
1040   /* Sadly, we cannot use alias sets here because we may overlap other
1041      data in a different alias set.  */
1042   /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */
1043
1044   *pbitnum = GEN_INT ((offset & 3) * 8);
1045 }
1046
1047 /* Similar, but just get the address.  Handle the two reload cases.  
1048    Add EXTRA_OFFSET to the address we return.  */
1049
1050 rtx
1051 get_unaligned_address (ref, extra_offset)
1052      rtx ref;
1053      int extra_offset;
1054 {
1055   rtx base;
1056   HOST_WIDE_INT offset = 0;
1057
1058   if (GET_CODE (ref) != MEM)
1059     abort ();
1060
1061   if (reload_in_progress
1062       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1063     {
1064       base = find_replacement (&XEXP (ref, 0));
1065
1066       if (! memory_address_p (GET_MODE (ref), base))
1067         abort ();
1068     }
1069   else
1070     {
1071       base = XEXP (ref, 0);
1072     }
1073
1074   if (GET_CODE (base) == PLUS)
1075     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1076
1077   return plus_constant (base, offset + extra_offset);
1078 }
1079
1080 /* Loading and storing HImode or QImode values to and from memory
1081    usually requires a scratch register.  The exceptions are loading
1082    QImode and HImode from an aligned address to a general register
1083    unless byte instructions are permitted. 
1084
1085    We also cannot load an unaligned address or a paradoxical SUBREG
1086    into an FP register. 
1087
1088    We also cannot do integral arithmetic into FP regs, as might result
1089    from register elimination into a DImode fp register.  */
1090
1091 enum reg_class
1092 secondary_reload_class (class, mode, x, in)
1093      enum reg_class class;
1094      enum machine_mode mode;
1095      rtx x;
1096      int in;
1097 {
1098   if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
1099     {
1100       if (GET_CODE (x) == MEM
1101           || (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
1102           || (GET_CODE (x) == SUBREG
1103               && (GET_CODE (SUBREG_REG (x)) == MEM
1104                   || (GET_CODE (SUBREG_REG (x)) == REG
1105                       && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER))))
1106         {
1107           if (!in || !aligned_memory_operand(x, mode))
1108             return GENERAL_REGS;
1109         }
1110     }
1111
1112   if (class == FLOAT_REGS)
1113     {
1114       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
1115         return GENERAL_REGS;
1116
1117       if (GET_CODE (x) == SUBREG
1118           && (GET_MODE_SIZE (GET_MODE (x))
1119               > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
1120         return GENERAL_REGS;
1121
1122       if (in && INTEGRAL_MODE_P (mode) && ! general_operand (x, mode))
1123         return GENERAL_REGS;
1124     }
1125
1126   return NO_REGS;
1127 }
1128 \f
1129 /* Subfunction of the following function.  Update the flags of any MEM
1130    found in part of X.  */
1131
1132 static void
1133 alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
1134      rtx x;
1135      int in_struct_p, volatile_p, unchanging_p;
1136 {
1137   int i;
1138
1139   switch (GET_CODE (x))
1140     {
1141     case SEQUENCE:
1142     case PARALLEL:
1143       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1144         alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
1145                               unchanging_p);
1146       break;
1147
1148     case INSN:
1149       alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
1150                             unchanging_p);
1151       break;
1152
1153     case SET:
1154       alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
1155                             unchanging_p);
1156       alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
1157                             unchanging_p);
1158       break;
1159
1160     case MEM:
1161       MEM_IN_STRUCT_P (x) = in_struct_p;
1162       MEM_VOLATILE_P (x) = volatile_p;
1163       RTX_UNCHANGING_P (x) = unchanging_p;
1164       /* Sadly, we cannot use alias sets because the extra aliasing
1165          produced by the AND interferes.  Given that two-byte quantities
1166          are the only thing we would be able to differentiate anyway,
1167          there does not seem to be any point in convoluting the early
1168          out of the alias check.  */
1169       /* MEM_ALIAS_SET (x) = alias_set; */
1170       break;
1171
1172     default:
1173       break;
1174     }
1175 }
1176
1177 /* Given INSN, which is either an INSN or a SEQUENCE generated to
1178    perform a memory operation, look for any MEMs in either a SET_DEST or
1179    a SET_SRC and copy the in-struct, unchanging, and volatile flags from
1180    REF into each of the MEMs found.  If REF is not a MEM, don't do
1181    anything.  */
1182
1183 void
1184 alpha_set_memflags (insn, ref)
1185      rtx insn;
1186      rtx ref;
1187 {
1188   int in_struct_p, volatile_p, unchanging_p;
1189
1190   if (GET_CODE (ref) != MEM)
1191     return;
1192
1193   in_struct_p = MEM_IN_STRUCT_P (ref);
1194   volatile_p = MEM_VOLATILE_P (ref);
1195   unchanging_p = RTX_UNCHANGING_P (ref);
1196
1197   /* This is only called from alpha.md, after having had something 
1198      generated from one of the insn patterns.  So if everything is
1199      zero, the pattern is already up-to-date.  */
1200   if (! in_struct_p && ! volatile_p && ! unchanging_p)
1201     return;
1202
1203   alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
1204 }
1205 \f
1206 /* Try to output insns to set TARGET equal to the constant C if it can be
1207    done in less than N insns.  Do all computations in MODE.  Returns the place
1208    where the output has been placed if it can be done and the insns have been
1209    emitted.  If it would take more than N insns, zero is returned and no
1210    insns and emitted.  */
1211
1212 rtx
1213 alpha_emit_set_const (target, mode, c, n)
1214      rtx target;
1215      enum machine_mode mode;
1216      HOST_WIDE_INT c;
1217      int n;
1218 {
1219   rtx pat;
1220   int i;
1221
1222   /* Try 1 insn, then 2, then up to N. */
1223   for (i = 1; i <= n; i++)
1224     if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0)
1225       return pat;
1226
1227   return 0;
1228 }
1229
1230 /* Internal routine for the above to check for N or below insns.  */
1231
1232 static rtx
1233 alpha_emit_set_const_1 (target, mode, c, n)
1234      rtx target;
1235      enum machine_mode mode;
1236      HOST_WIDE_INT c;
1237      int n;
1238 {
1239   HOST_WIDE_INT new = c;
1240   int i, bits;
1241   /* Use a pseudo if highly optimizing and still generating RTL.  */
1242   rtx subtarget
1243     = (flag_expensive_optimizations && rtx_equal_function_value_matters
1244        ? 0 : target);
1245   rtx temp;
1246
1247 #if HOST_BITS_PER_WIDE_INT == 64
1248   /* We are only called for SImode and DImode.  If this is SImode, ensure that
1249      we are sign extended to a full word.  This does not make any sense when
1250      cross-compiling on a narrow machine.  */
1251
1252   if (mode == SImode)
1253     c = (c & 0xffffffff) - 2 * (c & 0x80000000);
1254 #endif
1255
1256   /* If this is a sign-extended 32-bit constant, we can do this in at most
1257      three insns, so do it if we have enough insns left.  We always have
1258      a sign-extended 32-bit constant when compiling on a narrow machine.   */
1259
1260   if (HOST_BITS_PER_WIDE_INT != 64
1261       || c >> 31 == -1 || c >> 31 == 0)
1262     {
1263       HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
1264       HOST_WIDE_INT tmp1 = c - low;
1265       HOST_WIDE_INT high
1266         = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1267       HOST_WIDE_INT extra = 0;
1268
1269       /* If HIGH will be interpreted as negative but the constant is
1270          positive, we must adjust it to do two ldha insns.  */
1271
1272       if ((high & 0x8000) != 0 && c >= 0)
1273         {
1274           extra = 0x4000;
1275           tmp1 -= 0x40000000;
1276           high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1277         }
1278
1279       if (c == low || (low == 0 && extra == 0))
1280         {
1281           /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1282              but that meant that we can't handle INT_MIN on 32-bit machines
1283              (like NT/Alpha), because we recurse indefinitely through 
1284              emit_move_insn to gen_movdi.  So instead, since we know exactly
1285              what we want, create it explicitly.  */
1286
1287           if (target == NULL)
1288             target = gen_reg_rtx (mode);
1289           emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1290           return target;
1291         }
1292       else if (n >= 2 + (extra != 0))
1293         {
1294           temp = copy_to_suggested_reg (GEN_INT (low), subtarget, mode);
1295
1296           if (extra != 0)
1297             temp = expand_binop (mode, add_optab, temp, GEN_INT (extra << 16),
1298                                  subtarget, 0, OPTAB_WIDEN);
1299
1300           return expand_binop (mode, add_optab, temp, GEN_INT (high << 16),
1301                                target, 0, OPTAB_WIDEN);
1302         }
1303     }
1304
1305   /* If we couldn't do it that way, try some other methods.  But if we have
1306      no instructions left, don't bother.  Likewise, if this is SImode and
1307      we can't make pseudos, we can't do anything since the expand_binop
1308      and expand_unop calls will widen and try to make pseudos.  */
1309
1310   if (n == 1
1311       || (mode == SImode && ! rtx_equal_function_value_matters))
1312     return 0;
1313
1314 #if HOST_BITS_PER_WIDE_INT == 64
1315   /* First, see if can load a value into the target that is the same as the
1316      constant except that all bytes that are 0 are changed to be 0xff.  If we
1317      can, then we can do a ZAPNOT to obtain the desired constant.  */
1318
1319   for (i = 0; i < 64; i += 8)
1320     if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1321       new |= (HOST_WIDE_INT) 0xff << i;
1322
1323   /* We are only called for SImode and DImode.  If this is SImode, ensure that
1324      we are sign extended to a full word.  */
1325
1326   if (mode == SImode)
1327     new = (new & 0xffffffff) - 2 * (new & 0x80000000);
1328
1329   if (new != c
1330       && (temp = alpha_emit_set_const (subtarget, mode, new, n - 1)) != 0)
1331     return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new),
1332                          target, 0, OPTAB_WIDEN);
1333 #endif
1334
1335   /* Next, see if we can load a related constant and then shift and possibly
1336      negate it to get the constant we want.  Try this once each increasing
1337      numbers of insns.  */
1338
1339   for (i = 1; i < n; i++)
1340     {
1341       /* First try complementing.  */
1342       if ((temp = alpha_emit_set_const (subtarget, mode, ~ c, i)) != 0)
1343         return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1344
1345       /* Next try to form a constant and do a left shift.  We can do this
1346          if some low-order bits are zero; the exact_log2 call below tells
1347          us that information.  The bits we are shifting out could be any
1348          value, but here we'll just try the 0- and sign-extended forms of
1349          the constant.  To try to increase the chance of having the same
1350          constant in more than one insn, start at the highest number of
1351          bits to shift, but try all possibilities in case a ZAPNOT will
1352          be useful.  */
1353
1354       if ((bits = exact_log2 (c & - c)) > 0)
1355         for (; bits > 0; bits--)
1356           if ((temp = (alpha_emit_set_const
1357                        (subtarget, mode,
1358                         (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0
1359               || ((temp = (alpha_emit_set_const
1360                           (subtarget, mode,
1361                            ((unsigned HOST_WIDE_INT) c) >> bits, i)))
1362                   != 0))
1363             return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1364                                  target, 0, OPTAB_WIDEN);
1365
1366       /* Now try high-order zero bits.  Here we try the shifted-in bits as
1367          all zero and all ones.  Be careful to avoid shifting outside the
1368          mode and to avoid shifting outside the host wide int size.  */
1369       /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1370          confuse the recursive call and set all of the high 32 bits.  */
1371
1372       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1373                    - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64))) > 0)
1374         for (; bits > 0; bits--)
1375           if ((temp = alpha_emit_set_const (subtarget, mode,
1376                                             c << bits, i)) != 0
1377               || ((temp = (alpha_emit_set_const
1378                            (subtarget, mode,
1379                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1380                             i)))
1381                   != 0))
1382             return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1383                                  target, 1, OPTAB_WIDEN);
1384
1385       /* Now try high-order 1 bits.  We get that with a sign-extension.
1386          But one bit isn't enough here.  Be careful to avoid shifting outside
1387          the mode and to avoid shifting outside the host wide int size. */
1388       
1389       if ((bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1390                    - floor_log2 (~ c) - 2)) > 0)
1391         for (; bits > 0; bits--)
1392           if ((temp = alpha_emit_set_const (subtarget, mode,
1393                                             c << bits, i)) != 0
1394               || ((temp = (alpha_emit_set_const
1395                            (subtarget, mode,
1396                             ((c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1)),
1397                             i)))
1398                   != 0))
1399             return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1400                                  target, 0, OPTAB_WIDEN);
1401     }
1402
1403   /* Next, see if, minus some low bits, we've an easy load of high bits.  */
1404
1405   new = ((c & 0xffff) ^ 0x8000) - 0x8000;
1406   if (new != 0
1407       && (temp = alpha_emit_set_const (subtarget, mode, c - new, n - 1)) != 0)
1408     return expand_binop (mode, add_optab, temp, GEN_INT (new),
1409                          target, 0, OPTAB_WIDEN);
1410
1411   return 0;
1412 }
1413
1414 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1415    fall back to a straight forward decomposition.  We do this to avoid
1416    exponential run times encountered when looking for longer sequences
1417    with alpha_emit_set_const.  */
1418
1419 rtx
1420 alpha_emit_set_long_const (target, c1, c2)
1421      rtx target;
1422      HOST_WIDE_INT c1, c2;
1423 {
1424   HOST_WIDE_INT d1, d2, d3, d4;
1425
1426   /* Decompose the entire word */
1427 #if HOST_BITS_PER_WIDE_INT >= 64
1428   if (c2 != -(c1 < 0))
1429     abort ();
1430   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1431   c1 -= d1;
1432   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1433   c1 = (c1 - d2) >> 32;
1434   d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1435   c1 -= d3;
1436   d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1437   if (c1 != d4)
1438     abort ();
1439 #else
1440   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1441   c1 -= d1;
1442   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1443   if (c1 != d2)
1444     abort ();
1445   c2 += (d2 < 0);
1446   d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1447   c2 -= d3;
1448   d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1449   if (c2 != d4)
1450     abort ();
1451 #endif
1452
1453   /* Construct the high word */
1454   if (d4)
1455     {
1456       emit_move_insn (target, GEN_INT (d4));
1457       if (d3)
1458         emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1459     }
1460   else
1461     emit_move_insn (target, GEN_INT (d3));
1462
1463   /* Shift it into place */
1464   emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1465
1466   /* Add in the low bits.  */
1467   if (d2)
1468     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1469   if (d1)
1470     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1471
1472   return target;
1473 }
1474
1475 /* Generate an unsigned DImode to FP conversion.  This is the same code
1476    optabs would emit if we didn't have TFmode patterns.
1477
1478    For SFmode, this is the only construction I've found that can pass
1479    gcc.c-torture/execute/ieee/rbug.c.  No scenario that uses DFmode
1480    intermediates will work, because you'll get intermediate rounding
1481    that ruins the end result.  Some of this could be fixed by turning
1482    on round-to-positive-infinity, but that requires diddling the fpsr,
1483    which kills performance.  I tried turning this around and converting
1484    to a negative number, so that I could turn on /m, but either I did
1485    it wrong or there's something else cause I wound up with the exact
1486    same single-bit error.  There is a branch-less form of this same code:
1487
1488         srl     $16,1,$1
1489         and     $16,1,$2
1490         cmplt   $16,0,$3
1491         or      $1,$2,$2
1492         cmovge  $16,$16,$2
1493         itoft   $3,$f10
1494         itoft   $2,$f11
1495         cvtqs   $f11,$f11
1496         adds    $f11,$f11,$f0
1497         fcmoveq $f10,$f11,$f0
1498
1499    I'm not using it because it's the same number of instructions as
1500    this branch-full form, and it has more serialized long latency
1501    instructions on the critical path.
1502
1503    For DFmode, we can avoid rounding errors by breaking up the word
1504    into two pieces, converting them separately, and adding them back:
1505
1506    LC0: .long 0,0x5f800000
1507
1508         itoft   $16,$f11
1509         lda     $2,LC0
1510         cpyse   $f11,$f31,$f10
1511         cpyse   $f31,$f11,$f11
1512         s4addq  $1,$2,$1
1513         lds     $f12,0($1)
1514         cvtqt   $f10,$f10
1515         cvtqt   $f11,$f11
1516         addt    $f12,$f10,$f0
1517         addt    $f0,$f11,$f0
1518
1519    This doesn't seem to be a clear-cut win over the optabs form.
1520    It probably all depends on the distribution of numbers being
1521    converted -- in the optabs form, all but high-bit-set has a
1522    much lower minimum execution time.  */
1523
1524 void
1525 alpha_emit_floatuns (operands)
1526      rtx operands[2];
1527 {
1528   rtx neglab, donelab, i0, i1, f0, in, out;
1529   enum machine_mode mode;
1530
1531   out = operands[0];
1532   in = operands[1];
1533   mode = GET_MODE (out);
1534   neglab = gen_label_rtx ();
1535   donelab = gen_label_rtx ();
1536   i0 = gen_reg_rtx (DImode);
1537   i1 = gen_reg_rtx (DImode);
1538   f0 = gen_reg_rtx (mode);
1539
1540   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0,
1541                            8, neglab);
1542
1543   emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
1544   emit_jump_insn (gen_jump (donelab));
1545
1546   emit_label (neglab);
1547
1548   emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
1549   emit_insn (gen_anddi3 (i1, in, const1_rtx));
1550   emit_insn (gen_iordi3 (i0, i0, i1));
1551   emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
1552   emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
1553
1554   emit_label (donelab);
1555 }
1556
1557 /* Generate the comparison for a conditional branch.  */
1558
1559 rtx
1560 alpha_emit_conditional_branch (code)
1561      enum rtx_code code;
1562 {
1563   enum rtx_code cmp_code, branch_code;
1564   enum machine_mode cmp_mode, branch_mode = VOIDmode;
1565   rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
1566   rtx tem;
1567
1568   if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
1569     {
1570       if (! TARGET_HAS_XFLOATING_LIBS)
1571         abort ();
1572
1573       /* X_floating library comparison functions return
1574            -1  unordered
1575             0  false
1576             1  true
1577          Convert the compare against the raw return value.  */
1578
1579       op0 = alpha_emit_xfloating_compare (code, op0, op1);
1580       op1 = const0_rtx;
1581       alpha_compare.fp_p = 0;
1582       code = GT;
1583     }
1584
1585   /* The general case: fold the comparison code to the types of compares
1586      that we have, choosing the branch as necessary.  */
1587   switch (code)
1588     {
1589     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1590     case UNORDERED:
1591       /* We have these compares: */
1592       cmp_code = code, branch_code = NE;
1593       break;
1594
1595     case NE:
1596     case ORDERED:
1597       /* These must be reversed. */
1598       cmp_code = reverse_condition (code), branch_code = EQ;
1599       break;
1600
1601     case GE:  case GT: case GEU:  case GTU:
1602       /* For FP, we swap them, for INT, we reverse them.  */
1603       if (alpha_compare.fp_p)
1604         {
1605           cmp_code = swap_condition (code);
1606           branch_code = NE;
1607           tem = op0, op0 = op1, op1 = tem;
1608         }
1609       else
1610         {
1611           cmp_code = reverse_condition (code);
1612           branch_code = EQ;
1613         }
1614       break;
1615
1616     default:
1617       abort ();
1618     }
1619
1620   if (alpha_compare.fp_p)
1621     {
1622       cmp_mode = DFmode;
1623       if (flag_fast_math)
1624         {
1625           /* When we are not as concerned about non-finite values, and we
1626              are comparing against zero, we can branch directly.  */
1627           if (op1 == CONST0_RTX (DFmode))
1628             cmp_code = NIL, branch_code = code;
1629           else if (op0 == CONST0_RTX (DFmode))
1630             {
1631               /* Undo the swap we probably did just above.  */
1632               tem = op0, op0 = op1, op1 = tem;
1633               branch_code = swap_condition (cmp_code);
1634               cmp_code = NIL;
1635             }
1636         }
1637       else
1638         {
1639           /* ??? We mark the the branch mode to be CCmode to prevent the
1640              compare and branch from being combined, since the compare 
1641              insn follows IEEE rules that the branch does not.  */
1642           branch_mode = CCmode;
1643         }
1644     }
1645   else
1646     {
1647       cmp_mode = DImode;
1648
1649       /* The following optimizations are only for signed compares.  */
1650       if (code != LEU && code != LTU && code != GEU && code != GTU)
1651         {
1652           /* Whee.  Compare and branch against 0 directly.  */
1653           if (op1 == const0_rtx)
1654             cmp_code = NIL, branch_code = code;
1655
1656           /* We want to use cmpcc/bcc when we can, since there is a zero delay
1657              bypass between logicals and br/cmov on EV5.  But we don't want to
1658              force valid immediate constants into registers needlessly.  */
1659           else if (GET_CODE (op1) == CONST_INT)
1660             {
1661               HOST_WIDE_INT v = INTVAL (op1), n = -v;
1662
1663               if (! CONST_OK_FOR_LETTER_P (v, 'I')
1664                   && (CONST_OK_FOR_LETTER_P (n, 'K')
1665                       || CONST_OK_FOR_LETTER_P (n, 'L')))
1666                 {
1667                   cmp_code = PLUS, branch_code = code;
1668                   op1 = GEN_INT (n);
1669                 }
1670             }
1671         }
1672     }
1673
1674   /* Force op0 into a register.  */
1675   if (GET_CODE (op0) != REG)
1676     op0 = force_reg (cmp_mode, op0);
1677
1678   /* Emit an initial compare instruction, if necessary.  */
1679   tem = op0;
1680   if (cmp_code != NIL)
1681     {
1682       tem = gen_reg_rtx (cmp_mode);
1683       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
1684     }
1685
1686   /* Zero the operands.  */
1687   memset (&alpha_compare, 0, sizeof (alpha_compare));
1688
1689   /* Return the branch comparison.  */
1690   return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
1691 }
1692
1693
1694 /* Rewrite a comparison against zero CMP of the form
1695    (CODE (cc0) (const_int 0)) so it can be written validly in
1696    a conditional move (if_then_else CMP ...).
1697    If both of the operands that set cc0 are non-zero we must emit
1698    an insn to perform the compare (it can't be done within
1699    the conditional move). */
1700 rtx
1701 alpha_emit_conditional_move (cmp, mode)
1702      rtx cmp;
1703      enum machine_mode mode;
1704 {
1705   enum rtx_code code = GET_CODE (cmp);
1706   enum rtx_code cmov_code = NE;
1707   rtx op0 = alpha_compare.op0;
1708   rtx op1 = alpha_compare.op1;
1709   int fp_p = alpha_compare.fp_p;
1710   enum machine_mode cmp_mode
1711     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
1712   enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
1713   enum machine_mode cmov_mode = VOIDmode;
1714   int local_fast_math = flag_fast_math;
1715   rtx tem;
1716
1717   /* Zero the operands.  */
1718   memset (&alpha_compare, 0, sizeof (alpha_compare));
1719
1720   if (fp_p != FLOAT_MODE_P (mode))
1721     {
1722       enum rtx_code cmp_code;
1723
1724       if (! TARGET_FIX)
1725         return 0;
1726
1727       /* If we have fp<->int register move instructions, do a cmov by
1728          performing the comparison in fp registers, and move the
1729          zero/non-zero value to integer registers, where we can then
1730          use a normal cmov, or vice-versa.  */
1731
1732       switch (code)
1733         {
1734         case EQ: case LE: case LT: case LEU: case LTU:
1735           /* We have these compares.  */
1736           cmp_code = code, code = NE;
1737           break;
1738
1739         case NE:
1740           /* This must be reversed.  */
1741           cmp_code = EQ, code = EQ;
1742           break;
1743
1744         case GE: case GT: case GEU: case GTU:
1745           /* These must be swapped.  */
1746           cmp_code = swap_condition (code);
1747           code = NE;
1748           tem = op0, op0 = op1, op1 = tem;
1749           break;
1750
1751         default:
1752           abort ();
1753         }
1754
1755       tem = gen_reg_rtx (cmp_op_mode);
1756       emit_insn (gen_rtx_SET (VOIDmode, tem,
1757                               gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
1758                                               op0, op1)));
1759
1760       cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
1761       op0 = gen_lowpart (cmp_op_mode, tem);
1762       op1 = CONST0_RTX (cmp_op_mode);
1763       fp_p = !fp_p;
1764       local_fast_math = 1;
1765     }
1766
1767   /* We may be able to use a conditional move directly.
1768      This avoids emitting spurious compares. */
1769   if (signed_comparison_operator (cmp, VOIDmode)
1770       && (!fp_p || local_fast_math)
1771       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
1772     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
1773
1774   /* We can't put the comparison insides a conditional move;
1775      emit a compare instruction and put that inside the
1776      conditional move.  Make sure we emit only comparisons we have;
1777      swap or reverse as necessary.  */
1778
1779   switch (code)
1780     {
1781     case EQ:  case LE:  case LT:  case LEU:  case LTU:
1782       /* We have these compares: */
1783       break;
1784
1785     case NE:
1786       /* This must be reversed. */
1787       code = reverse_condition (code);
1788       cmov_code = EQ;
1789       break;
1790
1791     case GE:  case GT:  case GEU:  case GTU:
1792       /* These must be swapped.  Make sure the new first operand is in
1793          a register.  */
1794       code = swap_condition (code);
1795       tem = op0, op0 = op1, op1 = tem;
1796       op0 = force_reg (cmp_mode, op0);
1797       break;
1798
1799     default:
1800       abort ();
1801     }
1802
1803   /* ??? We mark the branch mode to be CCmode to prevent the compare
1804      and cmov from being combined, since the compare insn follows IEEE
1805      rules that the cmov does not.  */
1806   if (fp_p && !local_fast_math)
1807     cmov_mode = CCmode;
1808
1809   tem = gen_reg_rtx (cmp_op_mode);
1810   emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
1811   return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
1812 }
1813 \f
1814 /* Look up the function X_floating library function name for the
1815    given operation.  */
1816
1817 static const char *
1818 alpha_lookup_xfloating_lib_func (code)
1819      enum rtx_code code;
1820 {
1821   struct xfloating_op
1822     {
1823       enum rtx_code code;
1824       const char *func;
1825     };
1826
1827   static const struct xfloating_op vms_xfloating_ops[] = 
1828     {
1829       { PLUS,           "OTS$ADD_X" },
1830       { MINUS,          "OTS$SUB_X" },
1831       { MULT,           "OTS$MUL_X" },
1832       { DIV,            "OTS$DIV_X" },
1833       { EQ,             "OTS$EQL_X" },
1834       { NE,             "OTS$NEQ_X" },
1835       { LT,             "OTS$LSS_X" },
1836       { LE,             "OTS$LEQ_X" },
1837       { GT,             "OTS$GTR_X" },
1838       { GE,             "OTS$GEQ_X" },
1839       { FIX,            "OTS$CVTXQ" },
1840       { FLOAT,          "OTS$CVTQX" },
1841       { UNSIGNED_FLOAT, "OTS$CVTQUX" },
1842       { FLOAT_EXTEND,   "OTS$CVT_FLOAT_T_X" },
1843       { FLOAT_TRUNCATE, "OTS$CVT_FLOAT_X_T" },
1844     };
1845
1846   static const struct xfloating_op osf_xfloating_ops[] = 
1847     {
1848       { PLUS,           "_OtsAddX" },
1849       { MINUS,          "_OtsSubX" },
1850       { MULT,           "_OtsMulX" },
1851       { DIV,            "_OtsDivX" },
1852       { EQ,             "_OtsEqlX" },
1853       { NE,             "_OtsNeqX" },
1854       { LT,             "_OtsLssX" },
1855       { LE,             "_OtsLeqX" },
1856       { GT,             "_OtsGtrX" },
1857       { GE,             "_OtsGeqX" },
1858       { FIX,            "_OtsCvtXQ" },
1859       { FLOAT,          "_OtsCvtQX" },
1860       { UNSIGNED_FLOAT, "_OtsCvtQUX" },
1861       { FLOAT_EXTEND,   "_OtsConvertFloatTX" },
1862       { FLOAT_TRUNCATE, "_OtsConvertFloatXT" },
1863     };
1864
1865   const struct xfloating_op *ops;
1866   const long n = sizeof(osf_xfloating_ops) / sizeof(osf_xfloating_ops[0]);
1867   long i;
1868
1869   /* How irritating.  Nothing to key off for the table.  Hardcode
1870      knowledge of the G_floating routines.  */
1871   if (TARGET_FLOAT_VAX)
1872     {
1873       if (TARGET_OPEN_VMS)
1874         {
1875           if (code == FLOAT_EXTEND)
1876             return "OTS$CVT_FLOAT_G_X";
1877           if (code == FLOAT_TRUNCATE)
1878             return "OTS$CVT_FLOAT_X_G";
1879         }
1880       else
1881         {
1882           if (code == FLOAT_EXTEND)
1883             return "_OtsConvertFloatGX";
1884           if (code == FLOAT_TRUNCATE)
1885             return "_OtsConvertFloatXG";
1886         }
1887     }
1888
1889   if (TARGET_OPEN_VMS)
1890     ops = vms_xfloating_ops;
1891   else
1892     ops = osf_xfloating_ops;
1893
1894   for (i = 0; i < n; ++i)
1895     if (ops[i].code == code)
1896       return ops[i].func;
1897
1898   abort();
1899 }
1900
1901 /* Most X_floating operations take the rounding mode as an argument.
1902    Compute that here.  */
1903
1904 static int
1905 alpha_compute_xfloating_mode_arg (code, round)
1906      enum rtx_code code;
1907      enum alpha_fp_rounding_mode round;
1908 {
1909   int mode;
1910
1911   switch (round)
1912     {
1913     case ALPHA_FPRM_NORM:
1914       mode = 2;
1915       break;
1916     case ALPHA_FPRM_MINF:
1917       mode = 1;
1918       break;
1919     case ALPHA_FPRM_CHOP:
1920       mode = 0;
1921       break;
1922     case ALPHA_FPRM_DYN:
1923       mode = 4;
1924       break;
1925     default:
1926       abort ();
1927
1928     /* XXX For reference, round to +inf is mode = 3.  */
1929     }
1930
1931   if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
1932     mode |= 0x10000;
1933
1934   return mode;
1935 }
1936
1937 /* Emit an X_floating library function call.
1938
1939    Note that these functions do not follow normal calling conventions:
1940    TFmode arguments are passed in two integer registers (as opposed to
1941    indirect); TFmode return values appear in R16+R17. 
1942
1943    FUNC is the function name to call.
1944    TARGET is where the output belongs.
1945    OPERANDS are the inputs.
1946    NOPERANDS is the count of inputs.
1947    EQUIV is the expression equivalent for the function.
1948 */
1949
1950 static void
1951 alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
1952      const char *func;
1953      rtx target;
1954      rtx operands[];
1955      int noperands;
1956      rtx equiv;
1957 {
1958   rtx usage = NULL_RTX, tmp, reg;
1959   int regno = 16, i;
1960
1961   start_sequence ();
1962
1963   for (i = 0; i < noperands; ++i)
1964     {
1965       switch (GET_MODE (operands[i]))
1966         {
1967         case TFmode:
1968           reg = gen_rtx_REG (TFmode, regno);
1969           regno += 2;
1970           break;
1971
1972         case DFmode:
1973           reg = gen_rtx_REG (DFmode, regno + 32);
1974           regno += 1;
1975           break;
1976
1977         case VOIDmode:
1978           if (GET_CODE (operands[i]) != CONST_INT)
1979             abort ();
1980           /* FALLTHRU */
1981         case DImode:
1982           reg = gen_rtx_REG (DImode, regno);
1983           regno += 1;
1984           break;
1985
1986         default:
1987           abort ();
1988         }
1989
1990       emit_move_insn (reg, operands[i]);
1991       usage = alloc_EXPR_LIST (0, gen_rtx_USE (VOIDmode, reg), usage);
1992     }
1993
1994   switch (GET_MODE (target))
1995     {
1996     case TFmode:
1997       reg = gen_rtx_REG (TFmode, 16);
1998       break;
1999     case DFmode:
2000       reg = gen_rtx_REG (DFmode, 32);
2001       break;
2002     case DImode:
2003       reg = gen_rtx_REG (DImode, 0);
2004       break;
2005     default:
2006       abort ();
2007     }
2008
2009   tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
2010   tmp = emit_call_insn (gen_call_value (reg, tmp, const0_rtx,
2011                                         const0_rtx, const0_rtx));
2012   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
2013
2014   tmp = get_insns ();
2015   end_sequence ();
2016
2017   emit_libcall_block (tmp, target, reg, equiv);
2018 }
2019
2020 /* Emit an X_floating library function call for arithmetic (+,-,*,/).  */
2021
2022 void
2023 alpha_emit_xfloating_arith (code, operands)
2024      enum rtx_code code;
2025      rtx operands[];
2026 {
2027   const char *func;
2028   int mode;
2029   rtx out_operands[3];
2030
2031   func = alpha_lookup_xfloating_lib_func (code);
2032   mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2033
2034   out_operands[0] = operands[1];
2035   out_operands[1] = operands[2];
2036   out_operands[2] = GEN_INT (mode);
2037   alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,  
2038                                 gen_rtx_fmt_ee (code, TFmode, operands[1],
2039                                                 operands[2]));
2040 }
2041
2042 /* Emit an X_floating library function call for a comparison.  */
2043
2044 static rtx
2045 alpha_emit_xfloating_compare (code, op0, op1)
2046      enum rtx_code code;
2047      rtx op0, op1;
2048 {
2049   const char *func;
2050   rtx out, operands[2];
2051
2052   func = alpha_lookup_xfloating_lib_func (code);
2053
2054   operands[0] = op0;
2055   operands[1] = op1;
2056   out = gen_reg_rtx (DImode);
2057
2058   /* ??? Strange equiv cause what's actually returned is -1,0,1, not a
2059      proper boolean value.  */
2060   alpha_emit_xfloating_libcall (func, out, operands, 2, 
2061                                 gen_rtx_COMPARE (TFmode, op0, op1));
2062
2063   return out;
2064 }
2065
2066 /* Emit an X_floating library function call for a conversion.  */
2067
2068 void
2069 alpha_emit_xfloating_cvt (code, operands)
2070      enum rtx_code code;
2071      rtx operands[];
2072 {
2073   int noperands = 1, mode;
2074   rtx out_operands[2];
2075   const char *func;
2076
2077   func = alpha_lookup_xfloating_lib_func (code);
2078
2079   out_operands[0] = operands[1];
2080
2081   switch (code)
2082     {
2083     case FIX:
2084       mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
2085       out_operands[1] = GEN_INT (mode);
2086       noperands = 2;
2087       break;
2088     case FLOAT_TRUNCATE:
2089       mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
2090       out_operands[1] = GEN_INT (mode);
2091       noperands = 2;
2092       break;
2093     default:
2094       break;
2095     }
2096
2097   alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
2098                                 gen_rtx_fmt_e (code, GET_MODE (operands[0]),
2099                                                operands[1]));
2100 }
2101
2102 void
2103 alpha_split_tfmode_pair (operands)
2104      rtx operands[4];
2105 {
2106   if (GET_CODE (operands[1]) == REG)
2107     {
2108       operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
2109       operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
2110     }
2111   else if (GET_CODE (operands[1]) == MEM)
2112     {
2113       operands[3] = change_address (operands[1], DImode,
2114                                     plus_constant (XEXP (operands[1], 0), 8));
2115       operands[2] = change_address (operands[1], DImode, NULL_RTX);
2116     }
2117   else if (operands[1] == CONST0_RTX (TFmode))
2118     operands[2] = operands[3] = const0_rtx;
2119   else
2120     abort ();
2121
2122   if (GET_CODE (operands[0]) == REG)
2123     {
2124       operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
2125       operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
2126     }
2127   else if (GET_CODE (operands[0]) == MEM)
2128     {
2129       operands[1] = change_address (operands[0], DImode,
2130                                     plus_constant (XEXP (operands[0], 0), 8));
2131       operands[0] = change_address (operands[0], DImode, NULL_RTX);
2132     }
2133   else
2134     abort ();
2135 }
2136 \f
2137 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
2138    unaligned data:
2139
2140            unsigned:                       signed:
2141    word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
2142            ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
2143            lda    r3,X(r11)                lda    r3,X+2(r11)
2144            extwl  r1,r3,r1                 extql  r1,r3,r1
2145            extwh  r2,r3,r2                 extqh  r2,r3,r2
2146            or     r1.r2.r1                 or     r1,r2,r1
2147                                            sra    r1,48,r1
2148
2149    long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
2150            ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
2151            lda    r3,X(r11)                lda    r3,X(r11)
2152            extll  r1,r3,r1                 extll  r1,r3,r1
2153            extlh  r2,r3,r2                 extlh  r2,r3,r2
2154            or     r1.r2.r1                 addl   r1,r2,r1
2155
2156    quad:   ldq_u  r1,X(r11)
2157            ldq_u  r2,X+7(r11)
2158            lda    r3,X(r11)
2159            extql  r1,r3,r1
2160            extqh  r2,r3,r2
2161            or     r1.r2.r1
2162 */
2163
2164 void
2165 alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
2166      rtx tgt, mem;
2167      HOST_WIDE_INT size, ofs;
2168      int sign;
2169 {
2170   rtx meml, memh, addr, extl, exth;
2171   enum machine_mode mode;
2172
2173   meml = gen_reg_rtx (DImode);
2174   memh = gen_reg_rtx (DImode);
2175   addr = gen_reg_rtx (DImode);
2176   extl = gen_reg_rtx (DImode);
2177   exth = gen_reg_rtx (DImode);
2178
2179   emit_move_insn (meml,
2180                   change_address (mem, DImode,
2181                                   gen_rtx_AND (DImode, 
2182                                                plus_constant (XEXP (mem, 0),
2183                                                               ofs),
2184                                                GEN_INT (-8))));
2185
2186   emit_move_insn (memh,
2187                   change_address (mem, DImode,
2188                                   gen_rtx_AND (DImode, 
2189                                                plus_constant (XEXP (mem, 0),
2190                                                               ofs + size - 1),
2191                                                GEN_INT (-8))));
2192
2193   if (sign && size == 2)
2194     {
2195       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs+2));
2196
2197       emit_insn (gen_extxl (extl, meml, GEN_INT (64), addr));
2198       emit_insn (gen_extqh (exth, memh, addr));
2199
2200       /* We must use tgt here for the target.  Alpha-vms port fails if we use
2201          addr for the target, because addr is marked as a pointer and combine
2202          knows that pointers are always sign-extended 32 bit values.  */
2203       addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
2204       addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48), 
2205                            addr, 1, OPTAB_WIDEN);
2206     }
2207   else
2208     {
2209       emit_move_insn (addr, plus_constant (XEXP (mem, 0), ofs));
2210       emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
2211       switch ((int) size)
2212         {
2213         case 2:
2214           emit_insn (gen_extwh (exth, memh, addr));
2215           mode = HImode;
2216           break;
2217
2218         case 4:
2219           emit_insn (gen_extlh (exth, memh, addr));
2220           mode = SImode;
2221           break;
2222
2223         case 8:
2224           emit_insn (gen_extqh (exth, memh, addr));
2225           mode = DImode;
2226           break;
2227
2228         default:
2229           abort();
2230         }
2231
2232       addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
2233                            gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
2234                            sign, OPTAB_WIDEN);
2235     }
2236
2237   if (addr != tgt)
2238     emit_move_insn (tgt, gen_lowpart(GET_MODE (tgt), addr));
2239 }
2240
2241 /* Similarly, use ins and msk instructions to perform unaligned stores.  */
2242
2243 void
2244 alpha_expand_unaligned_store (dst, src, size, ofs)
2245      rtx dst, src;
2246      HOST_WIDE_INT size, ofs;
2247 {
2248   rtx dstl, dsth, addr, insl, insh, meml, memh;
2249   
2250   dstl = gen_reg_rtx (DImode);
2251   dsth = gen_reg_rtx (DImode);
2252   insl = gen_reg_rtx (DImode);
2253   insh = gen_reg_rtx (DImode);
2254
2255   meml = change_address (dst, DImode,
2256                          gen_rtx_AND (DImode, 
2257                                       plus_constant (XEXP (dst, 0), ofs),
2258                                       GEN_INT (-8)));
2259   memh = change_address (dst, DImode,
2260                          gen_rtx_AND (DImode, 
2261                                       plus_constant (XEXP (dst, 0),
2262                                                      ofs+size-1),
2263                                       GEN_INT (-8)));
2264
2265   emit_move_insn (dsth, memh);
2266   emit_move_insn (dstl, meml);
2267   addr = copy_addr_to_reg (plus_constant (XEXP (dst, 0), ofs));
2268
2269   if (src != const0_rtx)
2270     {
2271       emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
2272                             GEN_INT (size*8), addr));
2273
2274       switch ((int) size)
2275         {
2276         case 2:
2277           emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
2278           break;
2279         case 4:
2280           emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
2281           break;
2282         case 8:
2283           emit_insn (gen_insql (insl, src, addr));
2284           break;
2285         }
2286     }
2287
2288   emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
2289
2290   switch ((int) size)
2291     {
2292     case 2:
2293       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffff), addr));
2294       break;
2295     case 4:
2296       emit_insn (gen_mskxl (dstl, dstl, GEN_INT (0xffffffff), addr));
2297       break;
2298     case 8:
2299       {
2300 #if HOST_BITS_PER_WIDE_INT == 32
2301         rtx msk = immed_double_const (0xffffffff, 0xffffffff, DImode);
2302 #else
2303         rtx msk = immed_double_const (0xffffffffffffffff, 0, DImode);
2304 #endif
2305         emit_insn (gen_mskxl (dstl, dstl, msk, addr));
2306       }
2307       break;
2308     }
2309
2310   if (src != const0_rtx)
2311     {
2312       dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
2313       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
2314     }
2315   
2316   /* Must store high before low for degenerate case of aligned.  */
2317   emit_move_insn (memh, dsth);
2318   emit_move_insn (meml, dstl);
2319 }
2320
2321 /* The block move code tries to maximize speed by separating loads and
2322    stores at the expense of register pressure: we load all of the data
2323    before we store it back out.  There are two secondary effects worth
2324    mentioning, that this speeds copying to/from aligned and unaligned
2325    buffers, and that it makes the code significantly easier to write.  */
2326
2327 #define MAX_MOVE_WORDS  8
2328
2329 /* Load an integral number of consecutive unaligned quadwords.  */
2330
2331 static void
2332 alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
2333      rtx *out_regs;
2334      rtx smem;
2335      HOST_WIDE_INT words, ofs;
2336 {
2337   rtx const im8 = GEN_INT (-8);
2338   rtx const i64 = GEN_INT (64);
2339   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
2340   rtx sreg, areg;
2341   HOST_WIDE_INT i;
2342
2343   /* Generate all the tmp registers we need.  */
2344   for (i = 0; i < words; ++i)
2345     {
2346       data_regs[i] = out_regs[i];
2347       ext_tmps[i] = gen_reg_rtx (DImode);
2348     }
2349   data_regs[words] = gen_reg_rtx (DImode);
2350
2351   if (ofs != 0)
2352     smem = change_address (smem, GET_MODE (smem),
2353                            plus_constant (XEXP (smem, 0), ofs));
2354   
2355   /* Load up all of the source data.  */
2356   for (i = 0; i < words; ++i)
2357     {
2358       emit_move_insn (data_regs[i],
2359                       change_address (smem, DImode,
2360                                       gen_rtx_AND (DImode,
2361                                                    plus_constant (XEXP(smem,0),
2362                                                                   8*i),
2363                                                    im8)));
2364     }
2365   emit_move_insn (data_regs[words],
2366                   change_address (smem, DImode,
2367                                   gen_rtx_AND (DImode,
2368                                                plus_constant (XEXP(smem,0),
2369                                                               8*words - 1),
2370                                                im8)));
2371
2372   /* Extract the half-word fragments.  Unfortunately DEC decided to make
2373      extxh with offset zero a noop instead of zeroing the register, so 
2374      we must take care of that edge condition ourselves with cmov.  */
2375
2376   sreg = copy_addr_to_reg (XEXP (smem, 0));
2377   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL, 
2378                        1, OPTAB_WIDEN);
2379   for (i = 0; i < words; ++i)
2380     {
2381       emit_insn (gen_extxl (data_regs[i], data_regs[i], i64, sreg));
2382
2383       emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
2384       emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
2385                               gen_rtx_IF_THEN_ELSE (DImode,
2386                                                     gen_rtx_EQ (DImode, areg,
2387                                                                 const0_rtx),
2388                                                     const0_rtx, ext_tmps[i])));
2389     }
2390
2391   /* Merge the half-words into whole words.  */
2392   for (i = 0; i < words; ++i)
2393     {
2394       out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
2395                                   ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
2396     }
2397 }
2398
2399 /* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
2400    may be NULL to store zeros.  */
2401
2402 static void
2403 alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
2404      rtx *data_regs;
2405      rtx dmem;
2406      HOST_WIDE_INT words, ofs;
2407 {
2408   rtx const im8 = GEN_INT (-8);
2409   rtx const i64 = GEN_INT (64);
2410 #if HOST_BITS_PER_WIDE_INT == 32
2411   rtx const im1 = immed_double_const (0xffffffff, 0xffffffff, DImode);
2412 #else
2413   rtx const im1 = immed_double_const (0xffffffffffffffff, 0, DImode);
2414 #endif
2415   rtx ins_tmps[MAX_MOVE_WORDS];
2416   rtx st_tmp_1, st_tmp_2, dreg;
2417   rtx st_addr_1, st_addr_2;
2418   HOST_WIDE_INT i;
2419
2420   /* Generate all the tmp registers we need.  */
2421   if (data_regs != NULL)
2422     for (i = 0; i < words; ++i)
2423       ins_tmps[i] = gen_reg_rtx(DImode);
2424   st_tmp_1 = gen_reg_rtx(DImode);
2425   st_tmp_2 = gen_reg_rtx(DImode);
2426   
2427   if (ofs != 0)
2428     dmem = change_address (dmem, GET_MODE (dmem),
2429                            plus_constant (XEXP (dmem, 0), ofs));
2430   
2431
2432   st_addr_2 = change_address (dmem, DImode,
2433                               gen_rtx_AND (DImode,
2434                                            plus_constant (XEXP(dmem,0),
2435                                                           words*8 - 1),
2436                                        im8));
2437   st_addr_1 = change_address (dmem, DImode,
2438                               gen_rtx_AND (DImode, 
2439                                            XEXP (dmem, 0),
2440                                            im8));
2441
2442   /* Load up the destination end bits.  */
2443   emit_move_insn (st_tmp_2, st_addr_2);
2444   emit_move_insn (st_tmp_1, st_addr_1);
2445
2446   /* Shift the input data into place.  */
2447   dreg = copy_addr_to_reg (XEXP (dmem, 0));
2448   if (data_regs != NULL)
2449     {
2450       for (i = words-1; i >= 0; --i)
2451         {
2452           emit_insn (gen_insxh (ins_tmps[i], data_regs[i], i64, dreg));
2453           emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
2454         }
2455       for (i = words-1; i > 0; --i)
2456         {
2457           ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
2458                                         ins_tmps[i-1], ins_tmps[i-1], 1,
2459                                         OPTAB_WIDEN);
2460         }
2461     }
2462
2463   /* Split and merge the ends with the destination data.  */
2464   emit_insn (gen_mskxh (st_tmp_2, st_tmp_2, i64, dreg));
2465   emit_insn (gen_mskxl (st_tmp_1, st_tmp_1, im1, dreg));
2466
2467   if (data_regs != NULL)
2468     {
2469       st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
2470                                st_tmp_2, 1, OPTAB_WIDEN);
2471       st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
2472                                st_tmp_1, 1, OPTAB_WIDEN);
2473     }
2474
2475   /* Store it all.  */
2476   emit_move_insn (st_addr_2, st_tmp_2);
2477   for (i = words-1; i > 0; --i)
2478     {
2479       emit_move_insn (change_address (dmem, DImode,
2480                                       gen_rtx_AND (DImode,
2481                                                    plus_constant(XEXP (dmem,0),
2482                                                                  i*8),
2483                                                im8)),
2484                       data_regs ? ins_tmps[i-1] : const0_rtx);
2485     }
2486   emit_move_insn (st_addr_1, st_tmp_1);
2487 }
2488
2489
2490 /* Expand string/block move operations.
2491
2492    operands[0] is the pointer to the destination.
2493    operands[1] is the pointer to the source.
2494    operands[2] is the number of bytes to move.
2495    operands[3] is the alignment.  */
2496
2497 int
2498 alpha_expand_block_move (operands)
2499      rtx operands[];
2500 {
2501   rtx bytes_rtx = operands[2];
2502   rtx align_rtx = operands[3];
2503   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
2504   HOST_WIDE_INT bytes = orig_bytes;
2505   HOST_WIDE_INT src_align = INTVAL (align_rtx);
2506   HOST_WIDE_INT dst_align = src_align;
2507   rtx orig_src  = operands[1];
2508   rtx orig_dst  = operands[0];
2509   rtx data_regs[2*MAX_MOVE_WORDS+16];
2510   rtx tmp;
2511   int i, words, ofs, nregs = 0;
2512   
2513   if (bytes <= 0)
2514     return 1;
2515   if (bytes > MAX_MOVE_WORDS*8)
2516     return 0;
2517
2518   /* Look for additional alignment information from recorded register info.  */
2519
2520   tmp = XEXP (orig_src, 0);
2521   if (GET_CODE (tmp) == REG)
2522     {
2523       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
2524         src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
2525     }
2526   else if (GET_CODE (tmp) == PLUS
2527            && GET_CODE (XEXP (tmp, 0)) == REG
2528            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2529     {
2530       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2531       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2532
2533       if (a > src_align)
2534         {
2535           if (a >= 8 && c % 8 == 0)
2536             src_align = 8;
2537           else if (a >= 4 && c % 4 == 0)
2538             src_align = 4;
2539           else if (a >= 2 && c % 2 == 0)
2540             src_align = 2;
2541         }
2542     }
2543         
2544   tmp = XEXP (orig_dst, 0);
2545   if (GET_CODE (tmp) == REG)
2546     {
2547       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
2548         dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
2549     }
2550   else if (GET_CODE (tmp) == PLUS
2551            && GET_CODE (XEXP (tmp, 0)) == REG
2552            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2553     {
2554       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2555       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2556
2557       if (a > dst_align)
2558         {
2559           if (a >= 8 && c % 8 == 0)
2560             dst_align = 8;
2561           else if (a >= 4 && c % 4 == 0)
2562             dst_align = 4;
2563           else if (a >= 2 && c % 2 == 0)
2564             dst_align = 2;
2565         }
2566     }
2567
2568   /*
2569    * Load the entire block into registers.
2570    */
2571
2572   if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
2573     {
2574       enum machine_mode mode;
2575       tmp = XEXP (XEXP (orig_src, 0), 0);
2576
2577       /* Don't use the existing register if we're reading more than
2578          is held in the register.  Nor if there is not a mode that
2579          handles the exact size.  */
2580       mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2581       if (mode != BLKmode
2582           && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
2583         {
2584           if (mode == TImode)
2585             {
2586               data_regs[nregs] = gen_lowpart (DImode, tmp);
2587               data_regs[nregs+1] = gen_highpart (DImode, tmp);
2588               nregs += 2;
2589             }
2590           else
2591             data_regs[nregs++] = gen_lowpart (mode, tmp);
2592           goto src_done;
2593         }
2594
2595       /* No appropriate mode; fall back on memory.  */
2596       orig_src = change_address (orig_src, GET_MODE (orig_src),
2597                                  copy_addr_to_reg (XEXP (orig_src, 0)));
2598     }
2599
2600   ofs = 0;
2601   if (src_align >= 8 && bytes >= 8)
2602     {
2603       words = bytes / 8;
2604
2605       for (i = 0; i < words; ++i)
2606         data_regs[nregs+i] = gen_reg_rtx(DImode);
2607
2608       for (i = 0; i < words; ++i)
2609         {
2610           emit_move_insn (data_regs[nregs+i],
2611                           change_address (orig_src, DImode,
2612                                           plus_constant (XEXP (orig_src, 0),
2613                                                          ofs + i*8)));
2614         }
2615
2616       nregs += words;
2617       bytes -= words * 8;
2618       ofs += words * 8;
2619     }
2620   if (src_align >= 4 && bytes >= 4)
2621     {
2622       words = bytes / 4;
2623
2624       for (i = 0; i < words; ++i)
2625         data_regs[nregs+i] = gen_reg_rtx(SImode);
2626
2627       for (i = 0; i < words; ++i)
2628         {
2629           emit_move_insn (data_regs[nregs+i],
2630                           change_address (orig_src, SImode,
2631                                           plus_constant (XEXP (orig_src, 0),
2632                                                          ofs + i*4)));
2633         }
2634
2635       nregs += words;
2636       bytes -= words * 4;
2637       ofs += words * 4;
2638     }
2639   if (bytes >= 16)
2640     {
2641       words = bytes / 8;
2642
2643       for (i = 0; i < words+1; ++i)
2644         data_regs[nregs+i] = gen_reg_rtx(DImode);
2645
2646       alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
2647                                          words, ofs);
2648
2649       nregs += words;
2650       bytes -= words * 8;
2651       ofs += words * 8;
2652     }
2653   if (!TARGET_BWX && bytes >= 8)
2654     {
2655       data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
2656       alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
2657       bytes -= 8;
2658       ofs += 8;
2659     }
2660   if (!TARGET_BWX && bytes >= 4)
2661     {
2662       data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
2663       alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
2664       bytes -= 4;
2665       ofs += 4;
2666     }
2667   if (bytes >= 2)
2668     {
2669       if (src_align >= 2)
2670         {
2671           do {
2672             data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2673             emit_move_insn (tmp,
2674                             change_address (orig_src, HImode,
2675                                             plus_constant (XEXP (orig_src, 0),
2676                                                            ofs)));
2677             bytes -= 2;
2678             ofs += 2;
2679           } while (bytes >= 2);
2680         }
2681       else if (!TARGET_BWX)
2682         {
2683           data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
2684           alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
2685           bytes -= 2;
2686           ofs += 2;
2687         }
2688     }
2689   while (bytes > 0)
2690     {
2691       data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
2692       emit_move_insn (tmp,
2693                       change_address (orig_src, QImode,
2694                                       plus_constant (XEXP (orig_src, 0),
2695                                                      ofs)));
2696       bytes -= 1;
2697       ofs += 1;
2698     }
2699  src_done:
2700
2701   if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
2702     abort();
2703
2704   /*
2705    * Now save it back out again.
2706    */
2707
2708   i = 0, ofs = 0;
2709
2710   if (GET_CODE (XEXP (orig_dst, 0)) == ADDRESSOF)
2711     {
2712       enum machine_mode mode;
2713       tmp = XEXP (XEXP (orig_dst, 0), 0);
2714
2715       mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
2716       if (GET_MODE (tmp) == mode)
2717         {
2718           if (nregs == 1)
2719             {
2720               emit_move_insn (tmp, data_regs[0]);
2721               i = 1;
2722               goto dst_done;
2723             }
2724           else if (nregs == 2 && mode == TImode)
2725             {
2726               /* Undo the subregging done above when copying between
2727                  two TImode registers.  */
2728               if (GET_CODE (data_regs[0]) == SUBREG
2729                   && GET_MODE (SUBREG_REG (data_regs[0])) == TImode)
2730                 {
2731                   emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
2732                 }
2733               else
2734                 {
2735                   rtx seq;
2736
2737                   start_sequence ();
2738                   emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]);
2739                   emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]);
2740                   seq = get_insns ();
2741                   end_sequence ();
2742
2743                   emit_no_conflict_block (seq, tmp, data_regs[0],
2744                                           data_regs[1], NULL_RTX);
2745                 }
2746
2747               i = 2;
2748               goto dst_done;
2749             }
2750         }
2751
2752       /* ??? If nregs > 1, consider reconstructing the word in regs.  */
2753       /* ??? Optimize mode < dst_mode with strict_low_part.  */
2754
2755       /* No appropriate mode; fall back on memory.  We can speed things
2756          up by recognizing extra alignment information.  */
2757       orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2758                                  copy_addr_to_reg (XEXP (orig_dst, 0)));
2759       dst_align = GET_MODE_SIZE (GET_MODE (tmp));
2760     }
2761
2762   /* Write out the data in whatever chunks reading the source allowed.  */
2763   if (dst_align >= 8)
2764     {
2765       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2766         {
2767           emit_move_insn (change_address (orig_dst, DImode,
2768                                           plus_constant (XEXP (orig_dst, 0),
2769                                                          ofs)),
2770                           data_regs[i]);
2771           ofs += 8;
2772           i++;
2773         }
2774     }
2775   if (dst_align >= 4)
2776     {
2777       /* If the source has remaining DImode regs, write them out in
2778          two pieces.  */
2779       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
2780         {
2781           tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
2782                               NULL_RTX, 1, OPTAB_WIDEN);
2783
2784           emit_move_insn (change_address (orig_dst, SImode,
2785                                           plus_constant (XEXP (orig_dst, 0),
2786                                                          ofs)),
2787                           gen_lowpart (SImode, data_regs[i]));
2788           emit_move_insn (change_address (orig_dst, SImode,
2789                                           plus_constant (XEXP (orig_dst, 0),
2790                                                          ofs+4)),
2791                           gen_lowpart (SImode, tmp));
2792           ofs += 8;
2793           i++;
2794         }
2795
2796       while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2797         {
2798           emit_move_insn (change_address(orig_dst, SImode,
2799                                          plus_constant (XEXP (orig_dst, 0),
2800                                                         ofs)),
2801                           data_regs[i]);
2802           ofs += 4;
2803           i++;
2804         }
2805     }
2806   if (i < nregs && GET_MODE (data_regs[i]) == DImode)
2807     {
2808       /* Write out a remaining block of words using unaligned methods.  */
2809
2810       for (words = 1; i+words < nregs ; ++words)
2811         if (GET_MODE (data_regs[i+words]) != DImode)
2812           break;
2813
2814       if (words == 1)
2815         alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
2816       else
2817         alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
2818      
2819       i += words;
2820       ofs += words * 8;
2821     }
2822
2823   /* Due to the above, this won't be aligned.  */
2824   /* ??? If we have more than one of these, consider constructing full
2825      words in registers and using alpha_expand_unaligned_store_words.  */
2826   while (i < nregs && GET_MODE (data_regs[i]) == SImode)
2827     {
2828       alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
2829       ofs += 4;
2830       i++;
2831     }
2832
2833   if (dst_align >= 2)
2834     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2835       {
2836         emit_move_insn (change_address (orig_dst, HImode,
2837                                         plus_constant (XEXP (orig_dst, 0),
2838                                                        ofs)),
2839                         data_regs[i]);
2840         i++;
2841         ofs += 2;
2842       }
2843   else
2844     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
2845       {
2846         alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
2847         i++;
2848         ofs += 2;
2849       }
2850   while (i < nregs && GET_MODE (data_regs[i]) == QImode)
2851     {
2852       emit_move_insn (change_address (orig_dst, QImode,
2853                                       plus_constant (XEXP (orig_dst, 0),
2854                                                      ofs)),
2855                       data_regs[i]);
2856       i++;
2857       ofs += 1;
2858     }
2859  dst_done:
2860
2861   if (i != nregs)
2862     abort();
2863
2864   return 1;
2865 }
2866
2867 int
2868 alpha_expand_block_clear (operands)
2869      rtx operands[];
2870 {
2871   rtx bytes_rtx = operands[1];
2872   rtx align_rtx = operands[2];
2873   HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
2874   HOST_WIDE_INT align = INTVAL (align_rtx);
2875   rtx orig_dst  = operands[0];
2876   rtx tmp;
2877   HOST_WIDE_INT i, words, ofs = 0;
2878   
2879   if (bytes <= 0)
2880     return 1;
2881   if (bytes > MAX_MOVE_WORDS*8)
2882     return 0;
2883
2884   /* Look for stricter alignment.  */
2885
2886   tmp = XEXP (orig_dst, 0);
2887   if (GET_CODE (tmp) == REG)
2888     {
2889       if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
2890         align = REGNO_POINTER_ALIGN (REGNO (tmp));
2891     }
2892   else if (GET_CODE (tmp) == PLUS
2893            && GET_CODE (XEXP (tmp, 0)) == REG
2894            && GET_CODE (XEXP (tmp, 1)) == CONST_INT)
2895     {
2896       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
2897       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
2898
2899       if (a > align)
2900         {
2901           if (a >= 8 && c % 8 == 0)
2902             align = 8;
2903           else if (a >= 4 && c % 4 == 0)
2904             align = 4;
2905           else if (a >= 2 && c % 2 == 0)
2906             align = 2;
2907         }
2908     }
2909   else if (GET_CODE (tmp) == ADDRESSOF)
2910     {
2911       enum machine_mode mode;
2912
2913       mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
2914       if (GET_MODE (XEXP (tmp, 0)) == mode)
2915         {
2916           emit_move_insn (XEXP (tmp, 0), const0_rtx);
2917           return 1;
2918         }
2919
2920       /* No appropriate mode; fall back on memory.  */
2921       orig_dst = change_address (orig_dst, GET_MODE (orig_dst),
2922                                  copy_addr_to_reg (tmp));
2923       align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0)));
2924     }
2925
2926   /* Handle a block of contiguous words first.  */
2927
2928   if (align >= 8 && bytes >= 8)
2929     {
2930       words = bytes / 8;
2931
2932       for (i = 0; i < words; ++i)
2933         {
2934           emit_move_insn (change_address(orig_dst, DImode,
2935                                          plus_constant (XEXP (orig_dst, 0),
2936                                                         ofs + i*8)),
2937                           const0_rtx);
2938         }
2939
2940       bytes -= words * 8;
2941       ofs += words * 8;
2942     }
2943   if (align >= 4 && bytes >= 4)
2944     {
2945       words = bytes / 4;
2946
2947       for (i = 0; i < words; ++i)
2948         {
2949           emit_move_insn (change_address (orig_dst, SImode,
2950                                           plus_constant (XEXP (orig_dst, 0),
2951                                                          ofs + i*4)),
2952                           const0_rtx);
2953         }
2954
2955       bytes -= words * 4;
2956       ofs += words * 4;
2957     }
2958   if (bytes >= 16)
2959     {
2960       words = bytes / 8;
2961
2962       alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
2963
2964       bytes -= words * 8;
2965       ofs += words * 8;
2966     }
2967
2968   /* Next clean up any trailing pieces.  We know from the contiguous
2969      block move that there are no aligned SImode or DImode hunks left.  */
2970
2971   if (!TARGET_BWX && bytes >= 8)
2972     {
2973       alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
2974       bytes -= 8;
2975       ofs += 8;
2976     }
2977   if (!TARGET_BWX && bytes >= 4)
2978     {
2979       alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
2980       bytes -= 4;
2981       ofs += 4;
2982     }
2983   if (bytes >= 2)
2984     {
2985       if (align >= 2)
2986         {
2987           do {
2988             emit_move_insn (change_address (orig_dst, HImode,
2989                                             plus_constant (XEXP (orig_dst, 0),
2990                                                            ofs)),
2991                             const0_rtx);
2992             bytes -= 2;
2993             ofs += 2;
2994           } while (bytes >= 2);
2995         }
2996       else if (!TARGET_BWX)
2997         {
2998           alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
2999           bytes -= 2;
3000           ofs += 2;
3001         }
3002     }
3003   while (bytes > 0)
3004     {
3005       emit_move_insn (change_address (orig_dst, QImode,
3006                                       plus_constant (XEXP (orig_dst, 0),
3007                                                      ofs)),
3008                       const0_rtx);
3009       bytes -= 1;
3010       ofs += 1;
3011     }
3012
3013   return 1;
3014 }
3015
3016 \f
3017 /* Adjust the cost of a scheduling dependency.  Return the new cost of
3018    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
3019
3020 int
3021 alpha_adjust_cost (insn, link, dep_insn, cost)
3022      rtx insn;
3023      rtx link;
3024      rtx dep_insn;
3025      int cost;
3026 {
3027   rtx set, set_src;
3028   enum attr_type insn_type, dep_insn_type;
3029
3030   /* If the dependence is an anti-dependence, there is no cost.  For an
3031      output dependence, there is sometimes a cost, but it doesn't seem
3032      worth handling those few cases.  */
3033
3034   if (REG_NOTE_KIND (link) != 0)
3035     return 0;
3036
3037   /* If we can't recognize the insns, we can't really do anything.  */
3038   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
3039     return cost;
3040
3041   insn_type = get_attr_type (insn);
3042   dep_insn_type = get_attr_type (dep_insn);
3043
3044   /* Bring in the user-defined memory latency.  */
3045   if (dep_insn_type == TYPE_ILD
3046       || dep_insn_type == TYPE_FLD
3047       || dep_insn_type == TYPE_LDSYM)
3048     cost += alpha_memory_latency-1;
3049
3050   switch (alpha_cpu)
3051     {
3052     case PROCESSOR_EV4:
3053       /* On EV4, if INSN is a store insn and DEP_INSN is setting the data
3054          being stored, we can sometimes lower the cost.  */
3055
3056       if ((insn_type == TYPE_IST || insn_type == TYPE_FST)
3057           && (set = single_set (dep_insn)) != 0
3058           && GET_CODE (PATTERN (insn)) == SET
3059           && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
3060         {
3061           switch (dep_insn_type)
3062             {
3063             case TYPE_ILD:
3064             case TYPE_FLD:
3065               /* No savings here.  */
3066               return cost;
3067
3068             case TYPE_IMUL:
3069               /* In these cases, we save one cycle.  */
3070               return cost - 1;
3071
3072             default:
3073               /* In all other cases, we save two cycles.  */
3074               return MAX (0, cost - 2);
3075             }
3076         }
3077
3078       /* Another case that needs adjustment is an arithmetic or logical
3079          operation.  It's cost is usually one cycle, but we default it to
3080          two in the MD file.  The only case that it is actually two is
3081          for the address in loads, stores, and jumps.  */
3082
3083       if (dep_insn_type == TYPE_IADD || dep_insn_type == TYPE_ILOG)
3084         {
3085           switch (insn_type)
3086             {
3087             case TYPE_ILD:
3088             case TYPE_IST:
3089             case TYPE_FLD:
3090             case TYPE_FST:
3091             case TYPE_JSR:
3092               return cost;
3093             default:
3094               return 1;
3095             }
3096         }
3097
3098       /* The final case is when a compare feeds into an integer branch;
3099          the cost is only one cycle in that case.  */
3100
3101       if (dep_insn_type == TYPE_ICMP && insn_type == TYPE_IBR)
3102         return 1;
3103       break;
3104
3105     case PROCESSOR_EV5:
3106       /* And the lord DEC saith:  "A special bypass provides an effective
3107          latency of 0 cycles for an ICMP or ILOG insn producing the test
3108          operand of an IBR or ICMOV insn." */
3109
3110       if ((dep_insn_type == TYPE_ICMP || dep_insn_type == TYPE_ILOG)
3111           && (set = single_set (dep_insn)) != 0)
3112         {
3113           /* A branch only has one input.  This must be it.  */
3114           if (insn_type == TYPE_IBR)
3115             return 0;
3116           /* A conditional move has three, make sure it is the test.  */
3117           if (insn_type == TYPE_ICMOV
3118               && GET_CODE (set_src = PATTERN (insn)) == SET
3119               && GET_CODE (set_src = SET_SRC (set_src)) == IF_THEN_ELSE
3120               && rtx_equal_p (SET_DEST (set), XEXP (set_src, 0)))
3121             return 0;
3122         }
3123
3124       /* "The multiplier is unable to receive data from IEU bypass paths.
3125          The instruction issues at the expected time, but its latency is
3126          increased by the time it takes for the input data to become
3127          available to the multiplier" -- which happens in pipeline stage
3128          six, when results are comitted to the register file.  */
3129
3130       if (insn_type == TYPE_IMUL)
3131         {
3132           switch (dep_insn_type)
3133             {
3134             /* These insns produce their results in pipeline stage five.  */
3135             case TYPE_ILD:
3136             case TYPE_ICMOV:
3137             case TYPE_IMUL:
3138             case TYPE_MVI:
3139               return cost + 1;
3140
3141             /* Other integer insns produce results in pipeline stage four.  */
3142             default:
3143               return cost + 2;
3144             }
3145         }
3146       break;
3147
3148     case PROCESSOR_EV6:
3149       /* There is additional latency to move the result of (most) FP 
3150          operations anywhere but the FP register file.  */
3151
3152       if ((insn_type == TYPE_FST || insn_type == TYPE_FTOI)
3153           && (dep_insn_type == TYPE_FADD ||
3154               dep_insn_type == TYPE_FMUL ||
3155               dep_insn_type == TYPE_FCMOV))
3156         return cost + 2;
3157
3158       break;
3159     }
3160
3161   /* Otherwise, return the default cost. */
3162   return cost;
3163 }
3164 \f
3165 /* Functions to save and restore alpha_return_addr_rtx.  */
3166
3167 static void
3168 alpha_init_machine_status (p)
3169      struct function *p;
3170 {
3171   p->machine =
3172     (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
3173 }
3174
3175 static void
3176 alpha_mark_machine_status (p)
3177      struct function *p;
3178 {
3179   struct machine_function *machine = p->machine;
3180
3181   ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
3182   ggc_mark_rtx (machine->ra_rtx);
3183 }
3184
3185 /* Start the ball rolling with RETURN_ADDR_RTX.  */
3186
3187 rtx
3188 alpha_return_addr (count, frame)
3189      int count;
3190      rtx frame ATTRIBUTE_UNUSED;
3191 {
3192   rtx init, reg;
3193
3194   if (count != 0)
3195     return const0_rtx;
3196
3197   reg = cfun->machine->ra_rtx;
3198   if (reg == NULL)
3199     {
3200       /* No rtx yet.  Invent one, and initialize it from $26 in
3201          the prologue.  */
3202       reg = gen_reg_rtx (Pmode);
3203       cfun->machine->ra_rtx = reg;
3204       init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
3205
3206       /* Emit the insn to the prologue with the other argument copies.  */
3207       push_topmost_sequence ();
3208       emit_insn_after (init, get_insns ());
3209       pop_topmost_sequence ();
3210     }
3211
3212   return reg;
3213 }
3214
3215 static int
3216 alpha_ra_ever_killed ()
3217 {
3218   rtx top;
3219
3220 #ifdef ASM_OUTPUT_MI_THUNK
3221   if (current_function_is_thunk)
3222     return 0;
3223 #endif
3224   if (!cfun->machine->ra_rtx)
3225     return regs_ever_live[REG_RA];
3226
3227   push_topmost_sequence ();
3228   top = get_insns ();
3229   pop_topmost_sequence ();
3230
3231   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
3232 }
3233
3234 \f
3235 /* Print an operand.  Recognize special options, documented below.  */
3236
3237 void
3238 print_operand (file, x, code)
3239     FILE *file;
3240     rtx x;
3241     int code;
3242 {
3243   int i;
3244
3245   switch (code)
3246     {
3247     case '&':
3248       /* Generates fp-rounding mode suffix: nothing for normal, 'c' for
3249          chopped, 'm' for minus-infinity, and 'd' for dynamic rounding
3250          mode.  alpha_fprm controls which suffix is generated.  */
3251       switch (alpha_fprm)
3252         {
3253         case ALPHA_FPRM_NORM:
3254           break;
3255         case ALPHA_FPRM_MINF: 
3256           fputc ('m', file);
3257           break;
3258         case ALPHA_FPRM_CHOP:
3259           fputc ('c', file);
3260           break;
3261         case ALPHA_FPRM_DYN:
3262           fputc ('d', file);
3263           break;
3264         default:
3265           abort ();
3266         }
3267       break;
3268
3269     case '\'':
3270       /* Generates trap-mode suffix for instructions that accept the su
3271          suffix only (cmpt et al).  */
3272       if (alpha_fptm >= ALPHA_FPTM_SU)
3273         fputs ("su", file);
3274       break;
3275
3276     case '`':
3277       /* Generates trap-mode suffix for instructions that accept the
3278          v and sv suffix.  The only instruction that needs this is cvtql.  */
3279       switch (alpha_fptm)
3280         {
3281         case ALPHA_FPTM_N:
3282           break;
3283         case ALPHA_FPTM_U:
3284           fputs ("v", file);
3285           break;
3286         case ALPHA_FPTM_SU:
3287         case ALPHA_FPTM_SUI:
3288           fputs ("sv", file);
3289           break;
3290         }
3291       break;
3292
3293     case '(':
3294       /* Generates trap-mode suffix for instructions that accept the
3295          v, sv, and svi suffix.  The only instruction that needs this
3296          is cvttq.  */
3297       switch (alpha_fptm)
3298         {
3299         case ALPHA_FPTM_N:
3300           break;
3301         case ALPHA_FPTM_U:
3302           fputs ("v", file);
3303           break;
3304         case ALPHA_FPTM_SU:
3305           fputs ("sv", file);
3306           break;
3307         case ALPHA_FPTM_SUI:
3308           fputs ("svi", file);
3309           break;
3310         }
3311       break;
3312
3313     case ')':
3314       /* Generates trap-mode suffix for instructions that accept the u, su,
3315          and sui suffix.  This is the bulk of the IEEE floating point
3316          instructions (addt et al).  */
3317       switch (alpha_fptm)
3318         {
3319         case ALPHA_FPTM_N:
3320           break;
3321         case ALPHA_FPTM_U:
3322           fputc ('u', file);
3323           break;
3324         case ALPHA_FPTM_SU:
3325           fputs ("su", file);
3326           break;
3327         case ALPHA_FPTM_SUI:
3328           fputs ("sui", file);
3329           break;
3330         }
3331       break;
3332
3333     case '+':
3334       /* Generates trap-mode suffix for instructions that accept the sui
3335          suffix (cvtqt and cvtqs).  */
3336       switch (alpha_fptm)
3337         {
3338         case ALPHA_FPTM_N:
3339         case ALPHA_FPTM_U:
3340         case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
3341           break;
3342         case ALPHA_FPTM_SUI:
3343           fputs ("sui", file);
3344           break;
3345         }
3346       break;
3347
3348     case ',':
3349       /* Generates single precision instruction suffix.  */
3350       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
3351       break;
3352
3353     case '-':
3354       /* Generates double precision instruction suffix.  */
3355       fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
3356       break;
3357
3358     case 'r':
3359       /* If this operand is the constant zero, write it as "$31".  */
3360       if (GET_CODE (x) == REG)
3361         fprintf (file, "%s", reg_names[REGNO (x)]);
3362       else if (x == CONST0_RTX (GET_MODE (x)))
3363         fprintf (file, "$31");
3364       else
3365         output_operand_lossage ("invalid %%r value");
3366
3367       break;
3368
3369     case 'R':
3370       /* Similar, but for floating-point.  */
3371       if (GET_CODE (x) == REG)
3372         fprintf (file, "%s", reg_names[REGNO (x)]);
3373       else if (x == CONST0_RTX (GET_MODE (x)))
3374         fprintf (file, "$f31");
3375       else
3376         output_operand_lossage ("invalid %%R value");
3377
3378       break;
3379
3380     case 'N':
3381       /* Write the 1's complement of a constant.  */
3382       if (GET_CODE (x) != CONST_INT)
3383         output_operand_lossage ("invalid %%N value");
3384
3385       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
3386       break;
3387
3388     case 'P':
3389       /* Write 1 << C, for a constant C.  */
3390       if (GET_CODE (x) != CONST_INT)
3391         output_operand_lossage ("invalid %%P value");
3392
3393       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
3394       break;
3395
3396     case 'h':
3397       /* Write the high-order 16 bits of a constant, sign-extended.  */
3398       if (GET_CODE (x) != CONST_INT)
3399         output_operand_lossage ("invalid %%h value");
3400
3401       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
3402       break;
3403
3404     case 'L':
3405       /* Write the low-order 16 bits of a constant, sign-extended.  */
3406       if (GET_CODE (x) != CONST_INT)
3407         output_operand_lossage ("invalid %%L value");
3408
3409       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
3410                (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
3411       break;
3412
3413     case 'm':
3414       /* Write mask for ZAP insn.  */
3415       if (GET_CODE (x) == CONST_DOUBLE)
3416         {
3417           HOST_WIDE_INT mask = 0;
3418           HOST_WIDE_INT value;
3419
3420           value = CONST_DOUBLE_LOW (x);
3421           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3422                i++, value >>= 8)
3423             if (value & 0xff)
3424               mask |= (1 << i);
3425
3426           value = CONST_DOUBLE_HIGH (x);
3427           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
3428                i++, value >>= 8)
3429             if (value & 0xff)
3430               mask |= (1 << (i + sizeof (int)));
3431
3432           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
3433         }
3434
3435       else if (GET_CODE (x) == CONST_INT)
3436         {
3437           HOST_WIDE_INT mask = 0, value = INTVAL (x);
3438
3439           for (i = 0; i < 8; i++, value >>= 8)
3440             if (value & 0xff)
3441               mask |= (1 << i);
3442
3443           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
3444         }
3445       else
3446         output_operand_lossage ("invalid %%m value");
3447       break;
3448
3449     case 'M':
3450       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
3451       if (GET_CODE (x) != CONST_INT
3452           || (INTVAL (x) != 8 && INTVAL (x) != 16
3453               && INTVAL (x) != 32 && INTVAL (x) != 64))
3454         output_operand_lossage ("invalid %%M value");
3455
3456       fprintf (file, "%s",
3457                (INTVAL (x) == 8 ? "b"
3458                 : INTVAL (x) == 16 ? "w"
3459                 : INTVAL (x) == 32 ? "l"
3460                 : "q"));
3461       break;
3462
3463     case 'U':
3464       /* Similar, except do it from the mask.  */
3465       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
3466         fprintf (file, "b");
3467       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
3468         fprintf (file, "w");
3469       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
3470         fprintf (file, "l");
3471 #if HOST_BITS_PER_WIDE_INT == 32
3472       else if (GET_CODE (x) == CONST_DOUBLE
3473                && CONST_DOUBLE_HIGH (x) == 0
3474                && CONST_DOUBLE_LOW (x) == -1)
3475         fprintf (file, "l");
3476       else if (GET_CODE (x) == CONST_DOUBLE
3477                && CONST_DOUBLE_HIGH (x) == -1
3478                && CONST_DOUBLE_LOW (x) == -1)
3479         fprintf (file, "q");
3480 #else
3481       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1)
3482         fprintf (file, "q");
3483       else if (GET_CODE (x) == CONST_DOUBLE
3484                && CONST_DOUBLE_HIGH (x) == 0
3485                && CONST_DOUBLE_LOW (x) == -1)
3486         fprintf (file, "q");
3487 #endif
3488       else
3489         output_operand_lossage ("invalid %%U value");
3490       break;
3491
3492     case 's':
3493       /* Write the constant value divided by 8.  */
3494       if (GET_CODE (x) != CONST_INT
3495           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3496           && (INTVAL (x) & 7) != 8)
3497         output_operand_lossage ("invalid %%s value");
3498
3499       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3500       break;
3501
3502     case 'S':
3503       /* Same, except compute (64 - c) / 8 */
3504
3505       if (GET_CODE (x) != CONST_INT
3506           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
3507           && (INTVAL (x) & 7) != 8)
3508         output_operand_lossage ("invalid %%s value");
3509
3510       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
3511       break;
3512
3513     case 'C': case 'D': case 'c': case 'd':
3514       /* Write out comparison name.  */
3515       {
3516         enum rtx_code c = GET_CODE (x);
3517
3518         if (GET_RTX_CLASS (c) != '<')
3519           output_operand_lossage ("invalid %%C value");
3520
3521         if (code == 'D')
3522           c = reverse_condition (c);
3523         else if (code == 'c')
3524           c = swap_condition (c);
3525         else if (code == 'd')
3526           c = swap_condition (reverse_condition (c));
3527
3528         if (c == LEU)
3529           fprintf (file, "ule");
3530         else if (c == LTU)
3531           fprintf (file, "ult");
3532         else if (c == UNORDERED)
3533           fprintf (file, "un");
3534         else
3535           fprintf (file, "%s", GET_RTX_NAME (c));
3536       }
3537       break;
3538
3539     case 'E':
3540       /* Write the divide or modulus operator.  */
3541       switch (GET_CODE (x))
3542         {
3543         case DIV:
3544           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
3545           break;
3546         case UDIV:
3547           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
3548           break;
3549         case MOD:
3550           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
3551           break;
3552         case UMOD:
3553           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
3554           break;
3555         default:
3556           output_operand_lossage ("invalid %%E value");
3557           break;
3558         }
3559       break;
3560
3561     case 'A':
3562       /* Write "_u" for unaligned access.  */
3563       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
3564         fprintf (file, "_u");
3565       break;
3566
3567     case 0:
3568       if (GET_CODE (x) == REG)
3569         fprintf (file, "%s", reg_names[REGNO (x)]);
3570       else if (GET_CODE (x) == MEM)
3571         output_address (XEXP (x, 0));
3572       else
3573         output_addr_const (file, x);
3574       break;
3575
3576     default:
3577       output_operand_lossage ("invalid %%xn code");
3578     }
3579 }
3580
3581 void
3582 print_operand_address (file, addr)
3583     FILE *file;
3584      rtx addr;
3585 {
3586   int basereg = 31;
3587   HOST_WIDE_INT offset = 0;
3588
3589   if (GET_CODE (addr) == AND)
3590     addr = XEXP (addr, 0);
3591
3592   if (GET_CODE (addr) == PLUS
3593       && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3594     {
3595       offset = INTVAL (XEXP (addr, 1));
3596       addr = XEXP (addr, 0);
3597     }
3598   if (GET_CODE (addr) == REG)
3599     basereg = REGNO (addr);
3600   else if (GET_CODE (addr) == SUBREG
3601            && GET_CODE (SUBREG_REG (addr)) == REG)
3602     basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr);
3603   else if (GET_CODE (addr) == CONST_INT)
3604     offset = INTVAL (addr);
3605   else
3606     abort ();
3607
3608   fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
3609   fprintf (file, "($%d)", basereg);
3610 }
3611 \f
3612 /* Emit RTL insns to initialize the variable parts of a trampoline at
3613    TRAMP. FNADDR is an RTX for the address of the function's pure
3614    code.  CXT is an RTX for the static chain value for the function.
3615
3616    The three offset parameters are for the individual template's
3617    layout.  A JMPOFS < 0 indicates that the trampoline does not 
3618    contain instructions at all.
3619
3620    We assume here that a function will be called many more times than
3621    its address is taken (e.g., it might be passed to qsort), so we
3622    take the trouble to initialize the "hint" field in the JMP insn.
3623    Note that the hint field is PC (new) + 4 * bits 13:0.  */
3624
3625 void
3626 alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
3627      rtx tramp, fnaddr, cxt;
3628      int fnofs, cxtofs, jmpofs;
3629 {
3630   rtx temp, temp1, addr;
3631   /* VMS really uses DImode pointers in memory at this point.  */
3632   enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode;
3633
3634 #ifdef POINTERS_EXTEND_UNSIGNED
3635   fnaddr = convert_memory_address (mode, fnaddr);
3636   cxt = convert_memory_address (mode, cxt);
3637 #endif
3638
3639   /* Store function address and CXT.  */
3640   addr = memory_address (mode, plus_constant (tramp, fnofs));
3641   emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
3642   addr = memory_address (mode, plus_constant (tramp, cxtofs));
3643   emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
3644
3645   /* This has been disabled since the hint only has a 32k range, and in
3646      no existing OS is the stack within 32k of the text segment. */
3647   if (0 && jmpofs >= 0)
3648     {
3649       /* Compute hint value.  */
3650       temp = force_operand (plus_constant (tramp, jmpofs+4), NULL_RTX);
3651       temp = expand_binop (DImode, sub_optab, fnaddr, temp, temp, 1,
3652                            OPTAB_WIDEN);
3653       temp = expand_shift (RSHIFT_EXPR, Pmode, temp,
3654                            build_int_2 (2, 0), NULL_RTX, 1);
3655       temp = expand_and (gen_lowpart (SImode, temp), GEN_INT (0x3fff), 0);
3656
3657       /* Merge in the hint.  */
3658       addr = memory_address (SImode, plus_constant (tramp, jmpofs));
3659       temp1 = force_reg (SImode, gen_rtx_MEM (SImode, addr));
3660       temp1 = expand_and (temp1, GEN_INT (0xffffc000), NULL_RTX);
3661       temp1 = expand_binop (SImode, ior_optab, temp1, temp, temp1, 1,
3662                             OPTAB_WIDEN);
3663       emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
3664     }
3665
3666 #ifdef TRANSFER_FROM_TRAMPOLINE
3667   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
3668                      0, VOIDmode, 1, addr, Pmode);
3669 #endif
3670
3671   if (jmpofs >= 0)
3672     emit_insn (gen_imb ());
3673 }
3674 \f
3675 /* Determine where to put an argument to a function.
3676    Value is zero to push the argument on the stack,
3677    or a hard register in which to store the argument.
3678
3679    MODE is the argument's machine mode.
3680    TYPE is the data type of the argument (as a tree).
3681     This is null for libcalls where that information may
3682     not be available.
3683    CUM is a variable of type CUMULATIVE_ARGS which gives info about
3684     the preceding args and about the function being called.
3685    NAMED is nonzero if this argument is a named parameter
3686     (otherwise it is an extra parameter matching an ellipsis).
3687
3688    On Alpha the first 6 words of args are normally in registers
3689    and the rest are pushed.  */
3690
3691 rtx
3692 function_arg(cum, mode, type, named)
3693      CUMULATIVE_ARGS cum;
3694      enum machine_mode mode;
3695      tree type;
3696      int named ATTRIBUTE_UNUSED;
3697 {
3698   int basereg;
3699
3700   if (cum >= 6 || MUST_PASS_IN_STACK (mode, type))
3701     return NULL_RTX;
3702
3703   if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
3704     basereg = 16;
3705   else if (TARGET_FPREGS
3706            && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
3707                || GET_MODE_CLASS (mode) == MODE_FLOAT))
3708     basereg = 32 + 16;
3709   else
3710     basereg = 16;
3711
3712   return gen_rtx_REG (mode, cum + basereg);
3713 }
3714
3715 tree
3716 alpha_build_va_list ()
3717 {
3718   tree base, ofs, record, type_decl;
3719
3720   if (TARGET_OPEN_VMS)
3721     return ptr_type_node;
3722
3723   record = make_lang_type (RECORD_TYPE);
3724   type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
3725   TREE_CHAIN (record) = type_decl;
3726   TYPE_NAME (record) = type_decl;
3727
3728   /* C++? SET_IS_AGGR_TYPE (record, 1); */
3729
3730   ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
3731                     integer_type_node);
3732   DECL_FIELD_CONTEXT (ofs) = record;
3733
3734   base = build_decl (FIELD_DECL, get_identifier ("__base"),
3735                      ptr_type_node);
3736   DECL_FIELD_CONTEXT (base) = record;
3737   TREE_CHAIN (base) = ofs;
3738
3739   TYPE_FIELDS (record) = base;
3740   layout_type (record);
3741
3742   return record;
3743 }
3744
3745 void
3746 alpha_va_start (stdarg_p, valist, nextarg)
3747      int stdarg_p;
3748      tree valist;
3749      rtx nextarg ATTRIBUTE_UNUSED;
3750 {
3751   HOST_WIDE_INT offset;
3752   tree t, offset_field, base_field;
3753
3754   if (TARGET_OPEN_VMS)
3755     std_expand_builtin_va_start (stdarg_p, valist, nextarg);
3756
3757   /* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
3758      up by 48, storing fp arg registers in the first 48 bytes, and the
3759      integer arg registers in the next 48 bytes.  This is only done,
3760      however, if any integer registers need to be stored.
3761
3762      If no integer registers need be stored, then we must subtract 48
3763      in order to account for the integer arg registers which are counted
3764      in argsize above, but which are not actually stored on the stack.  */
3765
3766   if (NUM_ARGS <= 5 + stdarg_p)
3767     offset = 6 * UNITS_PER_WORD;
3768   else
3769     offset = -6 * UNITS_PER_WORD;
3770
3771   base_field = TYPE_FIELDS (TREE_TYPE (valist));
3772   offset_field = TREE_CHAIN (base_field);
3773
3774   base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3775                       valist, base_field);
3776   offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3777                         valist, offset_field);
3778
3779   t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3780   t = build (PLUS_EXPR, ptr_type_node, t, build_int_2 (offset, 0));
3781   t = build (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
3782   TREE_SIDE_EFFECTS (t) = 1;
3783   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3784
3785   t = build_int_2 (NUM_ARGS*UNITS_PER_WORD, 0);
3786   t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
3787   TREE_SIDE_EFFECTS (t) = 1;
3788   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3789 }
3790
3791 rtx
3792 alpha_va_arg (valist, type)
3793      tree valist, type;
3794 {
3795   HOST_WIDE_INT tsize;
3796   rtx addr;
3797   tree t;
3798   tree offset_field, base_field, addr_tree, addend;
3799   tree wide_type, wide_ofs;
3800
3801   if (TARGET_OPEN_VMS)
3802     return std_expand_builtin_va_arg (valist, type);
3803
3804   tsize = ((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT + 7) / 8) * 8;
3805
3806   base_field = TYPE_FIELDS (TREE_TYPE (valist));
3807   offset_field = TREE_CHAIN (base_field);
3808
3809   base_field = build (COMPONENT_REF, TREE_TYPE (base_field),
3810                       valist, base_field);
3811   offset_field = build (COMPONENT_REF, TREE_TYPE (offset_field),
3812                         valist, offset_field);
3813
3814   wide_type = make_signed_type (64);
3815   wide_ofs = save_expr (build1 (CONVERT_EXPR, wide_type, offset_field));
3816
3817   addend = wide_ofs;
3818   if (FLOAT_TYPE_P (type))
3819     {
3820       tree fpaddend, cond;
3821
3822       fpaddend = fold (build (PLUS_EXPR, TREE_TYPE (addend),
3823                               addend, build_int_2 (-6*8, 0)));
3824
3825       cond = fold (build (LT_EXPR, integer_type_node,
3826                           wide_ofs, build_int_2 (6*8, 0)));
3827
3828       addend = fold (build (COND_EXPR, TREE_TYPE (addend), cond,
3829                             fpaddend, addend));
3830     }
3831
3832   addr_tree = build (PLUS_EXPR, TREE_TYPE (base_field),
3833                      base_field, addend);
3834
3835   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3836   addr = copy_to_reg (addr);
3837
3838   t = build (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field,
3839              build (PLUS_EXPR, TREE_TYPE (offset_field), 
3840                     offset_field, build_int_2 (tsize, 0)));
3841   TREE_SIDE_EFFECTS (t) = 1;
3842   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3843
3844   return addr;
3845 }
3846 \f
3847 /* This page contains routines that are used to determine what the function
3848    prologue and epilogue code will do and write them out.  */
3849
3850 /* Compute the size of the save area in the stack.  */
3851
3852 /* These variables are used for communication between the following functions.
3853    They indicate various things about the current function being compiled
3854    that are used to tell what kind of prologue, epilogue and procedure
3855    descriptior to generate. */
3856
3857 /* Nonzero if we need a stack procedure.  */
3858 static int vms_is_stack_procedure;
3859
3860 /* Register number (either FP or SP) that is used to unwind the frame.  */
3861 static int vms_unwind_regno;
3862
3863 /* Register number used to save FP.  We need not have one for RA since
3864    we don't modify it for register procedures.  This is only defined
3865    for register frame procedures.  */
3866 static int vms_save_fp_regno;
3867
3868 /* Register number used to reference objects off our PV.  */
3869 static int vms_base_regno;
3870
3871 /* Compute register masks for saved registers.  */
3872
3873 static void
3874 alpha_sa_mask (imaskP, fmaskP)
3875     unsigned long *imaskP;
3876     unsigned long *fmaskP;
3877 {
3878   unsigned long imask = 0;
3879   unsigned long fmask = 0;
3880   int i;
3881
3882 #ifdef ASM_OUTPUT_MI_THUNK
3883   if (!current_function_is_thunk)
3884 #endif
3885     {
3886       if (TARGET_OPEN_VMS && vms_is_stack_procedure)
3887         imask |= (1L << HARD_FRAME_POINTER_REGNUM);
3888
3889       /* One for every register we have to save.  */
3890       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3891         if (! fixed_regs[i] && ! call_used_regs[i]
3892             && regs_ever_live[i] && i != REG_RA)
3893           {
3894             if (i < 32)
3895               imask |= (1L << i);
3896             else
3897               fmask |= (1L << (i - 32));
3898           }
3899
3900       if (imask || fmask || alpha_ra_ever_killed ())
3901         imask |= (1L << REG_RA);
3902     }
3903
3904   *imaskP = imask;
3905   *fmaskP = fmask;
3906 }
3907
3908 int
3909 alpha_sa_size ()
3910 {
3911   int sa_size = 0;
3912   int i;
3913
3914 #ifdef ASM_OUTPUT_MI_THUNK
3915   if (current_function_is_thunk)
3916     sa_size = 0;
3917   else
3918 #endif
3919     {
3920       /* One for every register we have to save.  */
3921       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3922         if (! fixed_regs[i] && ! call_used_regs[i]
3923             && regs_ever_live[i] && i != REG_RA)
3924           sa_size++;
3925     }
3926
3927   if (TARGET_OPEN_VMS)
3928     {
3929       /* Start by assuming we can use a register procedure if we don't
3930          make any calls (REG_RA not used) or need to save any
3931          registers and a stack procedure if we do.  */
3932       vms_is_stack_procedure = sa_size != 0 || alpha_ra_ever_killed ();
3933
3934       /* Decide whether to refer to objects off our PV via FP or PV.
3935          If we need FP for something else or if we receive a nonlocal
3936          goto (which expects PV to contain the value), we must use PV.
3937          Otherwise, start by assuming we can use FP.  */
3938       vms_base_regno = (frame_pointer_needed
3939                         || current_function_has_nonlocal_label
3940                         || vms_is_stack_procedure
3941                         || current_function_outgoing_args_size
3942                         ? REG_PV : HARD_FRAME_POINTER_REGNUM);
3943
3944       /* If we want to copy PV into FP, we need to find some register
3945          in which to save FP.  */
3946
3947       vms_save_fp_regno = -1;
3948       if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
3949         for (i = 0; i < 32; i++)
3950           if (! fixed_regs[i] && call_used_regs[i] && ! regs_ever_live[i])
3951             vms_save_fp_regno = i;
3952
3953       if (vms_save_fp_regno == -1)
3954         vms_base_regno = REG_PV, vms_is_stack_procedure = 1;
3955
3956       /* Stack unwinding should be done via FP unless we use it for PV.  */
3957       vms_unwind_regno = (vms_base_regno == REG_PV
3958                           ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
3959
3960       /* If this is a stack procedure, allow space for saving FP and RA.  */
3961       if (vms_is_stack_procedure)
3962         sa_size += 2;
3963     }
3964   else
3965     {
3966       /* If some registers were saved but not RA, RA must also be saved,
3967          so leave space for it.  */
3968       if (sa_size != 0 || alpha_ra_ever_killed ())
3969         sa_size++;
3970
3971       /* Our size must be even (multiple of 16 bytes).  */
3972       if (sa_size & 1)
3973         sa_size++;
3974     }
3975
3976   return sa_size * 8;
3977 }
3978
3979 int
3980 alpha_pv_save_size ()
3981 {
3982   alpha_sa_size ();
3983   return vms_is_stack_procedure ? 8 : 0;
3984 }
3985
3986 int
3987 alpha_using_fp ()
3988 {
3989   alpha_sa_size ();
3990   return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
3991 }
3992
3993 int
3994 vms_valid_decl_attribute_p (decl, attributes, identifier, args)
3995      tree decl ATTRIBUTE_UNUSED;
3996      tree attributes ATTRIBUTE_UNUSED;
3997      tree identifier;
3998      tree args;
3999 {
4000   if (is_attribute_p ("overlaid", identifier))
4001     return (args == NULL_TREE);
4002   return 0;
4003 }
4004
4005 static int
4006 alpha_does_function_need_gp ()
4007 {
4008   rtx insn;
4009
4010   /* We never need a GP for Windows/NT or VMS.  */
4011   if (TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4012     return 0;
4013
4014 #ifdef TARGET_PROFILING_NEEDS_GP
4015   if (profile_flag)
4016     return 1;
4017 #endif
4018
4019 #ifdef ASM_OUTPUT_MI_THUNK
4020   if (current_function_is_thunk)
4021     return 1;
4022 #endif
4023
4024   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
4025      Even if we are a static function, we still need to do this in case
4026      our address is taken and passed to something like qsort.  */
4027
4028   push_topmost_sequence ();
4029   insn = get_insns ();
4030   pop_topmost_sequence ();
4031
4032   for (; insn; insn = NEXT_INSN (insn))
4033     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
4034         && GET_CODE (PATTERN (insn)) != USE
4035         && GET_CODE (PATTERN (insn)) != CLOBBER)
4036       {
4037         enum attr_type type = get_attr_type (insn);
4038         if (type == TYPE_LDSYM || type == TYPE_JSR)
4039           return 1;
4040       }
4041
4042   return 0;
4043 }
4044
4045 /* Write a version stamp.  Don't write anything if we are running as a
4046    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
4047
4048 #ifdef HAVE_STAMP_H
4049 #include <stamp.h>
4050 #endif
4051
4052 void
4053 alpha_write_verstamp (file)
4054      FILE *file ATTRIBUTE_UNUSED;
4055 {
4056 #ifdef MS_STAMP
4057   fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
4058 #endif
4059 }
4060 \f
4061 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
4062    sequences.  */
4063
4064 static rtx
4065 set_frame_related_p ()
4066 {
4067   rtx seq = gen_sequence ();
4068   end_sequence ();
4069
4070   if (GET_CODE (seq) == SEQUENCE)
4071     {
4072       int i = XVECLEN (seq, 0);
4073       while (--i >= 0)
4074         RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
4075      return emit_insn (seq);
4076     }
4077   else
4078     {
4079       seq = emit_insn (seq);
4080       RTX_FRAME_RELATED_P (seq) = 1;
4081       return seq;
4082     }
4083 }
4084
4085 #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
4086
4087 /* Write function prologue.  */
4088
4089 /* On vms we have two kinds of functions:
4090
4091    - stack frame (PROC_STACK)
4092         these are 'normal' functions with local vars and which are
4093         calling other functions
4094    - register frame (PROC_REGISTER)
4095         keeps all data in registers, needs no stack
4096
4097    We must pass this to the assembler so it can generate the
4098    proper pdsc (procedure descriptor)
4099    This is done with the '.pdesc' command.
4100
4101    On not-vms, we don't really differentiate between the two, as we can
4102    simply allocate stack without saving registers.  */
4103
4104 void
4105 alpha_expand_prologue ()
4106 {
4107   /* Registers to save.  */
4108   unsigned long imask = 0;
4109   unsigned long fmask = 0;
4110   /* Stack space needed for pushing registers clobbered by us.  */
4111   HOST_WIDE_INT sa_size;
4112   /* Complete stack size needed.  */
4113   HOST_WIDE_INT frame_size;
4114   /* Offset from base reg to register save area.  */
4115   HOST_WIDE_INT reg_offset;
4116   rtx sa_reg, mem;
4117   int i;
4118
4119   sa_size = alpha_sa_size ();
4120
4121   frame_size = get_frame_size ();
4122   if (TARGET_OPEN_VMS)
4123     frame_size = ALPHA_ROUND (sa_size 
4124                               + (vms_is_stack_procedure ? 8 : 0)
4125                               + frame_size
4126                               + current_function_pretend_args_size);
4127   else
4128     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4129                   + sa_size
4130                   + ALPHA_ROUND (frame_size
4131                                  + current_function_pretend_args_size));
4132
4133   if (TARGET_OPEN_VMS)
4134     reg_offset = 8;
4135   else
4136     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4137
4138   alpha_sa_mask (&imask, &fmask);
4139
4140   /* Adjust the stack by the frame size.  If the frame size is > 4096
4141      bytes, we need to be sure we probe somewhere in the first and last
4142      4096 bytes (we can probably get away without the latter test) and
4143      every 8192 bytes in between.  If the frame size is > 32768, we
4144      do this in a loop.  Otherwise, we generate the explicit probe
4145      instructions. 
4146
4147      Note that we are only allowed to adjust sp once in the prologue.  */
4148
4149   if (frame_size <= 32768)
4150     {
4151       if (frame_size > 4096)
4152         {
4153           int probed = 4096;
4154
4155           do
4156             emit_insn (gen_probe_stack (GEN_INT (-probed)));
4157           while ((probed += 8192) < frame_size);
4158
4159           /* We only have to do this probe if we aren't saving registers.  */
4160           if (sa_size == 0 && probed + 4096 < frame_size)
4161             emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
4162         }
4163
4164       if (frame_size != 0)
4165         {
4166           FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
4167                                       GEN_INT (-frame_size))));
4168         }
4169     }
4170   else
4171     {
4172       /* Here we generate code to set R22 to SP + 4096 and set R23 to the
4173          number of 8192 byte blocks to probe.  We then probe each block
4174          in the loop and then set SP to the proper location.  If the
4175          amount remaining is > 4096, we have to do one more probe if we
4176          are not saving any registers.  */
4177
4178       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
4179       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
4180       rtx ptr = gen_rtx_REG (DImode, 22);
4181       rtx count = gen_rtx_REG (DImode, 23);
4182       rtx seq;
4183
4184       emit_move_insn (count, GEN_INT (blocks));
4185       emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
4186
4187       /* Because of the difficulty in emitting a new basic block this
4188          late in the compilation, generate the loop as a single insn.  */
4189       emit_insn (gen_prologue_stack_probe_loop (count, ptr));
4190
4191       if (leftover > 4096 && sa_size == 0)
4192         {
4193           rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
4194           MEM_VOLATILE_P (last) = 1;
4195           emit_move_insn (last, const0_rtx);
4196         }
4197
4198       if (TARGET_WINDOWS_NT)
4199         {
4200           /* For NT stack unwind (done by 'reverse execution'), it's
4201              not OK to take the result of a loop, even though the value
4202              is already in ptr, so we reload it via a single operation
4203              and subtract it to sp. 
4204
4205              Yes, that's correct -- we have to reload the whole constant
4206              into a temporary via ldah+lda then subtract from sp.  To
4207              ensure we get ldah+lda, we use a special pattern.  */
4208
4209           HOST_WIDE_INT lo, hi;
4210           lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4211           hi = frame_size - lo;
4212
4213           emit_move_insn (ptr, GEN_INT (hi));
4214           emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
4215           seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
4216                                        ptr));
4217         }
4218       else
4219         {
4220           seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
4221                                        GEN_INT (-leftover)));
4222         }
4223
4224       /* This alternative is special, because the DWARF code cannot
4225          possibly intuit through the loop above.  So we invent this
4226          note it looks at instead.  */
4227       RTX_FRAME_RELATED_P (seq) = 1;
4228       REG_NOTES (seq)
4229         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
4230                              gen_rtx_SET (VOIDmode, stack_pointer_rtx,
4231                                gen_rtx_PLUS (Pmode, stack_pointer_rtx,
4232                                              GEN_INT (-frame_size))),
4233                              REG_NOTES (seq));
4234     }
4235
4236   /* Cope with very large offsets to the register save area.  */
4237   sa_reg = stack_pointer_rtx;
4238   if (reg_offset + sa_size > 0x8000)
4239     {
4240       int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4241       HOST_WIDE_INT bias;
4242
4243       if (low + sa_size <= 0x8000)
4244         bias = reg_offset - low, reg_offset = low;
4245       else 
4246         bias = reg_offset, reg_offset = 0;
4247
4248       sa_reg = gen_rtx_REG (DImode, 24);
4249       FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias))));
4250     }
4251     
4252   /* Save regs in stack order.  Beginning with VMS PV.  */
4253   if (TARGET_OPEN_VMS && vms_is_stack_procedure)
4254     {
4255       mem = gen_rtx_MEM (DImode, stack_pointer_rtx);
4256       MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4257       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV)));
4258     }
4259
4260   /* Save register RA next.  */
4261   if (imask & (1L << REG_RA))
4262     {
4263       mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4264       MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4265       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
4266       imask &= ~(1L << REG_RA);
4267       reg_offset += 8;
4268     }
4269
4270   /* Now save any other registers required to be saved.  */
4271   for (i = 0; i < 32; i++)
4272     if (imask & (1L << i))
4273       {
4274         mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
4275         MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4276         FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i)));
4277         reg_offset += 8;
4278       }
4279
4280   for (i = 0; i < 32; i++)
4281     if (fmask & (1L << i))
4282       {
4283         mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
4284         MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4285         FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32)));
4286         reg_offset += 8;
4287       }
4288
4289   if (TARGET_OPEN_VMS)
4290     {
4291       if (!vms_is_stack_procedure)
4292         {
4293           /* Register frame procedures fave the fp.  */
4294           FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
4295                                hard_frame_pointer_rtx));
4296         }
4297
4298       if (vms_base_regno != REG_PV)
4299         FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
4300                              gen_rtx_REG (DImode, REG_PV)));
4301
4302       if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4303         {
4304           FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4305         }
4306
4307       /* If we have to allocate space for outgoing args, do it now.  */
4308       if (current_function_outgoing_args_size != 0)
4309         {
4310           FRP (emit_move_insn (stack_pointer_rtx, 
4311                 plus_constant (hard_frame_pointer_rtx,
4312                  - ALPHA_ROUND (current_function_outgoing_args_size))));
4313         }
4314     }
4315   else
4316     {
4317       /* If we need a frame pointer, set it from the stack pointer.  */
4318       if (frame_pointer_needed)
4319         {
4320           if (TARGET_CAN_FAULT_IN_PROLOGUE)
4321             FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
4322           else
4323             {
4324               /* This must always be the last instruction in the
4325                  prologue, thus we emit a special move + clobber.  */
4326               FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
4327                                            stack_pointer_rtx, sa_reg)));
4328             }
4329         }
4330     }
4331
4332   /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
4333      the prologue, for exception handling reasons, we cannot do this for
4334      any insn that might fault.  We could prevent this for mems with a
4335      (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
4336      have to prevent all such scheduling with a blockage.
4337
4338      Linux, on the other hand, never bothered to implement OSF/1's 
4339      exception handling, and so doesn't care about such things.  Anyone
4340      planning to use dwarf2 frame-unwind info can also omit the blockage.  */
4341
4342   if (! TARGET_CAN_FAULT_IN_PROLOGUE)
4343     emit_insn (gen_blockage ());
4344 }
4345
4346 /* Output the textual info surrounding the prologue.  */
4347
4348 void
4349 alpha_start_function (file, fnname, decl)
4350      FILE *file;
4351      const char *fnname;
4352      tree decl ATTRIBUTE_UNUSED;
4353 {
4354   unsigned long imask = 0;
4355   unsigned long fmask = 0;
4356   /* Stack space needed for pushing registers clobbered by us.  */
4357   HOST_WIDE_INT sa_size;
4358   /* Complete stack size needed.  */
4359   HOST_WIDE_INT frame_size;
4360   /* Offset from base reg to register save area.  */
4361   HOST_WIDE_INT reg_offset;
4362   char *entry_label = (char *) alloca (strlen (fnname) + 6);
4363   int i;
4364
4365   sa_size = alpha_sa_size ();
4366
4367   frame_size = get_frame_size ();
4368   if (TARGET_OPEN_VMS)
4369     frame_size = ALPHA_ROUND (sa_size 
4370                               + (vms_is_stack_procedure ? 8 : 0)
4371                               + frame_size
4372                               + current_function_pretend_args_size);
4373   else
4374     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4375                   + sa_size
4376                   + ALPHA_ROUND (frame_size
4377                                  + current_function_pretend_args_size));
4378
4379   if (TARGET_OPEN_VMS)
4380     reg_offset = 8;
4381   else
4382     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4383
4384   alpha_sa_mask (&imask, &fmask);
4385
4386   /* Ecoff can handle multiple .file directives, so put out file and lineno.
4387      We have to do that before the .ent directive as we cannot switch
4388      files within procedures with native ecoff because line numbers are
4389      linked to procedure descriptors.
4390      Outputting the lineno helps debugging of one line functions as they
4391      would otherwise get no line number at all. Please note that we would
4392      like to put out last_linenum from final.c, but it is not accessible.  */
4393
4394   if (write_symbols == SDB_DEBUG)
4395     {
4396       ASM_OUTPUT_SOURCE_FILENAME (file,
4397                                   DECL_SOURCE_FILE (current_function_decl));
4398       if (debug_info_level != DINFO_LEVEL_TERSE)
4399         ASM_OUTPUT_SOURCE_LINE (file,
4400                                 DECL_SOURCE_LINE (current_function_decl));
4401     }
4402
4403   /* Issue function start and label.  */
4404   if (TARGET_OPEN_VMS || !flag_inhibit_size_directive)
4405     {
4406       fputs ("\t.ent ", file);
4407       assemble_name (file, fnname);
4408       putc ('\n', file);
4409     }
4410
4411   strcpy (entry_label, fnname);
4412   if (TARGET_OPEN_VMS)
4413     strcat (entry_label, "..en");
4414   ASM_OUTPUT_LABEL (file, entry_label);
4415   inside_function = TRUE;
4416
4417   if (TARGET_OPEN_VMS)
4418     fprintf (file, "\t.base $%d\n", vms_base_regno);
4419
4420   if (!TARGET_OPEN_VMS && TARGET_IEEE_CONFORMANT
4421       && !flag_inhibit_size_directive)
4422     {
4423       /* Set flags in procedure descriptor to request IEEE-conformant
4424          math-library routines.  The value we set it to is PDSC_EXC_IEEE
4425          (/usr/include/pdsc.h). */
4426       fputs ("\t.eflag 48\n", file);
4427     }
4428
4429   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
4430   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
4431   alpha_arg_offset = -frame_size + 48;
4432
4433   /* Describe our frame.  If the frame size is larger than an integer,
4434      print it as zero to avoid an assembler error.  We won't be
4435      properly describing such a frame, but that's the best we can do.  */
4436   if (TARGET_OPEN_VMS)
4437     {
4438       fprintf (file, "\t.frame $%d,", vms_unwind_regno);
4439       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4440                frame_size >= (1l << 31) ? 0 : frame_size);
4441       fputs (",$26,", file);
4442       fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
4443       fputs ("\n", file);
4444     }
4445   else if (!flag_inhibit_size_directive)
4446     {
4447       fprintf (file, "\t.frame $%d,",
4448                (frame_pointer_needed
4449                 ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
4450       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4451                frame_size >= (1l << 31) ? 0 : frame_size);
4452       fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
4453     }
4454
4455   /* Describe which registers were spilled.  */
4456   if (TARGET_OPEN_VMS)
4457     {
4458       if (imask)
4459         /* ??? Does VMS care if mask contains ra?  The old code did'nt
4460            set it, so I don't here.  */
4461         fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
4462       if (fmask)
4463         fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
4464       if (!vms_is_stack_procedure)
4465         fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
4466     }
4467   else if (!flag_inhibit_size_directive)
4468     {
4469       if (imask)
4470         {
4471           fprintf (file, "\t.mask 0x%lx,", imask);
4472           fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4473                    frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4474           putc ('\n', file);
4475
4476           for (i = 0; i < 32; ++i)
4477             if (imask & (1L << i))
4478               reg_offset += 8;
4479         }
4480
4481       if (fmask)
4482         {
4483           fprintf (file, "\t.fmask 0x%lx,", fmask);
4484           fprintf (file, HOST_WIDE_INT_PRINT_DEC,
4485                    frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
4486           putc ('\n', file);
4487         }
4488     }
4489
4490   /* Emit GP related things.  It is rather unfortunate about the alignment
4491      issues surrounding a CODE_LABEL that forces us to do the label in 
4492      plain text.  */
4493   if (!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT)
4494     {
4495       alpha_function_needs_gp = alpha_does_function_need_gp ();
4496       if (alpha_function_needs_gp)
4497         fputs ("\tldgp $29,0($27)\n", file);
4498
4499       putc ('$', file);
4500       assemble_name (file, fnname);
4501       fputs ("..ng:\n", file);
4502     }
4503
4504 #ifdef OPEN_VMS
4505   /* Ifdef'ed cause readonly_section and link_section are only
4506      available then.  */
4507   readonly_section ();
4508   fprintf (file, "\t.align 3\n");
4509   assemble_name (file, fnname); fputs ("..na:\n", file);
4510   fputs ("\t.ascii \"", file);
4511   assemble_name (file, fnname);
4512   fputs ("\\0\"\n", file);
4513       
4514   link_section ();
4515   fprintf (file, "\t.align 3\n");
4516   fputs ("\t.name ", file);
4517   assemble_name (file, fnname);
4518   fputs ("..na\n", file);
4519   ASM_OUTPUT_LABEL (file, fnname);
4520   fprintf (file, "\t.pdesc ");
4521   assemble_name (file, fnname);
4522   fprintf (file, "..en,%s\n", vms_is_stack_procedure ? "stack" : "reg");
4523   alpha_need_linkage (fnname, 1);
4524   text_section ();
4525 #endif
4526 }
4527
4528 /* Emit the .prologue note at the scheduled end of the prologue.  */
4529
4530 void
4531 output_end_prologue (file)
4532      FILE *file;
4533 {
4534   if (TARGET_OPEN_VMS)
4535     fputs ("\t.prologue\n", file);
4536   else if (TARGET_WINDOWS_NT)
4537     fputs ("\t.prologue 0\n", file);
4538   else if (!flag_inhibit_size_directive)
4539     fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
4540 }
4541
4542 /* Write function epilogue.  */
4543
4544 /* ??? At some point we will want to support full unwind, and so will 
4545    need to mark the epilogue as well.  At the moment, we just confuse
4546    dwarf2out.  */
4547 #undef FRP
4548 #define FRP(exp) exp
4549
4550 void
4551 alpha_expand_epilogue ()
4552 {
4553   /* Registers to save.  */
4554   unsigned long imask = 0;
4555   unsigned long fmask = 0;
4556   /* Stack space needed for pushing registers clobbered by us.  */
4557   HOST_WIDE_INT sa_size;
4558   /* Complete stack size needed.  */
4559   HOST_WIDE_INT frame_size;
4560   /* Offset from base reg to register save area.  */
4561   HOST_WIDE_INT reg_offset;
4562   int fp_is_frame_pointer, fp_offset;
4563   rtx sa_reg, sa_reg_exp = NULL;
4564   rtx sp_adj1, sp_adj2, mem;
4565   rtx eh_ofs;
4566   int i;
4567
4568   sa_size = alpha_sa_size ();
4569
4570   frame_size = get_frame_size ();
4571   if (TARGET_OPEN_VMS)
4572     frame_size = ALPHA_ROUND (sa_size 
4573                               + (vms_is_stack_procedure ? 8 : 0)
4574                               + frame_size
4575                               + current_function_pretend_args_size);
4576   else
4577     frame_size = (ALPHA_ROUND (current_function_outgoing_args_size)
4578                   + sa_size
4579                   + ALPHA_ROUND (frame_size
4580                                  + current_function_pretend_args_size));
4581
4582   if (TARGET_OPEN_VMS)
4583     reg_offset = 8;
4584   else
4585     reg_offset = ALPHA_ROUND (current_function_outgoing_args_size);
4586
4587   alpha_sa_mask (&imask, &fmask);
4588
4589   fp_is_frame_pointer = ((TARGET_OPEN_VMS && vms_is_stack_procedure)
4590                          || (!TARGET_OPEN_VMS && frame_pointer_needed));
4591   fp_offset = 0;
4592   sa_reg = stack_pointer_rtx;
4593
4594   eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
4595   if (sa_size)
4596     {
4597       /* If we have a frame pointer, restore SP from it.  */
4598       if ((TARGET_OPEN_VMS
4599            && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
4600           || (!TARGET_OPEN_VMS && frame_pointer_needed))
4601         {
4602           FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
4603         }
4604
4605       /* Cope with very large offsets to the register save area.  */
4606       if (reg_offset + sa_size > 0x8000)
4607         {
4608           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
4609           HOST_WIDE_INT bias;
4610
4611           if (low + sa_size <= 0x8000)
4612             bias = reg_offset - low, reg_offset = low;
4613           else 
4614             bias = reg_offset, reg_offset = 0;
4615
4616           sa_reg = gen_rtx_REG (DImode, 22);
4617           sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
4618
4619           FRP (emit_move_insn (sa_reg, sa_reg_exp));
4620         }
4621           
4622       /* Restore registers in order, excepting a true frame pointer. */
4623
4624       if (! eh_ofs)
4625         {
4626           mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4627           MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4628           FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
4629         }
4630       reg_offset += 8;
4631       imask &= ~(1L << REG_RA);
4632
4633       for (i = 0; i < 32; ++i)
4634         if (imask & (1L << i))
4635           {
4636             if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
4637               fp_offset = reg_offset;
4638             else
4639               {
4640                 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
4641                 MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4642                 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
4643               }
4644             reg_offset += 8;
4645           }
4646
4647       for (i = 0; i < 32; ++i)
4648         if (fmask & (1L << i))
4649           {
4650             mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
4651             MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4652             FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
4653             reg_offset += 8;
4654           }
4655     }
4656
4657   if (frame_size || eh_ofs)
4658     {
4659       sp_adj1 = stack_pointer_rtx;
4660
4661       if (eh_ofs)
4662         {
4663           sp_adj1 = gen_rtx_REG (DImode, 23);
4664           emit_move_insn (sp_adj1,
4665                           gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
4666         }
4667
4668       /* If the stack size is large, begin computation into a temporary
4669          register so as not to interfere with a potential fp restore,
4670          which must be consecutive with an SP restore.  */
4671       if (frame_size < 32768)
4672         sp_adj2 = GEN_INT (frame_size);
4673       else if (frame_size < 0x40007fffL)
4674         {
4675           int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
4676
4677           sp_adj2 = plus_constant (sp_adj1, frame_size - low);
4678           if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
4679             sp_adj1 = sa_reg;
4680           else
4681             {
4682               sp_adj1 = gen_rtx_REG (DImode, 23);
4683               FRP (emit_move_insn (sp_adj1, sp_adj2));
4684             }
4685           sp_adj2 = GEN_INT (low);
4686         }
4687       else
4688         {
4689           rtx tmp = gen_rtx_REG (DImode, 23);
4690           FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3));
4691           if (!sp_adj2)
4692             {
4693               /* We can't drop new things to memory this late, afaik,
4694                  so build it up by pieces.  */
4695               FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
4696                                                         -(frame_size < 0)));
4697               if (!sp_adj2)
4698                 abort ();
4699             }
4700         }
4701
4702       /* From now on, things must be in order.  So emit blockages.  */
4703
4704       /* Restore the frame pointer.  */
4705       if (fp_is_frame_pointer)
4706         {
4707           emit_insn (gen_blockage ());
4708           mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset));
4709           MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
4710           FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
4711         }
4712       else if (TARGET_OPEN_VMS)
4713         {
4714           emit_insn (gen_blockage ());
4715           FRP (emit_move_insn (hard_frame_pointer_rtx,
4716                                gen_rtx_REG (DImode, vms_save_fp_regno)));
4717         }
4718
4719       /* Restore the stack pointer.  */
4720       emit_insn (gen_blockage ());
4721       FRP (emit_move_insn (stack_pointer_rtx,
4722                            gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
4723     }
4724   else 
4725     {
4726       if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
4727         {
4728           emit_insn (gen_blockage ());
4729           FRP (emit_move_insn (hard_frame_pointer_rtx,
4730                                gen_rtx_REG (DImode, vms_save_fp_regno)));
4731         }
4732     }
4733 }
4734
4735 /* Output the rest of the textual info surrounding the epilogue.  */
4736
4737 void
4738 alpha_end_function (file, fnname, decl)
4739      FILE *file;
4740      const char *fnname;
4741      tree decl ATTRIBUTE_UNUSED;
4742 {
4743   /* End the function.  */
4744   if (!flag_inhibit_size_directive)
4745     {
4746       fputs ("\t.end ", file);
4747       assemble_name (file, fnname);
4748       putc ('\n', file);
4749     }
4750   inside_function = FALSE;
4751
4752   /* Show that we know this function if it is called again. 
4753
4754      Don't do this for global functions in object files destined for a
4755      shared library because the function may be overridden by the application
4756      or other libraries.  Similarly, don't do this for weak functions.  */
4757
4758   if (!DECL_WEAK (current_function_decl)
4759       && (!flag_pic || !TREE_PUBLIC (current_function_decl)))
4760     SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
4761 }
4762 \f
4763 /* Debugging support.  */
4764
4765 #include "gstab.h"
4766
4767 /* Count the number of sdb related labels are generated (to find block
4768    start and end boundaries).  */
4769
4770 int sdb_label_count = 0;
4771
4772 /* Next label # for each statement.  */
4773
4774 static int sym_lineno = 0;
4775
4776 /* Count the number of .file directives, so that .loc is up to date.  */
4777
4778 static int num_source_filenames = 0;
4779
4780 /* Name of the file containing the current function.  */
4781
4782 static const char *current_function_file = "";
4783
4784 /* Offsets to alpha virtual arg/local debugging pointers.  */
4785
4786 long alpha_arg_offset;
4787 long alpha_auto_offset;
4788 \f
4789 /* Emit a new filename to a stream.  */
4790
4791 void
4792 alpha_output_filename (stream, name)
4793      FILE *stream;
4794      const char *name;
4795 {
4796   static int first_time = TRUE;
4797   char ltext_label_name[100];
4798
4799   if (first_time)
4800     {
4801       first_time = FALSE;
4802       ++num_source_filenames;
4803       current_function_file = name;
4804       fprintf (stream, "\t.file\t%d ", num_source_filenames);
4805       output_quoted_string (stream, name);
4806       fprintf (stream, "\n");
4807       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
4808         fprintf (stream, "\t#@stabs\n");
4809     }
4810
4811   else if (write_symbols == DBX_DEBUG)
4812     {
4813       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
4814       fprintf (stream, "%s ", ASM_STABS_OP);
4815       output_quoted_string (stream, name);
4816       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
4817     }
4818
4819   else if (name != current_function_file
4820            && strcmp (name, current_function_file) != 0)
4821     {
4822       if (inside_function && ! TARGET_GAS)
4823         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
4824       else
4825         {
4826           ++num_source_filenames;
4827           current_function_file = name;
4828           fprintf (stream, "\t.file\t%d ", num_source_filenames);
4829         }
4830
4831       output_quoted_string (stream, name);
4832       fprintf (stream, "\n");
4833     }
4834 }
4835 \f
4836 /* Emit a linenumber to a stream.  */
4837
4838 void
4839 alpha_output_lineno (stream, line)
4840      FILE *stream;
4841      int line;
4842 {
4843   if (write_symbols == DBX_DEBUG)
4844     {
4845       /* mips-tfile doesn't understand .stabd directives.  */
4846       ++sym_lineno;
4847       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
4848                sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
4849     }
4850   else
4851     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
4852 }
4853 \f
4854 /* Structure to show the current status of registers and memory.  */
4855
4856 struct shadow_summary
4857 {
4858   struct {
4859     unsigned long i     : 31;   /* Mask of int regs */
4860     unsigned long fp    : 31;   /* Mask of fp regs */
4861     unsigned long mem   :  1;   /* mem == imem | fpmem */
4862   } used, defd;
4863 };
4864
4865 static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
4866 static void alpha_handle_trap_shadows PARAMS ((rtx));
4867
4868 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
4869    to the summary structure.  SET is nonzero if the insn is setting the
4870    object, otherwise zero.  */
4871
4872 static void
4873 summarize_insn (x, sum, set)
4874      rtx x;
4875      struct shadow_summary *sum;
4876      int set;
4877 {
4878   const char *format_ptr;
4879   int i, j;
4880
4881   if (x == 0)
4882     return;
4883
4884   switch (GET_CODE (x))
4885     {
4886       /* ??? Note that this case would be incorrect if the Alpha had a
4887          ZERO_EXTRACT in SET_DEST.  */
4888     case SET:
4889       summarize_insn (SET_SRC (x), sum, 0);
4890       summarize_insn (SET_DEST (x), sum, 1);
4891       break;
4892
4893     case CLOBBER:
4894       summarize_insn (XEXP (x, 0), sum, 1);
4895       break;
4896
4897     case USE:
4898       summarize_insn (XEXP (x, 0), sum, 0);
4899       break;
4900
4901     case ASM_OPERANDS:
4902       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
4903         summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
4904       break;
4905
4906     case PARALLEL:
4907       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
4908         summarize_insn (XVECEXP (x, 0, i), sum, 0);
4909       break;
4910
4911     case SUBREG:
4912       summarize_insn (SUBREG_REG (x), sum, 0);
4913       break;
4914
4915     case REG:
4916       {
4917         int regno = REGNO (x);
4918         unsigned long mask = 1UL << (regno % 32);
4919
4920         if (regno == 31 || regno == 63)
4921           break;
4922
4923         if (set)
4924           {
4925             if (regno < 32)
4926               sum->defd.i |= mask;
4927             else
4928               sum->defd.fp |= mask;
4929           }
4930         else
4931           {
4932             if (regno < 32)
4933               sum->used.i  |= mask;
4934             else
4935               sum->used.fp |= mask;
4936           }
4937         }
4938       break;
4939
4940     case MEM:
4941       if (set)
4942         sum->defd.mem = 1;
4943       else
4944         sum->used.mem = 1;
4945
4946       /* Find the regs used in memory address computation: */
4947       summarize_insn (XEXP (x, 0), sum, 0);
4948       break;
4949
4950     case CONST_INT:   case CONST_DOUBLE:
4951     case SYMBOL_REF:  case LABEL_REF:     case CONST:
4952       break;
4953
4954       /* Handle common unary and binary ops for efficiency.  */
4955     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
4956     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
4957     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
4958     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
4959     case NE:       case EQ:      case GE:      case GT:        case LE:
4960     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
4961       summarize_insn (XEXP (x, 0), sum, 0);
4962       summarize_insn (XEXP (x, 1), sum, 0);
4963       break;
4964
4965     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
4966     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
4967     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
4968     case SQRT:  case FFS: 
4969       summarize_insn (XEXP (x, 0), sum, 0);
4970       break;
4971
4972     default:
4973       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
4974       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4975         switch (format_ptr[i])
4976           {
4977           case 'e':
4978             summarize_insn (XEXP (x, i), sum, 0);
4979             break;
4980
4981           case 'E':
4982             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4983               summarize_insn (XVECEXP (x, i, j), sum, 0);
4984             break;
4985
4986           case 'i':
4987             break;
4988
4989           default:
4990             abort ();
4991           }
4992     }
4993 }
4994
4995 /* Ensure a sufficient number of `trapb' insns are in the code when
4996    the user requests code with a trap precision of functions or
4997    instructions.
4998
4999    In naive mode, when the user requests a trap-precision of
5000    "instruction", a trapb is needed after every instruction that may
5001    generate a trap.  This ensures that the code is resumption safe but
5002    it is also slow.
5003
5004    When optimizations are turned on, we delay issuing a trapb as long
5005    as possible.  In this context, a trap shadow is the sequence of
5006    instructions that starts with a (potentially) trap generating
5007    instruction and extends to the next trapb or call_pal instruction
5008    (but GCC never generates call_pal by itself).  We can delay (and
5009    therefore sometimes omit) a trapb subject to the following
5010    conditions:
5011
5012    (a) On entry to the trap shadow, if any Alpha register or memory
5013    location contains a value that is used as an operand value by some
5014    instruction in the trap shadow (live on entry), then no instruction
5015    in the trap shadow may modify the register or memory location.
5016
5017    (b) Within the trap shadow, the computation of the base register
5018    for a memory load or store instruction may not involve using the
5019    result of an instruction that might generate an UNPREDICTABLE
5020    result.
5021
5022    (c) Within the trap shadow, no register may be used more than once
5023    as a destination register.  (This is to make life easier for the
5024    trap-handler.)
5025
5026    (d) The trap shadow may not include any branch instructions.  */
5027
5028 static void
5029 alpha_handle_trap_shadows (insns)
5030      rtx insns;
5031 {
5032   struct shadow_summary shadow;
5033   int trap_pending, exception_nesting;
5034   rtx i, n;
5035
5036   trap_pending = 0;
5037   exception_nesting = 0;
5038   shadow.used.i = 0;
5039   shadow.used.fp = 0;
5040   shadow.used.mem = 0;
5041   shadow.defd = shadow.used;
5042   
5043   for (i = insns; i ; i = NEXT_INSN (i))
5044     {
5045       if (GET_CODE (i) == NOTE)
5046         {
5047           switch (NOTE_LINE_NUMBER (i))
5048             {
5049             case NOTE_INSN_EH_REGION_BEG:
5050               exception_nesting++;
5051               if (trap_pending)
5052                 goto close_shadow;
5053               break;
5054
5055             case NOTE_INSN_EH_REGION_END:
5056               exception_nesting--;
5057               if (trap_pending)
5058                 goto close_shadow;
5059               break;
5060
5061             case NOTE_INSN_EPILOGUE_BEG:
5062               if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
5063                 goto close_shadow;
5064               break;
5065             }
5066         }
5067       else if (trap_pending)
5068         {
5069           if (alpha_tp == ALPHA_TP_FUNC)
5070             {
5071               if (GET_CODE (i) == JUMP_INSN
5072                   && GET_CODE (PATTERN (i)) == RETURN)
5073                 goto close_shadow;
5074             }
5075           else if (alpha_tp == ALPHA_TP_INSN)
5076             {
5077               if (optimize > 0)
5078                 {
5079                   struct shadow_summary sum;
5080
5081                   sum.used.i = 0;
5082                   sum.used.fp = 0;
5083                   sum.used.mem = 0;
5084                   sum.defd = sum.used;
5085
5086                   switch (GET_CODE (i))
5087                     {
5088                     case INSN:
5089                       /* Annoyingly, get_attr_trap will abort on these.  */
5090                       if (GET_CODE (PATTERN (i)) == USE
5091                           || GET_CODE (PATTERN (i)) == CLOBBER)
5092                         break;
5093
5094                       summarize_insn (PATTERN (i), &sum, 0);
5095
5096                       if ((sum.defd.i & shadow.defd.i)
5097                           || (sum.defd.fp & shadow.defd.fp))
5098                         {
5099                           /* (c) would be violated */
5100                           goto close_shadow;
5101                         }
5102
5103                       /* Combine shadow with summary of current insn: */
5104                       shadow.used.i   |= sum.used.i;
5105                       shadow.used.fp  |= sum.used.fp;
5106                       shadow.used.mem |= sum.used.mem;
5107                       shadow.defd.i   |= sum.defd.i;
5108                       shadow.defd.fp  |= sum.defd.fp;
5109                       shadow.defd.mem |= sum.defd.mem;
5110
5111                       if ((sum.defd.i & shadow.used.i)
5112                           || (sum.defd.fp & shadow.used.fp)
5113                           || (sum.defd.mem & shadow.used.mem))
5114                         {
5115                           /* (a) would be violated (also takes care of (b))  */
5116                           if (get_attr_trap (i) == TRAP_YES
5117                               && ((sum.defd.i & sum.used.i)
5118                                   || (sum.defd.fp & sum.used.fp)))
5119                             abort ();
5120
5121                           goto close_shadow;
5122                         }
5123                       break;
5124
5125                     case JUMP_INSN:
5126                     case CALL_INSN:
5127                     case CODE_LABEL:
5128                       goto close_shadow;
5129
5130                     default:
5131                       abort ();
5132                     }
5133                 }
5134               else
5135                 {
5136                 close_shadow:
5137                   n = emit_insn_before (gen_trapb (), i);
5138                   PUT_MODE (n, TImode);
5139                   PUT_MODE (i, TImode);
5140                   trap_pending = 0;
5141                   shadow.used.i = 0;
5142                   shadow.used.fp = 0;
5143                   shadow.used.mem = 0;
5144                   shadow.defd = shadow.used;
5145                 }
5146             }
5147         }
5148
5149       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
5150           && GET_CODE (i) == INSN
5151           && GET_CODE (PATTERN (i)) != USE
5152           && GET_CODE (PATTERN (i)) != CLOBBER
5153           && get_attr_trap (i) == TRAP_YES)
5154         {
5155           if (optimize && !trap_pending)
5156             summarize_insn (PATTERN (i), &shadow, 0);
5157           trap_pending = 1;
5158         }
5159     }
5160 }
5161 \f
5162 #ifdef HAIFA
5163 /* Alpha can only issue instruction groups simultaneously if they are
5164    suitibly aligned.  This is very processor-specific.  */
5165
5166 enum alphaev4_pipe {
5167   EV4_STOP = 0,
5168   EV4_IB0 = 1,
5169   EV4_IB1 = 2,
5170   EV4_IBX = 4
5171 };
5172
5173 enum alphaev5_pipe {
5174   EV5_STOP = 0,
5175   EV5_NONE = 1,
5176   EV5_E01 = 2,
5177   EV5_E0 = 4,
5178   EV5_E1 = 8,
5179   EV5_FAM = 16,
5180   EV5_FA = 32,
5181   EV5_FM = 64
5182 };
5183
5184 static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
5185 static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
5186 static rtx alphaev4_next_group PARAMS ((rtx, int*, int*));
5187 static rtx alphaev5_next_group PARAMS ((rtx, int*, int*));
5188 static rtx alphaev4_next_nop PARAMS ((int*));
5189 static rtx alphaev5_next_nop PARAMS ((int*));
5190
5191 static void alpha_align_insns
5192   PARAMS ((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int));
5193
5194 static enum alphaev4_pipe
5195 alphaev4_insn_pipe (insn)
5196      rtx insn;
5197 {
5198   if (recog_memoized (insn) < 0)
5199     return EV4_STOP;
5200   if (get_attr_length (insn) != 4)
5201     return EV4_STOP;
5202
5203   switch (get_attr_type (insn))
5204     {
5205     case TYPE_ILD:
5206     case TYPE_FLD:
5207       return EV4_IBX;
5208
5209     case TYPE_LDSYM:
5210     case TYPE_IADD:
5211     case TYPE_ILOG:
5212     case TYPE_ICMOV:
5213     case TYPE_ICMP:
5214     case TYPE_IST:
5215     case TYPE_FST:
5216     case TYPE_SHIFT:
5217     case TYPE_IMUL:
5218     case TYPE_FBR:
5219       return EV4_IB0;
5220
5221     case TYPE_MISC:
5222     case TYPE_IBR:
5223     case TYPE_JSR:
5224     case TYPE_FCPYS:
5225     case TYPE_FCMOV:
5226     case TYPE_FADD:
5227     case TYPE_FDIV:
5228     case TYPE_FMUL:
5229       return EV4_IB1;
5230
5231     default:
5232       abort();
5233     }
5234 }
5235
5236 static enum alphaev5_pipe
5237 alphaev5_insn_pipe (insn)
5238      rtx insn;
5239 {
5240   if (recog_memoized (insn) < 0)
5241     return EV5_STOP;
5242   if (get_attr_length (insn) != 4)
5243     return EV5_STOP;
5244
5245   switch (get_attr_type (insn))
5246     {
5247     case TYPE_ILD:
5248     case TYPE_FLD:
5249     case TYPE_LDSYM:
5250     case TYPE_IADD:
5251     case TYPE_ILOG:
5252     case TYPE_ICMOV:
5253     case TYPE_ICMP:
5254       return EV5_E01;
5255
5256     case TYPE_IST:
5257     case TYPE_FST:
5258     case TYPE_SHIFT:
5259     case TYPE_IMUL:
5260     case TYPE_MISC:
5261     case TYPE_MVI:
5262       return EV5_E0;
5263
5264     case TYPE_IBR:
5265     case TYPE_JSR:
5266       return EV5_E1;
5267
5268     case TYPE_FCPYS:
5269       return EV5_FAM;
5270
5271     case TYPE_FBR:
5272     case TYPE_FCMOV:
5273     case TYPE_FADD:
5274     case TYPE_FDIV:
5275       return EV5_FA;
5276
5277     case TYPE_FMUL:
5278       return EV5_FM;
5279
5280     default:
5281       abort();
5282     }
5283 }
5284
5285 /* IN_USE is a mask of the slots currently filled within the insn group. 
5286    The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
5287    the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1. 
5288
5289    LEN is, of course, the length of the group in bytes.  */
5290
5291 static rtx
5292 alphaev4_next_group (insn, pin_use, plen)
5293      rtx insn;
5294      int *pin_use, *plen;
5295 {
5296   int len, in_use;
5297
5298   len = in_use = 0;
5299
5300   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
5301       || GET_CODE (PATTERN (insn)) == CLOBBER
5302       || GET_CODE (PATTERN (insn)) == USE)
5303     goto next_and_done;
5304
5305   while (1)
5306     {
5307       enum alphaev4_pipe pipe;
5308
5309       pipe = alphaev4_insn_pipe (insn);
5310       switch (pipe)
5311         {
5312         case EV4_STOP:
5313           /* Force complex instructions to start new groups.  */
5314           if (in_use)
5315             goto done;
5316
5317           /* If this is a completely unrecognized insn, its an asm.
5318              We don't know how long it is, so record length as -1 to
5319              signal a needed realignment.  */
5320           if (recog_memoized (insn) < 0)
5321             len = -1;
5322           else
5323             len = get_attr_length (insn);
5324           goto next_and_done;
5325
5326         case EV4_IBX:
5327           if (in_use & EV4_IB0)
5328             {
5329               if (in_use & EV4_IB1)
5330                 goto done;
5331               in_use |= EV4_IB1;
5332             }
5333           else
5334             in_use |= EV4_IB0 | EV4_IBX;
5335           break;
5336
5337         case EV4_IB0:
5338           if (in_use & EV4_IB0)
5339             {
5340               if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
5341                 goto done;
5342               in_use |= EV4_IB1;
5343             }
5344           in_use |= EV4_IB0;
5345           break;
5346
5347         case EV4_IB1:
5348           if (in_use & EV4_IB1)
5349             goto done;
5350           in_use |= EV4_IB1;
5351           break;
5352
5353         default:
5354           abort();
5355         }
5356       len += 4;
5357       
5358       /* Haifa doesn't do well scheduling branches.  */
5359       if (GET_CODE (insn) == JUMP_INSN)
5360         goto next_and_done;
5361
5362     next:
5363       insn = next_nonnote_insn (insn);
5364
5365       if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
5366         goto done;
5367
5368       /* Let Haifa tell us where it thinks insn group boundaries are.  */
5369       if (GET_MODE (insn) == TImode)
5370         goto done;
5371
5372       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5373         goto next;
5374     }
5375
5376  next_and_done:
5377   insn = next_nonnote_insn (insn);
5378
5379  done:
5380   *plen = len;
5381   *pin_use = in_use;
5382   return insn;
5383 }
5384
5385 /* IN_USE is a mask of the slots currently filled within the insn group. 
5386    The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
5387    the insn in EV5_E0 can be swapped by the hardware into EV5_E1. 
5388
5389    LEN is, of course, the length of the group in bytes.  */
5390
5391 static rtx
5392 alphaev5_next_group (insn, pin_use, plen)
5393      rtx insn;
5394      int *pin_use, *plen;
5395 {
5396   int len, in_use;
5397
5398   len = in_use = 0;
5399
5400   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
5401       || GET_CODE (PATTERN (insn)) == CLOBBER
5402       || GET_CODE (PATTERN (insn)) == USE)
5403     goto next_and_done;
5404
5405   while (1)
5406     {
5407       enum alphaev5_pipe pipe;
5408
5409       pipe = alphaev5_insn_pipe (insn);
5410       switch (pipe)
5411         {
5412         case EV5_STOP:
5413           /* Force complex instructions to start new groups.  */
5414           if (in_use)
5415             goto done;
5416
5417           /* If this is a completely unrecognized insn, its an asm.
5418              We don't know how long it is, so record length as -1 to
5419              signal a needed realignment.  */
5420           if (recog_memoized (insn) < 0)
5421             len = -1;
5422           else
5423             len = get_attr_length (insn);
5424           goto next_and_done;
5425
5426         /* ??? Most of the places below, we would like to abort, as 
5427            it would indicate an error either in Haifa, or in the 
5428            scheduling description.  Unfortunately, Haifa never 
5429            schedules the last instruction of the BB, so we don't
5430            have an accurate TI bit to go off.  */
5431         case EV5_E01:
5432           if (in_use & EV5_E0)
5433             {
5434               if (in_use & EV5_E1)
5435                 goto done;
5436               in_use |= EV5_E1;
5437             }
5438           else
5439             in_use |= EV5_E0 | EV5_E01;
5440           break;
5441
5442         case EV5_E0:
5443           if (in_use & EV5_E0)
5444             {
5445               if (!(in_use & EV5_E01) || (in_use & EV5_E1))
5446                 goto done;
5447               in_use |= EV5_E1;
5448             }
5449           in_use |= EV5_E0;
5450           break;
5451
5452         case EV5_E1:
5453           if (in_use & EV5_E1)
5454             goto done;
5455           in_use |= EV5_E1;
5456           break;
5457
5458         case EV5_FAM:
5459           if (in_use & EV5_FA)
5460             {
5461               if (in_use & EV5_FM)
5462                 goto done;
5463               in_use |= EV5_FM;
5464             }
5465           else
5466             in_use |= EV5_FA | EV5_FAM;
5467           break;
5468
5469         case EV5_FA:
5470           if (in_use & EV5_FA)
5471             goto done;
5472           in_use |= EV5_FA;
5473           break;
5474
5475         case EV5_FM:
5476           if (in_use & EV5_FM)
5477             goto done;
5478           in_use |= EV5_FM;
5479           break;
5480
5481         case EV5_NONE:
5482           break;
5483
5484         default:
5485           abort();
5486         }
5487       len += 4;
5488       
5489       /* Haifa doesn't do well scheduling branches.  */
5490       /* ??? If this is predicted not-taken, slotting continues, except
5491          that no more IBR, FBR, or JSR insns may be slotted.  */
5492       if (GET_CODE (insn) == JUMP_INSN)
5493         goto next_and_done;
5494
5495     next:
5496       insn = next_nonnote_insn (insn);
5497
5498       if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i')
5499         goto done;
5500
5501       /* Let Haifa tell us where it thinks insn group boundaries are.  */
5502       if (GET_MODE (insn) == TImode)
5503         goto done;
5504
5505       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
5506         goto next;
5507     }
5508
5509  next_and_done:
5510   insn = next_nonnote_insn (insn);
5511
5512  done:
5513   *plen = len;
5514   *pin_use = in_use;
5515   return insn;
5516 }
5517
5518 static rtx
5519 alphaev4_next_nop (pin_use)
5520      int *pin_use;
5521 {
5522   int in_use = *pin_use;
5523   rtx nop;
5524
5525   if (!(in_use & EV4_IB0))
5526     {
5527       in_use |= EV4_IB0;
5528       nop = gen_nop ();
5529     }
5530   else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
5531     {
5532       in_use |= EV4_IB1;
5533       nop = gen_nop ();
5534     }
5535   else if (TARGET_FP && !(in_use & EV4_IB1))
5536     {
5537       in_use |= EV4_IB1;
5538       nop = gen_fnop ();
5539     }
5540   else
5541     nop = gen_unop ();
5542
5543   *pin_use = in_use;
5544   return nop;
5545 }
5546
5547 static rtx
5548 alphaev5_next_nop (pin_use)
5549      int *pin_use;
5550 {
5551   int in_use = *pin_use;
5552   rtx nop;
5553
5554   if (!(in_use & EV5_E1))
5555     {
5556       in_use |= EV5_E1;
5557       nop = gen_nop ();
5558     }
5559   else if (TARGET_FP && !(in_use & EV5_FA))
5560     {
5561       in_use |= EV5_FA;
5562       nop = gen_fnop ();
5563     }
5564   else if (TARGET_FP && !(in_use & EV5_FM))
5565     {
5566       in_use |= EV5_FM;
5567       nop = gen_fnop ();
5568     }
5569   else
5570     nop = gen_unop ();
5571
5572   *pin_use = in_use;
5573   return nop;
5574 }
5575
5576 /* The instruction group alignment main loop.  */
5577
5578 static void
5579 alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use)
5580      rtx insns;
5581      int max_align;
5582      rtx (*next_group) PARAMS ((rtx, int*, int*));
5583      rtx (*next_nop) PARAMS ((int*));
5584      int gp_in_use;
5585 {
5586   /* ALIGN is the known alignment for the insn group.  */
5587   int align;
5588   /* OFS is the offset of the current insn in the insn group.  */
5589   int ofs;
5590   int prev_in_use, in_use, len;
5591   rtx i, next;
5592
5593   /* Let shorten branches care for assigning alignments to code labels.  */
5594   shorten_branches (insns);
5595
5596   align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align
5597            ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align);
5598
5599   /* Account for the initial GP load, which happens before the scheduled
5600      prologue we emitted as RTL.  */
5601   ofs = prev_in_use = 0;
5602   if (alpha_does_function_need_gp())
5603     {
5604       ofs = 8 & (align - 1);
5605       prev_in_use = gp_in_use;
5606     }
5607
5608   i = insns;
5609   if (GET_CODE (i) == NOTE)
5610     i = next_nonnote_insn (i);
5611
5612   while (i)
5613     {
5614       next = (*next_group)(i, &in_use, &len);
5615
5616       /* When we see a label, resync alignment etc.  */
5617       if (GET_CODE (i) == CODE_LABEL)
5618         {
5619           int new_align = 1 << label_to_alignment (i);
5620           if (new_align >= align)
5621             {
5622               align = new_align < max_align ? new_align : max_align;
5623               ofs = 0;
5624             }
5625           else if (ofs & (new_align-1))
5626             ofs = (ofs | (new_align-1)) + 1;
5627           if (len != 0)
5628             abort();
5629         }
5630
5631       /* Handle complex instructions special.  */
5632       else if (in_use == 0)
5633         {
5634           /* Asms will have length < 0.  This is a signal that we have
5635              lost alignment knowledge.  Assume, however, that the asm
5636              will not mis-align instructions.  */
5637           if (len < 0)
5638             {
5639               ofs = 0;
5640               align = 4;
5641               len = 0;
5642             }
5643         }
5644
5645       /* If the known alignment is smaller than the recognized insn group,
5646          realign the output.  */
5647       else if (align < len)
5648         {
5649           int new_log_align = len > 8 ? 4 : 3;
5650           rtx where;
5651
5652           where = prev_nonnote_insn (i);
5653           if (!where || GET_CODE (where) != CODE_LABEL)
5654             where = i;
5655
5656           emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
5657           align = 1 << new_log_align;
5658           ofs = 0;
5659         }
5660
5661       /* If the group won't fit in the same INT16 as the previous,
5662          we need to add padding to keep the group together.  Rather
5663          than simply leaving the insn filling to the assembler, we
5664          can make use of the knowledge of what sorts of instructions
5665          were issued in the previous group to make sure that all of
5666          the added nops are really free.  */
5667       else if (ofs + len > align)
5668         {
5669           int nop_count = (align - ofs) / 4;
5670           rtx where;
5671
5672           /* Insert nops before labels and branches to truely merge the
5673              execution of the nops with the previous instruction group.  */
5674           where = prev_nonnote_insn (i);
5675           if (where)
5676             {
5677               if (GET_CODE (where) == CODE_LABEL)
5678                 {
5679                   rtx where2 = prev_nonnote_insn (where);
5680                   if (where2 && GET_CODE (where2) == JUMP_INSN)
5681                     where = where2;
5682                 }
5683               else if (GET_CODE (where) != JUMP_INSN)
5684                 where = i;
5685             }
5686           else
5687             where = i;
5688
5689           do 
5690             emit_insn_before ((*next_nop)(&prev_in_use), where);
5691           while (--nop_count);
5692           ofs = 0;
5693         }
5694
5695       ofs = (ofs + len) & (align - 1);
5696       prev_in_use = in_use;
5697       i = next;
5698     }
5699 }
5700 #endif /* HAIFA */
5701 \f
5702 /* Machine dependant reorg pass.  */
5703
5704 void
5705 alpha_reorg (insns)
5706      rtx insns;
5707 {
5708   if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
5709     alpha_handle_trap_shadows (insns);
5710
5711 #ifdef HAIFA
5712   /* Due to the number of extra trapb insns, don't bother fixing up
5713      alignment when trap precision is instruction.  Moreover, we can
5714      only do our job when sched2 is run and Haifa is our scheduler.  */
5715   if (optimize && !optimize_size
5716       && alpha_tp != ALPHA_TP_INSN
5717       && flag_schedule_insns_after_reload)
5718     {
5719       if (alpha_cpu == PROCESSOR_EV4)
5720         alpha_align_insns (insns, 8, alphaev4_next_group,
5721                            alphaev4_next_nop, EV4_IB0);
5722       else if (alpha_cpu == PROCESSOR_EV5)
5723         alpha_align_insns (insns, 16, alphaev5_next_group,
5724                            alphaev5_next_nop, EV5_E01 | EV5_E0);
5725     }
5726 #endif
5727 }
5728
5729 \f
5730 /* Check a floating-point value for validity for a particular machine mode.  */
5731
5732 static const char * const float_strings[] =
5733 {
5734   /* These are for FLOAT_VAX.  */
5735    "1.70141173319264430e+38", /* 2^127 (2^24 - 1) / 2^24 */
5736   "-1.70141173319264430e+38",
5737    "2.93873587705571877e-39", /* 2^-128 */
5738   "-2.93873587705571877e-39",
5739   /* These are for the default broken IEEE mode, which traps
5740      on infinity or denormal numbers.  */
5741    "3.402823466385288598117e+38", /* 2^128 (1 - 2^-24) */
5742   "-3.402823466385288598117e+38",
5743    "1.1754943508222875079687e-38", /* 2^-126 */
5744   "-1.1754943508222875079687e-38",
5745 };
5746
5747 static REAL_VALUE_TYPE float_values[8];
5748 static int inited_float_values = 0;
5749
5750 int
5751 check_float_value (mode, d, overflow)
5752      enum machine_mode mode;
5753      REAL_VALUE_TYPE *d;
5754      int overflow ATTRIBUTE_UNUSED;
5755 {
5756
5757   if (TARGET_IEEE || TARGET_IEEE_CONFORMANT || TARGET_IEEE_WITH_INEXACT)
5758     return 0;
5759
5760   if (inited_float_values == 0)
5761     {
5762       int i;
5763       for (i = 0; i < 8; i++)
5764         float_values[i] = REAL_VALUE_ATOF (float_strings[i], DFmode);
5765
5766       inited_float_values = 1;
5767     }
5768
5769   if (mode == SFmode)
5770     {
5771       REAL_VALUE_TYPE r;
5772       REAL_VALUE_TYPE *fvptr;
5773
5774       if (TARGET_FLOAT_VAX)
5775         fvptr = &float_values[0];
5776       else
5777         fvptr = &float_values[4];
5778
5779       bcopy ((char *) d, (char *) &r, sizeof (REAL_VALUE_TYPE));
5780       if (REAL_VALUES_LESS (fvptr[0], r))
5781         {
5782           bcopy ((char *) &fvptr[0], (char *) d,
5783                  sizeof (REAL_VALUE_TYPE));
5784           return 1;
5785         }
5786       else if (REAL_VALUES_LESS (r, fvptr[1]))
5787         {
5788           bcopy ((char *) &fvptr[1], (char *) d,
5789                  sizeof (REAL_VALUE_TYPE));
5790           return 1;
5791         }
5792       else if (REAL_VALUES_LESS (dconst0, r)
5793                 && REAL_VALUES_LESS (r, fvptr[2]))
5794         {
5795           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5796           return 1;
5797         }
5798       else if (REAL_VALUES_LESS (r, dconst0)
5799                 && REAL_VALUES_LESS (fvptr[3], r))
5800         {
5801           bcopy ((char *) &dconst0, (char *) d, sizeof (REAL_VALUE_TYPE));
5802           return 1;
5803         }
5804     }
5805
5806   return 0;
5807 }
5808
5809 #if OPEN_VMS
5810
5811 /* Return the VMS argument type corresponding to MODE.  */
5812
5813 enum avms_arg_type
5814 alpha_arg_type (mode)
5815      enum machine_mode mode;
5816 {
5817   switch (mode)
5818     {
5819     case SFmode:
5820       return TARGET_FLOAT_VAX ? FF : FS;
5821     case DFmode:
5822       return TARGET_FLOAT_VAX ? FD : FT;
5823     default:
5824       return I64;
5825     }
5826 }
5827
5828 /* Return an rtx for an integer representing the VMS Argument Information
5829    register value.  */
5830
5831 rtx
5832 alpha_arg_info_reg_val (cum)
5833      CUMULATIVE_ARGS cum;
5834 {
5835   unsigned HOST_WIDE_INT regval = cum.num_args;
5836   int i;
5837
5838   for (i = 0; i < 6; i++)
5839     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
5840
5841   return GEN_INT (regval);
5842 }
5843 \f
5844 /* Structure to collect function names for final output
5845    in link section.  */
5846
5847 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
5848
5849
5850 struct alpha_links {
5851   struct alpha_links *next;
5852   char *name;
5853   enum links_kind kind;
5854 };
5855
5856 static struct alpha_links *alpha_links_base = 0;
5857
5858 /* Make (or fake) .linkage entry for function call.
5859
5860    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.  */
5861
5862 void
5863 alpha_need_linkage (name, is_local)
5864     const char *name;
5865     int is_local;
5866 {
5867   rtx x;
5868   struct alpha_links *lptr, *nptr;
5869
5870   if (name[0] == '*')
5871     name++;
5872
5873   /* Is this name already defined ?  */
5874
5875   for (lptr = alpha_links_base; lptr; lptr = lptr->next)
5876     if (strcmp (lptr->name, name) == 0)
5877       {
5878         if (is_local)
5879           {
5880             /* Defined here but external assumed.  */
5881             if (lptr->kind == KIND_EXTERN)
5882               lptr->kind = KIND_LOCAL;
5883           }
5884         else
5885           {
5886             /* Used here but unused assumed.  */
5887             if (lptr->kind == KIND_UNUSED)
5888               lptr->kind = KIND_LOCAL;
5889           }
5890         return;
5891       }
5892
5893   nptr = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
5894   nptr->next = alpha_links_base;
5895   nptr->name = xstrdup (name);
5896
5897   /* Assume external if no definition.  */
5898   nptr->kind = (is_local ? KIND_UNUSED : KIND_EXTERN);
5899
5900   /* Ensure we have an IDENTIFIER so assemble_name can mark is used.  */
5901   get_identifier (name);
5902
5903   alpha_links_base = nptr;
5904
5905   return;
5906 }
5907
5908
5909 void
5910 alpha_write_linkage (stream)
5911     FILE *stream;
5912 {
5913   struct alpha_links *lptr, *nptr;
5914
5915   readonly_section ();
5916
5917   fprintf (stream, "\t.align 3\n");
5918
5919   for (lptr = alpha_links_base; lptr; lptr = nptr)
5920     {
5921       nptr = lptr->next;
5922
5923       if (lptr->kind == KIND_UNUSED
5924           || ! TREE_SYMBOL_REFERENCED (get_identifier (lptr->name)))
5925         continue;
5926
5927       fprintf (stream, "$%s..lk:\n", lptr->name);
5928       if (lptr->kind == KIND_LOCAL)   
5929         {
5930           /*  Local and used, build linkage pair.  */
5931           fprintf (stream, "\t.quad %s..en\n", lptr->name);
5932           fprintf (stream, "\t.quad %s\n", lptr->name);
5933         }
5934       else
5935         /* External and used, request linkage pair.  */
5936         fprintf (stream, "\t.linkage %s\n", lptr->name);
5937     }
5938 }
5939
5940 #else
5941
5942 void
5943 alpha_need_linkage (name, is_local)
5944      const char *name ATTRIBUTE_UNUSED;
5945      int is_local ATTRIBUTE_UNUSED;
5946 {
5947 }
5948
5949 #endif /* OPEN_VMS */