OSDN Git Service

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