OSDN Git Service

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