OSDN Git Service

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