OSDN Git Service

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