OSDN Git Service

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