OSDN Git Service

gcc/
[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, 2000, 2001,
3    2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4    Free Software Foundation, Inc.
5    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "output.h"
35 #include "insn-attr.h"
36 #include "flags.h"
37 #include "recog.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "reload.h"
41 #include "obstack.h"
42 #include "except.h"
43 #include "function.h"
44 #include "diagnostic-core.h"
45 #include "ggc.h"
46 #include "integrate.h"
47 #include "tm_p.h"
48 #include "target.h"
49 #include "target-def.h"
50 #include "debug.h"
51 #include "langhooks.h"
52 #include "splay-tree.h"
53 #include "cfglayout.h"
54 #include "gimple.h"
55 #include "tree-flow.h"
56 #include "tree-stdarg.h"
57 #include "tm-constrs.h"
58 #include "df.h"
59 #include "libfuncs.h"
60 #include "opts.h"
61
62 /* Specify which cpu to schedule for.  */
63 enum processor_type alpha_tune;
64
65 /* Which cpu we're generating code for.  */
66 enum processor_type alpha_cpu;
67
68 static const char * const alpha_cpu_name[] =
69 {
70   "ev4", "ev5", "ev6"
71 };
72
73 /* Specify how accurate floating-point traps need to be.  */
74
75 enum alpha_trap_precision alpha_tp;
76
77 /* Specify the floating-point rounding mode.  */
78
79 enum alpha_fp_rounding_mode alpha_fprm;
80
81 /* Specify which things cause traps.  */
82
83 enum alpha_fp_trap_mode alpha_fptm;
84
85 /* Nonzero if inside of a function, because the Alpha asm can't
86    handle .files inside of functions.  */
87
88 static int inside_function = FALSE;
89
90 /* The number of cycles of latency we should assume on memory reads.  */
91
92 int alpha_memory_latency = 3;
93
94 /* Whether the function needs the GP.  */
95
96 static int alpha_function_needs_gp;
97
98 /* The assembler name of the current function.  */
99
100 static const char *alpha_fnname;
101
102 /* The next explicit relocation sequence number.  */
103 extern GTY(()) int alpha_next_sequence_number;
104 int alpha_next_sequence_number = 1;
105
106 /* The literal and gpdisp sequence numbers for this insn, as printed
107    by %# and %* respectively.  */
108 extern GTY(()) int alpha_this_literal_sequence_number;
109 extern GTY(()) int alpha_this_gpdisp_sequence_number;
110 int alpha_this_literal_sequence_number;
111 int alpha_this_gpdisp_sequence_number;
112
113 /* Costs of various operations on the different architectures.  */
114
115 struct alpha_rtx_cost_data
116 {
117   unsigned char fp_add;
118   unsigned char fp_mult;
119   unsigned char fp_div_sf;
120   unsigned char fp_div_df;
121   unsigned char int_mult_si;
122   unsigned char int_mult_di;
123   unsigned char int_shift;
124   unsigned char int_cmov;
125   unsigned short int_div;
126 };
127
128 static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
129 {
130   { /* EV4 */
131     COSTS_N_INSNS (6),          /* fp_add */
132     COSTS_N_INSNS (6),          /* fp_mult */
133     COSTS_N_INSNS (34),         /* fp_div_sf */
134     COSTS_N_INSNS (63),         /* fp_div_df */
135     COSTS_N_INSNS (23),         /* int_mult_si */
136     COSTS_N_INSNS (23),         /* int_mult_di */
137     COSTS_N_INSNS (2),          /* int_shift */
138     COSTS_N_INSNS (2),          /* int_cmov */
139     COSTS_N_INSNS (97),         /* int_div */
140   },
141   { /* EV5 */
142     COSTS_N_INSNS (4),          /* fp_add */
143     COSTS_N_INSNS (4),          /* fp_mult */
144     COSTS_N_INSNS (15),         /* fp_div_sf */
145     COSTS_N_INSNS (22),         /* fp_div_df */
146     COSTS_N_INSNS (8),          /* int_mult_si */
147     COSTS_N_INSNS (12),         /* int_mult_di */
148     COSTS_N_INSNS (1) + 1,      /* int_shift */
149     COSTS_N_INSNS (1),          /* int_cmov */
150     COSTS_N_INSNS (83),         /* int_div */
151   },
152   { /* EV6 */
153     COSTS_N_INSNS (4),          /* fp_add */
154     COSTS_N_INSNS (4),          /* fp_mult */
155     COSTS_N_INSNS (12),         /* fp_div_sf */
156     COSTS_N_INSNS (15),         /* fp_div_df */
157     COSTS_N_INSNS (7),          /* int_mult_si */
158     COSTS_N_INSNS (7),          /* int_mult_di */
159     COSTS_N_INSNS (1),          /* int_shift */
160     COSTS_N_INSNS (2),          /* int_cmov */
161     COSTS_N_INSNS (86),         /* int_div */
162   },
163 };
164
165 /* Similar but tuned for code size instead of execution latency.  The
166    extra +N is fractional cost tuning based on latency.  It's used to
167    encourage use of cheaper insns like shift, but only if there's just
168    one of them.  */
169
170 static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
171 {
172   COSTS_N_INSNS (1),            /* fp_add */
173   COSTS_N_INSNS (1),            /* fp_mult */
174   COSTS_N_INSNS (1),            /* fp_div_sf */
175   COSTS_N_INSNS (1) + 1,        /* fp_div_df */
176   COSTS_N_INSNS (1) + 1,        /* int_mult_si */
177   COSTS_N_INSNS (1) + 2,        /* int_mult_di */
178   COSTS_N_INSNS (1),            /* int_shift */
179   COSTS_N_INSNS (1),            /* int_cmov */
180   COSTS_N_INSNS (6),            /* int_div */
181 };
182
183 /* Get the number of args of a function in one of two ways.  */
184 #if TARGET_ABI_OPEN_VMS
185 #define NUM_ARGS crtl->args.info.num_args
186 #else
187 #define NUM_ARGS crtl->args.info
188 #endif
189
190 #define REG_PV 27
191 #define REG_RA 26
192
193 /* Declarations of static functions.  */
194 static struct machine_function *alpha_init_machine_status (void);
195 static rtx alpha_emit_xfloating_compare (enum rtx_code *, rtx, rtx);
196
197 #if TARGET_ABI_OPEN_VMS
198 static void alpha_write_linkage (FILE *, const char *, tree);
199 static bool vms_valid_pointer_mode (enum machine_mode);
200 #endif
201 \f
202 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
203 static const struct default_options alpha_option_optimization_table[] =
204   {
205     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
206     { OPT_LEVELS_NONE, 0, NULL, 0 }
207   };
208
209 /* Implement TARGET_HANDLE_OPTION.  */
210
211 static bool
212 alpha_handle_option (struct gcc_options *opts,
213                      struct gcc_options *opts_set ATTRIBUTE_UNUSED,
214                      const struct cl_decoded_option *decoded,
215                      location_t loc)
216 {
217   size_t code = decoded->opt_index;
218   const char *arg = decoded->arg;
219   int value = decoded->value;
220
221   switch (code)
222     {
223     case OPT_mfp_regs:
224       if (value == 0)
225         opts->x_target_flags |= MASK_SOFT_FP;
226       break;
227
228     case OPT_mieee:
229     case OPT_mieee_with_inexact:
230       opts->x_target_flags |= MASK_IEEE_CONFORMANT;
231       break;
232
233     case OPT_mtls_size_:
234       if (value != 16 && value != 32 && value != 64)
235         error_at (loc, "bad value %qs for -mtls-size switch", arg);
236       break;
237     }
238
239   return true;
240 }
241
242 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
243 /* Implement TARGET_MANGLE_TYPE.  */
244
245 static const char *
246 alpha_mangle_type (const_tree type)
247 {
248   if (TYPE_MAIN_VARIANT (type) == long_double_type_node
249       && TARGET_LONG_DOUBLE_128)
250     return "g";
251
252   /* For all other types, use normal C++ mangling.  */
253   return NULL;
254 }
255 #endif
256
257 /* Parse target option strings.  */
258
259 static void
260 alpha_option_override (void)
261 {
262   static const struct cpu_table {
263     const char *const name;
264     const enum processor_type processor;
265     const int flags;
266   } cpu_table[] = {
267     { "ev4",    PROCESSOR_EV4, 0 },
268     { "ev45",   PROCESSOR_EV4, 0 },
269     { "21064",  PROCESSOR_EV4, 0 },
270     { "ev5",    PROCESSOR_EV5, 0 },
271     { "21164",  PROCESSOR_EV5, 0 },
272     { "ev56",   PROCESSOR_EV5, MASK_BWX },
273     { "21164a", PROCESSOR_EV5, MASK_BWX },
274     { "pca56",  PROCESSOR_EV5, MASK_BWX|MASK_MAX },
275     { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
276     { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX },
277     { "ev6",    PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
278     { "21264",  PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX },
279     { "ev67",   PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX },
280     { "21264a", PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX }
281   };
282
283   int const ct_size = ARRAY_SIZE (cpu_table);
284   int i;
285
286 #ifdef SUBTARGET_OVERRIDE_OPTIONS
287   SUBTARGET_OVERRIDE_OPTIONS;
288 #endif
289
290   alpha_fprm = ALPHA_FPRM_NORM;
291   alpha_tp = ALPHA_TP_PROG;
292   alpha_fptm = ALPHA_FPTM_N;
293
294   if (TARGET_IEEE)
295     {
296       alpha_tp = ALPHA_TP_INSN;
297       alpha_fptm = ALPHA_FPTM_SU;
298     }
299   if (TARGET_IEEE_WITH_INEXACT)
300     {
301       alpha_tp = ALPHA_TP_INSN;
302       alpha_fptm = ALPHA_FPTM_SUI;
303     }
304
305   if (alpha_tp_string)
306     {
307       if (! strcmp (alpha_tp_string, "p"))
308         alpha_tp = ALPHA_TP_PROG;
309       else if (! strcmp (alpha_tp_string, "f"))
310         alpha_tp = ALPHA_TP_FUNC;
311       else if (! strcmp (alpha_tp_string, "i"))
312         alpha_tp = ALPHA_TP_INSN;
313       else
314         error ("bad value %qs for -mtrap-precision switch", alpha_tp_string);
315     }
316
317   if (alpha_fprm_string)
318     {
319       if (! strcmp (alpha_fprm_string, "n"))
320         alpha_fprm = ALPHA_FPRM_NORM;
321       else if (! strcmp (alpha_fprm_string, "m"))
322         alpha_fprm = ALPHA_FPRM_MINF;
323       else if (! strcmp (alpha_fprm_string, "c"))
324         alpha_fprm = ALPHA_FPRM_CHOP;
325       else if (! strcmp (alpha_fprm_string,"d"))
326         alpha_fprm = ALPHA_FPRM_DYN;
327       else
328         error ("bad value %qs for -mfp-rounding-mode switch",
329                alpha_fprm_string);
330     }
331
332   if (alpha_fptm_string)
333     {
334       if (strcmp (alpha_fptm_string, "n") == 0)
335         alpha_fptm = ALPHA_FPTM_N;
336       else if (strcmp (alpha_fptm_string, "u") == 0)
337         alpha_fptm = ALPHA_FPTM_U;
338       else if (strcmp (alpha_fptm_string, "su") == 0)
339         alpha_fptm = ALPHA_FPTM_SU;
340       else if (strcmp (alpha_fptm_string, "sui") == 0)
341         alpha_fptm = ALPHA_FPTM_SUI;
342       else
343         error ("bad value %qs for -mfp-trap-mode switch", alpha_fptm_string);
344     }
345
346   if (alpha_cpu_string)
347     {
348       for (i = 0; i < ct_size; i++)
349         if (! strcmp (alpha_cpu_string, cpu_table [i].name))
350           {
351             alpha_tune = alpha_cpu = cpu_table [i].processor;
352             target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
353             target_flags |= cpu_table [i].flags;
354             break;
355           }
356       if (i == ct_size)
357         error ("bad value %qs for -mcpu switch", alpha_cpu_string);
358     }
359
360   if (alpha_tune_string)
361     {
362       for (i = 0; i < ct_size; i++)
363         if (! strcmp (alpha_tune_string, cpu_table [i].name))
364           {
365             alpha_tune = cpu_table [i].processor;
366             break;
367           }
368       if (i == ct_size)
369         error ("bad value %qs for -mtune switch", alpha_tune_string);
370     }
371
372   /* Do some sanity checks on the above options.  */
373
374   if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
375       && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
376     {
377       warning (0, "fp software completion requires -mtrap-precision=i");
378       alpha_tp = ALPHA_TP_INSN;
379     }
380
381   if (alpha_cpu == PROCESSOR_EV6)
382     {
383       /* Except for EV6 pass 1 (not released), we always have precise
384          arithmetic traps.  Which means we can do software completion
385          without minding trap shadows.  */
386       alpha_tp = ALPHA_TP_PROG;
387     }
388
389   if (TARGET_FLOAT_VAX)
390     {
391       if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
392         {
393           warning (0, "rounding mode not supported for VAX floats");
394           alpha_fprm = ALPHA_FPRM_NORM;
395         }
396       if (alpha_fptm == ALPHA_FPTM_SUI)
397         {
398           warning (0, "trap mode not supported for VAX floats");
399           alpha_fptm = ALPHA_FPTM_SU;
400         }
401       if (target_flags_explicit & MASK_LONG_DOUBLE_128)
402         warning (0, "128-bit long double not supported for VAX floats");
403       target_flags &= ~MASK_LONG_DOUBLE_128;
404     }
405
406   {
407     char *end;
408     int lat;
409
410     if (!alpha_mlat_string)
411       alpha_mlat_string = "L1";
412
413     if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
414         && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
415       ;
416     else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
417              && ISDIGIT ((unsigned char)alpha_mlat_string[1])
418              && alpha_mlat_string[2] == '\0')
419       {
420         static int const cache_latency[][4] =
421         {
422           { 3, 30, -1 },        /* ev4 -- Bcache is a guess */
423           { 2, 12, 38 },        /* ev5 -- Bcache from PC164 LMbench numbers */
424           { 3, 12, 30 },        /* ev6 -- Bcache from DS20 LMbench.  */
425         };
426
427         lat = alpha_mlat_string[1] - '0';
428         if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1)
429           {
430             warning (0, "L%d cache latency unknown for %s",
431                      lat, alpha_cpu_name[alpha_tune]);
432             lat = 3;
433           }
434         else
435           lat = cache_latency[alpha_tune][lat-1];
436       }
437     else if (! strcmp (alpha_mlat_string, "main"))
438       {
439         /* Most current memories have about 370ns latency.  This is
440            a reasonable guess for a fast cpu.  */
441         lat = 150;
442       }
443     else
444       {
445         warning (0, "bad value %qs for -mmemory-latency", alpha_mlat_string);
446         lat = 3;
447       }
448
449     alpha_memory_latency = lat;
450   }
451
452   /* Default the definition of "small data" to 8 bytes.  */
453   if (!global_options_set.x_g_switch_value)
454     g_switch_value = 8;
455
456   /* Infer TARGET_SMALL_DATA from -fpic/-fPIC.  */
457   if (flag_pic == 1)
458     target_flags |= MASK_SMALL_DATA;
459   else if (flag_pic == 2)
460     target_flags &= ~MASK_SMALL_DATA;
461
462   /* Align labels and loops for optimal branching.  */
463   /* ??? Kludge these by not doing anything if we don't optimize and also if
464      we are writing ECOFF symbols to work around a bug in DEC's assembler.  */
465   if (optimize > 0 && write_symbols != SDB_DEBUG)
466     {
467       if (align_loops <= 0)
468         align_loops = 16;
469       if (align_jumps <= 0)
470         align_jumps = 16;
471     }
472   if (align_functions <= 0)
473     align_functions = 16;
474
475   /* Register variables and functions with the garbage collector.  */
476
477   /* Set up function hooks.  */
478   init_machine_status = alpha_init_machine_status;
479
480   /* Tell the compiler when we're using VAX floating point.  */
481   if (TARGET_FLOAT_VAX)
482     {
483       REAL_MODE_FORMAT (SFmode) = &vax_f_format;
484       REAL_MODE_FORMAT (DFmode) = &vax_g_format;
485       REAL_MODE_FORMAT (TFmode) = NULL;
486     }
487
488 #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
489   if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
490     target_flags |= MASK_LONG_DOUBLE_128;
491 #endif
492 }
493 \f
494 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
495
496 int
497 zap_mask (HOST_WIDE_INT value)
498 {
499   int i;
500
501   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
502        i++, value >>= 8)
503     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
504       return 0;
505
506   return 1;
507 }
508
509 /* Return true if OP is valid for a particular TLS relocation.
510    We are already guaranteed that OP is a CONST.  */
511
512 int
513 tls_symbolic_operand_1 (rtx op, int size, int unspec)
514 {
515   op = XEXP (op, 0);
516
517   if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
518     return 0;
519   op = XVECEXP (op, 0, 0);
520
521   if (GET_CODE (op) != SYMBOL_REF)
522     return 0;
523
524   switch (SYMBOL_REF_TLS_MODEL (op))
525     {
526     case TLS_MODEL_LOCAL_DYNAMIC:
527       return unspec == UNSPEC_DTPREL && size == alpha_tls_size;
528     case TLS_MODEL_INITIAL_EXEC:
529       return unspec == UNSPEC_TPREL && size == 64;
530     case TLS_MODEL_LOCAL_EXEC:
531       return unspec == UNSPEC_TPREL && size == alpha_tls_size;
532     default:
533       gcc_unreachable ();
534     }
535 }
536
537 /* Used by aligned_memory_operand and unaligned_memory_operand to
538    resolve what reload is going to do with OP if it's a register.  */
539
540 rtx
541 resolve_reload_operand (rtx op)
542 {
543   if (reload_in_progress)
544     {
545       rtx tmp = op;
546       if (GET_CODE (tmp) == SUBREG)
547         tmp = SUBREG_REG (tmp);
548       if (REG_P (tmp)
549           && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
550         {
551           op = reg_equiv_memory_loc (REGNO (tmp));
552           if (op == 0)
553             return 0;
554         }
555     }
556   return op;
557 }
558
559 /* The scalar modes supported differs from the default check-what-c-supports
560    version in that sometimes TFmode is available even when long double
561    indicates only DFmode.  */
562
563 static bool
564 alpha_scalar_mode_supported_p (enum machine_mode mode)
565 {
566   switch (mode)
567     {
568     case QImode:
569     case HImode:
570     case SImode:
571     case DImode:
572     case TImode: /* via optabs.c */
573       return true;
574
575     case SFmode:
576     case DFmode:
577       return true;
578
579     case TFmode:
580       return TARGET_HAS_XFLOATING_LIBS;
581
582     default:
583       return false;
584     }
585 }
586
587 /* Alpha implements a couple of integer vector mode operations when
588    TARGET_MAX is enabled.  We do not check TARGET_MAX here, however,
589    which allows the vectorizer to operate on e.g. move instructions,
590    or when expand_vector_operations can do something useful.  */
591
592 static bool
593 alpha_vector_mode_supported_p (enum machine_mode mode)
594 {
595   return mode == V8QImode || mode == V4HImode || mode == V2SImode;
596 }
597
598 /* Return 1 if this function can directly return via $26.  */
599
600 int
601 direct_return (void)
602 {
603   return (TARGET_ABI_OSF
604           && reload_completed
605           && alpha_sa_size () == 0
606           && get_frame_size () == 0
607           && crtl->outgoing_args_size == 0
608           && crtl->args.pretend_args_size == 0);
609 }
610
611 /* Return the ADDR_VEC associated with a tablejump insn.  */
612
613 rtx
614 alpha_tablejump_addr_vec (rtx insn)
615 {
616   rtx tmp;
617
618   tmp = JUMP_LABEL (insn);
619   if (!tmp)
620     return NULL_RTX;
621   tmp = NEXT_INSN (tmp);
622   if (!tmp)
623     return NULL_RTX;
624   if (JUMP_P (tmp)
625       && GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC)
626     return PATTERN (tmp);
627   return NULL_RTX;
628 }
629
630 /* Return the label of the predicted edge, or CONST0_RTX if we don't know.  */
631
632 rtx
633 alpha_tablejump_best_label (rtx insn)
634 {
635   rtx jump_table = alpha_tablejump_addr_vec (insn);
636   rtx best_label = NULL_RTX;
637
638   /* ??? Once the CFG doesn't keep getting completely rebuilt, look
639      there for edge frequency counts from profile data.  */
640
641   if (jump_table)
642     {
643       int n_labels = XVECLEN (jump_table, 1);
644       int best_count = -1;
645       int i, j;
646
647       for (i = 0; i < n_labels; i++)
648         {
649           int count = 1;
650
651           for (j = i + 1; j < n_labels; j++)
652             if (XEXP (XVECEXP (jump_table, 1, i), 0)
653                 == XEXP (XVECEXP (jump_table, 1, j), 0))
654               count++;
655
656           if (count > best_count)
657             best_count = count, best_label = XVECEXP (jump_table, 1, i);
658         }
659     }
660
661   return best_label ? best_label : const0_rtx;
662 }
663
664 /* Return the TLS model to use for SYMBOL.  */
665
666 static enum tls_model
667 tls_symbolic_operand_type (rtx symbol)
668 {
669   enum tls_model model;
670
671   if (GET_CODE (symbol) != SYMBOL_REF)
672     return TLS_MODEL_NONE;
673   model = SYMBOL_REF_TLS_MODEL (symbol);
674
675   /* Local-exec with a 64-bit size is the same code as initial-exec.  */
676   if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
677     model = TLS_MODEL_INITIAL_EXEC;
678
679   return model;
680 }
681 \f
682 /* Return true if the function DECL will share the same GP as any
683    function in the current unit of translation.  */
684
685 static bool
686 decl_has_samegp (const_tree decl)
687 {
688   /* Functions that are not local can be overridden, and thus may
689      not share the same gp.  */
690   if (!(*targetm.binds_local_p) (decl))
691     return false;
692
693   /* If -msmall-data is in effect, assume that there is only one GP
694      for the module, and so any local symbol has this property.  We
695      need explicit relocations to be able to enforce this for symbols
696      not defined in this unit of translation, however.  */
697   if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
698     return true;
699
700   /* Functions that are not external are defined in this UoT.  */
701   /* ??? Irritatingly, static functions not yet emitted are still
702      marked "external".  Apply this to non-static functions only.  */
703   return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
704 }
705
706 /* Return true if EXP should be placed in the small data section.  */
707
708 static bool
709 alpha_in_small_data_p (const_tree exp)
710 {
711   /* We want to merge strings, so we never consider them small data.  */
712   if (TREE_CODE (exp) == STRING_CST)
713     return false;
714
715   /* Functions are never in the small data area.  Duh.  */
716   if (TREE_CODE (exp) == FUNCTION_DECL)
717     return false;
718
719   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
720     {
721       const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
722       if (strcmp (section, ".sdata") == 0
723           || strcmp (section, ".sbss") == 0)
724         return true;
725     }
726   else
727     {
728       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
729
730       /* If this is an incomplete type with size 0, then we can't put it
731          in sdata because it might be too big when completed.  */
732       if (size > 0 && size <= g_switch_value)
733         return true;
734     }
735
736   return false;
737 }
738
739 #if TARGET_ABI_OPEN_VMS
740 static bool
741 vms_valid_pointer_mode (enum machine_mode mode)
742 {
743   return (mode == SImode || mode == DImode);
744 }
745
746 static bool
747 alpha_linkage_symbol_p (const char *symname)
748 {
749   int symlen = strlen (symname);
750
751   if (symlen > 4)
752     return strcmp (&symname [symlen - 4], "..lk") == 0;
753
754   return false;
755 }
756
757 #define LINKAGE_SYMBOL_REF_P(X) \
758   ((GET_CODE (X) == SYMBOL_REF   \
759     && alpha_linkage_symbol_p (XSTR (X, 0))) \
760    || (GET_CODE (X) == CONST                 \
761        && GET_CODE (XEXP (X, 0)) == PLUS     \
762        && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
763        && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
764 #endif
765
766 /* legitimate_address_p recognizes an RTL expression that is a valid
767    memory address for an instruction.  The MODE argument is the
768    machine mode for the MEM expression that wants to use this address.
769
770    For Alpha, we have either a constant address or the sum of a
771    register and a constant address, or just a register.  For DImode,
772    any of those forms can be surrounded with an AND that clear the
773    low-order three bits; this is an "unaligned" access.  */
774
775 static bool
776 alpha_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
777 {
778   /* If this is an ldq_u type address, discard the outer AND.  */
779   if (mode == DImode
780       && GET_CODE (x) == AND
781       && CONST_INT_P (XEXP (x, 1))
782       && INTVAL (XEXP (x, 1)) == -8)
783     x = XEXP (x, 0);
784
785   /* Discard non-paradoxical subregs.  */
786   if (GET_CODE (x) == SUBREG
787       && (GET_MODE_SIZE (GET_MODE (x))
788           < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
789     x = SUBREG_REG (x);
790
791   /* Unadorned general registers are valid.  */
792   if (REG_P (x)
793       && (strict
794           ? STRICT_REG_OK_FOR_BASE_P (x)
795           : NONSTRICT_REG_OK_FOR_BASE_P (x)))
796     return true;
797
798   /* Constant addresses (i.e. +/- 32k) are valid.  */
799   if (CONSTANT_ADDRESS_P (x))
800     return true;
801
802 #if TARGET_ABI_OPEN_VMS
803   if (LINKAGE_SYMBOL_REF_P (x))
804     return true;
805 #endif
806
807   /* Register plus a small constant offset is valid.  */
808   if (GET_CODE (x) == PLUS)
809     {
810       rtx ofs = XEXP (x, 1);
811       x = XEXP (x, 0);
812
813       /* Discard non-paradoxical subregs.  */
814       if (GET_CODE (x) == SUBREG
815           && (GET_MODE_SIZE (GET_MODE (x))
816               < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
817         x = SUBREG_REG (x);
818
819       if (REG_P (x))
820         {
821           if (! strict
822               && NONSTRICT_REG_OK_FP_BASE_P (x)
823               && CONST_INT_P (ofs))
824             return true;
825           if ((strict
826                ? STRICT_REG_OK_FOR_BASE_P (x)
827                : NONSTRICT_REG_OK_FOR_BASE_P (x))
828               && CONSTANT_ADDRESS_P (ofs))
829             return true;
830         }
831     }
832
833   /* If we're managing explicit relocations, LO_SUM is valid, as are small
834      data symbols.  Avoid explicit relocations of modes larger than word
835      mode since i.e. $LC0+8($1) can fold around +/- 32k offset.  */
836   else if (TARGET_EXPLICIT_RELOCS
837            && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
838     {
839       if (small_symbolic_operand (x, Pmode))
840         return true;
841
842       if (GET_CODE (x) == LO_SUM)
843         {
844           rtx ofs = XEXP (x, 1);
845           x = XEXP (x, 0);
846
847           /* Discard non-paradoxical subregs.  */
848           if (GET_CODE (x) == SUBREG
849               && (GET_MODE_SIZE (GET_MODE (x))
850                   < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
851             x = SUBREG_REG (x);
852
853           /* Must have a valid base register.  */
854           if (! (REG_P (x)
855                  && (strict
856                      ? STRICT_REG_OK_FOR_BASE_P (x)
857                      : NONSTRICT_REG_OK_FOR_BASE_P (x))))
858             return false;
859
860           /* The symbol must be local.  */
861           if (local_symbolic_operand (ofs, Pmode)
862               || dtp32_symbolic_operand (ofs, Pmode)
863               || tp32_symbolic_operand (ofs, Pmode))
864             return true;
865         }
866     }
867
868   return false;
869 }
870
871 /* Build the SYMBOL_REF for __tls_get_addr.  */
872
873 static GTY(()) rtx tls_get_addr_libfunc;
874
875 static rtx
876 get_tls_get_addr (void)
877 {
878   if (!tls_get_addr_libfunc)
879     tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
880   return tls_get_addr_libfunc;
881 }
882
883 /* Try machine-dependent ways of modifying an illegitimate address
884    to be legitimate.  If we find one, return the new, valid address.  */
885
886 static rtx
887 alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
888 {
889   HOST_WIDE_INT addend;
890
891   /* If the address is (plus reg const_int) and the CONST_INT is not a
892      valid offset, compute the high part of the constant and add it to
893      the register.  Then our address is (plus temp low-part-const).  */
894   if (GET_CODE (x) == PLUS
895       && REG_P (XEXP (x, 0))
896       && CONST_INT_P (XEXP (x, 1))
897       && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
898     {
899       addend = INTVAL (XEXP (x, 1));
900       x = XEXP (x, 0);
901       goto split_addend;
902     }
903
904   /* If the address is (const (plus FOO const_int)), find the low-order
905      part of the CONST_INT.  Then load FOO plus any high-order part of the
906      CONST_INT into a register.  Our address is (plus reg low-part-const).
907      This is done to reduce the number of GOT entries.  */
908   if (can_create_pseudo_p ()
909       && GET_CODE (x) == CONST
910       && GET_CODE (XEXP (x, 0)) == PLUS
911       && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
912     {
913       addend = INTVAL (XEXP (XEXP (x, 0), 1));
914       x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
915       goto split_addend;
916     }
917
918   /* If we have a (plus reg const), emit the load as in (2), then add
919      the two registers, and finally generate (plus reg low-part-const) as
920      our address.  */
921   if (can_create_pseudo_p ()
922       && GET_CODE (x) == PLUS
923       && REG_P (XEXP (x, 0))
924       && GET_CODE (XEXP (x, 1)) == CONST
925       && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
926       && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1)))
927     {
928       addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
929       x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
930                                XEXP (XEXP (XEXP (x, 1), 0), 0),
931                                NULL_RTX, 1, OPTAB_LIB_WIDEN);
932       goto split_addend;
933     }
934
935   /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
936      Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
937      around +/- 32k offset.  */
938   if (TARGET_EXPLICIT_RELOCS
939       && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
940       && symbolic_operand (x, Pmode))
941     {
942       rtx r0, r16, eqv, tga, tp, insn, dest, seq;
943
944       switch (tls_symbolic_operand_type (x))
945         {
946         case TLS_MODEL_NONE:
947           break;
948
949         case TLS_MODEL_GLOBAL_DYNAMIC:
950           start_sequence ();
951
952           r0 = gen_rtx_REG (Pmode, 0);
953           r16 = gen_rtx_REG (Pmode, 16);
954           tga = get_tls_get_addr ();
955           dest = gen_reg_rtx (Pmode);
956           seq = GEN_INT (alpha_next_sequence_number++);
957
958           emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
959           insn = gen_call_value_osf_tlsgd (r0, tga, seq);
960           insn = emit_call_insn (insn);
961           RTL_CONST_CALL_P (insn) = 1;
962           use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
963
964           insn = get_insns ();
965           end_sequence ();
966
967           emit_libcall_block (insn, dest, r0, x);
968           return dest;
969
970         case TLS_MODEL_LOCAL_DYNAMIC:
971           start_sequence ();
972
973           r0 = gen_rtx_REG (Pmode, 0);
974           r16 = gen_rtx_REG (Pmode, 16);
975           tga = get_tls_get_addr ();
976           scratch = gen_reg_rtx (Pmode);
977           seq = GEN_INT (alpha_next_sequence_number++);
978
979           emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
980           insn = gen_call_value_osf_tlsldm (r0, tga, seq);
981           insn = emit_call_insn (insn);
982           RTL_CONST_CALL_P (insn) = 1;
983           use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
984
985           insn = get_insns ();
986           end_sequence ();
987
988           eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
989                                 UNSPEC_TLSLDM_CALL);
990           emit_libcall_block (insn, scratch, r0, eqv);
991
992           eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
993           eqv = gen_rtx_CONST (Pmode, eqv);
994
995           if (alpha_tls_size == 64)
996             {
997               dest = gen_reg_rtx (Pmode);
998               emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
999               emit_insn (gen_adddi3 (dest, dest, scratch));
1000               return dest;
1001             }
1002           if (alpha_tls_size == 32)
1003             {
1004               insn = gen_rtx_HIGH (Pmode, eqv);
1005               insn = gen_rtx_PLUS (Pmode, scratch, insn);
1006               scratch = gen_reg_rtx (Pmode);
1007               emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
1008             }
1009           return gen_rtx_LO_SUM (Pmode, scratch, eqv);
1010
1011         case TLS_MODEL_INITIAL_EXEC:
1012           eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1013           eqv = gen_rtx_CONST (Pmode, eqv);
1014           tp = gen_reg_rtx (Pmode);
1015           scratch = gen_reg_rtx (Pmode);
1016           dest = gen_reg_rtx (Pmode);
1017
1018           emit_insn (gen_load_tp (tp));
1019           emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
1020           emit_insn (gen_adddi3 (dest, tp, scratch));
1021           return dest;
1022
1023         case TLS_MODEL_LOCAL_EXEC:
1024           eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
1025           eqv = gen_rtx_CONST (Pmode, eqv);
1026           tp = gen_reg_rtx (Pmode);
1027
1028           emit_insn (gen_load_tp (tp));
1029           if (alpha_tls_size == 32)
1030             {
1031               insn = gen_rtx_HIGH (Pmode, eqv);
1032               insn = gen_rtx_PLUS (Pmode, tp, insn);
1033               tp = gen_reg_rtx (Pmode);
1034               emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
1035             }
1036           return gen_rtx_LO_SUM (Pmode, tp, eqv);
1037
1038         default:
1039           gcc_unreachable ();
1040         }
1041
1042       if (local_symbolic_operand (x, Pmode))
1043         {
1044           if (small_symbolic_operand (x, Pmode))
1045             return x;
1046           else
1047             {
1048               if (can_create_pseudo_p ())
1049                 scratch = gen_reg_rtx (Pmode);
1050               emit_insn (gen_rtx_SET (VOIDmode, scratch,
1051                                       gen_rtx_HIGH (Pmode, x)));
1052               return gen_rtx_LO_SUM (Pmode, scratch, x);
1053             }
1054         }
1055     }
1056
1057   return NULL;
1058
1059  split_addend:
1060   {
1061     HOST_WIDE_INT low, high;
1062
1063     low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
1064     addend -= low;
1065     high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
1066     addend -= high;
1067
1068     if (addend)
1069       x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
1070                                (!can_create_pseudo_p () ? scratch : NULL_RTX),
1071                                1, OPTAB_LIB_WIDEN);
1072     if (high)
1073       x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
1074                                (!can_create_pseudo_p () ? scratch : NULL_RTX),
1075                                1, OPTAB_LIB_WIDEN);
1076
1077     return plus_constant (x, low);
1078   }
1079 }
1080
1081
1082 /* Try machine-dependent ways of modifying an illegitimate address
1083    to be legitimate.  Return X or the new, valid address.  */
1084
1085 static rtx
1086 alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
1087                           enum machine_mode mode)
1088 {
1089   rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode);
1090   return new_x ? new_x : x;
1091 }
1092
1093 /* Primarily this is required for TLS symbols, but given that our move
1094    patterns *ought* to be able to handle any symbol at any time, we
1095    should never be spilling symbolic operands to the constant pool, ever.  */
1096
1097 static bool
1098 alpha_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1099 {
1100   enum rtx_code code = GET_CODE (x);
1101   return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
1102 }
1103
1104 /* We do not allow indirect calls to be optimized into sibling calls, nor
1105    can we allow a call to a function with a different GP to be optimized
1106    into a sibcall.  */
1107
1108 static bool
1109 alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
1110 {
1111   /* Can't do indirect tail calls, since we don't know if the target
1112      uses the same GP.  */
1113   if (!decl)
1114     return false;
1115
1116   /* Otherwise, we can make a tail call if the target function shares
1117      the same GP.  */
1118   return decl_has_samegp (decl);
1119 }
1120
1121 int
1122 some_small_symbolic_operand_int (rtx *px, void *data ATTRIBUTE_UNUSED)
1123 {
1124   rtx x = *px;
1125
1126   /* Don't re-split.  */
1127   if (GET_CODE (x) == LO_SUM)
1128     return -1;
1129
1130   return small_symbolic_operand (x, Pmode) != 0;
1131 }
1132
1133 static int
1134 split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
1135 {
1136   rtx x = *px;
1137
1138   /* Don't re-split.  */
1139   if (GET_CODE (x) == LO_SUM)
1140     return -1;
1141
1142   if (small_symbolic_operand (x, Pmode))
1143     {
1144       x = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
1145       *px = x;
1146       return -1;
1147     }
1148
1149   return 0;
1150 }
1151
1152 rtx
1153 split_small_symbolic_operand (rtx x)
1154 {
1155   x = copy_insn (x);
1156   for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
1157   return x;
1158 }
1159
1160 /* Indicate that INSN cannot be duplicated.  This is true for any insn
1161    that we've marked with gpdisp relocs, since those have to stay in
1162    1-1 correspondence with one another.
1163
1164    Technically we could copy them if we could set up a mapping from one
1165    sequence number to another, across the set of insns to be duplicated.
1166    This seems overly complicated and error-prone since interblock motion
1167    from sched-ebb could move one of the pair of insns to a different block.
1168
1169    Also cannot allow jsr insns to be duplicated.  If they throw exceptions,
1170    then they'll be in a different block from their ldgp.  Which could lead
1171    the bb reorder code to think that it would be ok to copy just the block
1172    containing the call and branch to the block containing the ldgp.  */
1173
1174 static bool
1175 alpha_cannot_copy_insn_p (rtx insn)
1176 {
1177   if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
1178     return false;
1179   if (recog_memoized (insn) >= 0)
1180     return get_attr_cannot_copy (insn);
1181   else
1182     return false;
1183 }
1184
1185
1186 /* Try a machine-dependent way of reloading an illegitimate address
1187    operand.  If we find one, push the reload and return the new rtx.  */
1188
1189 rtx
1190 alpha_legitimize_reload_address (rtx x,
1191                                  enum machine_mode mode ATTRIBUTE_UNUSED,
1192                                  int opnum, int type,
1193                                  int ind_levels ATTRIBUTE_UNUSED)
1194 {
1195   /* We must recognize output that we have already generated ourselves.  */
1196   if (GET_CODE (x) == PLUS
1197       && GET_CODE (XEXP (x, 0)) == PLUS
1198       && REG_P (XEXP (XEXP (x, 0), 0))
1199       && CONST_INT_P (XEXP (XEXP (x, 0), 1))
1200       && CONST_INT_P (XEXP (x, 1)))
1201     {
1202       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1203                    BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1204                    opnum, (enum reload_type) type);
1205       return x;
1206     }
1207
1208   /* We wish to handle large displacements off a base register by
1209      splitting the addend across an ldah and the mem insn.  This
1210      cuts number of extra insns needed from 3 to 1.  */
1211   if (GET_CODE (x) == PLUS
1212       && REG_P (XEXP (x, 0))
1213       && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
1214       && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
1215       && GET_CODE (XEXP (x, 1)) == CONST_INT)
1216     {
1217       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
1218       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1219       HOST_WIDE_INT high
1220         = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
1221
1222       /* Check for 32-bit overflow.  */
1223       if (high + low != val)
1224         return NULL_RTX;
1225
1226       /* Reload the high part into a base reg; leave the low part
1227          in the mem directly.  */
1228       x = gen_rtx_PLUS (GET_MODE (x),
1229                         gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
1230                                       GEN_INT (high)),
1231                         GEN_INT (low));
1232
1233       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
1234                    BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
1235                    opnum, (enum reload_type) type);
1236       return x;
1237     }
1238
1239   return NULL_RTX;
1240 }
1241 \f
1242 /* Compute a (partial) cost for rtx X.  Return true if the complete
1243    cost has been computed, and false if subexpressions should be
1244    scanned.  In either case, *TOTAL contains the cost result.  */
1245
1246 static bool
1247 alpha_rtx_costs (rtx x, int code, int outer_code, int *total,
1248                  bool speed)
1249 {
1250   enum machine_mode mode = GET_MODE (x);
1251   bool float_mode_p = FLOAT_MODE_P (mode);
1252   const struct alpha_rtx_cost_data *cost_data;
1253
1254   if (!speed)
1255     cost_data = &alpha_rtx_cost_size;
1256   else
1257     cost_data = &alpha_rtx_cost_data[alpha_tune];
1258
1259   switch (code)
1260     {
1261     case CONST_INT:
1262       /* If this is an 8-bit constant, return zero since it can be used
1263          nearly anywhere with no cost.  If it is a valid operand for an
1264          ADD or AND, likewise return 0 if we know it will be used in that
1265          context.  Otherwise, return 2 since it might be used there later.
1266          All other constants take at least two insns.  */
1267       if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1268         {
1269           *total = 0;
1270           return true;
1271         }
1272       /* FALLTHRU */
1273
1274     case CONST_DOUBLE:
1275       if (x == CONST0_RTX (mode))
1276         *total = 0;
1277       else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1278                || (outer_code == AND && and_operand (x, VOIDmode)))
1279         *total = 0;
1280       else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1281         *total = 2;
1282       else
1283         *total = COSTS_N_INSNS (2);
1284       return true;
1285
1286     case CONST:
1287     case SYMBOL_REF:
1288     case LABEL_REF:
1289       if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1290         *total = COSTS_N_INSNS (outer_code != MEM);
1291       else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1292         *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1293       else if (tls_symbolic_operand_type (x))
1294         /* Estimate of cost for call_pal rduniq.  */
1295         /* ??? How many insns do we emit here?  More than one...  */
1296         *total = COSTS_N_INSNS (15);
1297       else
1298         /* Otherwise we do a load from the GOT.  */
1299         *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
1300       return true;
1301
1302     case HIGH:
1303       /* This is effectively an add_operand.  */
1304       *total = 2;
1305       return true;
1306
1307     case PLUS:
1308     case MINUS:
1309       if (float_mode_p)
1310         *total = cost_data->fp_add;
1311       else if (GET_CODE (XEXP (x, 0)) == MULT
1312                && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1313         {
1314           *total = (rtx_cost (XEXP (XEXP (x, 0), 0),
1315                               (enum rtx_code) outer_code, speed)
1316                     + rtx_cost (XEXP (x, 1),
1317                                 (enum rtx_code) outer_code, speed)
1318                     + COSTS_N_INSNS (1));
1319           return true;
1320         }
1321       return false;
1322
1323     case MULT:
1324       if (float_mode_p)
1325         *total = cost_data->fp_mult;
1326       else if (mode == DImode)
1327         *total = cost_data->int_mult_di;
1328       else
1329         *total = cost_data->int_mult_si;
1330       return false;
1331
1332     case ASHIFT:
1333       if (CONST_INT_P (XEXP (x, 1))
1334           && INTVAL (XEXP (x, 1)) <= 3)
1335         {
1336           *total = COSTS_N_INSNS (1);
1337           return false;
1338         }
1339       /* FALLTHRU */
1340
1341     case ASHIFTRT:
1342     case LSHIFTRT:
1343       *total = cost_data->int_shift;
1344       return false;
1345
1346     case IF_THEN_ELSE:
1347       if (float_mode_p)
1348         *total = cost_data->fp_add;
1349       else
1350         *total = cost_data->int_cmov;
1351       return false;
1352
1353     case DIV:
1354     case UDIV:
1355     case MOD:
1356     case UMOD:
1357       if (!float_mode_p)
1358         *total = cost_data->int_div;
1359       else if (mode == SFmode)
1360         *total = cost_data->fp_div_sf;
1361       else
1362         *total = cost_data->fp_div_df;
1363       return false;
1364
1365     case MEM:
1366       *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
1367       return true;
1368
1369     case NEG:
1370       if (! float_mode_p)
1371         {
1372           *total = COSTS_N_INSNS (1);
1373           return false;
1374         }
1375       /* FALLTHRU */
1376
1377     case ABS:
1378       if (! float_mode_p)
1379         {
1380           *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1381           return false;
1382         }
1383       /* FALLTHRU */
1384
1385     case FLOAT:
1386     case UNSIGNED_FLOAT:
1387     case FIX:
1388     case UNSIGNED_FIX:
1389     case FLOAT_TRUNCATE:
1390       *total = cost_data->fp_add;
1391       return false;
1392
1393     case FLOAT_EXTEND:
1394       if (MEM_P (XEXP (x, 0)))
1395         *total = 0;
1396       else
1397         *total = cost_data->fp_add;
1398       return false;
1399
1400     default:
1401       return false;
1402     }
1403 }
1404 \f
1405 /* REF is an alignable memory location.  Place an aligned SImode
1406    reference into *PALIGNED_MEM and the number of bits to shift into
1407    *PBITNUM.  SCRATCH is a free register for use in reloading out
1408    of range stack slots.  */
1409
1410 void
1411 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1412 {
1413   rtx base;
1414   HOST_WIDE_INT disp, offset;
1415
1416   gcc_assert (MEM_P (ref));
1417
1418   if (reload_in_progress
1419       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1420     {
1421       base = find_replacement (&XEXP (ref, 0));
1422       gcc_assert (memory_address_p (GET_MODE (ref), base));
1423     }
1424   else
1425     base = XEXP (ref, 0);
1426
1427   if (GET_CODE (base) == PLUS)
1428     disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1429   else
1430     disp = 0;
1431
1432   /* Find the byte offset within an aligned word.  If the memory itself is
1433      claimed to be aligned, believe it.  Otherwise, aligned_memory_operand
1434      will have examined the base register and determined it is aligned, and
1435      thus displacements from it are naturally alignable.  */
1436   if (MEM_ALIGN (ref) >= 32)
1437     offset = 0;
1438   else
1439     offset = disp & 3;
1440
1441   /* The location should not cross aligned word boundary.  */
1442   gcc_assert (offset + GET_MODE_SIZE (GET_MODE (ref))
1443               <= GET_MODE_SIZE (SImode));
1444
1445   /* Access the entire aligned word.  */
1446   *paligned_mem = widen_memory_access (ref, SImode, -offset);
1447
1448   /* Convert the byte offset within the word to a bit offset.  */
1449   offset *= BITS_PER_UNIT;
1450   *pbitnum = GEN_INT (offset);
1451 }
1452
1453 /* Similar, but just get the address.  Handle the two reload cases.
1454    Add EXTRA_OFFSET to the address we return.  */
1455
1456 rtx
1457 get_unaligned_address (rtx ref)
1458 {
1459   rtx base;
1460   HOST_WIDE_INT offset = 0;
1461
1462   gcc_assert (MEM_P (ref));
1463
1464   if (reload_in_progress
1465       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1466     {
1467       base = find_replacement (&XEXP (ref, 0));
1468
1469       gcc_assert (memory_address_p (GET_MODE (ref), base));
1470     }
1471   else
1472     base = XEXP (ref, 0);
1473
1474   if (GET_CODE (base) == PLUS)
1475     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1476
1477   return plus_constant (base, offset);
1478 }
1479
1480 /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
1481    X is always returned in a register.  */
1482
1483 rtx
1484 get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
1485 {
1486   if (GET_CODE (addr) == PLUS)
1487     {
1488       ofs += INTVAL (XEXP (addr, 1));
1489       addr = XEXP (addr, 0);
1490     }
1491
1492   return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
1493                               NULL_RTX, 1, OPTAB_LIB_WIDEN);
1494 }
1495
1496 /* On the Alpha, all (non-symbolic) constants except zero go into
1497    a floating-point register via memory.  Note that we cannot
1498    return anything that is not a subset of RCLASS, and that some
1499    symbolic constants cannot be dropped to memory.  */
1500
1501 enum reg_class
1502 alpha_preferred_reload_class(rtx x, enum reg_class rclass)
1503 {
1504   /* Zero is present in any register class.  */
1505   if (x == CONST0_RTX (GET_MODE (x)))
1506     return rclass;
1507
1508   /* These sorts of constants we can easily drop to memory.  */
1509   if (CONST_INT_P (x)
1510       || GET_CODE (x) == CONST_DOUBLE
1511       || GET_CODE (x) == CONST_VECTOR)
1512     {
1513       if (rclass == FLOAT_REGS)
1514         return NO_REGS;
1515       if (rclass == ALL_REGS)
1516         return GENERAL_REGS;
1517       return rclass;
1518     }
1519
1520   /* All other kinds of constants should not (and in the case of HIGH
1521      cannot) be dropped to memory -- instead we use a GENERAL_REGS
1522      secondary reload.  */
1523   if (CONSTANT_P (x))
1524     return (rclass == ALL_REGS ? GENERAL_REGS : rclass);
1525
1526   return rclass;
1527 }
1528
1529 /* Inform reload about cases where moving X with a mode MODE to a register in
1530    RCLASS requires an extra scratch or immediate register.  Return the class
1531    needed for the immediate register.  */
1532
1533 static reg_class_t
1534 alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
1535                         enum machine_mode mode, secondary_reload_info *sri)
1536 {
1537   enum reg_class rclass = (enum reg_class) rclass_i;
1538
1539   /* Loading and storing HImode or QImode values to and from memory
1540      usually requires a scratch register.  */
1541   if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode))
1542     {
1543       if (any_memory_operand (x, mode))
1544         {
1545           if (in_p)
1546             {
1547               if (!aligned_memory_operand (x, mode))
1548                 sri->icode = direct_optab_handler (reload_in_optab, mode);
1549             }
1550           else
1551             sri->icode = direct_optab_handler (reload_out_optab, mode);
1552           return NO_REGS;
1553         }
1554     }
1555
1556   /* We also cannot do integral arithmetic into FP regs, as might result
1557      from register elimination into a DImode fp register.  */
1558   if (rclass == FLOAT_REGS)
1559     {
1560       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
1561         return GENERAL_REGS;
1562       if (in_p && INTEGRAL_MODE_P (mode)
1563           && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x))
1564         return GENERAL_REGS;
1565     }
1566
1567   return NO_REGS;
1568 }
1569 \f
1570 /* Subfunction of the following function.  Update the flags of any MEM
1571    found in part of X.  */
1572
1573 static int
1574 alpha_set_memflags_1 (rtx *xp, void *data)
1575 {
1576   rtx x = *xp, orig = (rtx) data;
1577
1578   if (!MEM_P (x))
1579     return 0;
1580
1581   MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1582   MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1583   MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1584   MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1585   MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1586
1587   /* Sadly, we cannot use alias sets because the extra aliasing
1588      produced by the AND interferes.  Given that two-byte quantities
1589      are the only thing we would be able to differentiate anyway,
1590      there does not seem to be any point in convoluting the early
1591      out of the alias check.  */
1592
1593   return -1;
1594 }
1595
1596 /* Given SEQ, which is an INSN list, look for any MEMs in either
1597    a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
1598    volatile flags from REF into each of the MEMs found.  If REF is not
1599    a MEM, don't do anything.  */
1600
1601 void
1602 alpha_set_memflags (rtx seq, rtx ref)
1603 {
1604   rtx insn;
1605
1606   if (!MEM_P (ref))
1607     return;
1608
1609   /* This is only called from alpha.md, after having had something
1610      generated from one of the insn patterns.  So if everything is
1611      zero, the pattern is already up-to-date.  */
1612   if (!MEM_VOLATILE_P (ref)
1613       && !MEM_IN_STRUCT_P (ref)
1614       && !MEM_SCALAR_P (ref)
1615       && !MEM_NOTRAP_P (ref)
1616       && !MEM_READONLY_P (ref))
1617     return;
1618
1619   for (insn = seq; insn; insn = NEXT_INSN (insn))
1620     if (INSN_P (insn))
1621       for_each_rtx (&PATTERN (insn), alpha_set_memflags_1, (void *) ref);
1622     else
1623       gcc_unreachable ();
1624 }
1625 \f
1626 static rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT,
1627                                  int, bool);
1628
1629 /* Internal routine for alpha_emit_set_const to check for N or below insns.
1630    If NO_OUTPUT is true, then we only check to see if N insns are possible,
1631    and return pc_rtx if successful.  */
1632
1633 static rtx
1634 alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
1635                         HOST_WIDE_INT c, int n, bool no_output)
1636 {
1637   HOST_WIDE_INT new_const;
1638   int i, bits;
1639   /* Use a pseudo if highly optimizing and still generating RTL.  */
1640   rtx subtarget
1641     = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target);
1642   rtx temp, insn;
1643
1644   /* If this is a sign-extended 32-bit constant, we can do this in at most
1645      three insns, so do it if we have enough insns left.  We always have
1646      a sign-extended 32-bit constant when compiling on a narrow machine.  */
1647
1648   if (HOST_BITS_PER_WIDE_INT != 64
1649       || c >> 31 == -1 || c >> 31 == 0)
1650     {
1651       HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
1652       HOST_WIDE_INT tmp1 = c - low;
1653       HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
1654       HOST_WIDE_INT extra = 0;
1655
1656       /* If HIGH will be interpreted as negative but the constant is
1657          positive, we must adjust it to do two ldha insns.  */
1658
1659       if ((high & 0x8000) != 0 && c >= 0)
1660         {
1661           extra = 0x4000;
1662           tmp1 -= 0x40000000;
1663           high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
1664         }
1665
1666       if (c == low || (low == 0 && extra == 0))
1667         {
1668           /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
1669              but that meant that we can't handle INT_MIN on 32-bit machines
1670              (like NT/Alpha), because we recurse indefinitely through
1671              emit_move_insn to gen_movdi.  So instead, since we know exactly
1672              what we want, create it explicitly.  */
1673
1674           if (no_output)
1675             return pc_rtx;
1676           if (target == NULL)
1677             target = gen_reg_rtx (mode);
1678           emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (c)));
1679           return target;
1680         }
1681       else if (n >= 2 + (extra != 0))
1682         {
1683           if (no_output)
1684             return pc_rtx;
1685           if (!can_create_pseudo_p ())
1686             {
1687               emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
1688               temp = target;
1689             }
1690           else
1691             temp = copy_to_suggested_reg (GEN_INT (high << 16),
1692                                           subtarget, mode);
1693
1694           /* As of 2002-02-23, addsi3 is only available when not optimizing.
1695              This means that if we go through expand_binop, we'll try to
1696              generate extensions, etc, which will require new pseudos, which
1697              will fail during some split phases.  The SImode add patterns
1698              still exist, but are not named.  So build the insns by hand.  */
1699
1700           if (extra != 0)
1701             {
1702               if (! subtarget)
1703                 subtarget = gen_reg_rtx (mode);
1704               insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
1705               insn = gen_rtx_SET (VOIDmode, subtarget, insn);
1706               emit_insn (insn);
1707               temp = subtarget;
1708             }
1709
1710           if (target == NULL)
1711             target = gen_reg_rtx (mode);
1712           insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
1713           insn = gen_rtx_SET (VOIDmode, target, insn);
1714           emit_insn (insn);
1715           return target;
1716         }
1717     }
1718
1719   /* If we couldn't do it that way, try some other methods.  But if we have
1720      no instructions left, don't bother.  Likewise, if this is SImode and
1721      we can't make pseudos, we can't do anything since the expand_binop
1722      and expand_unop calls will widen and try to make pseudos.  */
1723
1724   if (n == 1 || (mode == SImode && !can_create_pseudo_p ()))
1725     return 0;
1726
1727   /* Next, see if we can load a related constant and then shift and possibly
1728      negate it to get the constant we want.  Try this once each increasing
1729      numbers of insns.  */
1730
1731   for (i = 1; i < n; i++)
1732     {
1733       /* First, see if minus some low bits, we've an easy load of
1734          high bits.  */
1735
1736       new_const = ((c & 0xffff) ^ 0x8000) - 0x8000;
1737       if (new_const != 0)
1738         {
1739           temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output);
1740           if (temp)
1741             {
1742               if (no_output)
1743                 return temp;
1744               return expand_binop (mode, add_optab, temp, GEN_INT (new_const),
1745                                    target, 0, OPTAB_WIDEN);
1746             }
1747         }
1748
1749       /* Next try complementing.  */
1750       temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output);
1751       if (temp)
1752         {
1753           if (no_output)
1754             return temp;
1755           return expand_unop (mode, one_cmpl_optab, temp, target, 0);
1756         }
1757
1758       /* Next try to form a constant and do a left shift.  We can do this
1759          if some low-order bits are zero; the exact_log2 call below tells
1760          us that information.  The bits we are shifting out could be any
1761          value, but here we'll just try the 0- and sign-extended forms of
1762          the constant.  To try to increase the chance of having the same
1763          constant in more than one insn, start at the highest number of
1764          bits to shift, but try all possibilities in case a ZAPNOT will
1765          be useful.  */
1766
1767       bits = exact_log2 (c & -c);
1768       if (bits > 0)
1769         for (; bits > 0; bits--)
1770           {
1771             new_const = c >> bits;
1772             temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1773             if (!temp && c < 0)
1774               {
1775                 new_const = (unsigned HOST_WIDE_INT)c >> bits;
1776                 temp = alpha_emit_set_const (subtarget, mode, new_const,
1777                                              i, no_output);
1778               }
1779             if (temp)
1780               {
1781                 if (no_output)
1782                   return temp;
1783                 return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
1784                                      target, 0, OPTAB_WIDEN);
1785               }
1786           }
1787
1788       /* Now try high-order zero bits.  Here we try the shifted-in bits as
1789          all zero and all ones.  Be careful to avoid shifting outside the
1790          mode and to avoid shifting outside the host wide int size.  */
1791       /* On narrow hosts, don't shift a 1 into the high bit, since we'll
1792          confuse the recursive call and set all of the high 32 bits.  */
1793
1794       bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1795               - floor_log2 (c) - 1 - (HOST_BITS_PER_WIDE_INT < 64));
1796       if (bits > 0)
1797         for (; bits > 0; bits--)
1798           {
1799             new_const = c << bits;
1800             temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1801             if (!temp)
1802               {
1803                 new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1804                 temp = alpha_emit_set_const (subtarget, mode, new_const,
1805                                              i, no_output);
1806               }
1807             if (temp)
1808               {
1809                 if (no_output)
1810                   return temp;
1811                 return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
1812                                      target, 1, OPTAB_WIDEN);
1813               }
1814           }
1815
1816       /* Now try high-order 1 bits.  We get that with a sign-extension.
1817          But one bit isn't enough here.  Be careful to avoid shifting outside
1818          the mode and to avoid shifting outside the host wide int size.  */
1819
1820       bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
1821               - floor_log2 (~ c) - 2);
1822       if (bits > 0)
1823         for (; bits > 0; bits--)
1824           {
1825             new_const = c << bits;
1826             temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
1827             if (!temp)
1828               {
1829                 new_const = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1830                 temp = alpha_emit_set_const (subtarget, mode, new_const,
1831                                              i, no_output);
1832               }
1833             if (temp)
1834               {
1835                 if (no_output)
1836                   return temp;
1837                 return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
1838                                      target, 0, OPTAB_WIDEN);
1839               }
1840           }
1841     }
1842
1843 #if HOST_BITS_PER_WIDE_INT == 64
1844   /* Finally, see if can load a value into the target that is the same as the
1845      constant except that all bytes that are 0 are changed to be 0xff.  If we
1846      can, then we can do a ZAPNOT to obtain the desired constant.  */
1847
1848   new_const = c;
1849   for (i = 0; i < 64; i += 8)
1850     if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0)
1851       new_const |= (HOST_WIDE_INT) 0xff << i;
1852
1853   /* We are only called for SImode and DImode.  If this is SImode, ensure that
1854      we are sign extended to a full word.  */
1855
1856   if (mode == SImode)
1857     new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000;
1858
1859   if (new_const != c)
1860     {
1861       temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output);
1862       if (temp)
1863         {
1864           if (no_output)
1865             return temp;
1866           return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const),
1867                                target, 0, OPTAB_WIDEN);
1868         }
1869     }
1870 #endif
1871
1872   return 0;
1873 }
1874
1875 /* Try to output insns to set TARGET equal to the constant C if it can be
1876    done in less than N insns.  Do all computations in MODE.  Returns the place
1877    where the output has been placed if it can be done and the insns have been
1878    emitted.  If it would take more than N insns, zero is returned and no
1879    insns and emitted.  */
1880
1881 static rtx
1882 alpha_emit_set_const (rtx target, enum machine_mode mode,
1883                       HOST_WIDE_INT c, int n, bool no_output)
1884 {
1885   enum machine_mode orig_mode = mode;
1886   rtx orig_target = target;
1887   rtx result = 0;
1888   int i;
1889
1890   /* If we can't make any pseudos, TARGET is an SImode hard register, we
1891      can't load this constant in one insn, do this in DImode.  */
1892   if (!can_create_pseudo_p () && mode == SImode
1893       && REG_P (target) && REGNO (target) < FIRST_PSEUDO_REGISTER)
1894     {
1895       result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
1896       if (result)
1897         return result;
1898
1899       target = no_output ? NULL : gen_lowpart (DImode, target);
1900       mode = DImode;
1901     }
1902   else if (mode == V8QImode || mode == V4HImode || mode == V2SImode)
1903     {
1904       target = no_output ? NULL : gen_lowpart (DImode, target);
1905       mode = DImode;
1906     }
1907
1908   /* Try 1 insn, then 2, then up to N.  */
1909   for (i = 1; i <= n; i++)
1910     {
1911       result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
1912       if (result)
1913         {
1914           rtx insn, set;
1915
1916           if (no_output)
1917             return result;
1918
1919           insn = get_last_insn ();
1920           set = single_set (insn);
1921           if (! CONSTANT_P (SET_SRC (set)))
1922             set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
1923           break;
1924         }
1925     }
1926
1927   /* Allow for the case where we changed the mode of TARGET.  */
1928   if (result)
1929     {
1930       if (result == target)
1931         result = orig_target;
1932       else if (mode != orig_mode)
1933         result = gen_lowpart (orig_mode, result);
1934     }
1935
1936   return result;
1937 }
1938
1939 /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
1940    fall back to a straight forward decomposition.  We do this to avoid
1941    exponential run times encountered when looking for longer sequences
1942    with alpha_emit_set_const.  */
1943
1944 static rtx
1945 alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
1946 {
1947   HOST_WIDE_INT d1, d2, d3, d4;
1948
1949   /* Decompose the entire word */
1950 #if HOST_BITS_PER_WIDE_INT >= 64
1951   gcc_assert (c2 == -(c1 < 0));
1952   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1953   c1 -= d1;
1954   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1955   c1 = (c1 - d2) >> 32;
1956   d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1957   c1 -= d3;
1958   d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1959   gcc_assert (c1 == d4);
1960 #else
1961   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
1962   c1 -= d1;
1963   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1964   gcc_assert (c1 == d2);
1965   c2 += (d2 < 0);
1966   d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000;
1967   c2 -= d3;
1968   d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000;
1969   gcc_assert (c2 == d4);
1970 #endif
1971
1972   /* Construct the high word */
1973   if (d4)
1974     {
1975       emit_move_insn (target, GEN_INT (d4));
1976       if (d3)
1977         emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
1978     }
1979   else
1980     emit_move_insn (target, GEN_INT (d3));
1981
1982   /* Shift it into place */
1983   emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
1984
1985   /* Add in the low bits.  */
1986   if (d2)
1987     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
1988   if (d1)
1989     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
1990
1991   return target;
1992 }
1993
1994 /* Given an integral CONST_INT, CONST_DOUBLE, or CONST_VECTOR, return 
1995    the low 64 bits.  */
1996
1997 static void
1998 alpha_extract_integer (rtx x, HOST_WIDE_INT *p0, HOST_WIDE_INT *p1)
1999 {
2000   HOST_WIDE_INT i0, i1;
2001
2002   if (GET_CODE (x) == CONST_VECTOR)
2003     x = simplify_subreg (DImode, x, GET_MODE (x), 0);
2004
2005
2006   if (CONST_INT_P (x))
2007     {
2008       i0 = INTVAL (x);
2009       i1 = -(i0 < 0);
2010     }
2011   else if (HOST_BITS_PER_WIDE_INT >= 64)
2012     {
2013       i0 = CONST_DOUBLE_LOW (x);
2014       i1 = -(i0 < 0);
2015     }
2016   else
2017     {
2018       i0 = CONST_DOUBLE_LOW (x);
2019       i1 = CONST_DOUBLE_HIGH (x);
2020     }
2021
2022   *p0 = i0;
2023   *p1 = i1;
2024 }
2025
2026 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  This is all constants for which
2027    we are willing to load the value into a register via a move pattern.
2028    Normally this is all symbolic constants, integral constants that
2029    take three or fewer instructions, and floating-point zero.  */
2030
2031 bool
2032 alpha_legitimate_constant_p (enum machine_mode mode, rtx x)
2033 {
2034   HOST_WIDE_INT i0, i1;
2035
2036   switch (GET_CODE (x))
2037     {
2038     case LABEL_REF:
2039     case HIGH:
2040       return true;
2041
2042     case CONST:
2043       if (GET_CODE (XEXP (x, 0)) == PLUS
2044           && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
2045         x = XEXP (XEXP (x, 0), 0);
2046       else
2047         return true;
2048
2049       if (GET_CODE (x) != SYMBOL_REF)
2050         return true;
2051
2052       /* FALLTHRU */
2053
2054     case SYMBOL_REF:
2055       /* TLS symbols are never valid.  */
2056       return SYMBOL_REF_TLS_MODEL (x) == 0;
2057
2058     case CONST_DOUBLE:
2059       if (x == CONST0_RTX (mode))
2060         return true;
2061       if (FLOAT_MODE_P (mode))
2062         return false;
2063       goto do_integer;
2064
2065     case CONST_VECTOR:
2066       if (x == CONST0_RTX (mode))
2067         return true;
2068       if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
2069         return false;
2070       if (GET_MODE_SIZE (mode) != 8)
2071         return false;
2072       goto do_integer;
2073
2074     case CONST_INT:
2075     do_integer:
2076       if (TARGET_BUILD_CONSTANTS)
2077         return true;
2078       alpha_extract_integer (x, &i0, &i1);
2079       if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == (-i0 < 0))
2080         return alpha_emit_set_const_1 (x, mode, i0, 3, true) != NULL;
2081       return false;
2082
2083     default:
2084       return false;
2085     }
2086 }
2087
2088 /* Operand 1 is known to be a constant, and should require more than one
2089    instruction to load.  Emit that multi-part load.  */
2090
2091 bool
2092 alpha_split_const_mov (enum machine_mode mode, rtx *operands)
2093 {
2094   HOST_WIDE_INT i0, i1;
2095   rtx temp = NULL_RTX;
2096
2097   alpha_extract_integer (operands[1], &i0, &i1);
2098
2099   if (HOST_BITS_PER_WIDE_INT >= 64 || i1 == -(i0 < 0))
2100     temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);
2101
2102   if (!temp && TARGET_BUILD_CONSTANTS)
2103     temp = alpha_emit_set_long_const (operands[0], i0, i1);
2104
2105   if (temp)
2106     {
2107       if (!rtx_equal_p (operands[0], temp))
2108         emit_move_insn (operands[0], temp);
2109       return true;
2110     }
2111
2112   return false;
2113 }
2114
2115 /* Expand a move instruction; return true if all work is done.
2116    We don't handle non-bwx subword loads here.  */
2117
2118 bool
2119 alpha_expand_mov (enum machine_mode mode, rtx *operands)
2120 {
2121   rtx tmp;
2122
2123   /* If the output is not a register, the input must be.  */
2124   if (MEM_P (operands[0])
2125       && ! reg_or_0_operand (operands[1], mode))
2126     operands[1] = force_reg (mode, operands[1]);
2127
2128   /* Allow legitimize_address to perform some simplifications.  */
2129   if (mode == Pmode && symbolic_operand (operands[1], mode))
2130     {
2131       tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode);
2132       if (tmp)
2133         {
2134           if (tmp == operands[0])
2135             return true;
2136           operands[1] = tmp;
2137           return false;
2138         }
2139     }
2140
2141   /* Early out for non-constants and valid constants.  */
2142   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
2143     return false;
2144
2145   /* Split large integers.  */
2146   if (CONST_INT_P (operands[1])
2147       || GET_CODE (operands[1]) == CONST_DOUBLE
2148       || GET_CODE (operands[1]) == CONST_VECTOR)
2149     {
2150       if (alpha_split_const_mov (mode, operands))
2151         return true;
2152     }
2153
2154   /* Otherwise we've nothing left but to drop the thing to memory.  */
2155   tmp = force_const_mem (mode, operands[1]);
2156
2157   if (tmp == NULL_RTX)
2158     return false;
2159
2160   if (reload_in_progress)
2161     {
2162       emit_move_insn (operands[0], XEXP (tmp, 0));
2163       operands[1] = replace_equiv_address (tmp, operands[0]);
2164     }
2165   else
2166     operands[1] = validize_mem (tmp);
2167   return false;
2168 }
2169
2170 /* Expand a non-bwx QImode or HImode move instruction;
2171    return true if all work is done.  */
2172
2173 bool
2174 alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
2175 {
2176   rtx seq;
2177
2178   /* If the output is not a register, the input must be.  */
2179   if (MEM_P (operands[0]))
2180     operands[1] = force_reg (mode, operands[1]);
2181
2182   /* Handle four memory cases, unaligned and aligned for either the input
2183      or the output.  The only case where we can be called during reload is
2184      for aligned loads; all other cases require temporaries.  */
2185
2186   if (any_memory_operand (operands[1], mode))
2187     {
2188       if (aligned_memory_operand (operands[1], mode))
2189         {
2190           if (reload_in_progress)
2191             {
2192               if (mode == QImode)
2193                 seq = gen_reload_inqi_aligned (operands[0], operands[1]);
2194               else
2195                 seq = gen_reload_inhi_aligned (operands[0], operands[1]);
2196               emit_insn (seq);
2197             }
2198           else
2199             {
2200               rtx aligned_mem, bitnum;
2201               rtx scratch = gen_reg_rtx (SImode);
2202               rtx subtarget;
2203               bool copyout;
2204
2205               get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2206
2207               subtarget = operands[0];
2208               if (REG_P (subtarget))
2209                 subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2210               else
2211                 subtarget = gen_reg_rtx (DImode), copyout = true;
2212
2213               if (mode == QImode)
2214                 seq = gen_aligned_loadqi (subtarget, aligned_mem,
2215                                           bitnum, scratch);
2216               else
2217                 seq = gen_aligned_loadhi (subtarget, aligned_mem,
2218                                           bitnum, scratch);
2219               emit_insn (seq);
2220
2221               if (copyout)
2222                 emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2223             }
2224         }
2225       else
2226         {
2227           /* Don't pass these as parameters since that makes the generated
2228              code depend on parameter evaluation order which will cause
2229              bootstrap failures.  */
2230
2231           rtx temp1, temp2, subtarget, ua;
2232           bool copyout;
2233
2234           temp1 = gen_reg_rtx (DImode);
2235           temp2 = gen_reg_rtx (DImode);
2236
2237           subtarget = operands[0];
2238           if (REG_P (subtarget))
2239             subtarget = gen_lowpart (DImode, subtarget), copyout = false;
2240           else
2241             subtarget = gen_reg_rtx (DImode), copyout = true;
2242
2243           ua = get_unaligned_address (operands[1]);
2244           if (mode == QImode)
2245             seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2);
2246           else
2247             seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2);
2248
2249           alpha_set_memflags (seq, operands[1]);
2250           emit_insn (seq);
2251
2252           if (copyout)
2253             emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
2254         }
2255       return true;
2256     }
2257
2258   if (any_memory_operand (operands[0], mode))
2259     {
2260       if (aligned_memory_operand (operands[0], mode))
2261         {
2262           rtx aligned_mem, bitnum;
2263           rtx temp1 = gen_reg_rtx (SImode);
2264           rtx temp2 = gen_reg_rtx (SImode);
2265
2266           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2267
2268           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2269                                         temp1, temp2));
2270         }
2271       else
2272         {
2273           rtx temp1 = gen_reg_rtx (DImode);
2274           rtx temp2 = gen_reg_rtx (DImode);
2275           rtx temp3 = gen_reg_rtx (DImode);
2276           rtx ua = get_unaligned_address (operands[0]);
2277
2278           if (mode == QImode)
2279             seq = gen_unaligned_storeqi (ua, operands[1], temp1, temp2, temp3);
2280           else
2281             seq = gen_unaligned_storehi (ua, operands[1], temp1, temp2, temp3);
2282
2283           alpha_set_memflags (seq, operands[0]);
2284           emit_insn (seq);
2285         }
2286       return true;
2287     }
2288
2289   return false;
2290 }
2291
2292 /* Implement the movmisalign patterns.  One of the operands is a memory
2293    that is not naturally aligned.  Emit instructions to load it.  */
2294
2295 void
2296 alpha_expand_movmisalign (enum machine_mode mode, rtx *operands)
2297 {
2298   /* Honor misaligned loads, for those we promised to do so.  */
2299   if (MEM_P (operands[1]))
2300     {
2301       rtx tmp;
2302
2303       if (register_operand (operands[0], mode))
2304         tmp = operands[0];
2305       else
2306         tmp = gen_reg_rtx (mode);
2307
2308       alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
2309       if (tmp != operands[0])
2310         emit_move_insn (operands[0], tmp);
2311     }
2312   else if (MEM_P (operands[0]))
2313     {
2314       if (!reg_or_0_operand (operands[1], mode))
2315         operands[1] = force_reg (mode, operands[1]);
2316       alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
2317     }
2318   else
2319     gcc_unreachable ();
2320 }
2321
2322 /* Generate an unsigned DImode to FP conversion.  This is the same code
2323    optabs would emit if we didn't have TFmode patterns.
2324
2325    For SFmode, this is the only construction I've found that can pass
2326    gcc.c-torture/execute/ieee/rbug.c.  No scenario that uses DFmode
2327    intermediates will work, because you'll get intermediate rounding
2328    that ruins the end result.  Some of this could be fixed by turning
2329    on round-to-positive-infinity, but that requires diddling the fpsr,
2330    which kills performance.  I tried turning this around and converting
2331    to a negative number, so that I could turn on /m, but either I did
2332    it wrong or there's something else cause I wound up with the exact
2333    same single-bit error.  There is a branch-less form of this same code:
2334
2335         srl     $16,1,$1
2336         and     $16,1,$2
2337         cmplt   $16,0,$3
2338         or      $1,$2,$2
2339         cmovge  $16,$16,$2
2340         itoft   $3,$f10
2341         itoft   $2,$f11
2342         cvtqs   $f11,$f11
2343         adds    $f11,$f11,$f0
2344         fcmoveq $f10,$f11,$f0
2345
2346    I'm not using it because it's the same number of instructions as
2347    this branch-full form, and it has more serialized long latency
2348    instructions on the critical path.
2349
2350    For DFmode, we can avoid rounding errors by breaking up the word
2351    into two pieces, converting them separately, and adding them back:
2352
2353    LC0: .long 0,0x5f800000
2354
2355         itoft   $16,$f11
2356         lda     $2,LC0
2357         cmplt   $16,0,$1
2358         cpyse   $f11,$f31,$f10
2359         cpyse   $f31,$f11,$f11
2360         s4addq  $1,$2,$1
2361         lds     $f12,0($1)
2362         cvtqt   $f10,$f10
2363         cvtqt   $f11,$f11
2364         addt    $f12,$f10,$f0
2365         addt    $f0,$f11,$f0
2366
2367    This doesn't seem to be a clear-cut win over the optabs form.
2368    It probably all depends on the distribution of numbers being
2369    converted -- in the optabs form, all but high-bit-set has a
2370    much lower minimum execution time.  */
2371
2372 void
2373 alpha_emit_floatuns (rtx operands[2])
2374 {
2375   rtx neglab, donelab, i0, i1, f0, in, out;
2376   enum machine_mode mode;
2377
2378   out = operands[0];
2379   in = force_reg (DImode, operands[1]);
2380   mode = GET_MODE (out);
2381   neglab = gen_label_rtx ();
2382   donelab = gen_label_rtx ();
2383   i0 = gen_reg_rtx (DImode);
2384   i1 = gen_reg_rtx (DImode);
2385   f0 = gen_reg_rtx (mode);
2386
2387   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
2388
2389   emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
2390   emit_jump_insn (gen_jump (donelab));
2391   emit_barrier ();
2392
2393   emit_label (neglab);
2394
2395   emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
2396   emit_insn (gen_anddi3 (i1, in, const1_rtx));
2397   emit_insn (gen_iordi3 (i0, i0, i1));
2398   emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0)));
2399   emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
2400
2401   emit_label (donelab);
2402 }
2403
2404 /* Generate the comparison for a conditional branch.  */
2405
2406 void
2407 alpha_emit_conditional_branch (rtx operands[], enum machine_mode cmp_mode)
2408 {
2409   enum rtx_code cmp_code, branch_code;
2410   enum machine_mode branch_mode = VOIDmode;
2411   enum rtx_code code = GET_CODE (operands[0]);
2412   rtx op0 = operands[1], op1 = operands[2];
2413   rtx tem;
2414
2415   if (cmp_mode == TFmode)
2416     {
2417       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
2418       op1 = const0_rtx;
2419       cmp_mode = DImode;
2420     }
2421
2422   /* The general case: fold the comparison code to the types of compares
2423      that we have, choosing the branch as necessary.  */
2424   switch (code)
2425     {
2426     case EQ:  case LE:  case LT:  case LEU:  case LTU:
2427     case UNORDERED:
2428       /* We have these compares: */
2429       cmp_code = code, branch_code = NE;
2430       break;
2431
2432     case NE:
2433     case ORDERED:
2434       /* These must be reversed.  */
2435       cmp_code = reverse_condition (code), branch_code = EQ;
2436       break;
2437
2438     case GE:  case GT: case GEU:  case GTU:
2439       /* For FP, we swap them, for INT, we reverse them.  */
2440       if (cmp_mode == DFmode)
2441         {
2442           cmp_code = swap_condition (code);
2443           branch_code = NE;
2444           tem = op0, op0 = op1, op1 = tem;
2445         }
2446       else
2447         {
2448           cmp_code = reverse_condition (code);
2449           branch_code = EQ;
2450         }
2451       break;
2452
2453     default:
2454       gcc_unreachable ();
2455     }
2456
2457   if (cmp_mode == DFmode)
2458     {
2459       if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
2460         {
2461           /* When we are not as concerned about non-finite values, and we
2462              are comparing against zero, we can branch directly.  */
2463           if (op1 == CONST0_RTX (DFmode))
2464             cmp_code = UNKNOWN, branch_code = code;
2465           else if (op0 == CONST0_RTX (DFmode))
2466             {
2467               /* Undo the swap we probably did just above.  */
2468               tem = op0, op0 = op1, op1 = tem;
2469               branch_code = swap_condition (cmp_code);
2470               cmp_code = UNKNOWN;
2471             }
2472         }
2473       else
2474         {
2475           /* ??? We mark the branch mode to be CCmode to prevent the
2476              compare and branch from being combined, since the compare
2477              insn follows IEEE rules that the branch does not.  */
2478           branch_mode = CCmode;
2479         }
2480     }
2481   else
2482     {
2483       /* The following optimizations are only for signed compares.  */
2484       if (code != LEU && code != LTU && code != GEU && code != GTU)
2485         {
2486           /* Whee.  Compare and branch against 0 directly.  */
2487           if (op1 == const0_rtx)
2488             cmp_code = UNKNOWN, branch_code = code;
2489
2490           /* If the constants doesn't fit into an immediate, but can
2491              be generated by lda/ldah, we adjust the argument and
2492              compare against zero, so we can use beq/bne directly.  */
2493           /* ??? Don't do this when comparing against symbols, otherwise
2494              we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
2495              be declared false out of hand (at least for non-weak).  */
2496           else if (CONST_INT_P (op1)
2497                    && (code == EQ || code == NE)
2498                    && !(symbolic_operand (op0, VOIDmode)
2499                         || (REG_P (op0) && REG_POINTER (op0))))
2500             {
2501               rtx n_op1 = GEN_INT (-INTVAL (op1));
2502
2503               if (! satisfies_constraint_I (op1)
2504                   && (satisfies_constraint_K (n_op1)
2505                       || satisfies_constraint_L (n_op1)))
2506                 cmp_code = PLUS, branch_code = code, op1 = n_op1;
2507             }
2508         }
2509
2510       if (!reg_or_0_operand (op0, DImode))
2511         op0 = force_reg (DImode, op0);
2512       if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
2513         op1 = force_reg (DImode, op1);
2514     }
2515
2516   /* Emit an initial compare instruction, if necessary.  */
2517   tem = op0;
2518   if (cmp_code != UNKNOWN)
2519     {
2520       tem = gen_reg_rtx (cmp_mode);
2521       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
2522     }
2523
2524   /* Emit the branch instruction.  */
2525   tem = gen_rtx_SET (VOIDmode, pc_rtx,
2526                      gen_rtx_IF_THEN_ELSE (VOIDmode,
2527                                            gen_rtx_fmt_ee (branch_code,
2528                                                            branch_mode, tem,
2529                                                            CONST0_RTX (cmp_mode)),
2530                                            gen_rtx_LABEL_REF (VOIDmode,
2531                                                               operands[3]),
2532                                            pc_rtx));
2533   emit_jump_insn (tem);
2534 }
2535
2536 /* Certain simplifications can be done to make invalid setcc operations
2537    valid.  Return the final comparison, or NULL if we can't work.  */
2538
2539 bool
2540 alpha_emit_setcc (rtx operands[], enum machine_mode cmp_mode)
2541 {
2542   enum rtx_code cmp_code;
2543   enum rtx_code code = GET_CODE (operands[1]);
2544   rtx op0 = operands[2], op1 = operands[3];
2545   rtx tmp;
2546
2547   if (cmp_mode == TFmode)
2548     {
2549       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
2550       op1 = const0_rtx;
2551       cmp_mode = DImode;
2552     }
2553
2554   if (cmp_mode == DFmode && !TARGET_FIX)
2555     return 0;
2556
2557   /* The general case: fold the comparison code to the types of compares
2558      that we have, choosing the branch as necessary.  */
2559
2560   cmp_code = UNKNOWN;
2561   switch (code)
2562     {
2563     case EQ:  case LE:  case LT:  case LEU:  case LTU:
2564     case UNORDERED:
2565       /* We have these compares.  */
2566       if (cmp_mode == DFmode)
2567         cmp_code = code, code = NE;
2568       break;
2569
2570     case NE:
2571       if (cmp_mode == DImode && op1 == const0_rtx)
2572         break;
2573       /* FALLTHRU */
2574
2575     case ORDERED:
2576       cmp_code = reverse_condition (code);
2577       code = EQ;
2578       break;
2579
2580     case GE:  case GT: case GEU:  case GTU:
2581       /* These normally need swapping, but for integer zero we have
2582          special patterns that recognize swapped operands.  */
2583       if (cmp_mode == DImode && op1 == const0_rtx)
2584         break;
2585       code = swap_condition (code);
2586       if (cmp_mode == DFmode)
2587         cmp_code = code, code = NE;
2588       tmp = op0, op0 = op1, op1 = tmp;
2589       break;
2590
2591     default:
2592       gcc_unreachable ();
2593     }
2594
2595   if (cmp_mode == DImode)
2596     {
2597       if (!register_operand (op0, DImode))
2598         op0 = force_reg (DImode, op0);
2599       if (!reg_or_8bit_operand (op1, DImode))
2600         op1 = force_reg (DImode, op1);
2601     }
2602
2603   /* Emit an initial compare instruction, if necessary.  */
2604   if (cmp_code != UNKNOWN)
2605     {
2606       tmp = gen_reg_rtx (cmp_mode);
2607       emit_insn (gen_rtx_SET (VOIDmode, tmp,
2608                               gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)));
2609
2610       op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp;
2611       op1 = const0_rtx;
2612     }
2613
2614   /* Emit the setcc instruction.  */
2615   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2616                           gen_rtx_fmt_ee (code, DImode, op0, op1)));
2617   return true;
2618 }
2619
2620
2621 /* Rewrite a comparison against zero CMP of the form
2622    (CODE (cc0) (const_int 0)) so it can be written validly in
2623    a conditional move (if_then_else CMP ...).
2624    If both of the operands that set cc0 are nonzero we must emit
2625    an insn to perform the compare (it can't be done within
2626    the conditional move).  */
2627
2628 rtx
2629 alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
2630 {
2631   enum rtx_code code = GET_CODE (cmp);
2632   enum rtx_code cmov_code = NE;
2633   rtx op0 = XEXP (cmp, 0);
2634   rtx op1 = XEXP (cmp, 1);
2635   enum machine_mode cmp_mode
2636     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
2637   enum machine_mode cmov_mode = VOIDmode;
2638   int local_fast_math = flag_unsafe_math_optimizations;
2639   rtx tem;
2640
2641   if (cmp_mode == TFmode)
2642     {
2643       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
2644       op1 = const0_rtx;
2645       cmp_mode = DImode;
2646     }
2647
2648   gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);
2649
2650   if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
2651     {
2652       enum rtx_code cmp_code;
2653
2654       if (! TARGET_FIX)
2655         return 0;
2656
2657       /* If we have fp<->int register move instructions, do a cmov by
2658          performing the comparison in fp registers, and move the
2659          zero/nonzero value to integer registers, where we can then
2660          use a normal cmov, or vice-versa.  */
2661
2662       switch (code)
2663         {
2664         case EQ: case LE: case LT: case LEU: case LTU:
2665           /* We have these compares.  */
2666           cmp_code = code, code = NE;
2667           break;
2668
2669         case NE:
2670           /* This must be reversed.  */
2671           cmp_code = EQ, code = EQ;
2672           break;
2673
2674         case GE: case GT: case GEU: case GTU:
2675           /* These normally need swapping, but for integer zero we have
2676              special patterns that recognize swapped operands.  */
2677           if (cmp_mode == DImode && op1 == const0_rtx)
2678             cmp_code = code, code = NE;
2679           else
2680             {
2681               cmp_code = swap_condition (code);
2682               code = NE;
2683               tem = op0, op0 = op1, op1 = tem;
2684             }
2685           break;
2686
2687         default:
2688           gcc_unreachable ();
2689         }
2690
2691       tem = gen_reg_rtx (cmp_mode);
2692       emit_insn (gen_rtx_SET (VOIDmode, tem,
2693                               gen_rtx_fmt_ee (cmp_code, cmp_mode,
2694                                               op0, op1)));
2695
2696       cmp_mode = cmp_mode == DImode ? DFmode : DImode;
2697       op0 = gen_lowpart (cmp_mode, tem);
2698       op1 = CONST0_RTX (cmp_mode);
2699       local_fast_math = 1;
2700     }
2701
2702   /* We may be able to use a conditional move directly.
2703      This avoids emitting spurious compares.  */
2704   if (signed_comparison_operator (cmp, VOIDmode)
2705       && (cmp_mode == DImode || local_fast_math)
2706       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
2707     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
2708
2709   /* We can't put the comparison inside the conditional move;
2710      emit a compare instruction and put that inside the
2711      conditional move.  Make sure we emit only comparisons we have;
2712      swap or reverse as necessary.  */
2713
2714   if (!can_create_pseudo_p ())
2715     return NULL_RTX;
2716
2717   switch (code)
2718     {
2719     case EQ:  case LE:  case LT:  case LEU:  case LTU:
2720       /* We have these compares: */
2721       break;
2722
2723     case NE:
2724       /* This must be reversed.  */
2725       code = reverse_condition (code);
2726       cmov_code = EQ;
2727       break;
2728
2729     case GE:  case GT:  case GEU:  case GTU:
2730       /* These must be swapped.  */
2731       if (op1 != CONST0_RTX (cmp_mode))
2732         {
2733           code = swap_condition (code);
2734           tem = op0, op0 = op1, op1 = tem;
2735         }
2736       break;
2737
2738     default:
2739       gcc_unreachable ();
2740     }
2741
2742   if (cmp_mode == DImode)
2743     {
2744       if (!reg_or_0_operand (op0, DImode))
2745         op0 = force_reg (DImode, op0);
2746       if (!reg_or_8bit_operand (op1, DImode))
2747         op1 = force_reg (DImode, op1);
2748     }
2749
2750   /* ??? We mark the branch mode to be CCmode to prevent the compare
2751      and cmov from being combined, since the compare insn follows IEEE
2752      rules that the cmov does not.  */
2753   if (cmp_mode == DFmode && !local_fast_math)
2754     cmov_mode = CCmode;
2755
2756   tem = gen_reg_rtx (cmp_mode);
2757   emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
2758   return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
2759 }
2760
2761 /* Simplify a conditional move of two constants into a setcc with
2762    arithmetic.  This is done with a splitter since combine would
2763    just undo the work if done during code generation.  It also catches
2764    cases we wouldn't have before cse.  */
2765
2766 int
2767 alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
2768                               rtx t_rtx, rtx f_rtx)
2769 {
2770   HOST_WIDE_INT t, f, diff;
2771   enum machine_mode mode;
2772   rtx target, subtarget, tmp;
2773
2774   mode = GET_MODE (dest);
2775   t = INTVAL (t_rtx);
2776   f = INTVAL (f_rtx);
2777   diff = t - f;
2778
2779   if (((code == NE || code == EQ) && diff < 0)
2780       || (code == GE || code == GT))
2781     {
2782       code = reverse_condition (code);
2783       diff = t, t = f, f = diff;
2784       diff = t - f;
2785     }
2786
2787   subtarget = target = dest;
2788   if (mode != DImode)
2789     {
2790       target = gen_lowpart (DImode, dest);
2791       if (can_create_pseudo_p ())
2792         subtarget = gen_reg_rtx (DImode);
2793       else
2794         subtarget = target;
2795     }
2796   /* Below, we must be careful to use copy_rtx on target and subtarget
2797      in intermediate insns, as they may be a subreg rtx, which may not
2798      be shared.  */
2799
2800   if (f == 0 && exact_log2 (diff) > 0
2801       /* On EV6, we've got enough shifters to make non-arithmetic shifts
2802          viable over a longer latency cmove.  On EV5, the E0 slot is a
2803          scarce resource, and on EV4 shift has the same latency as a cmove.  */
2804       && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
2805     {
2806       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2807       emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2808
2809       tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
2810                             GEN_INT (exact_log2 (t)));
2811       emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2812     }
2813   else if (f == 0 && t == -1)
2814     {
2815       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2816       emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2817
2818       emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
2819     }
2820   else if (diff == 1 || diff == 4 || diff == 8)
2821     {
2822       rtx add_op;
2823
2824       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
2825       emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (subtarget), tmp));
2826
2827       if (diff == 1)
2828         emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
2829       else
2830         {
2831           add_op = GEN_INT (f);
2832           if (sext_add_operand (add_op, mode))
2833             {
2834               tmp = gen_rtx_MULT (DImode, copy_rtx (subtarget),
2835                                   GEN_INT (diff));
2836               tmp = gen_rtx_PLUS (DImode, tmp, add_op);
2837               emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
2838             }
2839           else
2840             return 0;
2841         }
2842     }
2843   else
2844     return 0;
2845
2846   return 1;
2847 }
2848 \f
2849 /* Look up the function X_floating library function name for the
2850    given operation.  */
2851
2852 struct GTY(()) xfloating_op
2853 {
2854   const enum rtx_code code;
2855   const char *const GTY((skip)) osf_func;
2856   const char *const GTY((skip)) vms_func;
2857   rtx libcall;
2858 };
2859
2860 static GTY(()) struct xfloating_op xfloating_ops[] =
2861 {
2862   { PLUS,               "_OtsAddX", "OTS$ADD_X", 0 },
2863   { MINUS,              "_OtsSubX", "OTS$SUB_X", 0 },
2864   { MULT,               "_OtsMulX", "OTS$MUL_X", 0 },
2865   { DIV,                "_OtsDivX", "OTS$DIV_X", 0 },
2866   { EQ,                 "_OtsEqlX", "OTS$EQL_X", 0 },
2867   { NE,                 "_OtsNeqX", "OTS$NEQ_X", 0 },
2868   { LT,                 "_OtsLssX", "OTS$LSS_X", 0 },
2869   { LE,                 "_OtsLeqX", "OTS$LEQ_X", 0 },
2870   { GT,                 "_OtsGtrX", "OTS$GTR_X", 0 },
2871   { GE,                 "_OtsGeqX", "OTS$GEQ_X", 0 },
2872   { FIX,                "_OtsCvtXQ", "OTS$CVTXQ", 0 },
2873   { FLOAT,              "_OtsCvtQX", "OTS$CVTQX", 0 },
2874   { UNSIGNED_FLOAT,     "_OtsCvtQUX", "OTS$CVTQUX", 0 },
2875   { FLOAT_EXTEND,       "_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
2876   { FLOAT_TRUNCATE,     "_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
2877 };
2878
2879 static GTY(()) struct xfloating_op vax_cvt_ops[] =
2880 {
2881   { FLOAT_EXTEND,       "_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
2882   { FLOAT_TRUNCATE,     "_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
2883 };
2884
2885 static rtx
2886 alpha_lookup_xfloating_lib_func (enum rtx_code code)
2887 {
2888   struct xfloating_op *ops = xfloating_ops;
2889   long n = ARRAY_SIZE (xfloating_ops);
2890   long i;
2891
2892   gcc_assert (TARGET_HAS_XFLOATING_LIBS);
2893
2894   /* How irritating.  Nothing to key off for the main table.  */
2895   if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
2896     {
2897       ops = vax_cvt_ops;
2898       n = ARRAY_SIZE (vax_cvt_ops);
2899     }
2900
2901   for (i = 0; i < n; ++i, ++ops)
2902     if (ops->code == code)
2903       {
2904         rtx func = ops->libcall;
2905         if (!func)
2906           {
2907             func = init_one_libfunc (TARGET_ABI_OPEN_VMS
2908                                      ? ops->vms_func : ops->osf_func);
2909             ops->libcall = func;
2910           }
2911         return func;
2912       }
2913
2914   gcc_unreachable ();
2915 }
2916
2917 /* Most X_floating operations take the rounding mode as an argument.
2918    Compute that here.  */
2919
2920 static int
2921 alpha_compute_xfloating_mode_arg (enum rtx_code code,
2922                                   enum alpha_fp_rounding_mode round)
2923 {
2924   int mode;
2925
2926   switch (round)
2927     {
2928     case ALPHA_FPRM_NORM:
2929       mode = 2;
2930       break;
2931     case ALPHA_FPRM_MINF:
2932       mode = 1;
2933       break;
2934     case ALPHA_FPRM_CHOP:
2935       mode = 0;
2936       break;
2937     case ALPHA_FPRM_DYN:
2938       mode = 4;
2939       break;
2940     default:
2941       gcc_unreachable ();
2942
2943     /* XXX For reference, round to +inf is mode = 3.  */
2944     }
2945
2946   if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
2947     mode |= 0x10000;
2948
2949   return mode;
2950 }
2951
2952 /* Emit an X_floating library function call.
2953
2954    Note that these functions do not follow normal calling conventions:
2955    TFmode arguments are passed in two integer registers (as opposed to
2956    indirect); TFmode return values appear in R16+R17.
2957
2958    FUNC is the function to call.
2959    TARGET is where the output belongs.
2960    OPERANDS are the inputs.
2961    NOPERANDS is the count of inputs.
2962    EQUIV is the expression equivalent for the function.
2963 */
2964
2965 static void
2966 alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
2967                               int noperands, rtx equiv)
2968 {
2969   rtx usage = NULL_RTX, tmp, reg;
2970   int regno = 16, i;
2971
2972   start_sequence ();
2973
2974   for (i = 0; i < noperands; ++i)
2975     {
2976       switch (GET_MODE (operands[i]))
2977         {
2978         case TFmode:
2979           reg = gen_rtx_REG (TFmode, regno);
2980           regno += 2;
2981           break;
2982
2983         case DFmode:
2984           reg = gen_rtx_REG (DFmode, regno + 32);
2985           regno += 1;
2986           break;
2987
2988         case VOIDmode:
2989           gcc_assert (CONST_INT_P (operands[i]));
2990           /* FALLTHRU */
2991         case DImode:
2992           reg = gen_rtx_REG (DImode, regno);
2993           regno += 1;
2994           break;
2995
2996         default:
2997           gcc_unreachable ();
2998         }
2999
3000       emit_move_insn (reg, operands[i]);
3001       use_reg (&usage, reg);
3002     }
3003
3004   switch (GET_MODE (target))
3005     {
3006     case TFmode:
3007       reg = gen_rtx_REG (TFmode, 16);
3008       break;
3009     case DFmode:
3010       reg = gen_rtx_REG (DFmode, 32);
3011       break;
3012     case DImode:
3013       reg = gen_rtx_REG (DImode, 0);
3014       break;
3015     default:
3016       gcc_unreachable ();
3017     }
3018
3019   tmp = gen_rtx_MEM (QImode, func);
3020   tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
3021                                         const0_rtx, const0_rtx));
3022   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
3023   RTL_CONST_CALL_P (tmp) = 1;
3024
3025   tmp = get_insns ();
3026   end_sequence ();
3027
3028   emit_libcall_block (tmp, target, reg, equiv);
3029 }
3030
3031 /* Emit an X_floating library function call for arithmetic (+,-,*,/).  */
3032
3033 void
3034 alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
3035 {
3036   rtx func;
3037   int mode;
3038   rtx out_operands[3];
3039
3040   func = alpha_lookup_xfloating_lib_func (code);
3041   mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3042
3043   out_operands[0] = operands[1];
3044   out_operands[1] = operands[2];
3045   out_operands[2] = GEN_INT (mode);
3046   alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
3047                                 gen_rtx_fmt_ee (code, TFmode, operands[1],
3048                                                 operands[2]));
3049 }
3050
3051 /* Emit an X_floating library function call for a comparison.  */
3052
3053 static rtx
3054 alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
3055 {
3056   enum rtx_code cmp_code, res_code;
3057   rtx func, out, operands[2], note;
3058
3059   /* X_floating library comparison functions return
3060            -1  unordered
3061             0  false
3062             1  true
3063      Convert the compare against the raw return value.  */
3064
3065   cmp_code = *pcode;
3066   switch (cmp_code)
3067     {
3068     case UNORDERED:
3069       cmp_code = EQ;
3070       res_code = LT;
3071       break;
3072     case ORDERED:
3073       cmp_code = EQ;
3074       res_code = GE;
3075       break;
3076     case NE:
3077       res_code = NE;
3078       break;
3079     case EQ:
3080     case LT:
3081     case GT:
3082     case LE:
3083     case GE:
3084       res_code = GT;
3085       break;
3086     default:
3087       gcc_unreachable ();
3088     }
3089   *pcode = res_code;
3090
3091   func = alpha_lookup_xfloating_lib_func (cmp_code);
3092
3093   operands[0] = op0;
3094   operands[1] = op1;
3095   out = gen_reg_rtx (DImode);
3096
3097   /* What's actually returned is -1,0,1, not a proper boolean value,
3098      so use an EXPR_LIST as with a generic libcall instead of a 
3099      comparison type expression.  */
3100   note = gen_rtx_EXPR_LIST (VOIDmode, op1, NULL_RTX);
3101   note = gen_rtx_EXPR_LIST (VOIDmode, op0, note);
3102   note = gen_rtx_EXPR_LIST (VOIDmode, func, note);
3103   alpha_emit_xfloating_libcall (func, out, operands, 2, note);
3104
3105   return out;
3106 }
3107
3108 /* Emit an X_floating library function call for a conversion.  */
3109
3110 void
3111 alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
3112 {
3113   int noperands = 1, mode;
3114   rtx out_operands[2];
3115   rtx func;
3116   enum rtx_code code = orig_code;
3117
3118   if (code == UNSIGNED_FIX)
3119     code = FIX;
3120
3121   func = alpha_lookup_xfloating_lib_func (code);
3122
3123   out_operands[0] = operands[1];
3124
3125   switch (code)
3126     {
3127     case FIX:
3128       mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
3129       out_operands[1] = GEN_INT (mode);
3130       noperands = 2;
3131       break;
3132     case FLOAT_TRUNCATE:
3133       mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
3134       out_operands[1] = GEN_INT (mode);
3135       noperands = 2;
3136       break;
3137     default:
3138       break;
3139     }
3140
3141   alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
3142                                 gen_rtx_fmt_e (orig_code,
3143                                                GET_MODE (operands[0]),
3144                                                operands[1]));
3145 }
3146
3147 /* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
3148    DImode moves from OP[2,3] to OP[0,1].  If FIXUP_OVERLAP is true,
3149    guarantee that the sequence
3150      set (OP[0] OP[2])
3151      set (OP[1] OP[3])
3152    is valid.  Naturally, output operand ordering is little-endian.
3153    This is used by *movtf_internal and *movti_internal.  */
3154   
3155 void
3156 alpha_split_tmode_pair (rtx operands[4], enum machine_mode mode,
3157                         bool fixup_overlap)
3158 {
3159   switch (GET_CODE (operands[1]))
3160     {
3161     case REG:
3162       operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
3163       operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
3164       break;
3165
3166     case MEM:
3167       operands[3] = adjust_address (operands[1], DImode, 8);
3168       operands[2] = adjust_address (operands[1], DImode, 0);
3169       break;
3170
3171     case CONST_INT:
3172     case CONST_DOUBLE:
3173       gcc_assert (operands[1] == CONST0_RTX (mode));
3174       operands[2] = operands[3] = const0_rtx;
3175       break;
3176
3177     default:
3178       gcc_unreachable ();
3179     }
3180
3181   switch (GET_CODE (operands[0]))
3182     {
3183     case REG:
3184       operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
3185       operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
3186       break;
3187
3188     case MEM:
3189       operands[1] = adjust_address (operands[0], DImode, 8);
3190       operands[0] = adjust_address (operands[0], DImode, 0);
3191       break;
3192
3193     default:
3194       gcc_unreachable ();
3195     }
3196
3197   if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
3198     {
3199       rtx tmp;
3200       tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
3201       tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
3202     }
3203 }
3204
3205 /* Implement negtf2 or abstf2.  Op0 is destination, op1 is source,
3206    op2 is a register containing the sign bit, operation is the
3207    logical operation to be performed.  */
3208
3209 void
3210 alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
3211 {
3212   rtx high_bit = operands[2];
3213   rtx scratch;
3214   int move;
3215
3216   alpha_split_tmode_pair (operands, TFmode, false);
3217
3218   /* Detect three flavors of operand overlap.  */
3219   move = 1;
3220   if (rtx_equal_p (operands[0], operands[2]))
3221     move = 0;
3222   else if (rtx_equal_p (operands[1], operands[2]))
3223     {
3224       if (rtx_equal_p (operands[0], high_bit))
3225         move = 2;
3226       else
3227         move = -1;
3228     }
3229
3230   if (move < 0)
3231     emit_move_insn (operands[0], operands[2]);
3232
3233   /* ??? If the destination overlaps both source tf and high_bit, then
3234      assume source tf is dead in its entirety and use the other half
3235      for a scratch register.  Otherwise "scratch" is just the proper
3236      destination register.  */
3237   scratch = operands[move < 2 ? 1 : 3];
3238
3239   emit_insn ((*operation) (scratch, high_bit, operands[3]));
3240
3241   if (move > 0)
3242     {
3243       emit_move_insn (operands[0], operands[2]);
3244       if (move > 1)
3245         emit_move_insn (operands[1], scratch);
3246     }
3247 }
3248 \f
3249 /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
3250    unaligned data:
3251
3252            unsigned:                       signed:
3253    word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
3254            ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
3255            lda    r3,X(r11)                lda    r3,X+2(r11)
3256            extwl  r1,r3,r1                 extql  r1,r3,r1
3257            extwh  r2,r3,r2                 extqh  r2,r3,r2
3258            or     r1.r2.r1                 or     r1,r2,r1
3259                                            sra    r1,48,r1
3260
3261    long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
3262            ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
3263            lda    r3,X(r11)                lda    r3,X(r11)
3264            extll  r1,r3,r1                 extll  r1,r3,r1
3265            extlh  r2,r3,r2                 extlh  r2,r3,r2
3266            or     r1.r2.r1                 addl   r1,r2,r1
3267
3268    quad:   ldq_u  r1,X(r11)
3269            ldq_u  r2,X+7(r11)
3270            lda    r3,X(r11)
3271            extql  r1,r3,r1
3272            extqh  r2,r3,r2
3273            or     r1.r2.r1
3274 */
3275
3276 void
3277 alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
3278                              HOST_WIDE_INT ofs, int sign)
3279 {
3280   rtx meml, memh, addr, extl, exth, tmp, mema;
3281   enum machine_mode mode;
3282
3283   if (TARGET_BWX && size == 2)
3284     {
3285       meml = adjust_address (mem, QImode, ofs);
3286       memh = adjust_address (mem, QImode, ofs+1);
3287       extl = gen_reg_rtx (DImode);
3288       exth = gen_reg_rtx (DImode);
3289       emit_insn (gen_zero_extendqidi2 (extl, meml));
3290       emit_insn (gen_zero_extendqidi2 (exth, memh));
3291       exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
3292                                   NULL, 1, OPTAB_LIB_WIDEN);
3293       addr = expand_simple_binop (DImode, IOR, extl, exth,
3294                                   NULL, 1, OPTAB_LIB_WIDEN);
3295
3296       if (sign && GET_MODE (tgt) != HImode)
3297         {
3298           addr = gen_lowpart (HImode, addr);
3299           emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
3300         }
3301       else
3302         {
3303           if (GET_MODE (tgt) != DImode)
3304             addr = gen_lowpart (GET_MODE (tgt), addr);
3305           emit_move_insn (tgt, addr);
3306         }
3307       return;
3308     }
3309
3310   meml = gen_reg_rtx (DImode);
3311   memh = gen_reg_rtx (DImode);
3312   addr = gen_reg_rtx (DImode);
3313   extl = gen_reg_rtx (DImode);
3314   exth = gen_reg_rtx (DImode);
3315
3316   mema = XEXP (mem, 0);
3317   if (GET_CODE (mema) == LO_SUM)
3318     mema = force_reg (Pmode, mema);
3319
3320   /* AND addresses cannot be in any alias set, since they may implicitly
3321      alias surrounding code.  Ideally we'd have some alias set that
3322      covered all types except those with alignment 8 or higher.  */
3323
3324   tmp = change_address (mem, DImode,
3325                         gen_rtx_AND (DImode,
3326                                      plus_constant (mema, ofs),
3327                                      GEN_INT (-8)));
3328   set_mem_alias_set (tmp, 0);
3329   emit_move_insn (meml, tmp);
3330
3331   tmp = change_address (mem, DImode,
3332                         gen_rtx_AND (DImode,
3333                                      plus_constant (mema, ofs + size - 1),
3334                                      GEN_INT (-8)));
3335   set_mem_alias_set (tmp, 0);
3336   emit_move_insn (memh, tmp);
3337
3338   if (sign && size == 2)
3339     {
3340       emit_move_insn (addr, plus_constant (mema, ofs+2));
3341
3342       emit_insn (gen_extql (extl, meml, addr));
3343       emit_insn (gen_extqh (exth, memh, addr));
3344
3345       /* We must use tgt here for the target.  Alpha-vms port fails if we use
3346          addr for the target, because addr is marked as a pointer and combine
3347          knows that pointers are always sign-extended 32-bit values.  */
3348       addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
3349       addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
3350                            addr, 1, OPTAB_WIDEN);
3351     }
3352   else
3353     {
3354       emit_move_insn (addr, plus_constant (mema, ofs));
3355       emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
3356       switch ((int) size)
3357         {
3358         case 2:
3359           emit_insn (gen_extwh (exth, memh, addr));
3360           mode = HImode;
3361           break;
3362         case 4:
3363           emit_insn (gen_extlh (exth, memh, addr));
3364           mode = SImode;
3365           break;
3366         case 8:
3367           emit_insn (gen_extqh (exth, memh, addr));
3368           mode = DImode;
3369           break;
3370         default:
3371           gcc_unreachable ();
3372         }
3373
3374       addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
3375                            gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
3376                            sign, OPTAB_WIDEN);
3377     }
3378
3379   if (addr != tgt)
3380     emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
3381 }
3382
3383 /* Similarly, use ins and msk instructions to perform unaligned stores.  */
3384
3385 void
3386 alpha_expand_unaligned_store (rtx dst, rtx src,
3387                               HOST_WIDE_INT size, HOST_WIDE_INT ofs)
3388 {
3389   rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
3390
3391   if (TARGET_BWX && size == 2)
3392     {
3393       if (src != const0_rtx)
3394         {
3395           dstl = gen_lowpart (QImode, src);
3396           dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
3397                                       NULL, 1, OPTAB_LIB_WIDEN);
3398           dsth = gen_lowpart (QImode, dsth);
3399         }
3400       else
3401         dstl = dsth = const0_rtx;
3402
3403       meml = adjust_address (dst, QImode, ofs);
3404       memh = adjust_address (dst, QImode, ofs+1);
3405
3406       emit_move_insn (meml, dstl);
3407       emit_move_insn (memh, dsth);
3408       return;
3409     }
3410
3411   dstl = gen_reg_rtx (DImode);
3412   dsth = gen_reg_rtx (DImode);
3413   insl = gen_reg_rtx (DImode);
3414   insh = gen_reg_rtx (DImode);
3415
3416   dsta = XEXP (dst, 0);
3417   if (GET_CODE (dsta) == LO_SUM)
3418     dsta = force_reg (Pmode, dsta);
3419
3420   /* AND addresses cannot be in any alias set, since they may implicitly
3421      alias surrounding code.  Ideally we'd have some alias set that
3422      covered all types except those with alignment 8 or higher.  */
3423
3424   meml = change_address (dst, DImode,
3425                          gen_rtx_AND (DImode,
3426                                       plus_constant (dsta, ofs),
3427                                       GEN_INT (-8)));
3428   set_mem_alias_set (meml, 0);
3429
3430   memh = change_address (dst, DImode,
3431                          gen_rtx_AND (DImode,
3432                                       plus_constant (dsta, ofs + size - 1),
3433                                       GEN_INT (-8)));
3434   set_mem_alias_set (memh, 0);
3435
3436   emit_move_insn (dsth, memh);
3437   emit_move_insn (dstl, meml);
3438
3439   addr = copy_addr_to_reg (plus_constant (dsta, ofs));
3440
3441   if (src != CONST0_RTX (GET_MODE (src)))
3442     {
3443       emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
3444                             GEN_INT (size*8), addr));
3445
3446       switch ((int) size)
3447         {
3448         case 2:
3449           emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
3450           break;
3451         case 4:
3452           emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
3453           break;
3454         case 8:
3455           emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr));
3456           break;
3457         default:
3458           gcc_unreachable ();
3459         }
3460     }
3461
3462   emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
3463
3464   switch ((int) size)
3465     {
3466     case 2:
3467       emit_insn (gen_mskwl (dstl, dstl, addr));
3468       break;
3469     case 4:
3470       emit_insn (gen_mskll (dstl, dstl, addr));
3471       break;
3472     case 8:
3473       emit_insn (gen_mskql (dstl, dstl, addr));
3474       break;
3475     default:
3476       gcc_unreachable ();
3477     }
3478
3479   if (src != CONST0_RTX (GET_MODE (src)))
3480     {
3481       dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
3482       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
3483     }
3484
3485   /* Must store high before low for degenerate case of aligned.  */
3486   emit_move_insn (memh, dsth);
3487   emit_move_insn (meml, dstl);
3488 }
3489
3490 /* The block move code tries to maximize speed by separating loads and
3491    stores at the expense of register pressure: we load all of the data
3492    before we store it back out.  There are two secondary effects worth
3493    mentioning, that this speeds copying to/from aligned and unaligned
3494    buffers, and that it makes the code significantly easier to write.  */
3495
3496 #define MAX_MOVE_WORDS  8
3497
3498 /* Load an integral number of consecutive unaligned quadwords.  */
3499
3500 static void
3501 alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
3502                                    HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3503 {
3504   rtx const im8 = GEN_INT (-8);
3505   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
3506   rtx sreg, areg, tmp, smema;
3507   HOST_WIDE_INT i;
3508
3509   smema = XEXP (smem, 0);
3510   if (GET_CODE (smema) == LO_SUM)
3511     smema = force_reg (Pmode, smema);
3512
3513   /* Generate all the tmp registers we need.  */
3514   for (i = 0; i < words; ++i)
3515     {
3516       data_regs[i] = out_regs[i];
3517       ext_tmps[i] = gen_reg_rtx (DImode);
3518     }
3519   data_regs[words] = gen_reg_rtx (DImode);
3520
3521   if (ofs != 0)
3522     smem = adjust_address (smem, GET_MODE (smem), ofs);
3523
3524   /* Load up all of the source data.  */
3525   for (i = 0; i < words; ++i)
3526     {
3527       tmp = change_address (smem, DImode,
3528                             gen_rtx_AND (DImode,
3529                                          plus_constant (smema, 8*i),
3530                                          im8));
3531       set_mem_alias_set (tmp, 0);
3532       emit_move_insn (data_regs[i], tmp);
3533     }
3534
3535   tmp = change_address (smem, DImode,
3536                         gen_rtx_AND (DImode,
3537                                      plus_constant (smema, 8*words - 1),
3538                                      im8));
3539   set_mem_alias_set (tmp, 0);
3540   emit_move_insn (data_regs[words], tmp);
3541
3542   /* Extract the half-word fragments.  Unfortunately DEC decided to make
3543      extxh with offset zero a noop instead of zeroing the register, so
3544      we must take care of that edge condition ourselves with cmov.  */
3545
3546   sreg = copy_addr_to_reg (smema);
3547   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
3548                        1, OPTAB_WIDEN);
3549   for (i = 0; i < words; ++i)
3550     {
3551       emit_insn (gen_extql (data_regs[i], data_regs[i], sreg));
3552       emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
3553       emit_insn (gen_rtx_SET (VOIDmode, ext_tmps[i],
3554                               gen_rtx_IF_THEN_ELSE (DImode,
3555                                                     gen_rtx_EQ (DImode, areg,
3556                                                                 const0_rtx),
3557                                                     const0_rtx, ext_tmps[i])));
3558     }
3559
3560   /* Merge the half-words into whole words.  */
3561   for (i = 0; i < words; ++i)
3562     {
3563       out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
3564                                   ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
3565     }
3566 }
3567
3568 /* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
3569    may be NULL to store zeros.  */
3570
3571 static void
3572 alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
3573                                     HOST_WIDE_INT words, HOST_WIDE_INT ofs)
3574 {
3575   rtx const im8 = GEN_INT (-8);
3576   rtx ins_tmps[MAX_MOVE_WORDS];
3577   rtx st_tmp_1, st_tmp_2, dreg;
3578   rtx st_addr_1, st_addr_2, dmema;
3579   HOST_WIDE_INT i;
3580
3581   dmema = XEXP (dmem, 0);
3582   if (GET_CODE (dmema) == LO_SUM)
3583     dmema = force_reg (Pmode, dmema);
3584
3585   /* Generate all the tmp registers we need.  */
3586   if (data_regs != NULL)
3587     for (i = 0; i < words; ++i)
3588       ins_tmps[i] = gen_reg_rtx(DImode);
3589   st_tmp_1 = gen_reg_rtx(DImode);
3590   st_tmp_2 = gen_reg_rtx(DImode);
3591
3592   if (ofs != 0)
3593     dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
3594
3595   st_addr_2 = change_address (dmem, DImode,
3596                               gen_rtx_AND (DImode,
3597                                            plus_constant (dmema, words*8 - 1),
3598                                        im8));
3599   set_mem_alias_set (st_addr_2, 0);
3600
3601   st_addr_1 = change_address (dmem, DImode,
3602                               gen_rtx_AND (DImode, dmema, im8));
3603   set_mem_alias_set (st_addr_1, 0);
3604
3605   /* Load up the destination end bits.  */
3606   emit_move_insn (st_tmp_2, st_addr_2);
3607   emit_move_insn (st_tmp_1, st_addr_1);
3608
3609   /* Shift the input data into place.  */
3610   dreg = copy_addr_to_reg (dmema);
3611   if (data_regs != NULL)
3612     {
3613       for (i = words-1; i >= 0; --i)
3614         {
3615           emit_insn (gen_insqh (ins_tmps[i], data_regs[i], dreg));
3616           emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
3617         }
3618       for (i = words-1; i > 0; --i)
3619         {
3620           ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
3621                                         ins_tmps[i-1], ins_tmps[i-1], 1,
3622                                         OPTAB_WIDEN);
3623         }
3624     }
3625
3626   /* Split and merge the ends with the destination data.  */
3627   emit_insn (gen_mskqh (st_tmp_2, st_tmp_2, dreg));
3628   emit_insn (gen_mskql (st_tmp_1, st_tmp_1, dreg));
3629
3630   if (data_regs != NULL)
3631     {
3632       st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
3633                                st_tmp_2, 1, OPTAB_WIDEN);
3634       st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
3635                                st_tmp_1, 1, OPTAB_WIDEN);
3636     }
3637
3638   /* Store it all.  */
3639   emit_move_insn (st_addr_2, st_tmp_2);
3640   for (i = words-1; i > 0; --i)
3641     {
3642       rtx tmp = change_address (dmem, DImode,
3643                                 gen_rtx_AND (DImode,
3644                                              plus_constant (dmema, i*8),
3645                                              im8));
3646       set_mem_alias_set (tmp, 0);
3647       emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
3648     }
3649   emit_move_insn (st_addr_1, st_tmp_1);
3650 }
3651
3652
3653 /* Expand string/block move operations.
3654
3655    operands[0] is the pointer to the destination.
3656    operands[1] is the pointer to the source.
3657    operands[2] is the number of bytes to move.
3658    operands[3] is the alignment.  */
3659
3660 int
3661 alpha_expand_block_move (rtx operands[])
3662 {
3663   rtx bytes_rtx = operands[2];
3664   rtx align_rtx = operands[3];
3665   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3666   HOST_WIDE_INT bytes = orig_bytes;
3667   HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
3668   HOST_WIDE_INT dst_align = src_align;
3669   rtx orig_src = operands[1];
3670   rtx orig_dst = operands[0];
3671   rtx data_regs[2 * MAX_MOVE_WORDS + 16];
3672   rtx tmp;
3673   unsigned int i, words, ofs, nregs = 0;
3674
3675   if (orig_bytes <= 0)
3676     return 1;
3677   else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3678     return 0;
3679
3680   /* Look for additional alignment information from recorded register info.  */
3681
3682   tmp = XEXP (orig_src, 0);
3683   if (REG_P (tmp))
3684     src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3685   else if (GET_CODE (tmp) == PLUS
3686            && REG_P (XEXP (tmp, 0))
3687            && CONST_INT_P (XEXP (tmp, 1)))
3688     {
3689       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3690       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3691
3692       if (a > src_align)
3693         {
3694           if (a >= 64 && c % 8 == 0)
3695             src_align = 64;
3696           else if (a >= 32 && c % 4 == 0)
3697             src_align = 32;
3698           else if (a >= 16 && c % 2 == 0)
3699             src_align = 16;
3700         }
3701     }
3702
3703   tmp = XEXP (orig_dst, 0);
3704   if (REG_P (tmp))
3705     dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3706   else if (GET_CODE (tmp) == PLUS
3707            && REG_P (XEXP (tmp, 0))
3708            && CONST_INT_P (XEXP (tmp, 1)))
3709     {
3710       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3711       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3712
3713       if (a > dst_align)
3714         {
3715           if (a >= 64 && c % 8 == 0)
3716             dst_align = 64;
3717           else if (a >= 32 && c % 4 == 0)
3718             dst_align = 32;
3719           else if (a >= 16 && c % 2 == 0)
3720             dst_align = 16;
3721         }
3722     }
3723
3724   ofs = 0;
3725   if (src_align >= 64 && bytes >= 8)
3726     {
3727       words = bytes / 8;
3728
3729       for (i = 0; i < words; ++i)
3730         data_regs[nregs + i] = gen_reg_rtx (DImode);
3731
3732       for (i = 0; i < words; ++i)
3733         emit_move_insn (data_regs[nregs + i],
3734                         adjust_address (orig_src, DImode, ofs + i * 8));
3735
3736       nregs += words;
3737       bytes -= words * 8;
3738       ofs += words * 8;
3739     }
3740
3741   if (src_align >= 32 && bytes >= 4)
3742     {
3743       words = bytes / 4;
3744
3745       for (i = 0; i < words; ++i)
3746         data_regs[nregs + i] = gen_reg_rtx (SImode);
3747
3748       for (i = 0; i < words; ++i)
3749         emit_move_insn (data_regs[nregs + i],
3750                         adjust_address (orig_src, SImode, ofs + i * 4));
3751
3752       nregs += words;
3753       bytes -= words * 4;
3754       ofs += words * 4;
3755     }
3756
3757   if (bytes >= 8)
3758     {
3759       words = bytes / 8;
3760
3761       for (i = 0; i < words+1; ++i)
3762         data_regs[nregs + i] = gen_reg_rtx (DImode);
3763
3764       alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
3765                                          words, ofs);
3766
3767       nregs += words;
3768       bytes -= words * 8;
3769       ofs += words * 8;
3770     }
3771
3772   if (! TARGET_BWX && bytes >= 4)
3773     {
3774       data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
3775       alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
3776       bytes -= 4;
3777       ofs += 4;
3778     }
3779
3780   if (bytes >= 2)
3781     {
3782       if (src_align >= 16)
3783         {
3784           do {
3785             data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3786             emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
3787             bytes -= 2;
3788             ofs += 2;
3789           } while (bytes >= 2);
3790         }
3791       else if (! TARGET_BWX)
3792         {
3793           data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
3794           alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
3795           bytes -= 2;
3796           ofs += 2;
3797         }
3798     }
3799
3800   while (bytes > 0)
3801     {
3802       data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
3803       emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
3804       bytes -= 1;
3805       ofs += 1;
3806     }
3807
3808   gcc_assert (nregs <= ARRAY_SIZE (data_regs));
3809
3810   /* Now save it back out again.  */
3811
3812   i = 0, ofs = 0;
3813
3814   /* Write out the data in whatever chunks reading the source allowed.  */
3815   if (dst_align >= 64)
3816     {
3817       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3818         {
3819           emit_move_insn (adjust_address (orig_dst, DImode, ofs),
3820                           data_regs[i]);
3821           ofs += 8;
3822           i++;
3823         }
3824     }
3825
3826   if (dst_align >= 32)
3827     {
3828       /* If the source has remaining DImode regs, write them out in
3829          two pieces.  */
3830       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
3831         {
3832           tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
3833                               NULL_RTX, 1, OPTAB_WIDEN);
3834
3835           emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3836                           gen_lowpart (SImode, data_regs[i]));
3837           emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
3838                           gen_lowpart (SImode, tmp));
3839           ofs += 8;
3840           i++;
3841         }
3842
3843       while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3844         {
3845           emit_move_insn (adjust_address (orig_dst, SImode, ofs),
3846                           data_regs[i]);
3847           ofs += 4;
3848           i++;
3849         }
3850     }
3851
3852   if (i < nregs && GET_MODE (data_regs[i]) == DImode)
3853     {
3854       /* Write out a remaining block of words using unaligned methods.  */
3855
3856       for (words = 1; i + words < nregs; words++)
3857         if (GET_MODE (data_regs[i + words]) != DImode)
3858           break;
3859
3860       if (words == 1)
3861         alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
3862       else
3863         alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
3864                                             words, ofs);
3865
3866       i += words;
3867       ofs += words * 8;
3868     }
3869
3870   /* Due to the above, this won't be aligned.  */
3871   /* ??? If we have more than one of these, consider constructing full
3872      words in registers and using alpha_expand_unaligned_store_words.  */
3873   while (i < nregs && GET_MODE (data_regs[i]) == SImode)
3874     {
3875       alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
3876       ofs += 4;
3877       i++;
3878     }
3879
3880   if (dst_align >= 16)
3881     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3882       {
3883         emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
3884         i++;
3885         ofs += 2;
3886       }
3887   else
3888     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
3889       {
3890         alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
3891         i++;
3892         ofs += 2;
3893       }
3894
3895   /* The remainder must be byte copies.  */
3896   while (i < nregs)
3897     {
3898       gcc_assert (GET_MODE (data_regs[i]) == QImode);
3899       emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
3900       i++;
3901       ofs += 1;
3902     }
3903
3904   return 1;
3905 }
3906
3907 int
3908 alpha_expand_block_clear (rtx operands[])
3909 {
3910   rtx bytes_rtx = operands[1];
3911   rtx align_rtx = operands[3];
3912   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
3913   HOST_WIDE_INT bytes = orig_bytes;
3914   HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
3915   HOST_WIDE_INT alignofs = 0;
3916   rtx orig_dst = operands[0];
3917   rtx tmp;
3918   int i, words, ofs = 0;
3919
3920   if (orig_bytes <= 0)
3921     return 1;
3922   if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
3923     return 0;
3924
3925   /* Look for stricter alignment.  */
3926   tmp = XEXP (orig_dst, 0);
3927   if (REG_P (tmp))
3928     align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
3929   else if (GET_CODE (tmp) == PLUS
3930            && REG_P (XEXP (tmp, 0))
3931            && CONST_INT_P (XEXP (tmp, 1)))
3932     {
3933       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
3934       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
3935
3936       if (a > align)
3937         {
3938           if (a >= 64)
3939             align = a, alignofs = 8 - c % 8;
3940           else if (a >= 32)
3941             align = a, alignofs = 4 - c % 4;
3942           else if (a >= 16)
3943             align = a, alignofs = 2 - c % 2;
3944         }
3945     }
3946
3947   /* Handle an unaligned prefix first.  */
3948
3949   if (alignofs > 0)
3950     {
3951 #if HOST_BITS_PER_WIDE_INT >= 64
3952       /* Given that alignofs is bounded by align, the only time BWX could
3953          generate three stores is for a 7 byte fill.  Prefer two individual
3954          stores over a load/mask/store sequence.  */
3955       if ((!TARGET_BWX || alignofs == 7)
3956                && align >= 32
3957                && !(alignofs == 4 && bytes >= 4))
3958         {
3959           enum machine_mode mode = (align >= 64 ? DImode : SImode);
3960           int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
3961           rtx mem, tmp;
3962           HOST_WIDE_INT mask;
3963
3964           mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
3965           set_mem_alias_set (mem, 0);
3966
3967           mask = ~(~(HOST_WIDE_INT)0 << (inv_alignofs * 8));
3968           if (bytes < alignofs)
3969             {
3970               mask |= ~(HOST_WIDE_INT)0 << ((inv_alignofs + bytes) * 8);
3971               ofs += bytes;
3972               bytes = 0;
3973             }
3974           else
3975             {
3976               bytes -= alignofs;
3977               ofs += alignofs;
3978             }
3979           alignofs = 0;
3980
3981           tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
3982                               NULL_RTX, 1, OPTAB_WIDEN);
3983
3984           emit_move_insn (mem, tmp);
3985         }
3986 #endif
3987
3988       if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
3989         {
3990           emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
3991           bytes -= 1;
3992           ofs += 1;
3993           alignofs -= 1;
3994         }
3995       if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
3996         {
3997           emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
3998           bytes -= 2;
3999           ofs += 2;
4000           alignofs -= 2;
4001         }
4002       if (alignofs == 4 && bytes >= 4)
4003         {
4004           emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4005           bytes -= 4;
4006           ofs += 4;
4007           alignofs = 0;
4008         }
4009
4010       /* If we've not used the extra lead alignment information by now,
4011          we won't be able to.  Downgrade align to match what's left over.  */
4012       if (alignofs > 0)
4013         {
4014           alignofs = alignofs & -alignofs;
4015           align = MIN (align, alignofs * BITS_PER_UNIT);
4016         }
4017     }
4018
4019   /* Handle a block of contiguous long-words.  */
4020
4021   if (align >= 64 && bytes >= 8)
4022     {
4023       words = bytes / 8;
4024
4025       for (i = 0; i < words; ++i)
4026         emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
4027                         const0_rtx);
4028
4029       bytes -= words * 8;
4030       ofs += words * 8;
4031     }
4032
4033   /* If the block is large and appropriately aligned, emit a single
4034      store followed by a sequence of stq_u insns.  */
4035
4036   if (align >= 32 && bytes > 16)
4037     {
4038       rtx orig_dsta;
4039
4040       emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
4041       bytes -= 4;
4042       ofs += 4;
4043
4044       orig_dsta = XEXP (orig_dst, 0);
4045       if (GET_CODE (orig_dsta) == LO_SUM)
4046         orig_dsta = force_reg (Pmode, orig_dsta);
4047
4048       words = bytes / 8;
4049       for (i = 0; i < words; ++i)
4050         {
4051           rtx mem
4052             = change_address (orig_dst, DImode,
4053                               gen_rtx_AND (DImode,
4054                                            plus_constant (orig_dsta, ofs + i*8),
4055                                            GEN_INT (-8)));
4056           set_mem_alias_set (mem, 0);
4057           emit_move_insn (mem, const0_rtx);
4058         }
4059
4060       /* Depending on the alignment, the first stq_u may have overlapped
4061          with the initial stl, which means that the last stq_u didn't
4062          write as much as it would appear.  Leave those questionable bytes
4063          unaccounted for.  */
4064       bytes -= words * 8 - 4;
4065       ofs += words * 8 - 4;
4066     }
4067
4068   /* Handle a smaller block of aligned words.  */
4069
4070   if ((align >= 64 && bytes == 4)
4071       || (align == 32 && bytes >= 4))
4072     {
4073       words = bytes / 4;
4074
4075       for (i = 0; i < words; ++i)
4076         emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
4077                         const0_rtx);
4078
4079       bytes -= words * 4;
4080       ofs += words * 4;
4081     }
4082
4083   /* An unaligned block uses stq_u stores for as many as possible.  */
4084
4085   if (bytes >= 8)
4086     {
4087       words = bytes / 8;
4088
4089       alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
4090
4091       bytes -= words * 8;
4092       ofs += words * 8;
4093     }
4094
4095   /* Next clean up any trailing pieces.  */
4096
4097 #if HOST_BITS_PER_WIDE_INT >= 64
4098   /* Count the number of bits in BYTES for which aligned stores could
4099      be emitted.  */
4100   words = 0;
4101   for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
4102     if (bytes & i)
4103       words += 1;
4104
4105   /* If we have appropriate alignment (and it wouldn't take too many
4106      instructions otherwise), mask out the bytes we need.  */
4107   if (TARGET_BWX ? words > 2 : bytes > 0)
4108     {
4109       if (align >= 64)
4110         {
4111           rtx mem, tmp;
4112           HOST_WIDE_INT mask;
4113
4114           mem = adjust_address (orig_dst, DImode, ofs);
4115           set_mem_alias_set (mem, 0);
4116
4117           mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4118
4119           tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
4120                               NULL_RTX, 1, OPTAB_WIDEN);
4121
4122           emit_move_insn (mem, tmp);
4123           return 1;
4124         }
4125       else if (align >= 32 && bytes < 4)
4126         {
4127           rtx mem, tmp;
4128           HOST_WIDE_INT mask;
4129
4130           mem = adjust_address (orig_dst, SImode, ofs);
4131           set_mem_alias_set (mem, 0);
4132
4133           mask = ~(HOST_WIDE_INT)0 << (bytes * 8);
4134
4135           tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
4136                               NULL_RTX, 1, OPTAB_WIDEN);
4137
4138           emit_move_insn (mem, tmp);
4139           return 1;
4140         }
4141     }
4142 #endif
4143
4144   if (!TARGET_BWX && bytes >= 4)
4145     {
4146       alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
4147       bytes -= 4;
4148       ofs += 4;
4149     }
4150
4151   if (bytes >= 2)
4152     {
4153       if (align >= 16)
4154         {
4155           do {
4156             emit_move_insn (adjust_address (orig_dst, HImode, ofs),
4157                             const0_rtx);
4158             bytes -= 2;
4159             ofs += 2;
4160           } while (bytes >= 2);
4161         }
4162       else if (! TARGET_BWX)
4163         {
4164           alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
4165           bytes -= 2;
4166           ofs += 2;
4167         }
4168     }
4169
4170   while (bytes > 0)
4171     {
4172       emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
4173       bytes -= 1;
4174       ofs += 1;
4175     }
4176
4177   return 1;
4178 }
4179
4180 /* Returns a mask so that zap(x, value) == x & mask.  */
4181
4182 rtx
4183 alpha_expand_zap_mask (HOST_WIDE_INT value)
4184 {
4185   rtx result;
4186   int i;
4187
4188   if (HOST_BITS_PER_WIDE_INT >= 64)
4189     {
4190       HOST_WIDE_INT mask = 0;
4191
4192       for (i = 7; i >= 0; --i)
4193         {
4194           mask <<= 8;
4195           if (!((value >> i) & 1))
4196             mask |= 0xff;
4197         }
4198
4199       result = gen_int_mode (mask, DImode);
4200     }
4201   else
4202     {
4203       HOST_WIDE_INT mask_lo = 0, mask_hi = 0;
4204
4205       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
4206       
4207       for (i = 7; i >= 4; --i)
4208         {
4209           mask_hi <<= 8;
4210           if (!((value >> i) & 1))
4211             mask_hi |= 0xff;
4212         }
4213
4214       for (i = 3; i >= 0; --i)
4215         {
4216           mask_lo <<= 8;
4217           if (!((value >> i) & 1))
4218             mask_lo |= 0xff;
4219         }
4220
4221       result = immed_double_const (mask_lo, mask_hi, DImode);
4222     }
4223
4224   return result;
4225 }
4226
4227 void
4228 alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
4229                                    enum machine_mode mode,
4230                                    rtx op0, rtx op1, rtx op2)
4231 {
4232   op0 = gen_lowpart (mode, op0);
4233
4234   if (op1 == const0_rtx)
4235     op1 = CONST0_RTX (mode);
4236   else
4237     op1 = gen_lowpart (mode, op1);
4238
4239   if (op2 == const0_rtx)
4240     op2 = CONST0_RTX (mode);
4241   else
4242     op2 = gen_lowpart (mode, op2);
4243
4244   emit_insn ((*gen) (op0, op1, op2));
4245 }
4246
4247 /* A subroutine of the atomic operation splitters.  Jump to LABEL if
4248    COND is true.  Mark the jump as unlikely to be taken.  */
4249
4250 static void
4251 emit_unlikely_jump (rtx cond, rtx label)
4252 {
4253   rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
4254   rtx x;
4255
4256   x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
4257   x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
4258   add_reg_note (x, REG_BR_PROB, very_unlikely);
4259 }
4260
4261 /* A subroutine of the atomic operation splitters.  Emit a load-locked
4262    instruction in MODE.  */
4263
4264 static void
4265 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
4266 {
4267   rtx (*fn) (rtx, rtx) = NULL;
4268   if (mode == SImode)
4269     fn = gen_load_locked_si;
4270   else if (mode == DImode)
4271     fn = gen_load_locked_di;
4272   emit_insn (fn (reg, mem));
4273 }
4274
4275 /* A subroutine of the atomic operation splitters.  Emit a store-conditional
4276    instruction in MODE.  */
4277
4278 static void
4279 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
4280 {
4281   rtx (*fn) (rtx, rtx, rtx) = NULL;
4282   if (mode == SImode)
4283     fn = gen_store_conditional_si;
4284   else if (mode == DImode)
4285     fn = gen_store_conditional_di;
4286   emit_insn (fn (res, mem, val));
4287 }
4288
4289 /* A subroutine of the atomic operation splitters.  Emit an insxl
4290    instruction in MODE.  */
4291
4292 static rtx
4293 emit_insxl (enum machine_mode mode, rtx op1, rtx op2)
4294 {
4295   rtx ret = gen_reg_rtx (DImode);
4296   rtx (*fn) (rtx, rtx, rtx);
4297
4298   switch (mode)
4299     {
4300     case QImode:
4301       fn = gen_insbl;
4302       break;
4303     case HImode:
4304       fn = gen_inswl;
4305       break;
4306     case SImode:
4307       fn = gen_insll;
4308       break;
4309     case DImode:
4310       fn = gen_insql;
4311       break;
4312     default:
4313       gcc_unreachable ();
4314     }
4315
4316   op1 = force_reg (mode, op1);
4317   emit_insn (fn (ret, op1, op2));
4318
4319   return ret;
4320 }
4321
4322 /* Expand an atomic fetch-and-operate pattern.  CODE is the binary operation
4323    to perform.  MEM is the memory on which to operate.  VAL is the second 
4324    operand of the binary operator.  BEFORE and AFTER are optional locations to
4325    return the value of MEM either before of after the operation.  SCRATCH is
4326    a scratch register.  */
4327
4328 void
4329 alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
4330                        rtx before, rtx after, rtx scratch)
4331 {
4332   enum machine_mode mode = GET_MODE (mem);
4333   rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch));
4334
4335   emit_insn (gen_memory_barrier ());
4336
4337   label = gen_label_rtx ();
4338   emit_label (label);
4339   label = gen_rtx_LABEL_REF (DImode, label);
4340
4341   if (before == NULL)
4342     before = scratch;
4343   emit_load_locked (mode, before, mem);
4344
4345   if (code == NOT)
4346     {
4347       x = gen_rtx_AND (mode, before, val);
4348       emit_insn (gen_rtx_SET (VOIDmode, val, x));
4349
4350       x = gen_rtx_NOT (mode, val);
4351     }
4352   else
4353     x = gen_rtx_fmt_ee (code, mode, before, val);
4354   if (after)
4355     emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
4356   emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
4357
4358   emit_store_conditional (mode, cond, mem, scratch);
4359
4360   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4361   emit_unlikely_jump (x, label);
4362
4363   emit_insn (gen_memory_barrier ());
4364 }
4365
4366 /* Expand a compare and swap operation.  */
4367
4368 void
4369 alpha_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
4370                               rtx scratch)
4371 {
4372   enum machine_mode mode = GET_MODE (mem);
4373   rtx label1, label2, x, cond = gen_lowpart (DImode, scratch);
4374
4375   emit_insn (gen_memory_barrier ());
4376
4377   label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4378   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4379   emit_label (XEXP (label1, 0));
4380
4381   emit_load_locked (mode, retval, mem);
4382
4383   x = gen_lowpart (DImode, retval);
4384   if (oldval == const0_rtx)
4385     x = gen_rtx_NE (DImode, x, const0_rtx);
4386   else
4387     {
4388       x = gen_rtx_EQ (DImode, x, oldval);
4389       emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4390       x = gen_rtx_EQ (DImode, cond, const0_rtx);
4391     }
4392   emit_unlikely_jump (x, label2);
4393
4394   emit_move_insn (scratch, newval);
4395   emit_store_conditional (mode, cond, mem, scratch);
4396
4397   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4398   emit_unlikely_jump (x, label1);
4399
4400   emit_insn (gen_memory_barrier ());
4401   emit_label (XEXP (label2, 0));
4402 }
4403
4404 void
4405 alpha_expand_compare_and_swap_12 (rtx dst, rtx mem, rtx oldval, rtx newval)
4406 {
4407   enum machine_mode mode = GET_MODE (mem);
4408   rtx addr, align, wdst;
4409   rtx (*fn5) (rtx, rtx, rtx, rtx, rtx);
4410
4411   addr = force_reg (DImode, XEXP (mem, 0));
4412   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4413                                NULL_RTX, 1, OPTAB_DIRECT);
4414
4415   oldval = convert_modes (DImode, mode, oldval, 1);
4416   newval = emit_insxl (mode, newval, addr);
4417
4418   wdst = gen_reg_rtx (DImode);
4419   if (mode == QImode)
4420     fn5 = gen_sync_compare_and_swapqi_1;
4421   else
4422     fn5 = gen_sync_compare_and_swaphi_1;
4423   emit_insn (fn5 (wdst, addr, oldval, newval, align));
4424
4425   emit_move_insn (dst, gen_lowpart (mode, wdst));
4426 }
4427
4428 void
4429 alpha_split_compare_and_swap_12 (enum machine_mode mode, rtx dest, rtx addr,
4430                                  rtx oldval, rtx newval, rtx align,
4431                                  rtx scratch, rtx cond)
4432 {
4433   rtx label1, label2, mem, width, mask, x;
4434
4435   mem = gen_rtx_MEM (DImode, align);
4436   MEM_VOLATILE_P (mem) = 1;
4437
4438   emit_insn (gen_memory_barrier ());
4439   label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4440   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4441   emit_label (XEXP (label1, 0));
4442
4443   emit_load_locked (DImode, scratch, mem);
4444   
4445   width = GEN_INT (GET_MODE_BITSIZE (mode));
4446   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4447   emit_insn (gen_extxl (dest, scratch, width, addr));
4448
4449   if (oldval == const0_rtx)
4450     x = gen_rtx_NE (DImode, dest, const0_rtx);
4451   else
4452     {
4453       x = gen_rtx_EQ (DImode, dest, oldval);
4454       emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4455       x = gen_rtx_EQ (DImode, cond, const0_rtx);
4456     }
4457   emit_unlikely_jump (x, label2);
4458
4459   emit_insn (gen_mskxl (scratch, scratch, mask, addr));
4460   emit_insn (gen_iordi3 (scratch, scratch, newval));
4461
4462   emit_store_conditional (DImode, scratch, mem, scratch);
4463
4464   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4465   emit_unlikely_jump (x, label1);
4466
4467   emit_insn (gen_memory_barrier ());
4468   emit_label (XEXP (label2, 0));
4469 }
4470
4471 /* Expand an atomic exchange operation.  */
4472
4473 void
4474 alpha_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
4475 {
4476   enum machine_mode mode = GET_MODE (mem);
4477   rtx label, x, cond = gen_lowpart (DImode, scratch);
4478
4479   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4480   emit_label (XEXP (label, 0));
4481
4482   emit_load_locked (mode, retval, mem);
4483   emit_move_insn (scratch, val);
4484   emit_store_conditional (mode, cond, mem, scratch);
4485
4486   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4487   emit_unlikely_jump (x, label);
4488
4489   emit_insn (gen_memory_barrier ());
4490 }
4491
4492 void
4493 alpha_expand_lock_test_and_set_12 (rtx dst, rtx mem, rtx val)
4494 {
4495   enum machine_mode mode = GET_MODE (mem);
4496   rtx addr, align, wdst;
4497   rtx (*fn4) (rtx, rtx, rtx, rtx);
4498
4499   /* Force the address into a register.  */
4500   addr = force_reg (DImode, XEXP (mem, 0));
4501
4502   /* Align it to a multiple of 8.  */
4503   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4504                                NULL_RTX, 1, OPTAB_DIRECT);
4505
4506   /* Insert val into the correct byte location within the word.  */
4507   val = emit_insxl (mode, val, addr);
4508
4509   wdst = gen_reg_rtx (DImode);
4510   if (mode == QImode)
4511     fn4 = gen_sync_lock_test_and_setqi_1;
4512   else
4513     fn4 = gen_sync_lock_test_and_sethi_1;
4514   emit_insn (fn4 (wdst, addr, val, align));
4515
4516   emit_move_insn (dst, gen_lowpart (mode, wdst));
4517 }
4518
4519 void
4520 alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
4521                                   rtx val, rtx align, rtx scratch)
4522 {
4523   rtx label, mem, width, mask, x;
4524
4525   mem = gen_rtx_MEM (DImode, align);
4526   MEM_VOLATILE_P (mem) = 1;
4527
4528   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4529   emit_label (XEXP (label, 0));
4530
4531   emit_load_locked (DImode, scratch, mem);
4532   
4533   width = GEN_INT (GET_MODE_BITSIZE (mode));
4534   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4535   emit_insn (gen_extxl (dest, scratch, width, addr));
4536   emit_insn (gen_mskxl (scratch, scratch, mask, addr));
4537   emit_insn (gen_iordi3 (scratch, scratch, val));
4538
4539   emit_store_conditional (DImode, scratch, mem, scratch);
4540
4541   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4542   emit_unlikely_jump (x, label);
4543
4544   emit_insn (gen_memory_barrier ());
4545 }
4546 \f
4547 /* Adjust the cost of a scheduling dependency.  Return the new cost of
4548    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
4549
4550 static int
4551 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4552 {
4553   enum attr_type dep_insn_type;
4554
4555   /* If the dependence is an anti-dependence, there is no cost.  For an
4556      output dependence, there is sometimes a cost, but it doesn't seem
4557      worth handling those few cases.  */
4558   if (REG_NOTE_KIND (link) != 0)
4559     return cost;
4560
4561   /* If we can't recognize the insns, we can't really do anything.  */
4562   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4563     return cost;
4564
4565   dep_insn_type = get_attr_type (dep_insn);
4566
4567   /* Bring in the user-defined memory latency.  */
4568   if (dep_insn_type == TYPE_ILD
4569       || dep_insn_type == TYPE_FLD
4570       || dep_insn_type == TYPE_LDSYM)
4571     cost += alpha_memory_latency-1;
4572
4573   /* Everything else handled in DFA bypasses now.  */
4574
4575   return cost;
4576 }
4577
4578 /* The number of instructions that can be issued per cycle.  */
4579
4580 static int
4581 alpha_issue_rate (void)
4582 {
4583   return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
4584 }
4585
4586 /* How many alternative schedules to try.  This should be as wide as the
4587    scheduling freedom in the DFA, but no wider.  Making this value too
4588    large results extra work for the scheduler.
4589
4590    For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4591    alternative schedules.  For EV5, we can choose between E0/E1 and
4592    FA/FM.  For EV6, an arithmetic insn can be issued to U0/U1/L0/L1.  */
4593
4594 static int
4595 alpha_multipass_dfa_lookahead (void)
4596 {
4597   return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
4598 }
4599 \f
4600 /* Machine-specific function data.  */
4601
4602 struct GTY(()) machine_function
4603 {
4604   /* For OSF.  */
4605   const char *some_ld_name;
4606
4607   /* For TARGET_LD_BUGGY_LDGP.  */
4608   struct rtx_def *gp_save_rtx;
4609
4610   /* For VMS condition handlers.  */
4611   bool uses_condition_handler;  
4612 };
4613
4614 /* How to allocate a 'struct machine_function'.  */
4615
4616 static struct machine_function *
4617 alpha_init_machine_status (void)
4618 {
4619   return ggc_alloc_cleared_machine_function ();
4620 }
4621
4622 /* Support for frame based VMS condition handlers.  */
4623
4624 /* A VMS condition handler may be established for a function with a call to
4625    __builtin_establish_vms_condition_handler, and cancelled with a call to
4626    __builtin_revert_vms_condition_handler.
4627
4628    The VMS Condition Handling Facility knows about the existence of a handler
4629    from the procedure descriptor .handler field.  As the VMS native compilers,
4630    we store the user specified handler's address at a fixed location in the
4631    stack frame and point the procedure descriptor at a common wrapper which
4632    fetches the real handler's address and issues an indirect call.
4633
4634    The indirection wrapper is "__gcc_shell_handler", provided by libgcc.
4635
4636    We force the procedure kind to PT_STACK, and the fixed frame location is
4637    fp+8, just before the register save area. We use the handler_data field in
4638    the procedure descriptor to state the fp offset at which the installed
4639    handler address can be found.  */
4640
4641 #define VMS_COND_HANDLER_FP_OFFSET 8
4642
4643 /* Expand code to store the currently installed user VMS condition handler
4644    into TARGET and install HANDLER as the new condition handler.  */
4645
4646 void
4647 alpha_expand_builtin_establish_vms_condition_handler (rtx target, rtx handler)
4648 {
4649   rtx handler_slot_address
4650     = plus_constant (hard_frame_pointer_rtx, VMS_COND_HANDLER_FP_OFFSET);
4651
4652   rtx handler_slot
4653     = gen_rtx_MEM (DImode, handler_slot_address);
4654
4655   emit_move_insn (target, handler_slot);
4656   emit_move_insn (handler_slot, handler);
4657
4658   /* Notify the start/prologue/epilogue emitters that the condition handler
4659      slot is needed.  In addition to reserving the slot space, this will force
4660      the procedure kind to PT_STACK so ensure that the hard_frame_pointer_rtx
4661      use above is correct.  */
4662   cfun->machine->uses_condition_handler = true;
4663 }
4664
4665 /* Expand code to store the current VMS condition handler into TARGET and
4666    nullify it.  */
4667
4668 void
4669 alpha_expand_builtin_revert_vms_condition_handler (rtx target)
4670 {
4671   /* We implement this by establishing a null condition handler, with the tiny
4672      side effect of setting uses_condition_handler.  This is a little bit
4673      pessimistic if no actual builtin_establish call is ever issued, which is
4674      not a real problem and expected never to happen anyway.  */
4675
4676   alpha_expand_builtin_establish_vms_condition_handler (target, const0_rtx);
4677 }
4678
4679 /* Functions to save and restore alpha_return_addr_rtx.  */
4680
4681 /* Start the ball rolling with RETURN_ADDR_RTX.  */
4682
4683 rtx
4684 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4685 {
4686   if (count != 0)
4687     return const0_rtx;
4688
4689   return get_hard_reg_initial_val (Pmode, REG_RA);
4690 }
4691
4692 /* Return or create a memory slot containing the gp value for the current
4693    function.  Needed only if TARGET_LD_BUGGY_LDGP.  */
4694
4695 rtx
4696 alpha_gp_save_rtx (void)
4697 {
4698   rtx seq, m = cfun->machine->gp_save_rtx;
4699
4700   if (m == NULL)
4701     {
4702       start_sequence ();
4703
4704       m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4705       m = validize_mem (m);
4706       emit_move_insn (m, pic_offset_table_rtx);
4707
4708       seq = get_insns ();
4709       end_sequence ();
4710
4711       /* We used to simply emit the sequence after entry_of_function.
4712          However this breaks the CFG if the first instruction in the
4713          first block is not the NOTE_INSN_BASIC_BLOCK, for example a
4714          label.  Emit the sequence properly on the edge.  We are only
4715          invoked from dw2_build_landing_pads and finish_eh_generation
4716          will call commit_edge_insertions thanks to a kludge.  */
4717       insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
4718
4719       cfun->machine->gp_save_rtx = m;
4720     }
4721
4722   return m;
4723 }
4724
4725 static int
4726 alpha_ra_ever_killed (void)
4727 {
4728   rtx top;
4729
4730   if (!has_hard_reg_initial_val (Pmode, REG_RA))
4731     return (int)df_regs_ever_live_p (REG_RA);
4732
4733   push_topmost_sequence ();
4734   top = get_insns ();
4735   pop_topmost_sequence ();
4736
4737   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4738 }
4739
4740 \f
4741 /* Return the trap mode suffix applicable to the current
4742    instruction, or NULL.  */
4743
4744 static const char *
4745 get_trap_mode_suffix (void)
4746 {
4747   enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4748
4749   switch (s)
4750     {
4751     case TRAP_SUFFIX_NONE:
4752       return NULL;
4753
4754     case TRAP_SUFFIX_SU:
4755       if (alpha_fptm >= ALPHA_FPTM_SU)
4756         return "su";
4757       return NULL;
4758
4759     case TRAP_SUFFIX_SUI:
4760       if (alpha_fptm >= ALPHA_FPTM_SUI)
4761         return "sui";
4762       return NULL;
4763
4764     case TRAP_SUFFIX_V_SV:
4765       switch (alpha_fptm)
4766         {
4767         case ALPHA_FPTM_N:
4768           return NULL;
4769         case ALPHA_FPTM_U:
4770           return "v";
4771         case ALPHA_FPTM_SU:
4772         case ALPHA_FPTM_SUI:
4773           return "sv";
4774         default:
4775           gcc_unreachable ();
4776         }
4777
4778     case TRAP_SUFFIX_V_SV_SVI:
4779       switch (alpha_fptm)
4780         {
4781         case ALPHA_FPTM_N:
4782           return NULL;
4783         case ALPHA_FPTM_U:
4784           return "v";
4785         case ALPHA_FPTM_SU:
4786           return "sv";
4787         case ALPHA_FPTM_SUI:
4788           return "svi";
4789         default:
4790           gcc_unreachable ();
4791         }
4792       break;
4793
4794     case TRAP_SUFFIX_U_SU_SUI:
4795       switch (alpha_fptm)
4796         {
4797         case ALPHA_FPTM_N:
4798           return NULL;
4799         case ALPHA_FPTM_U:
4800           return "u";
4801         case ALPHA_FPTM_SU:
4802           return "su";
4803         case ALPHA_FPTM_SUI:
4804           return "sui";
4805         default:
4806           gcc_unreachable ();
4807         }
4808       break;
4809       
4810     default:
4811       gcc_unreachable ();
4812     }
4813   gcc_unreachable ();
4814 }
4815
4816 /* Return the rounding mode suffix applicable to the current
4817    instruction, or NULL.  */
4818
4819 static const char *
4820 get_round_mode_suffix (void)
4821 {
4822   enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4823
4824   switch (s)
4825     {
4826     case ROUND_SUFFIX_NONE:
4827       return NULL;
4828     case ROUND_SUFFIX_NORMAL:
4829       switch (alpha_fprm)
4830         {
4831         case ALPHA_FPRM_NORM:
4832           return NULL;
4833         case ALPHA_FPRM_MINF:
4834           return "m";
4835         case ALPHA_FPRM_CHOP:
4836           return "c";
4837         case ALPHA_FPRM_DYN:
4838           return "d";
4839         default:
4840           gcc_unreachable ();
4841         }
4842       break;
4843
4844     case ROUND_SUFFIX_C:
4845       return "c";
4846       
4847     default:
4848       gcc_unreachable ();
4849     }
4850   gcc_unreachable ();
4851 }
4852
4853 /* Locate some local-dynamic symbol still in use by this function
4854    so that we can print its name in some movdi_er_tlsldm pattern.  */
4855
4856 static int
4857 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4858 {
4859   rtx x = *px;
4860
4861   if (GET_CODE (x) == SYMBOL_REF
4862       && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4863     {
4864       cfun->machine->some_ld_name = XSTR (x, 0);
4865       return 1;
4866     }
4867
4868   return 0;
4869 }
4870
4871 static const char *
4872 get_some_local_dynamic_name (void)
4873 {
4874   rtx insn;
4875
4876   if (cfun->machine->some_ld_name)
4877     return cfun->machine->some_ld_name;
4878
4879   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4880     if (INSN_P (insn)
4881         && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4882       return cfun->machine->some_ld_name;
4883
4884   gcc_unreachable ();
4885 }
4886
4887 /* Print an operand.  Recognize special options, documented below.  */
4888
4889 void
4890 print_operand (FILE *file, rtx x, int code)
4891 {
4892   int i;
4893
4894   switch (code)
4895     {
4896     case '~':
4897       /* Print the assembler name of the current function.  */
4898       assemble_name (file, alpha_fnname);
4899       break;
4900
4901     case '&':
4902       assemble_name (file, get_some_local_dynamic_name ());
4903       break;
4904
4905     case '/':
4906       {
4907         const char *trap = get_trap_mode_suffix ();
4908         const char *round = get_round_mode_suffix ();
4909
4910         if (trap || round)
4911           fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4912                    (trap ? trap : ""), (round ? round : ""));
4913         break;
4914       }
4915
4916     case ',':
4917       /* Generates single precision instruction suffix.  */
4918       fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
4919       break;
4920
4921     case '-':
4922       /* Generates double precision instruction suffix.  */
4923       fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
4924       break;
4925
4926     case '#':
4927       if (alpha_this_literal_sequence_number == 0)
4928         alpha_this_literal_sequence_number = alpha_next_sequence_number++;
4929       fprintf (file, "%d", alpha_this_literal_sequence_number);
4930       break;
4931
4932     case '*':
4933       if (alpha_this_gpdisp_sequence_number == 0)
4934         alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
4935       fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
4936       break;
4937
4938     case 'H':
4939       if (GET_CODE (x) == HIGH)
4940         output_addr_const (file, XEXP (x, 0));
4941       else
4942         output_operand_lossage ("invalid %%H value");
4943       break;
4944
4945     case 'J':
4946       {
4947         const char *lituse;
4948
4949         if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
4950           {
4951             x = XVECEXP (x, 0, 0);
4952             lituse = "lituse_tlsgd";
4953           }
4954         else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
4955           {
4956             x = XVECEXP (x, 0, 0);
4957             lituse = "lituse_tlsldm";
4958           }
4959         else if (CONST_INT_P (x))
4960           lituse = "lituse_jsr";
4961         else
4962           {
4963             output_operand_lossage ("invalid %%J value");
4964             break;
4965           }
4966
4967         if (x != const0_rtx)
4968           fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4969       }
4970       break;
4971
4972     case 'j':
4973       {
4974         const char *lituse;
4975
4976 #ifdef HAVE_AS_JSRDIRECT_RELOCS
4977         lituse = "lituse_jsrdirect";
4978 #else
4979         lituse = "lituse_jsr";
4980 #endif
4981
4982         gcc_assert (INTVAL (x) != 0);
4983         fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
4984       }
4985       break;
4986     case 'r':
4987       /* If this operand is the constant zero, write it as "$31".  */
4988       if (REG_P (x))
4989         fprintf (file, "%s", reg_names[REGNO (x)]);
4990       else if (x == CONST0_RTX (GET_MODE (x)))
4991         fprintf (file, "$31");
4992       else
4993         output_operand_lossage ("invalid %%r value");
4994       break;
4995
4996     case 'R':
4997       /* Similar, but for floating-point.  */
4998       if (REG_P (x))
4999         fprintf (file, "%s", reg_names[REGNO (x)]);
5000       else if (x == CONST0_RTX (GET_MODE (x)))
5001         fprintf (file, "$f31");
5002       else
5003         output_operand_lossage ("invalid %%R value");
5004       break;
5005
5006     case 'N':
5007       /* Write the 1's complement of a constant.  */
5008       if (!CONST_INT_P (x))
5009         output_operand_lossage ("invalid %%N value");
5010
5011       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
5012       break;
5013
5014     case 'P':
5015       /* Write 1 << C, for a constant C.  */
5016       if (!CONST_INT_P (x))
5017         output_operand_lossage ("invalid %%P value");
5018
5019       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
5020       break;
5021
5022     case 'h':
5023       /* Write the high-order 16 bits of a constant, sign-extended.  */
5024       if (!CONST_INT_P (x))
5025         output_operand_lossage ("invalid %%h value");
5026
5027       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
5028       break;
5029
5030     case 'L':
5031       /* Write the low-order 16 bits of a constant, sign-extended.  */
5032       if (!CONST_INT_P (x))
5033         output_operand_lossage ("invalid %%L value");
5034
5035       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5036                (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
5037       break;
5038
5039     case 'm':
5040       /* Write mask for ZAP insn.  */
5041       if (GET_CODE (x) == CONST_DOUBLE)
5042         {
5043           HOST_WIDE_INT mask = 0;
5044           HOST_WIDE_INT value;
5045
5046           value = CONST_DOUBLE_LOW (x);
5047           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5048                i++, value >>= 8)
5049             if (value & 0xff)
5050               mask |= (1 << i);
5051
5052           value = CONST_DOUBLE_HIGH (x);
5053           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5054                i++, value >>= 8)
5055             if (value & 0xff)
5056               mask |= (1 << (i + sizeof (int)));
5057
5058           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
5059         }
5060
5061       else if (CONST_INT_P (x))
5062         {
5063           HOST_WIDE_INT mask = 0, value = INTVAL (x);
5064
5065           for (i = 0; i < 8; i++, value >>= 8)
5066             if (value & 0xff)
5067               mask |= (1 << i);
5068
5069           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
5070         }
5071       else
5072         output_operand_lossage ("invalid %%m value");
5073       break;
5074
5075     case 'M':
5076       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
5077       if (!CONST_INT_P (x)
5078           || (INTVAL (x) != 8 && INTVAL (x) != 16
5079               && INTVAL (x) != 32 && INTVAL (x) != 64))
5080         output_operand_lossage ("invalid %%M value");
5081
5082       fprintf (file, "%s",
5083                (INTVAL (x) == 8 ? "b"
5084                 : INTVAL (x) == 16 ? "w"
5085                 : INTVAL (x) == 32 ? "l"
5086                 : "q"));
5087       break;
5088
5089     case 'U':
5090       /* Similar, except do it from the mask.  */
5091       if (CONST_INT_P (x))
5092         {
5093           HOST_WIDE_INT value = INTVAL (x);
5094
5095           if (value == 0xff)
5096             {
5097               fputc ('b', file);
5098               break;
5099             }
5100           if (value == 0xffff)
5101             {
5102               fputc ('w', file);
5103               break;
5104             }
5105           if (value == 0xffffffff)
5106             {
5107               fputc ('l', file);
5108               break;
5109             }
5110           if (value == -1)
5111             {
5112               fputc ('q', file);
5113               break;
5114             }
5115         }
5116       else if (HOST_BITS_PER_WIDE_INT == 32
5117                && GET_CODE (x) == CONST_DOUBLE
5118                && CONST_DOUBLE_LOW (x) == 0xffffffff
5119                && CONST_DOUBLE_HIGH (x) == 0)
5120         {
5121           fputc ('l', file);
5122           break;
5123         }
5124       output_operand_lossage ("invalid %%U value");
5125       break;
5126
5127     case 's':
5128       /* Write the constant value divided by 8.  */
5129       if (!CONST_INT_P (x)
5130           || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5131           || (INTVAL (x) & 7) != 0)
5132         output_operand_lossage ("invalid %%s value");
5133
5134       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
5135       break;
5136
5137     case 'S':
5138       /* Same, except compute (64 - c) / 8 */
5139
5140       if (!CONST_INT_P (x)
5141           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5142           && (INTVAL (x) & 7) != 8)
5143         output_operand_lossage ("invalid %%s value");
5144
5145       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5146       break;
5147
5148     case 'C': case 'D': case 'c': case 'd':
5149       /* Write out comparison name.  */
5150       {
5151         enum rtx_code c = GET_CODE (x);
5152
5153         if (!COMPARISON_P (x))
5154           output_operand_lossage ("invalid %%C value");
5155
5156         else if (code == 'D')
5157           c = reverse_condition (c);
5158         else if (code == 'c')
5159           c = swap_condition (c);
5160         else if (code == 'd')
5161           c = swap_condition (reverse_condition (c));
5162
5163         if (c == LEU)
5164           fprintf (file, "ule");
5165         else if (c == LTU)
5166           fprintf (file, "ult");
5167         else if (c == UNORDERED)
5168           fprintf (file, "un");
5169         else
5170           fprintf (file, "%s", GET_RTX_NAME (c));
5171       }
5172       break;
5173
5174     case 'E':
5175       /* Write the divide or modulus operator.  */
5176       switch (GET_CODE (x))
5177         {
5178         case DIV:
5179           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
5180           break;
5181         case UDIV:
5182           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
5183           break;
5184         case MOD:
5185           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
5186           break;
5187         case UMOD:
5188           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
5189           break;
5190         default:
5191           output_operand_lossage ("invalid %%E value");
5192           break;
5193         }
5194       break;
5195
5196     case 'A':
5197       /* Write "_u" for unaligned access.  */
5198       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
5199         fprintf (file, "_u");
5200       break;
5201
5202     case 0:
5203       if (REG_P (x))
5204         fprintf (file, "%s", reg_names[REGNO (x)]);
5205       else if (MEM_P (x))
5206         output_address (XEXP (x, 0));
5207       else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
5208         {
5209           switch (XINT (XEXP (x, 0), 1))
5210             {
5211             case UNSPEC_DTPREL:
5212             case UNSPEC_TPREL:
5213               output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
5214               break;
5215             default:
5216               output_operand_lossage ("unknown relocation unspec");
5217               break;
5218             }
5219         }
5220       else
5221         output_addr_const (file, x);
5222       break;
5223
5224     default:
5225       output_operand_lossage ("invalid %%xn code");
5226     }
5227 }
5228
5229 void
5230 print_operand_address (FILE *file, rtx addr)
5231 {
5232   int basereg = 31;
5233   HOST_WIDE_INT offset = 0;
5234
5235   if (GET_CODE (addr) == AND)
5236     addr = XEXP (addr, 0);
5237
5238   if (GET_CODE (addr) == PLUS
5239       && CONST_INT_P (XEXP (addr, 1)))
5240     {
5241       offset = INTVAL (XEXP (addr, 1));
5242       addr = XEXP (addr, 0);
5243     }
5244
5245   if (GET_CODE (addr) == LO_SUM)
5246     {
5247       const char *reloc16, *reloclo;
5248       rtx op1 = XEXP (addr, 1);
5249
5250       if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
5251         {
5252           op1 = XEXP (op1, 0);
5253           switch (XINT (op1, 1))
5254             {
5255             case UNSPEC_DTPREL:
5256               reloc16 = NULL;
5257               reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
5258               break;
5259             case UNSPEC_TPREL:
5260               reloc16 = NULL;
5261               reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
5262               break;
5263             default:
5264               output_operand_lossage ("unknown relocation unspec");
5265               return;
5266             }
5267
5268           output_addr_const (file, XVECEXP (op1, 0, 0));
5269         }
5270       else
5271         {
5272           reloc16 = "gprel";
5273           reloclo = "gprellow";
5274           output_addr_const (file, op1);
5275         }
5276
5277       if (offset)
5278         fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
5279
5280       addr = XEXP (addr, 0);
5281       switch (GET_CODE (addr))
5282         {
5283         case REG:
5284           basereg = REGNO (addr);
5285           break;
5286
5287         case SUBREG:
5288           basereg = subreg_regno (addr);
5289           break;
5290
5291         default:
5292           gcc_unreachable ();
5293         }
5294
5295       fprintf (file, "($%d)\t\t!%s", basereg,
5296                (basereg == 29 ? reloc16 : reloclo));
5297       return;
5298     }
5299
5300   switch (GET_CODE (addr))
5301     {
5302     case REG:
5303       basereg = REGNO (addr);
5304       break;
5305
5306     case SUBREG:
5307       basereg = subreg_regno (addr);
5308       break;
5309
5310     case CONST_INT:
5311       offset = INTVAL (addr);
5312       break;
5313
5314 #if TARGET_ABI_OPEN_VMS
5315     case SYMBOL_REF:
5316       fprintf (file, "%s", XSTR (addr, 0));
5317       return;
5318
5319     case CONST:
5320       gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS
5321                   && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF);
5322       fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
5323                XSTR (XEXP (XEXP (addr, 0), 0), 0),
5324                INTVAL (XEXP (XEXP (addr, 0), 1)));
5325       return;
5326     
5327 #endif
5328     default:
5329       gcc_unreachable ();
5330     }
5331
5332   fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
5333 }
5334 \f
5335 /* Emit RTL insns to initialize the variable parts of a trampoline at
5336    M_TRAMP.  FNDECL is target function's decl.  CHAIN_VALUE is an rtx
5337    for the static chain value for the function.  */
5338
5339 static void
5340 alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
5341 {
5342   rtx fnaddr, mem, word1, word2;
5343
5344   fnaddr = XEXP (DECL_RTL (fndecl), 0);
5345
5346 #ifdef POINTERS_EXTEND_UNSIGNED
5347   fnaddr = convert_memory_address (Pmode, fnaddr);
5348   chain_value = convert_memory_address (Pmode, chain_value);
5349 #endif
5350
5351   if (TARGET_ABI_OPEN_VMS)
5352     {
5353       const char *fnname;
5354       char *trname;
5355
5356       /* Construct the name of the trampoline entry point.  */
5357       fnname = XSTR (fnaddr, 0);
5358       trname = (char *) alloca (strlen (fnname) + 5);
5359       strcpy (trname, fnname);
5360       strcat (trname, "..tr");
5361       fnname = ggc_alloc_string (trname, strlen (trname) + 1);
5362       word2 = gen_rtx_SYMBOL_REF (Pmode, fnname);
5363
5364       /* Trampoline (or "bounded") procedure descriptor is constructed from
5365          the function's procedure descriptor with certain fields zeroed IAW
5366          the VMS calling standard. This is stored in the first quadword.  */
5367       word1 = force_reg (DImode, gen_const_mem (DImode, fnaddr));
5368       word1 = expand_and (DImode, word1, GEN_INT (0xffff0fff0000fff0), NULL);
5369     }
5370   else
5371     {
5372       /* These 4 instructions are:
5373             ldq $1,24($27)
5374             ldq $27,16($27)
5375             jmp $31,($27),0
5376             nop
5377          We don't bother setting the HINT field of the jump; the nop
5378          is merely there for padding.  */
5379       word1 = GEN_INT (0xa77b0010a43b0018);
5380       word2 = GEN_INT (0x47ff041f6bfb0000);
5381     }
5382
5383   /* Store the first two words, as computed above.  */
5384   mem = adjust_address (m_tramp, DImode, 0);
5385   emit_move_insn (mem, word1);
5386   mem = adjust_address (m_tramp, DImode, 8);
5387   emit_move_insn (mem, word2);
5388
5389   /* Store function address and static chain value.  */
5390   mem = adjust_address (m_tramp, Pmode, 16);
5391   emit_move_insn (mem, fnaddr);
5392   mem = adjust_address (m_tramp, Pmode, 24);
5393   emit_move_insn (mem, chain_value);
5394
5395   if (TARGET_ABI_OSF)
5396     {
5397       emit_insn (gen_imb ());
5398 #ifdef ENABLE_EXECUTE_STACK
5399       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5400                          LCT_NORMAL, VOIDmode, 1, XEXP (m_tramp, 0), Pmode);
5401 #endif
5402     }
5403 }
5404 \f
5405 /* Determine where to put an argument to a function.
5406    Value is zero to push the argument on the stack,
5407    or a hard register in which to store the argument.
5408
5409    MODE is the argument's machine mode.
5410    TYPE is the data type of the argument (as a tree).
5411     This is null for libcalls where that information may
5412     not be available.
5413    CUM is a variable of type CUMULATIVE_ARGS which gives info about
5414     the preceding args and about the function being called.
5415    NAMED is nonzero if this argument is a named parameter
5416     (otherwise it is an extra parameter matching an ellipsis).
5417
5418    On Alpha the first 6 words of args are normally in registers
5419    and the rest are pushed.  */
5420
5421 static rtx
5422 alpha_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5423                     const_tree type, bool named ATTRIBUTE_UNUSED)
5424 {
5425   int basereg;
5426   int num_args;
5427
5428   /* Don't get confused and pass small structures in FP registers.  */
5429   if (type && AGGREGATE_TYPE_P (type))
5430     basereg = 16;
5431   else
5432     {
5433 #ifdef ENABLE_CHECKING
5434       /* With alpha_split_complex_arg, we shouldn't see any raw complex
5435          values here.  */
5436       gcc_assert (!COMPLEX_MODE_P (mode));
5437 #endif
5438
5439       /* Set up defaults for FP operands passed in FP registers, and
5440          integral operands passed in integer registers.  */
5441       if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5442         basereg = 32 + 16;
5443       else
5444         basereg = 16;
5445     }
5446
5447   /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5448      the two platforms, so we can't avoid conditional compilation.  */
5449 #if TARGET_ABI_OPEN_VMS
5450     {
5451       if (mode == VOIDmode)
5452         return alpha_arg_info_reg_val (*cum);
5453
5454       num_args = cum->num_args;
5455       if (num_args >= 6
5456           || targetm.calls.must_pass_in_stack (mode, type))
5457         return NULL_RTX;
5458     }
5459 #elif TARGET_ABI_OSF
5460     {
5461       if (*cum >= 6)
5462         return NULL_RTX;
5463       num_args = *cum;
5464
5465       /* VOID is passed as a special flag for "last argument".  */
5466       if (type == void_type_node)
5467         basereg = 16;
5468       else if (targetm.calls.must_pass_in_stack (mode, type))
5469         return NULL_RTX;
5470     }
5471 #else
5472 #error Unhandled ABI
5473 #endif
5474
5475   return gen_rtx_REG (mode, num_args + basereg);
5476 }
5477
5478 /* Update the data in CUM to advance over an argument
5479    of mode MODE and data type TYPE.
5480    (TYPE is null for libcalls where that information may not be available.)  */
5481
5482 static void
5483 alpha_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5484                             const_tree type, bool named ATTRIBUTE_UNUSED)
5485 {
5486   bool onstack = targetm.calls.must_pass_in_stack (mode, type);
5487   int increment = onstack ? 6 : ALPHA_ARG_SIZE (mode, type, named);
5488
5489 #if TARGET_ABI_OSF
5490   *cum += increment;
5491 #else
5492   if (!onstack && cum->num_args < 6)
5493     cum->atypes[cum->num_args] = alpha_arg_type (mode);
5494   cum->num_args += increment;
5495 #endif
5496 }
5497
5498 static int
5499 alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5500                          enum machine_mode mode ATTRIBUTE_UNUSED,
5501                          tree type ATTRIBUTE_UNUSED,
5502                          bool named ATTRIBUTE_UNUSED)
5503 {
5504   int words = 0;
5505
5506 #if TARGET_ABI_OPEN_VMS
5507   if (cum->num_args < 6
5508       && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
5509     words = 6 - cum->num_args;
5510 #elif TARGET_ABI_OSF
5511   if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
5512     words = 6 - *cum;
5513 #else
5514 #error Unhandled ABI
5515 #endif
5516
5517   return words * UNITS_PER_WORD;
5518 }
5519
5520
5521 /* Return true if TYPE must be returned in memory, instead of in registers.  */
5522
5523 static bool
5524 alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
5525 {
5526   enum machine_mode mode = VOIDmode;
5527   int size;
5528
5529   if (type)
5530     {
5531       mode = TYPE_MODE (type);
5532
5533       /* All aggregates are returned in memory, except on OpenVMS where
5534          records that fit 64 bits should be returned by immediate value
5535          as required by section 3.8.7.1 of the OpenVMS Calling Standard.  */
5536       if (TARGET_ABI_OPEN_VMS
5537           && TREE_CODE (type) != ARRAY_TYPE
5538           && (unsigned HOST_WIDE_INT) int_size_in_bytes(type) <= 8)
5539         return false;
5540
5541       if (AGGREGATE_TYPE_P (type))
5542         return true;
5543     }
5544
5545   size = GET_MODE_SIZE (mode);
5546   switch (GET_MODE_CLASS (mode))
5547     {
5548     case MODE_VECTOR_FLOAT:
5549       /* Pass all float vectors in memory, like an aggregate.  */
5550       return true;
5551
5552     case MODE_COMPLEX_FLOAT:
5553       /* We judge complex floats on the size of their element,
5554          not the size of the whole type.  */
5555       size = GET_MODE_UNIT_SIZE (mode);
5556       break;
5557
5558     case MODE_INT:
5559     case MODE_FLOAT:
5560     case MODE_COMPLEX_INT:
5561     case MODE_VECTOR_INT:
5562       break;
5563
5564     default:
5565       /* ??? We get called on all sorts of random stuff from
5566          aggregate_value_p.  We must return something, but it's not
5567          clear what's safe to return.  Pretend it's a struct I
5568          guess.  */
5569       return true;
5570     }
5571
5572   /* Otherwise types must fit in one register.  */
5573   return size > UNITS_PER_WORD;
5574 }
5575
5576 /* Return true if TYPE should be passed by invisible reference.  */
5577
5578 static bool
5579 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5580                          enum machine_mode mode,
5581                          const_tree type ATTRIBUTE_UNUSED,
5582                          bool named ATTRIBUTE_UNUSED)
5583 {
5584   return mode == TFmode || mode == TCmode;
5585 }
5586
5587 /* Define how to find the value returned by a function.  VALTYPE is the
5588    data type of the value (as a tree).  If the precise function being
5589    called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5590    MODE is set instead of VALTYPE for libcalls.
5591
5592    On Alpha the value is found in $0 for integer functions and
5593    $f0 for floating-point functions.  */
5594
5595 rtx
5596 function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
5597                 enum machine_mode mode)
5598 {
5599   unsigned int regnum, dummy ATTRIBUTE_UNUSED;
5600   enum mode_class mclass;
5601
5602   gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));
5603
5604   if (valtype)
5605     mode = TYPE_MODE (valtype);
5606
5607   mclass = GET_MODE_CLASS (mode);
5608   switch (mclass)
5609     {
5610     case MODE_INT:
5611       /* Do the same thing as PROMOTE_MODE except for libcalls on VMS,
5612          where we have them returning both SImode and DImode.  */
5613       if (!(TARGET_ABI_OPEN_VMS && valtype && AGGREGATE_TYPE_P (valtype)))
5614         PROMOTE_MODE (mode, dummy, valtype);
5615       /* FALLTHRU */
5616
5617     case MODE_COMPLEX_INT:
5618     case MODE_VECTOR_INT:
5619       regnum = 0;
5620       break;
5621
5622     case MODE_FLOAT:
5623       regnum = 32;
5624       break;
5625
5626     case MODE_COMPLEX_FLOAT:
5627       {
5628         enum machine_mode cmode = GET_MODE_INNER (mode);
5629
5630         return gen_rtx_PARALLEL
5631           (VOIDmode,
5632            gen_rtvec (2,
5633                       gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5634                                          const0_rtx),
5635                       gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5636                                          GEN_INT (GET_MODE_SIZE (cmode)))));
5637       }
5638
5639     case MODE_RANDOM:
5640       /* We should only reach here for BLKmode on VMS.  */
5641       gcc_assert (TARGET_ABI_OPEN_VMS && mode == BLKmode);
5642       regnum = 0;
5643       break;
5644
5645     default:
5646       gcc_unreachable ();
5647     }
5648
5649   return gen_rtx_REG (mode, regnum);
5650 }
5651
5652 /* TCmode complex values are passed by invisible reference.  We
5653    should not split these values.  */
5654
5655 static bool
5656 alpha_split_complex_arg (const_tree type)
5657 {
5658   return TYPE_MODE (type) != TCmode;
5659 }
5660
5661 static tree
5662 alpha_build_builtin_va_list (void)
5663 {
5664   tree base, ofs, space, record, type_decl;
5665
5666   if (TARGET_ABI_OPEN_VMS)
5667     return ptr_type_node;
5668
5669   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5670   type_decl = build_decl (BUILTINS_LOCATION,
5671                           TYPE_DECL, get_identifier ("__va_list_tag"), record);
5672   TYPE_STUB_DECL (record) = type_decl;
5673   TYPE_NAME (record) = type_decl;
5674
5675   /* C++? SET_IS_AGGR_TYPE (record, 1); */
5676
5677   /* Dummy field to prevent alignment warnings.  */
5678   space = build_decl (BUILTINS_LOCATION,
5679                       FIELD_DECL, NULL_TREE, integer_type_node);
5680   DECL_FIELD_CONTEXT (space) = record;
5681   DECL_ARTIFICIAL (space) = 1;
5682   DECL_IGNORED_P (space) = 1;
5683
5684   ofs = build_decl (BUILTINS_LOCATION,
5685                     FIELD_DECL, get_identifier ("__offset"),
5686                     integer_type_node);
5687   DECL_FIELD_CONTEXT (ofs) = record;
5688   DECL_CHAIN (ofs) = space;
5689   /* ??? This is a hack, __offset is marked volatile to prevent
5690      DCE that confuses stdarg optimization and results in
5691      gcc.c-torture/execute/stdarg-1.c failure.  See PR 41089.  */
5692   TREE_THIS_VOLATILE (ofs) = 1;
5693
5694   base = build_decl (BUILTINS_LOCATION,
5695                      FIELD_DECL, get_identifier ("__base"),
5696                      ptr_type_node);
5697   DECL_FIELD_CONTEXT (base) = record;
5698   DECL_CHAIN (base) = ofs;
5699
5700   TYPE_FIELDS (record) = base;
5701   layout_type (record);
5702
5703   va_list_gpr_counter_field = ofs;
5704   return record;
5705 }
5706
5707 #if TARGET_ABI_OSF
5708 /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
5709    and constant additions.  */
5710
5711 static gimple
5712 va_list_skip_additions (tree lhs)
5713 {
5714   gimple stmt;
5715
5716   for (;;)
5717     {
5718       enum tree_code code;
5719
5720       stmt = SSA_NAME_DEF_STMT (lhs);
5721
5722       if (gimple_code (stmt) == GIMPLE_PHI)
5723         return stmt;
5724
5725       if (!is_gimple_assign (stmt)
5726           || gimple_assign_lhs (stmt) != lhs)
5727         return NULL;
5728
5729       if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
5730         return stmt;
5731       code = gimple_assign_rhs_code (stmt);
5732       if (!CONVERT_EXPR_CODE_P (code)
5733           && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
5734               || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
5735               || !host_integerp (gimple_assign_rhs2 (stmt), 1)))
5736         return stmt;
5737
5738       lhs = gimple_assign_rhs1 (stmt);
5739     }
5740 }
5741
5742 /* Check if LHS = RHS statement is
5743    LHS = *(ap.__base + ap.__offset + cst)
5744    or
5745    LHS = *(ap.__base
5746            + ((ap.__offset + cst <= 47)
5747               ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
5748    If the former, indicate that GPR registers are needed,
5749    if the latter, indicate that FPR registers are needed.
5750
5751    Also look for LHS = (*ptr).field, where ptr is one of the forms
5752    listed above.
5753
5754    On alpha, cfun->va_list_gpr_size is used as size of the needed
5755    regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
5756    registers are needed and bit 1 set if FPR registers are needed.
5757    Return true if va_list references should not be scanned for the
5758    current statement.  */
5759
5760 static bool
5761 alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
5762 {
5763   tree base, offset, rhs;
5764   int offset_arg = 1;
5765   gimple base_stmt;
5766
5767   if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
5768       != GIMPLE_SINGLE_RHS)
5769     return false;
5770
5771   rhs = gimple_assign_rhs1 (stmt);
5772   while (handled_component_p (rhs))
5773     rhs = TREE_OPERAND (rhs, 0);
5774   if (TREE_CODE (rhs) != MEM_REF
5775       || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
5776     return false;
5777
5778   stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
5779   if (stmt == NULL
5780       || !is_gimple_assign (stmt)
5781       || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
5782     return false;
5783
5784   base = gimple_assign_rhs1 (stmt);
5785   if (TREE_CODE (base) == SSA_NAME)
5786     {
5787       base_stmt = va_list_skip_additions (base);
5788       if (base_stmt
5789           && is_gimple_assign (base_stmt)
5790           && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
5791         base = gimple_assign_rhs1 (base_stmt);
5792     }
5793
5794   if (TREE_CODE (base) != COMPONENT_REF
5795       || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5796     {
5797       base = gimple_assign_rhs2 (stmt);
5798       if (TREE_CODE (base) == SSA_NAME)
5799         {
5800           base_stmt = va_list_skip_additions (base);
5801           if (base_stmt
5802               && is_gimple_assign (base_stmt)
5803               && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
5804             base = gimple_assign_rhs1 (base_stmt);
5805         }
5806
5807       if (TREE_CODE (base) != COMPONENT_REF
5808           || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5809         return false;
5810
5811       offset_arg = 0;
5812     }
5813
5814   base = get_base_address (base);
5815   if (TREE_CODE (base) != VAR_DECL
5816       || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
5817     return false;
5818
5819   offset = gimple_op (stmt, 1 + offset_arg);
5820   if (TREE_CODE (offset) == SSA_NAME)
5821     {
5822       gimple offset_stmt = va_list_skip_additions (offset);
5823
5824       if (offset_stmt
5825           && gimple_code (offset_stmt) == GIMPLE_PHI)
5826         {
5827           HOST_WIDE_INT sub;
5828           gimple arg1_stmt, arg2_stmt;
5829           tree arg1, arg2;
5830           enum tree_code code1, code2;
5831
5832           if (gimple_phi_num_args (offset_stmt) != 2)
5833             goto escapes;
5834
5835           arg1_stmt
5836             = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
5837           arg2_stmt
5838             = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
5839           if (arg1_stmt == NULL
5840               || !is_gimple_assign (arg1_stmt)
5841               || arg2_stmt == NULL
5842               || !is_gimple_assign (arg2_stmt))
5843             goto escapes;
5844
5845           code1 = gimple_assign_rhs_code (arg1_stmt);
5846           code2 = gimple_assign_rhs_code (arg2_stmt);
5847           if (code1 == COMPONENT_REF
5848               && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
5849             /* Do nothing.  */;
5850           else if (code2 == COMPONENT_REF
5851                    && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
5852             {
5853               gimple tem = arg1_stmt;
5854               code2 = code1;
5855               arg1_stmt = arg2_stmt;
5856               arg2_stmt = tem;
5857             }
5858           else
5859             goto escapes;
5860
5861           if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
5862             goto escapes;
5863
5864           sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
5865           if (code2 == MINUS_EXPR)
5866             sub = -sub;
5867           if (sub < -48 || sub > -32)
5868             goto escapes;
5869
5870           arg1 = gimple_assign_rhs1 (arg1_stmt);
5871           arg2 = gimple_assign_rhs1 (arg2_stmt);
5872           if (TREE_CODE (arg2) == SSA_NAME)
5873             {
5874               arg2_stmt = va_list_skip_additions (arg2);
5875               if (arg2_stmt == NULL
5876                   || !is_gimple_assign (arg2_stmt)
5877                   || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
5878                 goto escapes;
5879               arg2 = gimple_assign_rhs1 (arg2_stmt);
5880             }
5881           if (arg1 != arg2)
5882             goto escapes;
5883
5884           if (TREE_CODE (arg1) != COMPONENT_REF
5885               || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
5886               || get_base_address (arg1) != base)
5887             goto escapes;
5888
5889           /* Need floating point regs.  */
5890           cfun->va_list_fpr_size |= 2;
5891           return false;
5892         }
5893       if (offset_stmt
5894           && is_gimple_assign (offset_stmt)
5895           && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
5896         offset = gimple_assign_rhs1 (offset_stmt);
5897     }
5898   if (TREE_CODE (offset) != COMPONENT_REF
5899       || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
5900       || get_base_address (offset) != base)
5901     goto escapes;
5902   else
5903     /* Need general regs.  */
5904     cfun->va_list_fpr_size |= 1;
5905   return false;
5906
5907 escapes:
5908   si->va_list_escapes = true;
5909   return false;
5910 }
5911 #endif
5912
5913 /* Perform any needed actions needed for a function that is receiving a
5914    variable number of arguments.  */
5915
5916 static void
5917 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
5918                               tree type, int *pretend_size, int no_rtl)
5919 {
5920   CUMULATIVE_ARGS cum = *pcum;
5921
5922   /* Skip the current argument.  */
5923   targetm.calls.function_arg_advance (&cum, mode, type, true);
5924
5925 #if TARGET_ABI_OPEN_VMS
5926   /* For VMS, we allocate space for all 6 arg registers plus a count.
5927
5928      However, if NO registers need to be saved, don't allocate any space.
5929      This is not only because we won't need the space, but because AP
5930      includes the current_pretend_args_size and we don't want to mess up
5931      any ap-relative addresses already made.  */
5932   if (cum.num_args < 6)
5933     {
5934       if (!no_rtl)
5935         {
5936           emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5937           emit_insn (gen_arg_home ());
5938         }
5939       *pretend_size = 7 * UNITS_PER_WORD;
5940     }
5941 #else
5942   /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
5943      only push those that are remaining.  However, if NO registers need to
5944      be saved, don't allocate any space.  This is not only because we won't
5945      need the space, but because AP includes the current_pretend_args_size
5946      and we don't want to mess up any ap-relative addresses already made.
5947
5948      If we are not to use the floating-point registers, save the integer
5949      registers where we would put the floating-point registers.  This is
5950      not the most efficient way to implement varargs with just one register
5951      class, but it isn't worth doing anything more efficient in this rare
5952      case.  */
5953   if (cum >= 6)
5954     return;
5955
5956   if (!no_rtl)
5957     {
5958       int count;
5959       alias_set_type set = get_varargs_alias_set ();
5960       rtx tmp;
5961
5962       count = cfun->va_list_gpr_size / UNITS_PER_WORD;
5963       if (count > 6 - cum)
5964         count = 6 - cum;
5965
5966       /* Detect whether integer registers or floating-point registers
5967          are needed by the detected va_arg statements.  See above for
5968          how these values are computed.  Note that the "escape" value
5969          is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of 
5970          these bits set.  */
5971       gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
5972
5973       if (cfun->va_list_fpr_size & 1)
5974         {
5975           tmp = gen_rtx_MEM (BLKmode,
5976                              plus_constant (virtual_incoming_args_rtx,
5977                                             (cum + 6) * UNITS_PER_WORD));
5978           MEM_NOTRAP_P (tmp) = 1;
5979           set_mem_alias_set (tmp, set);
5980           move_block_from_reg (16 + cum, tmp, count);
5981         }
5982
5983       if (cfun->va_list_fpr_size & 2)
5984         {
5985           tmp = gen_rtx_MEM (BLKmode,
5986                              plus_constant (virtual_incoming_args_rtx,
5987                                             cum * UNITS_PER_WORD));
5988           MEM_NOTRAP_P (tmp) = 1;
5989           set_mem_alias_set (tmp, set);
5990           move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
5991         }
5992      }
5993   *pretend_size = 12 * UNITS_PER_WORD;
5994 #endif
5995 }
5996
5997 static void
5998 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
5999 {
6000   HOST_WIDE_INT offset;
6001   tree t, offset_field, base_field;
6002
6003   if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
6004     return;
6005
6006   /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6007      up by 48, storing fp arg registers in the first 48 bytes, and the
6008      integer arg registers in the next 48 bytes.  This is only done,
6009      however, if any integer registers need to be stored.
6010
6011      If no integer registers need be stored, then we must subtract 48
6012      in order to account for the integer arg registers which are counted
6013      in argsize above, but which are not actually stored on the stack.
6014      Must further be careful here about structures straddling the last
6015      integer argument register; that futzes with pretend_args_size,
6016      which changes the meaning of AP.  */
6017
6018   if (NUM_ARGS < 6)
6019     offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
6020   else
6021     offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
6022
6023   if (TARGET_ABI_OPEN_VMS)
6024     {
6025       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6026       t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6027                  size_int (offset + NUM_ARGS * UNITS_PER_WORD));
6028       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
6029       TREE_SIDE_EFFECTS (t) = 1;
6030       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6031     }
6032   else
6033     {
6034       base_field = TYPE_FIELDS (TREE_TYPE (valist));
6035       offset_field = DECL_CHAIN (base_field);
6036
6037       base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6038                            valist, base_field, NULL_TREE);
6039       offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6040                              valist, offset_field, NULL_TREE);
6041
6042       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6043       t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6044                   size_int (offset));
6045       t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
6046       TREE_SIDE_EFFECTS (t) = 1;
6047       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6048
6049       t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
6050       t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
6051       TREE_SIDE_EFFECTS (t) = 1;
6052       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6053     }
6054 }
6055
6056 static tree
6057 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
6058                          gimple_seq *pre_p)
6059 {
6060   tree type_size, ptr_type, addend, t, addr;
6061   gimple_seq internal_post;
6062
6063   /* If the type could not be passed in registers, skip the block
6064      reserved for the registers.  */
6065   if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
6066     {
6067       t = build_int_cst (TREE_TYPE (offset), 6*8);
6068       gimplify_assign (offset,
6069                        build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
6070                        pre_p);
6071     }
6072
6073   addend = offset;
6074   ptr_type = build_pointer_type_for_mode (type, ptr_mode, true);
6075
6076   if (TREE_CODE (type) == COMPLEX_TYPE)
6077     {
6078       tree real_part, imag_part, real_temp;
6079
6080       real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6081                                            offset, pre_p);
6082
6083       /* Copy the value into a new temporary, lest the formal temporary
6084          be reused out from under us.  */
6085       real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
6086
6087       imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6088                                            offset, pre_p);
6089
6090       return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
6091     }
6092   else if (TREE_CODE (type) == REAL_TYPE)
6093     {
6094       tree fpaddend, cond, fourtyeight;
6095
6096       fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
6097       fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
6098                               addend, fourtyeight);
6099       cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
6100       addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
6101                             fpaddend, addend);
6102     }
6103
6104   /* Build the final address and force that value into a temporary.  */
6105   addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
6106                  fold_convert (sizetype, addend));
6107   internal_post = NULL;
6108   gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
6109   gimple_seq_add_seq (pre_p, internal_post);
6110
6111   /* Update the offset field.  */
6112   type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
6113   if (type_size == NULL || TREE_OVERFLOW (type_size))
6114     t = size_zero_node;
6115   else
6116     {
6117       t = size_binop (PLUS_EXPR, type_size, size_int (7));
6118       t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
6119       t = size_binop (MULT_EXPR, t, size_int (8));
6120     }
6121   t = fold_convert (TREE_TYPE (offset), t);
6122   gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
6123                    pre_p);
6124
6125   return build_va_arg_indirect_ref (addr);
6126 }
6127
6128 static tree
6129 alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
6130                        gimple_seq *post_p)
6131 {
6132   tree offset_field, base_field, offset, base, t, r;
6133   bool indirect;
6134
6135   if (TARGET_ABI_OPEN_VMS)
6136     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6137
6138   base_field = TYPE_FIELDS (va_list_type_node);
6139   offset_field = DECL_CHAIN (base_field);
6140   base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6141                        valist, base_field, NULL_TREE);
6142   offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6143                          valist, offset_field, NULL_TREE);
6144
6145   /* Pull the fields of the structure out into temporaries.  Since we never
6146      modify the base field, we can use a formal temporary.  Sign-extend the
6147      offset field so that it's the proper width for pointer arithmetic.  */
6148   base = get_formal_tmp_var (base_field, pre_p);
6149
6150   t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
6151   offset = get_initialized_tmp_var (t, pre_p, NULL);
6152
6153   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
6154   if (indirect)
6155     type = build_pointer_type_for_mode (type, ptr_mode, true);
6156
6157   /* Find the value.  Note that this will be a stable indirection, or
6158      a composite of stable indirections in the case of complex.  */
6159   r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
6160
6161   /* Stuff the offset temporary back into its field.  */
6162   gimplify_assign (unshare_expr (offset_field),
6163                    fold_convert (TREE_TYPE (offset_field), offset), pre_p);
6164
6165   if (indirect)
6166     r = build_va_arg_indirect_ref (r);
6167
6168   return r;
6169 }
6170 \f
6171 /* Builtins.  */
6172
6173 enum alpha_builtin
6174 {
6175   ALPHA_BUILTIN_CMPBGE,
6176   ALPHA_BUILTIN_EXTBL,
6177   ALPHA_BUILTIN_EXTWL,
6178   ALPHA_BUILTIN_EXTLL,
6179   ALPHA_BUILTIN_EXTQL,
6180   ALPHA_BUILTIN_EXTWH,
6181   ALPHA_BUILTIN_EXTLH,
6182   ALPHA_BUILTIN_EXTQH,
6183   ALPHA_BUILTIN_INSBL,
6184   ALPHA_BUILTIN_INSWL,
6185   ALPHA_BUILTIN_INSLL,
6186   ALPHA_BUILTIN_INSQL,
6187   ALPHA_BUILTIN_INSWH,
6188   ALPHA_BUILTIN_INSLH,
6189   ALPHA_BUILTIN_INSQH,
6190   ALPHA_BUILTIN_MSKBL,
6191   ALPHA_BUILTIN_MSKWL,
6192   ALPHA_BUILTIN_MSKLL,
6193   ALPHA_BUILTIN_MSKQL,
6194   ALPHA_BUILTIN_MSKWH,
6195   ALPHA_BUILTIN_MSKLH,
6196   ALPHA_BUILTIN_MSKQH,
6197   ALPHA_BUILTIN_UMULH,
6198   ALPHA_BUILTIN_ZAP,
6199   ALPHA_BUILTIN_ZAPNOT,
6200   ALPHA_BUILTIN_AMASK,
6201   ALPHA_BUILTIN_IMPLVER,
6202   ALPHA_BUILTIN_RPCC,
6203   ALPHA_BUILTIN_THREAD_POINTER,
6204   ALPHA_BUILTIN_SET_THREAD_POINTER,
6205   ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
6206   ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
6207
6208   /* TARGET_MAX */
6209   ALPHA_BUILTIN_MINUB8,
6210   ALPHA_BUILTIN_MINSB8,
6211   ALPHA_BUILTIN_MINUW4,
6212   ALPHA_BUILTIN_MINSW4,
6213   ALPHA_BUILTIN_MAXUB8,
6214   ALPHA_BUILTIN_MAXSB8,
6215   ALPHA_BUILTIN_MAXUW4,
6216   ALPHA_BUILTIN_MAXSW4,
6217   ALPHA_BUILTIN_PERR,
6218   ALPHA_BUILTIN_PKLB,
6219   ALPHA_BUILTIN_PKWB,
6220   ALPHA_BUILTIN_UNPKBL,
6221   ALPHA_BUILTIN_UNPKBW,
6222
6223   /* TARGET_CIX */
6224   ALPHA_BUILTIN_CTTZ,
6225   ALPHA_BUILTIN_CTLZ,
6226   ALPHA_BUILTIN_CTPOP,
6227
6228   ALPHA_BUILTIN_max
6229 };
6230
6231 static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
6232   CODE_FOR_builtin_cmpbge,
6233   CODE_FOR_extbl,
6234   CODE_FOR_extwl,
6235   CODE_FOR_extll,
6236   CODE_FOR_extql,
6237   CODE_FOR_extwh,
6238   CODE_FOR_extlh,
6239   CODE_FOR_extqh,
6240   CODE_FOR_builtin_insbl,
6241   CODE_FOR_builtin_inswl,
6242   CODE_FOR_builtin_insll,
6243   CODE_FOR_insql,
6244   CODE_FOR_inswh,
6245   CODE_FOR_inslh,
6246   CODE_FOR_insqh,
6247   CODE_FOR_mskbl,
6248   CODE_FOR_mskwl,
6249   CODE_FOR_mskll,
6250   CODE_FOR_mskql,
6251   CODE_FOR_mskwh,
6252   CODE_FOR_msklh,
6253   CODE_FOR_mskqh,
6254   CODE_FOR_umuldi3_highpart,
6255   CODE_FOR_builtin_zap,
6256   CODE_FOR_builtin_zapnot,
6257   CODE_FOR_builtin_amask,
6258   CODE_FOR_builtin_implver,
6259   CODE_FOR_builtin_rpcc,
6260   CODE_FOR_load_tp,
6261   CODE_FOR_set_tp,
6262   CODE_FOR_builtin_establish_vms_condition_handler,
6263   CODE_FOR_builtin_revert_vms_condition_handler,
6264
6265   /* TARGET_MAX */
6266   CODE_FOR_builtin_minub8,
6267   CODE_FOR_builtin_minsb8,
6268   CODE_FOR_builtin_minuw4,
6269   CODE_FOR_builtin_minsw4,
6270   CODE_FOR_builtin_maxub8,
6271   CODE_FOR_builtin_maxsb8,
6272   CODE_FOR_builtin_maxuw4,
6273   CODE_FOR_builtin_maxsw4,
6274   CODE_FOR_builtin_perr,
6275   CODE_FOR_builtin_pklb,
6276   CODE_FOR_builtin_pkwb,
6277   CODE_FOR_builtin_unpkbl,
6278   CODE_FOR_builtin_unpkbw,
6279
6280   /* TARGET_CIX */
6281   CODE_FOR_ctzdi2,
6282   CODE_FOR_clzdi2,
6283   CODE_FOR_popcountdi2
6284 };
6285
6286 struct alpha_builtin_def
6287 {
6288   const char *name;
6289   enum alpha_builtin code;
6290   unsigned int target_mask;
6291   bool is_const;
6292 };
6293
6294 static struct alpha_builtin_def const zero_arg_builtins[] = {
6295   { "__builtin_alpha_implver",  ALPHA_BUILTIN_IMPLVER,  0, true },
6296   { "__builtin_alpha_rpcc",     ALPHA_BUILTIN_RPCC,     0, false }
6297 };
6298
6299 static struct alpha_builtin_def const one_arg_builtins[] = {
6300   { "__builtin_alpha_amask",    ALPHA_BUILTIN_AMASK,    0, true },
6301   { "__builtin_alpha_pklb",     ALPHA_BUILTIN_PKLB,     MASK_MAX, true },
6302   { "__builtin_alpha_pkwb",     ALPHA_BUILTIN_PKWB,     MASK_MAX, true },
6303   { "__builtin_alpha_unpkbl",   ALPHA_BUILTIN_UNPKBL,   MASK_MAX, true },
6304   { "__builtin_alpha_unpkbw",   ALPHA_BUILTIN_UNPKBW,   MASK_MAX, true },
6305   { "__builtin_alpha_cttz",     ALPHA_BUILTIN_CTTZ,     MASK_CIX, true },
6306   { "__builtin_alpha_ctlz",     ALPHA_BUILTIN_CTLZ,     MASK_CIX, true },
6307   { "__builtin_alpha_ctpop",    ALPHA_BUILTIN_CTPOP,    MASK_CIX, true }
6308 };
6309
6310 static struct alpha_builtin_def const two_arg_builtins[] = {
6311   { "__builtin_alpha_cmpbge",   ALPHA_BUILTIN_CMPBGE,   0, true },
6312   { "__builtin_alpha_extbl",    ALPHA_BUILTIN_EXTBL,    0, true },
6313   { "__builtin_alpha_extwl",    ALPHA_BUILTIN_EXTWL,    0, true },
6314   { "__builtin_alpha_extll",    ALPHA_BUILTIN_EXTLL,    0, true },
6315   { "__builtin_alpha_extql",    ALPHA_BUILTIN_EXTQL,    0, true },
6316   { "__builtin_alpha_extwh",    ALPHA_BUILTIN_EXTWH,    0, true },
6317   { "__builtin_alpha_extlh",    ALPHA_BUILTIN_EXTLH,    0, true },
6318   { "__builtin_alpha_extqh",    ALPHA_BUILTIN_EXTQH,    0, true },
6319   { "__builtin_alpha_insbl",    ALPHA_BUILTIN_INSBL,    0, true },
6320   { "__builtin_alpha_inswl",    ALPHA_BUILTIN_INSWL,    0, true },
6321   { "__builtin_alpha_insll",    ALPHA_BUILTIN_INSLL,    0, true },
6322   { "__builtin_alpha_insql",    ALPHA_BUILTIN_INSQL,    0, true },
6323   { "__builtin_alpha_inswh",    ALPHA_BUILTIN_INSWH,    0, true },
6324   { "__builtin_alpha_inslh",    ALPHA_BUILTIN_INSLH,    0, true },
6325   { "__builtin_alpha_insqh",    ALPHA_BUILTIN_INSQH,    0, true },
6326   { "__builtin_alpha_mskbl",    ALPHA_BUILTIN_MSKBL,    0, true },
6327   { "__builtin_alpha_mskwl",    ALPHA_BUILTIN_MSKWL,    0, true },
6328   { "__builtin_alpha_mskll",    ALPHA_BUILTIN_MSKLL,    0, true },
6329   { "__builtin_alpha_mskql",    ALPHA_BUILTIN_MSKQL,    0, true },
6330   { "__builtin_alpha_mskwh",    ALPHA_BUILTIN_MSKWH,    0, true },
6331   { "__builtin_alpha_msklh",    ALPHA_BUILTIN_MSKLH,    0, true },
6332   { "__builtin_alpha_mskqh",    ALPHA_BUILTIN_MSKQH,    0, true },
6333   { "__builtin_alpha_umulh",    ALPHA_BUILTIN_UMULH,    0, true },
6334   { "__builtin_alpha_zap",      ALPHA_BUILTIN_ZAP,      0, true },
6335   { "__builtin_alpha_zapnot",   ALPHA_BUILTIN_ZAPNOT,   0, true },
6336   { "__builtin_alpha_minub8",   ALPHA_BUILTIN_MINUB8,   MASK_MAX, true },
6337   { "__builtin_alpha_minsb8",   ALPHA_BUILTIN_MINSB8,   MASK_MAX, true },
6338   { "__builtin_alpha_minuw4",   ALPHA_BUILTIN_MINUW4,   MASK_MAX, true },
6339   { "__builtin_alpha_minsw4",   ALPHA_BUILTIN_MINSW4,   MASK_MAX, true },
6340   { "__builtin_alpha_maxub8",   ALPHA_BUILTIN_MAXUB8,   MASK_MAX, true },
6341   { "__builtin_alpha_maxsb8",   ALPHA_BUILTIN_MAXSB8,   MASK_MAX, true },
6342   { "__builtin_alpha_maxuw4",   ALPHA_BUILTIN_MAXUW4,   MASK_MAX, true },
6343   { "__builtin_alpha_maxsw4",   ALPHA_BUILTIN_MAXSW4,   MASK_MAX, true },
6344   { "__builtin_alpha_perr",     ALPHA_BUILTIN_PERR,     MASK_MAX, true }
6345 };
6346
6347 static GTY(()) tree alpha_v8qi_u;
6348 static GTY(()) tree alpha_v8qi_s;
6349 static GTY(()) tree alpha_v4hi_u;
6350 static GTY(()) tree alpha_v4hi_s;
6351
6352 static GTY(()) tree alpha_builtins[(int) ALPHA_BUILTIN_max];
6353
6354 /* Return the alpha builtin for CODE.  */
6355
6356 static tree
6357 alpha_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
6358 {
6359   if (code >= ALPHA_BUILTIN_max)
6360     return error_mark_node;
6361   return alpha_builtins[code];
6362 }
6363
6364 /* Helper function of alpha_init_builtins.  Add the built-in specified
6365    by NAME, TYPE, CODE, and ECF.  */
6366
6367 static void
6368 alpha_builtin_function (const char *name, tree ftype,
6369                         enum alpha_builtin code, unsigned ecf)
6370 {
6371   tree decl = add_builtin_function (name, ftype, (int) code,
6372                                     BUILT_IN_MD, NULL, NULL_TREE);
6373
6374   if (ecf & ECF_CONST)
6375     TREE_READONLY (decl) = 1;
6376   if (ecf & ECF_NOTHROW)
6377     TREE_NOTHROW (decl) = 1;
6378
6379   alpha_builtins [(int) code] = decl;
6380 }
6381
6382 /* Helper function of alpha_init_builtins.  Add the COUNT built-in
6383    functions pointed to by P, with function type FTYPE.  */
6384
6385 static void
6386 alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
6387                     tree ftype)
6388 {
6389   size_t i;
6390
6391   for (i = 0; i < count; ++i, ++p)
6392     if ((target_flags & p->target_mask) == p->target_mask)
6393       alpha_builtin_function (p->name, ftype, p->code,
6394                               (p->is_const ? ECF_CONST : 0) | ECF_NOTHROW);
6395 }
6396
6397 static void
6398 alpha_init_builtins (void)
6399 {
6400   tree dimode_integer_type_node;
6401   tree ftype;
6402
6403   dimode_integer_type_node = lang_hooks.types.type_for_mode (DImode, 0);
6404
6405   /* Fwrite on VMS is non-standard.  */
6406 #if TARGET_ABI_OPEN_VMS
6407   implicit_built_in_decls[(int) BUILT_IN_FWRITE] = NULL_TREE;
6408   implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE;
6409 #endif
6410
6411   ftype = build_function_type (dimode_integer_type_node, void_list_node);
6412   alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
6413                       ftype);
6414
6415   ftype = build_function_type_list (dimode_integer_type_node,
6416                                     dimode_integer_type_node, NULL_TREE);
6417   alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins),
6418                       ftype);
6419
6420   ftype = build_function_type_list (dimode_integer_type_node,
6421                                     dimode_integer_type_node,
6422                                     dimode_integer_type_node, NULL_TREE);
6423   alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
6424                       ftype);
6425
6426   ftype = build_function_type (ptr_type_node, void_list_node);
6427   alpha_builtin_function ("__builtin_thread_pointer", ftype,
6428                           ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
6429
6430   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6431   alpha_builtin_function ("__builtin_set_thread_pointer", ftype,
6432                           ALPHA_BUILTIN_SET_THREAD_POINTER, ECF_NOTHROW);
6433
6434   if (TARGET_ABI_OPEN_VMS)
6435     {
6436       ftype = build_function_type_list (ptr_type_node, ptr_type_node,
6437                                         NULL_TREE);
6438       alpha_builtin_function ("__builtin_establish_vms_condition_handler",
6439                               ftype,
6440                               ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
6441                               0);
6442
6443       ftype = build_function_type_list (ptr_type_node, void_type_node,
6444                                         NULL_TREE);
6445       alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype,
6446                               ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 0);
6447     }
6448
6449   alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
6450   alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
6451   alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
6452   alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
6453 }
6454
6455 /* Expand an expression EXP that calls a built-in function,
6456    with result going to TARGET if that's convenient
6457    (and in mode MODE if that's convenient).
6458    SUBTARGET may be used as the target for computing one of EXP's operands.
6459    IGNORE is nonzero if the value is to be ignored.  */
6460
6461 static rtx
6462 alpha_expand_builtin (tree exp, rtx target,
6463                       rtx subtarget ATTRIBUTE_UNUSED,
6464                       enum machine_mode mode ATTRIBUTE_UNUSED,
6465                       int ignore ATTRIBUTE_UNUSED)
6466 {
6467 #define MAX_ARGS 2
6468
6469   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6470   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6471   tree arg;
6472   call_expr_arg_iterator iter;
6473   enum insn_code icode;
6474   rtx op[MAX_ARGS], pat;
6475   int arity;
6476   bool nonvoid;
6477
6478   if (fcode >= ALPHA_BUILTIN_max)
6479     internal_error ("bad builtin fcode");
6480   icode = code_for_builtin[fcode];
6481   if (icode == 0)
6482     internal_error ("bad builtin fcode");
6483
6484   nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6485
6486   arity = 0;
6487   FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6488     {
6489       const struct insn_operand_data *insn_op;
6490
6491       if (arg == error_mark_node)
6492         return NULL_RTX;
6493       if (arity > MAX_ARGS)
6494         return NULL_RTX;
6495
6496       insn_op = &insn_data[icode].operand[arity + nonvoid];
6497
6498       op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
6499
6500       if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6501         op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6502       arity++;
6503     }
6504
6505   if (nonvoid)
6506     {
6507       enum machine_mode tmode = insn_data[icode].operand[0].mode;
6508       if (!target
6509           || GET_MODE (target) != tmode
6510           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6511         target = gen_reg_rtx (tmode);
6512     }
6513
6514   switch (arity)
6515     {
6516     case 0:
6517       pat = GEN_FCN (icode) (target);
6518       break;
6519     case 1:
6520       if (nonvoid)
6521         pat = GEN_FCN (icode) (target, op[0]);
6522       else
6523         pat = GEN_FCN (icode) (op[0]);
6524       break;
6525     case 2:
6526       pat = GEN_FCN (icode) (target, op[0], op[1]);
6527       break;
6528     default:
6529       gcc_unreachable ();
6530     }
6531   if (!pat)
6532     return NULL_RTX;
6533   emit_insn (pat);
6534
6535   if (nonvoid)
6536     return target;
6537   else
6538     return const0_rtx;
6539 }
6540
6541
6542 /* Several bits below assume HWI >= 64 bits.  This should be enforced
6543    by config.gcc.  */
6544 #if HOST_BITS_PER_WIDE_INT < 64
6545 # error "HOST_WIDE_INT too small"
6546 #endif
6547
6548 /* Fold the builtin for the CMPBGE instruction.  This is a vector comparison
6549    with an 8-bit output vector.  OPINT contains the integer operands; bit N
6550    of OP_CONST is set if OPINT[N] is valid.  */
6551
6552 static tree
6553 alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
6554 {
6555   if (op_const == 3)
6556     {
6557       int i, val;
6558       for (i = 0, val = 0; i < 8; ++i)
6559         {
6560           unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
6561           unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
6562           if (c0 >= c1)
6563             val |= 1 << i;
6564         }
6565       return build_int_cst (long_integer_type_node, val);
6566     }
6567   else if (op_const == 2 && opint[1] == 0)
6568     return build_int_cst (long_integer_type_node, 0xff);
6569   return NULL;
6570 }
6571
6572 /* Fold the builtin for the ZAPNOT instruction.  This is essentially a 
6573    specialized form of an AND operation.  Other byte manipulation instructions
6574    are defined in terms of this instruction, so this is also used as a
6575    subroutine for other builtins.
6576
6577    OP contains the tree operands; OPINT contains the extracted integer values.
6578    Bit N of OP_CONST it set if OPINT[N] is valid.  OP may be null if only
6579    OPINT may be considered.  */
6580
6581 static tree
6582 alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
6583                            long op_const)
6584 {
6585   if (op_const & 2)
6586     {
6587       unsigned HOST_WIDE_INT mask = 0;
6588       int i;
6589
6590       for (i = 0; i < 8; ++i)
6591         if ((opint[1] >> i) & 1)
6592           mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
6593
6594       if (op_const & 1)
6595         return build_int_cst (long_integer_type_node, opint[0] & mask);
6596
6597       if (op)
6598         return fold_build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
6599                             build_int_cst (long_integer_type_node, mask));
6600     }
6601   else if ((op_const & 1) && opint[0] == 0)
6602     return build_int_cst (long_integer_type_node, 0);
6603   return NULL;
6604 }
6605
6606 /* Fold the builtins for the EXT family of instructions.  */
6607
6608 static tree
6609 alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
6610                           long op_const, unsigned HOST_WIDE_INT bytemask,
6611                           bool is_high)
6612 {
6613   long zap_const = 2;
6614   tree *zap_op = NULL;
6615
6616   if (op_const & 2)
6617     {
6618       unsigned HOST_WIDE_INT loc;
6619
6620       loc = opint[1] & 7;
6621       loc *= BITS_PER_UNIT;
6622
6623       if (loc != 0)
6624         {
6625           if (op_const & 1)
6626             {
6627               unsigned HOST_WIDE_INT temp = opint[0];
6628               if (is_high)
6629                 temp <<= loc;
6630               else
6631                 temp >>= loc;
6632               opint[0] = temp;
6633               zap_const = 3;
6634             }
6635         }
6636       else
6637         zap_op = op;
6638     }
6639   
6640   opint[1] = bytemask;
6641   return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
6642 }
6643
6644 /* Fold the builtins for the INS family of instructions.  */
6645
6646 static tree
6647 alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
6648                           long op_const, unsigned HOST_WIDE_INT bytemask,
6649                           bool is_high)
6650 {
6651   if ((op_const & 1) && opint[0] == 0)
6652     return build_int_cst (long_integer_type_node, 0);
6653
6654   if (op_const & 2)
6655     {
6656       unsigned HOST_WIDE_INT temp, loc, byteloc;
6657       tree *zap_op = NULL;
6658
6659       loc = opint[1] & 7;
6660       bytemask <<= loc;
6661
6662       temp = opint[0];
6663       if (is_high)
6664         {
6665           byteloc = (64 - (loc * 8)) & 0x3f;
6666           if (byteloc == 0)
6667             zap_op = op;
6668           else
6669             temp >>= byteloc;
6670           bytemask >>= 8;
6671         }
6672       else
6673         {
6674           byteloc = loc * 8;
6675           if (byteloc == 0)
6676             zap_op = op;
6677           else
6678             temp <<= byteloc;
6679         }
6680
6681       opint[0] = temp;
6682       opint[1] = bytemask;
6683       return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
6684     }
6685
6686   return NULL;
6687 }
6688
6689 static tree
6690 alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
6691                           long op_const, unsigned HOST_WIDE_INT bytemask,
6692                           bool is_high)
6693 {
6694   if (op_const & 2)
6695     {
6696       unsigned HOST_WIDE_INT loc;
6697
6698       loc = opint[1] & 7;
6699       bytemask <<= loc;
6700
6701       if (is_high)
6702         bytemask >>= 8;
6703
6704       opint[1] = bytemask ^ 0xff;
6705     }
6706
6707   return alpha_fold_builtin_zapnot (op, opint, op_const);
6708 }
6709
6710 static tree
6711 alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
6712 {
6713   switch (op_const)
6714     {
6715     case 3:
6716       {
6717         unsigned HOST_WIDE_INT l;
6718         HOST_WIDE_INT h;
6719
6720         mul_double (opint[0], 0, opint[1], 0, &l, &h);
6721
6722 #if HOST_BITS_PER_WIDE_INT > 64
6723 # error fixme
6724 #endif
6725
6726         return build_int_cst (long_integer_type_node, h);
6727       }
6728
6729     case 1:
6730       opint[1] = opint[0];
6731       /* FALLTHRU */
6732     case 2:
6733       /* Note that (X*1) >> 64 == 0.  */
6734       if (opint[1] == 0 || opint[1] == 1)
6735         return build_int_cst (long_integer_type_node, 0);
6736       break;
6737     }
6738   return NULL;
6739 }
6740
6741 static tree
6742 alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
6743 {
6744   tree op0 = fold_convert (vtype, op[0]);
6745   tree op1 = fold_convert (vtype, op[1]);
6746   tree val = fold_build2 (code, vtype, op0, op1);
6747   return fold_build1 (VIEW_CONVERT_EXPR, long_integer_type_node, val);
6748 }
6749
6750 static tree
6751 alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
6752 {
6753   unsigned HOST_WIDE_INT temp = 0;
6754   int i;
6755
6756   if (op_const != 3)
6757     return NULL;
6758
6759   for (i = 0; i < 8; ++i)
6760     {
6761       unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
6762       unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
6763       if (a >= b)
6764         temp += a - b;
6765       else
6766         temp += b - a;
6767     }
6768
6769   return build_int_cst (long_integer_type_node, temp);
6770 }
6771
6772 static tree
6773 alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
6774 {
6775   unsigned HOST_WIDE_INT temp;
6776
6777   if (op_const == 0)
6778     return NULL;
6779
6780   temp = opint[0] & 0xff;
6781   temp |= (opint[0] >> 24) & 0xff00;
6782
6783   return build_int_cst (long_integer_type_node, temp);
6784 }
6785
6786 static tree
6787 alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
6788 {
6789   unsigned HOST_WIDE_INT temp;
6790
6791   if (op_const == 0)
6792     return NULL;
6793
6794   temp = opint[0] & 0xff;
6795   temp |= (opint[0] >>  8) & 0xff00;
6796   temp |= (opint[0] >> 16) & 0xff0000;
6797   temp |= (opint[0] >> 24) & 0xff000000;
6798
6799   return build_int_cst (long_integer_type_node, temp);
6800 }
6801
6802 static tree
6803 alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
6804 {
6805   unsigned HOST_WIDE_INT temp;
6806
6807   if (op_const == 0)
6808     return NULL;
6809
6810   temp = opint[0] & 0xff;
6811   temp |= (opint[0] & 0xff00) << 24;
6812
6813   return build_int_cst (long_integer_type_node, temp);
6814 }
6815
6816 static tree
6817 alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
6818 {
6819   unsigned HOST_WIDE_INT temp;
6820
6821   if (op_const == 0)
6822     return NULL;
6823
6824   temp = opint[0] & 0xff;
6825   temp |= (opint[0] & 0x0000ff00) << 8;
6826   temp |= (opint[0] & 0x00ff0000) << 16;
6827   temp |= (opint[0] & 0xff000000) << 24;
6828
6829   return build_int_cst (long_integer_type_node, temp);
6830 }
6831
6832 static tree
6833 alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
6834 {
6835   unsigned HOST_WIDE_INT temp;
6836
6837   if (op_const == 0)
6838     return NULL;
6839
6840   if (opint[0] == 0)
6841     temp = 64;
6842   else
6843     temp = exact_log2 (opint[0] & -opint[0]);
6844
6845   return build_int_cst (long_integer_type_node, temp);
6846 }
6847
6848 static tree
6849 alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
6850 {
6851   unsigned HOST_WIDE_INT temp;
6852
6853   if (op_const == 0)
6854     return NULL;
6855
6856   if (opint[0] == 0)
6857     temp = 64;
6858   else
6859     temp = 64 - floor_log2 (opint[0]) - 1;
6860
6861   return build_int_cst (long_integer_type_node, temp);
6862 }
6863
6864 static tree
6865 alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
6866 {
6867   unsigned HOST_WIDE_INT temp, op;
6868
6869   if (op_const == 0)
6870     return NULL;
6871
6872   op = opint[0];
6873   temp = 0;
6874   while (op)
6875     temp++, op &= op - 1;
6876
6877   return build_int_cst (long_integer_type_node, temp);
6878 }
6879
6880 /* Fold one of our builtin functions.  */
6881
6882 static tree
6883 alpha_fold_builtin (tree fndecl, int n_args, tree *op,
6884                     bool ignore ATTRIBUTE_UNUSED)
6885 {
6886   unsigned HOST_WIDE_INT opint[MAX_ARGS];
6887   long op_const = 0;
6888   int i;
6889
6890   if (n_args >= MAX_ARGS)
6891     return NULL;
6892
6893   for (i = 0; i < n_args; i++)
6894     {
6895       tree arg = op[i];
6896       if (arg == error_mark_node)
6897         return NULL;
6898
6899       opint[i] = 0;
6900       if (TREE_CODE (arg) == INTEGER_CST)
6901         {
6902           op_const |= 1L << i;
6903           opint[i] = int_cst_value (arg);
6904         }
6905     }
6906
6907   switch (DECL_FUNCTION_CODE (fndecl))
6908     {
6909     case ALPHA_BUILTIN_CMPBGE:
6910       return alpha_fold_builtin_cmpbge (opint, op_const);
6911
6912     case ALPHA_BUILTIN_EXTBL:
6913       return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
6914     case ALPHA_BUILTIN_EXTWL:
6915       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
6916     case ALPHA_BUILTIN_EXTLL:
6917       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
6918     case ALPHA_BUILTIN_EXTQL:
6919       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
6920     case ALPHA_BUILTIN_EXTWH:
6921       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
6922     case ALPHA_BUILTIN_EXTLH:
6923       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
6924     case ALPHA_BUILTIN_EXTQH:
6925       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
6926
6927     case ALPHA_BUILTIN_INSBL:
6928       return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
6929     case ALPHA_BUILTIN_INSWL:
6930       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
6931     case ALPHA_BUILTIN_INSLL:
6932       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
6933     case ALPHA_BUILTIN_INSQL:
6934       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
6935     case ALPHA_BUILTIN_INSWH:
6936       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
6937     case ALPHA_BUILTIN_INSLH:
6938       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
6939     case ALPHA_BUILTIN_INSQH:
6940       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
6941
6942     case ALPHA_BUILTIN_MSKBL:
6943       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
6944     case ALPHA_BUILTIN_MSKWL:
6945       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
6946     case ALPHA_BUILTIN_MSKLL:
6947       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
6948     case ALPHA_BUILTIN_MSKQL:
6949       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
6950     case ALPHA_BUILTIN_MSKWH:
6951       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
6952     case ALPHA_BUILTIN_MSKLH:
6953       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
6954     case ALPHA_BUILTIN_MSKQH:
6955       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
6956
6957     case ALPHA_BUILTIN_UMULH:
6958       return alpha_fold_builtin_umulh (opint, op_const);
6959
6960     case ALPHA_BUILTIN_ZAP:
6961       opint[1] ^= 0xff;
6962       /* FALLTHRU */
6963     case ALPHA_BUILTIN_ZAPNOT:
6964       return alpha_fold_builtin_zapnot (op, opint, op_const);
6965
6966     case ALPHA_BUILTIN_MINUB8:
6967       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
6968     case ALPHA_BUILTIN_MINSB8:
6969       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
6970     case ALPHA_BUILTIN_MINUW4:
6971       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
6972     case ALPHA_BUILTIN_MINSW4:
6973       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
6974     case ALPHA_BUILTIN_MAXUB8:
6975       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
6976     case ALPHA_BUILTIN_MAXSB8:
6977       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
6978     case ALPHA_BUILTIN_MAXUW4:
6979       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
6980     case ALPHA_BUILTIN_MAXSW4:
6981       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
6982
6983     case ALPHA_BUILTIN_PERR:
6984       return alpha_fold_builtin_perr (opint, op_const);
6985     case ALPHA_BUILTIN_PKLB:
6986       return alpha_fold_builtin_pklb (opint, op_const);
6987     case ALPHA_BUILTIN_PKWB:
6988       return alpha_fold_builtin_pkwb (opint, op_const);
6989     case ALPHA_BUILTIN_UNPKBL:
6990       return alpha_fold_builtin_unpkbl (opint, op_const);
6991     case ALPHA_BUILTIN_UNPKBW:
6992       return alpha_fold_builtin_unpkbw (opint, op_const);
6993
6994     case ALPHA_BUILTIN_CTTZ:
6995       return alpha_fold_builtin_cttz (opint, op_const);
6996     case ALPHA_BUILTIN_CTLZ:
6997       return alpha_fold_builtin_ctlz (opint, op_const);
6998     case ALPHA_BUILTIN_CTPOP:
6999       return alpha_fold_builtin_ctpop (opint, op_const);
7000
7001     case ALPHA_BUILTIN_AMASK:
7002     case ALPHA_BUILTIN_IMPLVER:
7003     case ALPHA_BUILTIN_RPCC:
7004     case ALPHA_BUILTIN_THREAD_POINTER:
7005     case ALPHA_BUILTIN_SET_THREAD_POINTER:
7006       /* None of these are foldable at compile-time.  */
7007     default:
7008       return NULL;
7009     }
7010 }
7011 \f
7012 /* This page contains routines that are used to determine what the function
7013    prologue and epilogue code will do and write them out.  */
7014
7015 /* Compute the size of the save area in the stack.  */
7016
7017 /* These variables are used for communication between the following functions.
7018    They indicate various things about the current function being compiled
7019    that are used to tell what kind of prologue, epilogue and procedure
7020    descriptor to generate.  */
7021
7022 /* Nonzero if we need a stack procedure.  */
7023 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
7024 static enum alpha_procedure_types alpha_procedure_type;
7025
7026 /* Register number (either FP or SP) that is used to unwind the frame.  */
7027 static int vms_unwind_regno;
7028
7029 /* Register number used to save FP.  We need not have one for RA since
7030    we don't modify it for register procedures.  This is only defined
7031    for register frame procedures.  */
7032 static int vms_save_fp_regno;
7033
7034 /* Register number used to reference objects off our PV.  */
7035 static int vms_base_regno;
7036
7037 /* Compute register masks for saved registers.  */
7038
7039 static void
7040 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
7041 {
7042   unsigned long imask = 0;
7043   unsigned long fmask = 0;
7044   unsigned int i;
7045
7046   /* When outputting a thunk, we don't have valid register life info,
7047      but assemble_start_function wants to output .frame and .mask
7048      directives.  */
7049   if (cfun->is_thunk)
7050     {
7051       *imaskP = 0;
7052       *fmaskP = 0;
7053       return;
7054     }
7055
7056   if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7057     imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
7058
7059   /* One for every register we have to save.  */
7060   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7061     if (! fixed_regs[i] && ! call_used_regs[i]
7062         && df_regs_ever_live_p (i) && i != REG_RA)
7063       {
7064         if (i < 32)
7065           imask |= (1UL << i);
7066         else
7067           fmask |= (1UL << (i - 32));
7068       }
7069
7070   /* We need to restore these for the handler.  */
7071   if (crtl->calls_eh_return)
7072     {
7073       for (i = 0; ; ++i)
7074         {
7075           unsigned regno = EH_RETURN_DATA_REGNO (i);
7076           if (regno == INVALID_REGNUM)
7077             break;
7078           imask |= 1UL << regno;
7079         }
7080     }
7081
7082   /* If any register spilled, then spill the return address also.  */
7083   /* ??? This is required by the Digital stack unwind specification
7084      and isn't needed if we're doing Dwarf2 unwinding.  */
7085   if (imask || fmask || alpha_ra_ever_killed ())
7086     imask |= (1UL << REG_RA);
7087
7088   *imaskP = imask;
7089   *fmaskP = fmask;
7090 }
7091
7092 int
7093 alpha_sa_size (void)
7094 {
7095   unsigned long mask[2];
7096   int sa_size = 0;
7097   int i, j;
7098
7099   alpha_sa_mask (&mask[0], &mask[1]);
7100
7101   for (j = 0; j < 2; ++j)
7102     for (i = 0; i < 32; ++i)
7103       if ((mask[j] >> i) & 1)
7104         sa_size++;
7105
7106   if (TARGET_ABI_OPEN_VMS)
7107     {
7108       /* Start with a stack procedure if we make any calls (REG_RA used), or
7109          need a frame pointer, with a register procedure if we otherwise need
7110          at least a slot, and with a null procedure in other cases.  */
7111       if ((mask[0] >> REG_RA) & 1 || frame_pointer_needed)
7112         alpha_procedure_type = PT_STACK;
7113       else if (get_frame_size() != 0)
7114         alpha_procedure_type = PT_REGISTER;
7115       else
7116         alpha_procedure_type = PT_NULL;
7117
7118       /* Don't reserve space for saving FP & RA yet.  Do that later after we've
7119          made the final decision on stack procedure vs register procedure.  */
7120       if (alpha_procedure_type == PT_STACK)
7121         sa_size -= 2;
7122
7123       /* Decide whether to refer to objects off our PV via FP or PV.
7124          If we need FP for something else or if we receive a nonlocal
7125          goto (which expects PV to contain the value), we must use PV.
7126          Otherwise, start by assuming we can use FP.  */
7127
7128       vms_base_regno
7129         = (frame_pointer_needed
7130            || cfun->has_nonlocal_label
7131            || alpha_procedure_type == PT_STACK
7132            || crtl->outgoing_args_size)
7133           ? REG_PV : HARD_FRAME_POINTER_REGNUM;
7134
7135       /* If we want to copy PV into FP, we need to find some register
7136          in which to save FP.  */
7137
7138       vms_save_fp_regno = -1;
7139       if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
7140         for (i = 0; i < 32; i++)
7141           if (! fixed_regs[i] && call_used_regs[i] && ! df_regs_ever_live_p (i))
7142             vms_save_fp_regno = i;
7143
7144       /* A VMS condition handler requires a stack procedure in our
7145          implementation. (not required by the calling standard).  */
7146       if ((vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
7147           || cfun->machine->uses_condition_handler)
7148         vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
7149       else if (alpha_procedure_type == PT_NULL)
7150         vms_base_regno = REG_PV;
7151
7152       /* Stack unwinding should be done via FP unless we use it for PV.  */
7153       vms_unwind_regno = (vms_base_regno == REG_PV
7154                           ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
7155
7156       /* If this is a stack procedure, allow space for saving FP, RA and
7157          a condition handler slot if needed.  */
7158       if (alpha_procedure_type == PT_STACK)
7159         sa_size += 2 + cfun->machine->uses_condition_handler;
7160     }
7161   else
7162     {
7163       /* Our size must be even (multiple of 16 bytes).  */
7164       if (sa_size & 1)
7165         sa_size++;
7166     }
7167
7168   return sa_size * 8;
7169 }
7170
7171 /* Define the offset between two registers, one to be eliminated,
7172    and the other its replacement, at the start of a routine.  */
7173
7174 HOST_WIDE_INT
7175 alpha_initial_elimination_offset (unsigned int from,
7176                                   unsigned int to ATTRIBUTE_UNUSED)
7177 {
7178   HOST_WIDE_INT ret;
7179
7180   ret = alpha_sa_size ();
7181   ret += ALPHA_ROUND (crtl->outgoing_args_size);
7182
7183   switch (from)
7184     {
7185     case FRAME_POINTER_REGNUM:
7186       break;
7187
7188     case ARG_POINTER_REGNUM:
7189       ret += (ALPHA_ROUND (get_frame_size ()
7190                            + crtl->args.pretend_args_size)
7191               - crtl->args.pretend_args_size);
7192       break;
7193
7194     default:
7195       gcc_unreachable ();
7196     }
7197
7198   return ret;
7199 }
7200
7201 #if TARGET_ABI_OPEN_VMS
7202
7203 /* Worker function for TARGET_CAN_ELIMINATE.  */
7204
7205 static bool
7206 alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
7207 {
7208   /* We need the alpha_procedure_type to decide. Evaluate it now.  */
7209   alpha_sa_size ();
7210
7211   switch (alpha_procedure_type)
7212     {
7213     case PT_NULL:
7214       /* NULL procedures have no frame of their own and we only
7215          know how to resolve from the current stack pointer.  */
7216       return to == STACK_POINTER_REGNUM;
7217
7218     case PT_REGISTER:
7219     case PT_STACK:
7220       /* We always eliminate except to the stack pointer if there is no
7221          usable frame pointer at hand.  */
7222       return (to != STACK_POINTER_REGNUM
7223               || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM);
7224     }
7225
7226   gcc_unreachable ();
7227 }
7228
7229 /* FROM is to be eliminated for TO. Return the offset so that TO+offset
7230    designates the same location as FROM.  */
7231
7232 HOST_WIDE_INT
7233 alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to)
7234
7235   /* The only possible attempts we ever expect are ARG or FRAME_PTR to
7236      HARD_FRAME or STACK_PTR.  We need the alpha_procedure_type to decide
7237      on the proper computations and will need the register save area size
7238      in most cases.  */
7239
7240   HOST_WIDE_INT sa_size = alpha_sa_size ();
7241
7242   /* PT_NULL procedures have no frame of their own and we only allow
7243      elimination to the stack pointer. This is the argument pointer and we
7244      resolve the soft frame pointer to that as well.  */
7245      
7246   if (alpha_procedure_type == PT_NULL)
7247     return 0;
7248
7249   /* For a PT_STACK procedure the frame layout looks as follows
7250
7251                       -----> decreasing addresses
7252
7253                    <             size rounded up to 16       |   likewise   >
7254      --------------#------------------------------+++--------------+++-------#
7255      incoming args # pretended args | "frame" | regs sa | PV | outgoing args #
7256      --------------#---------------------------------------------------------#
7257                                    ^         ^              ^               ^
7258                               ARG_PTR FRAME_PTR HARD_FRAME_PTR       STACK_PTR
7259
7260                               
7261      PT_REGISTER procedures are similar in that they may have a frame of their
7262      own. They have no regs-sa/pv/outgoing-args area.
7263
7264      We first compute offset to HARD_FRAME_PTR, then add what we need to get
7265      to STACK_PTR if need be.  */
7266   
7267   {
7268     HOST_WIDE_INT offset;
7269     HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0;
7270
7271     switch (from)
7272       {
7273       case FRAME_POINTER_REGNUM:
7274         offset = ALPHA_ROUND (sa_size + pv_save_size);
7275         break;
7276       case ARG_POINTER_REGNUM:
7277         offset = (ALPHA_ROUND (sa_size + pv_save_size
7278                                + get_frame_size ()
7279                                + crtl->args.pretend_args_size)
7280                   - crtl->args.pretend_args_size);
7281         break;
7282       default:
7283         gcc_unreachable ();
7284       }
7285     
7286     if (to == STACK_POINTER_REGNUM)
7287       offset += ALPHA_ROUND (crtl->outgoing_args_size);
7288     
7289     return offset;
7290   }
7291 }
7292
7293 #define COMMON_OBJECT "common_object"
7294
7295 static tree
7296 common_object_handler (tree *node, tree name ATTRIBUTE_UNUSED,
7297                        tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
7298                        bool *no_add_attrs ATTRIBUTE_UNUSED)
7299 {
7300   tree decl = *node;
7301   gcc_assert (DECL_P (decl));
7302
7303   DECL_COMMON (decl) = 1;
7304   return NULL_TREE;
7305 }
7306
7307 static const struct attribute_spec vms_attribute_table[] =
7308 {
7309   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
7310        affects_type_identity } */
7311   { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler, false },
7312   { NULL,            0, 0, false, false, false, NULL, false }
7313 };
7314
7315 void
7316 vms_output_aligned_decl_common(FILE *file, tree decl, const char *name,
7317                                unsigned HOST_WIDE_INT size,
7318                                unsigned int align)
7319 {
7320   tree attr = DECL_ATTRIBUTES (decl);
7321   fprintf (file, "%s", COMMON_ASM_OP);
7322   assemble_name (file, name);
7323   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED, size);
7324   /* ??? Unlike on OSF/1, the alignment factor is not in log units.  */
7325   fprintf (file, ",%u", align / BITS_PER_UNIT);
7326   if (attr)
7327     {
7328       attr = lookup_attribute (COMMON_OBJECT, attr);
7329       if (attr)
7330         fprintf (file, ",%s",
7331                  IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr))));
7332     }
7333   fputc ('\n', file);
7334 }
7335
7336 #undef COMMON_OBJECT
7337
7338 #endif
7339
7340 static int
7341 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
7342 {
7343   return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
7344 }
7345
7346 int
7347 alpha_find_lo_sum_using_gp (rtx insn)
7348 {
7349   return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
7350 }
7351
7352 static int
7353 alpha_does_function_need_gp (void)
7354 {
7355   rtx insn;
7356
7357   /* The GP being variable is an OSF abi thing.  */
7358   if (! TARGET_ABI_OSF)
7359     return 0;
7360
7361   /* We need the gp to load the address of __mcount.  */
7362   if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7363     return 1;
7364
7365   /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
7366   if (cfun->is_thunk)
7367     return 1;
7368
7369   /* The nonlocal receiver pattern assumes that the gp is valid for
7370      the nested function.  Reasonable because it's almost always set
7371      correctly already.  For the cases where that's wrong, make sure
7372      the nested function loads its gp on entry.  */
7373   if (crtl->has_nonlocal_goto)
7374     return 1;
7375
7376   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7377      Even if we are a static function, we still need to do this in case
7378      our address is taken and passed to something like qsort.  */
7379
7380   push_topmost_sequence ();
7381   insn = get_insns ();
7382   pop_topmost_sequence ();
7383
7384   for (; insn; insn = NEXT_INSN (insn))
7385     if (NONDEBUG_INSN_P (insn)
7386         && ! JUMP_TABLE_DATA_P (insn)
7387         && GET_CODE (PATTERN (insn)) != USE
7388         && GET_CODE (PATTERN (insn)) != CLOBBER
7389         && get_attr_usegp (insn))
7390       return 1;
7391
7392   return 0;
7393 }
7394
7395 \f
7396 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7397    sequences.  */
7398
7399 static rtx
7400 set_frame_related_p (void)
7401 {
7402   rtx seq = get_insns ();
7403   rtx insn;
7404
7405   end_sequence ();
7406
7407   if (!seq)
7408     return NULL_RTX;
7409
7410   if (INSN_P (seq))
7411     {
7412       insn = seq;
7413       while (insn != NULL_RTX)
7414         {
7415           RTX_FRAME_RELATED_P (insn) = 1;
7416           insn = NEXT_INSN (insn);
7417         }
7418       seq = emit_insn (seq);
7419     }
7420   else
7421     {
7422       seq = emit_insn (seq);
7423       RTX_FRAME_RELATED_P (seq) = 1;
7424     }
7425   return seq;
7426 }
7427
7428 #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
7429
7430 /* Generates a store with the proper unwind info attached.  VALUE is
7431    stored at BASE_REG+BASE_OFS.  If FRAME_BIAS is nonzero, then BASE_REG
7432    contains SP+FRAME_BIAS, and that is the unwind info that should be
7433    generated.  If FRAME_REG != VALUE, then VALUE is being stored on
7434    behalf of FRAME_REG, and FRAME_REG should be present in the unwind.  */
7435
7436 static void
7437 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
7438                     HOST_WIDE_INT base_ofs, rtx frame_reg)
7439 {
7440   rtx addr, mem, insn;
7441
7442   addr = plus_constant (base_reg, base_ofs);
7443   mem = gen_frame_mem (DImode, addr);
7444
7445   insn = emit_move_insn (mem, value);
7446   RTX_FRAME_RELATED_P (insn) = 1;
7447
7448   if (frame_bias || value != frame_reg)
7449     {
7450       if (frame_bias)
7451         {
7452           addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
7453           mem = gen_rtx_MEM (DImode, addr);
7454         }
7455
7456       add_reg_note (insn, REG_FRAME_RELATED_EXPR,
7457                     gen_rtx_SET (VOIDmode, mem, frame_reg));
7458     }
7459 }
7460
7461 static void
7462 emit_frame_store (unsigned int regno, rtx base_reg,
7463                   HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
7464 {
7465   rtx reg = gen_rtx_REG (DImode, regno);
7466   emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
7467 }
7468
7469 /* Compute the frame size.  SIZE is the size of the "naked" frame
7470    and SA_SIZE is the size of the register save area.  */
7471
7472 static HOST_WIDE_INT
7473 compute_frame_size (HOST_WIDE_INT size, HOST_WIDE_INT sa_size)
7474 {
7475   if (TARGET_ABI_OPEN_VMS)
7476     return ALPHA_ROUND (sa_size 
7477                         + (alpha_procedure_type == PT_STACK ? 8 : 0)
7478                         + size
7479                         + crtl->args.pretend_args_size);
7480   else
7481     return ALPHA_ROUND (crtl->outgoing_args_size)
7482            + sa_size
7483            + ALPHA_ROUND (size
7484                           + crtl->args.pretend_args_size);
7485 }
7486
7487 /* Write function prologue.  */
7488
7489 /* On vms we have two kinds of functions:
7490
7491    - stack frame (PROC_STACK)
7492         these are 'normal' functions with local vars and which are
7493         calling other functions
7494    - register frame (PROC_REGISTER)
7495         keeps all data in registers, needs no stack
7496
7497    We must pass this to the assembler so it can generate the
7498    proper pdsc (procedure descriptor)
7499    This is done with the '.pdesc' command.
7500
7501    On not-vms, we don't really differentiate between the two, as we can
7502    simply allocate stack without saving registers.  */
7503
7504 void
7505 alpha_expand_prologue (void)
7506 {
7507   /* Registers to save.  */
7508   unsigned long imask = 0;
7509   unsigned long fmask = 0;
7510   /* Stack space needed for pushing registers clobbered by us.  */
7511   HOST_WIDE_INT sa_size, sa_bias;
7512   /* Complete stack size needed.  */
7513   HOST_WIDE_INT frame_size;
7514   /* Probed stack size; it additionally includes the size of
7515      the "reserve region" if any.  */
7516   HOST_WIDE_INT probed_size;
7517   /* Offset from base reg to register save area.  */
7518   HOST_WIDE_INT reg_offset;
7519   rtx sa_reg;
7520   int i;
7521
7522   sa_size = alpha_sa_size ();
7523   frame_size = compute_frame_size (get_frame_size (), sa_size);
7524
7525   if (flag_stack_usage)
7526     current_function_static_stack_size = frame_size;
7527
7528   if (TARGET_ABI_OPEN_VMS)
7529     reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
7530   else
7531     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7532
7533   alpha_sa_mask (&imask, &fmask);
7534
7535   /* Emit an insn to reload GP, if needed.  */
7536   if (TARGET_ABI_OSF)
7537     {
7538       alpha_function_needs_gp = alpha_does_function_need_gp ();
7539       if (alpha_function_needs_gp)
7540         emit_insn (gen_prologue_ldgp ());
7541     }
7542
7543   /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7544      the call to mcount ourselves, rather than having the linker do it
7545      magically in response to -pg.  Since _mcount has special linkage,
7546      don't represent the call as a call.  */
7547   if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7548     emit_insn (gen_prologue_mcount ());
7549
7550   /* Adjust the stack by the frame size.  If the frame size is > 4096
7551      bytes, we need to be sure we probe somewhere in the first and last
7552      4096 bytes (we can probably get away without the latter test) and
7553      every 8192 bytes in between.  If the frame size is > 32768, we
7554      do this in a loop.  Otherwise, we generate the explicit probe
7555      instructions.
7556
7557      Note that we are only allowed to adjust sp once in the prologue.  */
7558
7559   probed_size = frame_size;
7560   if (flag_stack_check)
7561     probed_size += STACK_CHECK_PROTECT;
7562
7563   if (probed_size <= 32768)
7564     {
7565       if (probed_size > 4096)
7566         {
7567           int probed;
7568
7569           for (probed = 4096; probed < probed_size; probed += 8192)
7570             emit_insn (gen_probe_stack (GEN_INT (-probed)));
7571
7572           /* We only have to do this probe if we aren't saving registers or
7573              if we are probing beyond the frame because of -fstack-check.  */
7574           if ((sa_size == 0 && probed_size > probed - 4096)
7575               || flag_stack_check)
7576             emit_insn (gen_probe_stack (GEN_INT (-probed_size)));
7577         }
7578
7579       if (frame_size != 0)
7580         FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7581                                     GEN_INT (-frame_size))));
7582     }
7583   else
7584     {
7585       /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7586          number of 8192 byte blocks to probe.  We then probe each block
7587          in the loop and then set SP to the proper location.  If the
7588          amount remaining is > 4096, we have to do one more probe if we
7589          are not saving any registers or if we are probing beyond the
7590          frame because of -fstack-check.  */
7591
7592       HOST_WIDE_INT blocks = (probed_size + 4096) / 8192;
7593       HOST_WIDE_INT leftover = probed_size + 4096 - blocks * 8192;
7594       rtx ptr = gen_rtx_REG (DImode, 22);
7595       rtx count = gen_rtx_REG (DImode, 23);
7596       rtx seq;
7597
7598       emit_move_insn (count, GEN_INT (blocks));
7599       emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
7600
7601       /* Because of the difficulty in emitting a new basic block this
7602          late in the compilation, generate the loop as a single insn.  */
7603       emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7604
7605       if ((leftover > 4096 && sa_size == 0) || flag_stack_check)
7606         {
7607           rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7608           MEM_VOLATILE_P (last) = 1;
7609           emit_move_insn (last, const0_rtx);
7610         }
7611
7612       if (flag_stack_check)
7613         {
7614           /* If -fstack-check is specified we have to load the entire
7615              constant into a register and subtract from the sp in one go,
7616              because the probed stack size is not equal to the frame size.  */
7617           HOST_WIDE_INT lo, hi;
7618           lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7619           hi = frame_size - lo;
7620
7621           emit_move_insn (ptr, GEN_INT (hi));
7622           emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
7623           seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7624                                        ptr));
7625         }
7626       else
7627         {
7628           seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7629                                        GEN_INT (-leftover)));
7630         }
7631
7632       /* This alternative is special, because the DWARF code cannot
7633          possibly intuit through the loop above.  So we invent this
7634          note it looks at instead.  */
7635       RTX_FRAME_RELATED_P (seq) = 1;
7636       add_reg_note (seq, REG_FRAME_RELATED_EXPR,
7637                     gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7638                                  plus_constant (stack_pointer_rtx,
7639                                                 -frame_size)));
7640     }
7641
7642   /* Cope with very large offsets to the register save area.  */
7643   sa_bias = 0;
7644   sa_reg = stack_pointer_rtx;
7645   if (reg_offset + sa_size > 0x8000)
7646     {
7647       int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7648       rtx sa_bias_rtx;
7649
7650       if (low + sa_size <= 0x8000)
7651         sa_bias = reg_offset - low, reg_offset = low;
7652       else
7653         sa_bias = reg_offset, reg_offset = 0;
7654
7655       sa_reg = gen_rtx_REG (DImode, 24);
7656       sa_bias_rtx = GEN_INT (sa_bias);
7657
7658       if (add_operand (sa_bias_rtx, DImode))
7659         emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
7660       else
7661         {
7662           emit_move_insn (sa_reg, sa_bias_rtx);
7663           emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
7664         }
7665     }
7666
7667   /* Save regs in stack order.  Beginning with VMS PV.  */
7668   if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7669     emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
7670
7671   /* Save register RA next.  */
7672   if (imask & (1UL << REG_RA))
7673     {
7674       emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
7675       imask &= ~(1UL << REG_RA);
7676       reg_offset += 8;
7677     }
7678
7679   /* Now save any other registers required to be saved.  */
7680   for (i = 0; i < 31; i++)
7681     if (imask & (1UL << i))
7682       {
7683         emit_frame_store (i, sa_reg, sa_bias, reg_offset);
7684         reg_offset += 8;
7685       }
7686
7687   for (i = 0; i < 31; i++)
7688     if (fmask & (1UL << i))
7689       {
7690         emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
7691         reg_offset += 8;
7692       }
7693
7694   if (TARGET_ABI_OPEN_VMS)
7695     {
7696       /* Register frame procedures save the fp.  */
7697       if (alpha_procedure_type == PT_REGISTER)
7698         {
7699           rtx insn = emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
7700                                      hard_frame_pointer_rtx);
7701           add_reg_note (insn, REG_CFA_REGISTER, NULL);
7702           RTX_FRAME_RELATED_P (insn) = 1;
7703         }
7704
7705       if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
7706         emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
7707                                     gen_rtx_REG (DImode, REG_PV)));
7708
7709       if (alpha_procedure_type != PT_NULL
7710           && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7711         FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7712
7713       /* If we have to allocate space for outgoing args, do it now.  */
7714       if (crtl->outgoing_args_size != 0)
7715         {
7716           rtx seq
7717             = emit_move_insn (stack_pointer_rtx,
7718                               plus_constant
7719                               (hard_frame_pointer_rtx,
7720                                - (ALPHA_ROUND
7721                                   (crtl->outgoing_args_size))));
7722
7723           /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7724              if ! frame_pointer_needed. Setting the bit will change the CFA
7725              computation rule to use sp again, which would be wrong if we had
7726              frame_pointer_needed, as this means sp might move unpredictably
7727              later on.
7728
7729              Also, note that
7730                frame_pointer_needed
7731                => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7732              and
7733                crtl->outgoing_args_size != 0
7734                => alpha_procedure_type != PT_NULL,
7735
7736              so when we are not setting the bit here, we are guaranteed to
7737              have emitted an FRP frame pointer update just before.  */
7738           RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
7739         }
7740     }
7741   else
7742     {
7743       /* If we need a frame pointer, set it from the stack pointer.  */
7744       if (frame_pointer_needed)
7745         {
7746           if (TARGET_CAN_FAULT_IN_PROLOGUE)
7747             FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7748           else
7749             /* This must always be the last instruction in the
7750                prologue, thus we emit a special move + clobber.  */
7751               FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
7752                                            stack_pointer_rtx, sa_reg)));
7753         }
7754     }
7755
7756   /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7757      the prologue, for exception handling reasons, we cannot do this for
7758      any insn that might fault.  We could prevent this for mems with a
7759      (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
7760      have to prevent all such scheduling with a blockage.
7761
7762      Linux, on the other hand, never bothered to implement OSF/1's
7763      exception handling, and so doesn't care about such things.  Anyone
7764      planning to use dwarf2 frame-unwind info can also omit the blockage.  */
7765
7766   if (! TARGET_CAN_FAULT_IN_PROLOGUE)
7767     emit_insn (gen_blockage ());
7768 }
7769
7770 /* Count the number of .file directives, so that .loc is up to date.  */
7771 int num_source_filenames = 0;
7772
7773 /* Output the textual info surrounding the prologue.  */
7774
7775 void
7776 alpha_start_function (FILE *file, const char *fnname,
7777                       tree decl ATTRIBUTE_UNUSED)
7778 {
7779   unsigned long imask = 0;
7780   unsigned long fmask = 0;
7781   /* Stack space needed for pushing registers clobbered by us.  */
7782   HOST_WIDE_INT sa_size;
7783   /* Complete stack size needed.  */
7784   unsigned HOST_WIDE_INT frame_size;
7785   /* The maximum debuggable frame size (512 Kbytes using Tru64 as).  */
7786   unsigned HOST_WIDE_INT max_frame_size = TARGET_ABI_OSF && !TARGET_GAS
7787                                           ? 524288
7788                                           : 1UL << 31;
7789   /* Offset from base reg to register save area.  */
7790   HOST_WIDE_INT reg_offset;
7791   char *entry_label = (char *) alloca (strlen (fnname) + 6);
7792   char *tramp_label = (char *) alloca (strlen (fnname) + 6);
7793   int i;
7794
7795 #if TARGET_ABI_OPEN_VMS
7796   if (vms_debug_main
7797       && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
7798     {
7799       targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
7800       ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
7801       switch_to_section (text_section);
7802       vms_debug_main = NULL;
7803     }
7804 #endif
7805
7806   alpha_fnname = fnname;
7807   sa_size = alpha_sa_size ();
7808   frame_size = compute_frame_size (get_frame_size (), sa_size);
7809
7810   if (TARGET_ABI_OPEN_VMS)
7811     reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
7812   else
7813     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7814
7815   alpha_sa_mask (&imask, &fmask);
7816
7817   /* Ecoff can handle multiple .file directives, so put out file and lineno.
7818      We have to do that before the .ent directive as we cannot switch
7819      files within procedures with native ecoff because line numbers are
7820      linked to procedure descriptors.
7821      Outputting the lineno helps debugging of one line functions as they
7822      would otherwise get no line number at all. Please note that we would
7823      like to put out last_linenum from final.c, but it is not accessible.  */
7824
7825   if (write_symbols == SDB_DEBUG)
7826     {
7827 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7828       ASM_OUTPUT_SOURCE_FILENAME (file,
7829                                   DECL_SOURCE_FILE (current_function_decl));
7830 #endif
7831 #ifdef SDB_OUTPUT_SOURCE_LINE
7832       if (debug_info_level != DINFO_LEVEL_TERSE)
7833         SDB_OUTPUT_SOURCE_LINE (file,
7834                                 DECL_SOURCE_LINE (current_function_decl));
7835 #endif
7836     }
7837
7838   /* Issue function start and label.  */
7839   if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive)
7840     {
7841       fputs ("\t.ent ", file);
7842       assemble_name (file, fnname);
7843       putc ('\n', file);
7844
7845       /* If the function needs GP, we'll write the "..ng" label there.
7846          Otherwise, do it here.  */
7847       if (TARGET_ABI_OSF
7848           && ! alpha_function_needs_gp
7849           && ! cfun->is_thunk)
7850         {
7851           putc ('$', file);
7852           assemble_name (file, fnname);
7853           fputs ("..ng:\n", file);
7854         }
7855     }
7856   /* Nested functions on VMS that are potentially called via trampoline
7857      get a special transfer entry point that loads the called functions
7858      procedure descriptor and static chain.  */
7859    if (TARGET_ABI_OPEN_VMS
7860        && !TREE_PUBLIC (decl)
7861        && DECL_CONTEXT (decl)
7862        && !TYPE_P (DECL_CONTEXT (decl)))
7863      {
7864         strcpy (tramp_label, fnname);
7865         strcat (tramp_label, "..tr");
7866         ASM_OUTPUT_LABEL (file, tramp_label);
7867         fprintf (file, "\tldq $1,24($27)\n");
7868         fprintf (file, "\tldq $27,16($27)\n");
7869      }
7870
7871   strcpy (entry_label, fnname);
7872   if (TARGET_ABI_OPEN_VMS)
7873     strcat (entry_label, "..en");
7874
7875   ASM_OUTPUT_LABEL (file, entry_label);
7876   inside_function = TRUE;
7877
7878   if (TARGET_ABI_OPEN_VMS)
7879     fprintf (file, "\t.base $%d\n", vms_base_regno);
7880
7881   if (TARGET_ABI_OSF
7882       && TARGET_IEEE_CONFORMANT
7883       && !flag_inhibit_size_directive)
7884     {
7885       /* Set flags in procedure descriptor to request IEEE-conformant
7886          math-library routines.  The value we set it to is PDSC_EXC_IEEE
7887          (/usr/include/pdsc.h).  */
7888       fputs ("\t.eflag 48\n", file);
7889     }
7890
7891   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
7892   alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
7893   alpha_arg_offset = -frame_size + 48;
7894
7895   /* Describe our frame.  If the frame size is larger than an integer,
7896      print it as zero to avoid an assembler error.  We won't be
7897      properly describing such a frame, but that's the best we can do.  */
7898   if (TARGET_ABI_OPEN_VMS)
7899     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
7900              HOST_WIDE_INT_PRINT_DEC "\n",
7901              vms_unwind_regno,
7902              frame_size >= (1UL << 31) ? 0 : frame_size,
7903              reg_offset);
7904   else if (!flag_inhibit_size_directive)
7905     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
7906              (frame_pointer_needed
7907               ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
7908              frame_size >= max_frame_size ? 0 : frame_size,
7909              crtl->args.pretend_args_size);
7910
7911   /* Describe which registers were spilled.  */
7912   if (TARGET_ABI_OPEN_VMS)
7913     {
7914       if (imask)
7915         /* ??? Does VMS care if mask contains ra?  The old code didn't
7916            set it, so I don't here.  */
7917         fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
7918       if (fmask)
7919         fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
7920       if (alpha_procedure_type == PT_REGISTER)
7921         fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
7922     }
7923   else if (!flag_inhibit_size_directive)
7924     {
7925       if (imask)
7926         {
7927           fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
7928                    frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7929
7930           for (i = 0; i < 32; ++i)
7931             if (imask & (1UL << i))
7932               reg_offset += 8;
7933         }
7934
7935       if (fmask)
7936         fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
7937                  frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7938     }
7939
7940 #if TARGET_ABI_OPEN_VMS
7941   /* If a user condition handler has been installed at some point, emit
7942      the procedure descriptor bits to point the Condition Handling Facility
7943      at the indirection wrapper, and state the fp offset at which the user
7944      handler may be found.  */
7945   if (cfun->machine->uses_condition_handler)
7946     {
7947       fprintf (file, "\t.handler __gcc_shell_handler\n");
7948       fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET);
7949     }
7950
7951   /* Ifdef'ed cause link_section are only available then.  */
7952   switch_to_section (readonly_data_section);
7953   fprintf (file, "\t.align 3\n");
7954   assemble_name (file, fnname); fputs ("..na:\n", file);
7955   fputs ("\t.ascii \"", file);
7956   assemble_name (file, fnname);
7957   fputs ("\\0\"\n", file);
7958   alpha_need_linkage (fnname, 1);
7959   switch_to_section (text_section);
7960 #endif
7961 }
7962
7963 /* Emit the .prologue note at the scheduled end of the prologue.  */
7964
7965 static void
7966 alpha_output_function_end_prologue (FILE *file)
7967 {
7968   if (TARGET_ABI_OPEN_VMS)
7969     fputs ("\t.prologue\n", file);
7970   else if (!flag_inhibit_size_directive)
7971     fprintf (file, "\t.prologue %d\n",
7972              alpha_function_needs_gp || cfun->is_thunk);
7973 }
7974
7975 /* Write function epilogue.  */
7976
7977 void
7978 alpha_expand_epilogue (void)
7979 {
7980   /* Registers to save.  */
7981   unsigned long imask = 0;
7982   unsigned long fmask = 0;
7983   /* Stack space needed for pushing registers clobbered by us.  */
7984   HOST_WIDE_INT sa_size;
7985   /* Complete stack size needed.  */
7986   HOST_WIDE_INT frame_size;
7987   /* Offset from base reg to register save area.  */
7988   HOST_WIDE_INT reg_offset;
7989   int fp_is_frame_pointer, fp_offset;
7990   rtx sa_reg, sa_reg_exp = NULL;
7991   rtx sp_adj1, sp_adj2, mem, reg, insn;
7992   rtx eh_ofs;
7993   rtx cfa_restores = NULL_RTX;
7994   int i;
7995
7996   sa_size = alpha_sa_size ();
7997   frame_size = compute_frame_size (get_frame_size (), sa_size);
7998
7999   if (TARGET_ABI_OPEN_VMS)
8000     {
8001        if (alpha_procedure_type == PT_STACK)
8002           reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
8003        else
8004           reg_offset = 0;
8005     }
8006   else
8007     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
8008
8009   alpha_sa_mask (&imask, &fmask);
8010
8011   fp_is_frame_pointer
8012     = (TARGET_ABI_OPEN_VMS
8013        ? alpha_procedure_type == PT_STACK
8014        : frame_pointer_needed);
8015   fp_offset = 0;
8016   sa_reg = stack_pointer_rtx;
8017
8018   if (crtl->calls_eh_return)
8019     eh_ofs = EH_RETURN_STACKADJ_RTX;
8020   else
8021     eh_ofs = NULL_RTX;
8022
8023   if (sa_size)
8024     {
8025       /* If we have a frame pointer, restore SP from it.  */
8026       if (TARGET_ABI_OPEN_VMS
8027           ? vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
8028           : frame_pointer_needed)
8029         emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
8030
8031       /* Cope with very large offsets to the register save area.  */
8032       if (reg_offset + sa_size > 0x8000)
8033         {
8034           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
8035           HOST_WIDE_INT bias;
8036
8037           if (low + sa_size <= 0x8000)
8038             bias = reg_offset - low, reg_offset = low;
8039           else
8040             bias = reg_offset, reg_offset = 0;
8041
8042           sa_reg = gen_rtx_REG (DImode, 22);
8043           sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
8044
8045           emit_move_insn (sa_reg, sa_reg_exp);
8046         }
8047
8048       /* Restore registers in order, excepting a true frame pointer.  */
8049
8050       mem = gen_frame_mem (DImode, plus_constant (sa_reg, reg_offset));
8051       reg = gen_rtx_REG (DImode, REG_RA);
8052       emit_move_insn (reg, mem);
8053       cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8054
8055       reg_offset += 8;
8056       imask &= ~(1UL << REG_RA);
8057
8058       for (i = 0; i < 31; ++i)
8059         if (imask & (1UL << i))
8060           {
8061             if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
8062               fp_offset = reg_offset;
8063             else
8064               {
8065                 mem = gen_frame_mem (DImode,
8066                                      plus_constant (sa_reg, reg_offset));
8067                 reg = gen_rtx_REG (DImode, i);
8068                 emit_move_insn (reg, mem);
8069                 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
8070                                                cfa_restores);
8071               }
8072             reg_offset += 8;
8073           }
8074
8075       for (i = 0; i < 31; ++i)
8076         if (fmask & (1UL << i))
8077           {
8078             mem = gen_frame_mem (DFmode, plus_constant (sa_reg, reg_offset));
8079             reg = gen_rtx_REG (DFmode, i+32);
8080             emit_move_insn (reg, mem);
8081             cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8082             reg_offset += 8;
8083           }
8084     }
8085
8086   if (frame_size || eh_ofs)
8087     {
8088       sp_adj1 = stack_pointer_rtx;
8089
8090       if (eh_ofs)
8091         {
8092           sp_adj1 = gen_rtx_REG (DImode, 23);
8093           emit_move_insn (sp_adj1,
8094                           gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
8095         }
8096
8097       /* If the stack size is large, begin computation into a temporary
8098          register so as not to interfere with a potential fp restore,
8099          which must be consecutive with an SP restore.  */
8100       if (frame_size < 32768 && !cfun->calls_alloca)
8101         sp_adj2 = GEN_INT (frame_size);
8102       else if (frame_size < 0x40007fffL)
8103         {
8104           int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
8105
8106           sp_adj2 = plus_constant (sp_adj1, frame_size - low);
8107           if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
8108             sp_adj1 = sa_reg;
8109           else
8110             {
8111               sp_adj1 = gen_rtx_REG (DImode, 23);
8112               emit_move_insn (sp_adj1, sp_adj2);
8113             }
8114           sp_adj2 = GEN_INT (low);
8115         }
8116       else
8117         {
8118           rtx tmp = gen_rtx_REG (DImode, 23);
8119           sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
8120           if (!sp_adj2)
8121             {
8122               /* We can't drop new things to memory this late, afaik,
8123                  so build it up by pieces.  */
8124               sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
8125                                                    -(frame_size < 0));
8126               gcc_assert (sp_adj2);
8127             }
8128         }
8129
8130       /* From now on, things must be in order.  So emit blockages.  */
8131
8132       /* Restore the frame pointer.  */
8133       if (fp_is_frame_pointer)
8134         {
8135           emit_insn (gen_blockage ());
8136           mem = gen_frame_mem (DImode, plus_constant (sa_reg, fp_offset));
8137           emit_move_insn (hard_frame_pointer_rtx, mem);
8138           cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
8139                                          hard_frame_pointer_rtx, cfa_restores);
8140         }
8141       else if (TARGET_ABI_OPEN_VMS)
8142         {
8143           emit_insn (gen_blockage ());
8144           emit_move_insn (hard_frame_pointer_rtx,
8145                           gen_rtx_REG (DImode, vms_save_fp_regno));
8146           cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
8147                                          hard_frame_pointer_rtx, cfa_restores);
8148         }
8149
8150       /* Restore the stack pointer.  */
8151       emit_insn (gen_blockage ());
8152       if (sp_adj2 == const0_rtx)
8153         insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
8154       else
8155         insn = emit_move_insn (stack_pointer_rtx,
8156                                gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
8157       REG_NOTES (insn) = cfa_restores;
8158       add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
8159       RTX_FRAME_RELATED_P (insn) = 1;
8160     }
8161   else
8162     {
8163       gcc_assert (cfa_restores == NULL);
8164
8165       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
8166         {
8167           emit_insn (gen_blockage ());
8168           insn = emit_move_insn (hard_frame_pointer_rtx,
8169                                  gen_rtx_REG (DImode, vms_save_fp_regno));
8170           add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
8171           RTX_FRAME_RELATED_P (insn) = 1;
8172         }
8173     }
8174 }
8175 \f
8176 /* Output the rest of the textual info surrounding the epilogue.  */
8177
8178 void
8179 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
8180 {
8181   rtx insn;
8182
8183   /* We output a nop after noreturn calls at the very end of the function to
8184      ensure that the return address always remains in the caller's code range,
8185      as not doing so might confuse unwinding engines.  */
8186   insn = get_last_insn ();
8187   if (!INSN_P (insn))
8188     insn = prev_active_insn (insn);
8189   if (insn && CALL_P (insn))
8190     output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
8191
8192 #if TARGET_ABI_OPEN_VMS
8193   alpha_write_linkage (file, fnname, decl);
8194 #endif
8195
8196   /* End the function.  */
8197   if (!flag_inhibit_size_directive)
8198     {
8199       fputs ("\t.end ", file);
8200       assemble_name (file, fnname);
8201       putc ('\n', file);
8202     }
8203   inside_function = FALSE;
8204 }
8205
8206 #if TARGET_ABI_OPEN_VMS
8207 void avms_asm_output_external (FILE *file, tree decl ATTRIBUTE_UNUSED, const char *name)
8208 {
8209 #ifdef DO_CRTL_NAMES
8210   DO_CRTL_NAMES;
8211 #endif
8212 }
8213 #endif
8214
8215 #if TARGET_ABI_OSF
8216 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8217
8218    In order to avoid the hordes of differences between generated code
8219    with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8220    lots of code loading up large constants, generate rtl and emit it
8221    instead of going straight to text.
8222
8223    Not sure why this idea hasn't been explored before...  */
8224
8225 static void
8226 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
8227                            HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8228                            tree function)
8229 {
8230   HOST_WIDE_INT hi, lo;
8231   rtx this_rtx, insn, funexp;
8232
8233   /* We always require a valid GP.  */
8234   emit_insn (gen_prologue_ldgp ());
8235   emit_note (NOTE_INSN_PROLOGUE_END);
8236
8237   /* Find the "this" pointer.  If the function returns a structure,
8238      the structure return pointer is in $16.  */
8239   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8240     this_rtx = gen_rtx_REG (Pmode, 17);
8241   else
8242     this_rtx = gen_rtx_REG (Pmode, 16);
8243
8244   /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
8245      entire constant for the add.  */
8246   lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
8247   hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8248   if (hi + lo == delta)
8249     {
8250       if (hi)
8251         emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
8252       if (lo)
8253         emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
8254     }
8255   else
8256     {
8257       rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
8258                                            delta, -(delta < 0));
8259       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8260     }
8261
8262   /* Add a delta stored in the vtable at VCALL_OFFSET.  */
8263   if (vcall_offset)
8264     {
8265       rtx tmp, tmp2;
8266
8267       tmp = gen_rtx_REG (Pmode, 0);
8268       emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
8269
8270       lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
8271       hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8272       if (hi + lo == vcall_offset)
8273         {
8274           if (hi)
8275             emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
8276         }
8277       else
8278         {
8279           tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
8280                                             vcall_offset, -(vcall_offset < 0));
8281           emit_insn (gen_adddi3 (tmp, tmp, tmp2));
8282           lo = 0;
8283         }
8284       if (lo)
8285         tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
8286       else
8287         tmp2 = tmp;
8288       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
8289
8290       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8291     }
8292
8293   /* Generate a tail call to the target function.  */
8294   if (! TREE_USED (function))
8295     {
8296       assemble_external (function);
8297       TREE_USED (function) = 1;
8298     }
8299   funexp = XEXP (DECL_RTL (function), 0);
8300   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
8301   insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
8302   SIBLING_CALL_P (insn) = 1;
8303
8304   /* Run just enough of rest_of_compilation to get the insns emitted.
8305      There's not really enough bulk here to make other passes such as
8306      instruction scheduling worth while.  Note that use_thunk calls
8307      assemble_start_function and assemble_end_function.  */
8308   insn = get_insns ();
8309   insn_locators_alloc ();
8310   shorten_branches (insn);
8311   final_start_function (insn, file, 1);
8312   final (insn, file, 1);
8313   final_end_function ();
8314 }
8315 #endif /* TARGET_ABI_OSF */
8316 \f
8317 /* Debugging support.  */
8318
8319 #include "gstab.h"
8320
8321 /* Count the number of sdb related labels are generated (to find block
8322    start and end boundaries).  */
8323
8324 int sdb_label_count = 0;
8325
8326 /* Name of the file containing the current function.  */
8327
8328 static const char *current_function_file = "";
8329
8330 /* Offsets to alpha virtual arg/local debugging pointers.  */
8331
8332 long alpha_arg_offset;
8333 long alpha_auto_offset;
8334 \f
8335 /* Emit a new filename to a stream.  */
8336
8337 void
8338 alpha_output_filename (FILE *stream, const char *name)
8339 {
8340   static int first_time = TRUE;
8341
8342   if (first_time)
8343     {
8344       first_time = FALSE;
8345       ++num_source_filenames;
8346       current_function_file = name;
8347       fprintf (stream, "\t.file\t%d ", num_source_filenames);
8348       output_quoted_string (stream, name);
8349       fprintf (stream, "\n");
8350       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
8351         fprintf (stream, "\t#@stabs\n");
8352     }
8353
8354   else if (write_symbols == DBX_DEBUG)
8355     /* dbxout.c will emit an appropriate .stabs directive.  */
8356     return;
8357
8358   else if (name != current_function_file
8359            && strcmp (name, current_function_file) != 0)
8360     {
8361       if (inside_function && ! TARGET_GAS)
8362         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
8363       else
8364         {
8365           ++num_source_filenames;
8366           current_function_file = name;
8367           fprintf (stream, "\t.file\t%d ", num_source_filenames);
8368         }
8369
8370       output_quoted_string (stream, name);
8371       fprintf (stream, "\n");
8372     }
8373 }
8374 \f
8375 /* Structure to show the current status of registers and memory.  */
8376
8377 struct shadow_summary
8378 {
8379   struct {
8380     unsigned int i     : 31;    /* Mask of int regs */
8381     unsigned int fp    : 31;    /* Mask of fp regs */
8382     unsigned int mem   :  1;    /* mem == imem | fpmem */
8383   } used, defd;
8384 };
8385
8386 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
8387    to the summary structure.  SET is nonzero if the insn is setting the
8388    object, otherwise zero.  */
8389
8390 static void
8391 summarize_insn (rtx x, struct shadow_summary *sum, int set)
8392 {
8393   const char *format_ptr;
8394   int i, j;
8395
8396   if (x == 0)
8397     return;
8398
8399   switch (GET_CODE (x))
8400     {
8401       /* ??? Note that this case would be incorrect if the Alpha had a
8402          ZERO_EXTRACT in SET_DEST.  */
8403     case SET:
8404       summarize_insn (SET_SRC (x), sum, 0);
8405       summarize_insn (SET_DEST (x), sum, 1);
8406       break;
8407
8408     case CLOBBER:
8409       summarize_insn (XEXP (x, 0), sum, 1);
8410       break;
8411
8412     case USE:
8413       summarize_insn (XEXP (x, 0), sum, 0);
8414       break;
8415
8416     case ASM_OPERANDS:
8417       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8418         summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8419       break;
8420
8421     case PARALLEL:
8422       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8423         summarize_insn (XVECEXP (x, 0, i), sum, 0);
8424       break;
8425
8426     case SUBREG:
8427       summarize_insn (SUBREG_REG (x), sum, 0);
8428       break;
8429
8430     case REG:
8431       {
8432         int regno = REGNO (x);
8433         unsigned long mask = ((unsigned long) 1) << (regno % 32);
8434
8435         if (regno == 31 || regno == 63)
8436           break;
8437
8438         if (set)
8439           {
8440             if (regno < 32)
8441               sum->defd.i |= mask;
8442             else
8443               sum->defd.fp |= mask;
8444           }
8445         else
8446           {
8447             if (regno < 32)
8448               sum->used.i  |= mask;
8449             else
8450               sum->used.fp |= mask;
8451           }
8452         }
8453       break;
8454
8455     case MEM:
8456       if (set)
8457         sum->defd.mem = 1;
8458       else
8459         sum->used.mem = 1;
8460
8461       /* Find the regs used in memory address computation: */
8462       summarize_insn (XEXP (x, 0), sum, 0);
8463       break;
8464
8465     case CONST_INT:   case CONST_DOUBLE:
8466     case SYMBOL_REF:  case LABEL_REF:     case CONST:
8467     case SCRATCH:     case ASM_INPUT:
8468       break;
8469
8470       /* Handle common unary and binary ops for efficiency.  */
8471     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
8472     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
8473     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
8474     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
8475     case NE:       case EQ:      case GE:      case GT:        case LE:
8476     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
8477       summarize_insn (XEXP (x, 0), sum, 0);
8478       summarize_insn (XEXP (x, 1), sum, 0);
8479       break;
8480
8481     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
8482     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
8483     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
8484     case SQRT:  case FFS:
8485       summarize_insn (XEXP (x, 0), sum, 0);
8486       break;
8487
8488     default:
8489       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8490       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8491         switch (format_ptr[i])
8492           {
8493           case 'e':
8494             summarize_insn (XEXP (x, i), sum, 0);
8495             break;
8496
8497           case 'E':
8498             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8499               summarize_insn (XVECEXP (x, i, j), sum, 0);
8500             break;
8501
8502           case 'i':
8503             break;
8504
8505           default:
8506             gcc_unreachable ();
8507           }
8508     }
8509 }
8510
8511 /* Ensure a sufficient number of `trapb' insns are in the code when
8512    the user requests code with a trap precision of functions or
8513    instructions.
8514
8515    In naive mode, when the user requests a trap-precision of
8516    "instruction", a trapb is needed after every instruction that may
8517    generate a trap.  This ensures that the code is resumption safe but
8518    it is also slow.
8519
8520    When optimizations are turned on, we delay issuing a trapb as long
8521    as possible.  In this context, a trap shadow is the sequence of
8522    instructions that starts with a (potentially) trap generating
8523    instruction and extends to the next trapb or call_pal instruction
8524    (but GCC never generates call_pal by itself).  We can delay (and
8525    therefore sometimes omit) a trapb subject to the following
8526    conditions:
8527
8528    (a) On entry to the trap shadow, if any Alpha register or memory
8529    location contains a value that is used as an operand value by some
8530    instruction in the trap shadow (live on entry), then no instruction
8531    in the trap shadow may modify the register or memory location.
8532
8533    (b) Within the trap shadow, the computation of the base register
8534    for a memory load or store instruction may not involve using the
8535    result of an instruction that might generate an UNPREDICTABLE
8536    result.
8537
8538    (c) Within the trap shadow, no register may be used more than once
8539    as a destination register.  (This is to make life easier for the
8540    trap-handler.)
8541
8542    (d) The trap shadow may not include any branch instructions.  */
8543
8544 static void
8545 alpha_handle_trap_shadows (void)
8546 {
8547   struct shadow_summary shadow;
8548   int trap_pending, exception_nesting;
8549   rtx i, n;
8550
8551   trap_pending = 0;
8552   exception_nesting = 0;
8553   shadow.used.i = 0;
8554   shadow.used.fp = 0;
8555   shadow.used.mem = 0;
8556   shadow.defd = shadow.used;
8557
8558   for (i = get_insns (); i ; i = NEXT_INSN (i))
8559     {
8560       if (NOTE_P (i))
8561         {
8562           switch (NOTE_KIND (i))
8563             {
8564             case NOTE_INSN_EH_REGION_BEG:
8565               exception_nesting++;
8566               if (trap_pending)
8567                 goto close_shadow;
8568               break;
8569
8570             case NOTE_INSN_EH_REGION_END:
8571               exception_nesting--;
8572               if (trap_pending)
8573                 goto close_shadow;
8574               break;
8575
8576             case NOTE_INSN_EPILOGUE_BEG:
8577               if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
8578                 goto close_shadow;
8579               break;
8580             }
8581         }
8582       else if (trap_pending)
8583         {
8584           if (alpha_tp == ALPHA_TP_FUNC)
8585             {
8586               if (JUMP_P (i)
8587                   && GET_CODE (PATTERN (i)) == RETURN)
8588                 goto close_shadow;
8589             }
8590           else if (alpha_tp == ALPHA_TP_INSN)
8591             {
8592               if (optimize > 0)
8593                 {
8594                   struct shadow_summary sum;
8595
8596                   sum.used.i = 0;
8597                   sum.used.fp = 0;
8598                   sum.used.mem = 0;
8599                   sum.defd = sum.used;
8600
8601                   switch (GET_CODE (i))
8602                     {
8603                     case INSN:
8604                       /* Annoyingly, get_attr_trap will die on these.  */
8605                       if (GET_CODE (PATTERN (i)) == USE
8606                           || GET_CODE (PATTERN (i)) == CLOBBER)
8607                         break;
8608
8609                       summarize_insn (PATTERN (i), &sum, 0);
8610
8611                       if ((sum.defd.i & shadow.defd.i)
8612                           || (sum.defd.fp & shadow.defd.fp))
8613                         {
8614                           /* (c) would be violated */
8615                           goto close_shadow;
8616                         }
8617
8618                       /* Combine shadow with summary of current insn: */
8619                       shadow.used.i   |= sum.used.i;
8620                       shadow.used.fp  |= sum.used.fp;
8621                       shadow.used.mem |= sum.used.mem;
8622                       shadow.defd.i   |= sum.defd.i;
8623                       shadow.defd.fp  |= sum.defd.fp;
8624                       shadow.defd.mem |= sum.defd.mem;
8625
8626                       if ((sum.defd.i & shadow.used.i)
8627                           || (sum.defd.fp & shadow.used.fp)
8628                           || (sum.defd.mem & shadow.used.mem))
8629                         {
8630                           /* (a) would be violated (also takes care of (b))  */
8631                           gcc_assert (get_attr_trap (i) != TRAP_YES
8632                                       || (!(sum.defd.i & sum.used.i)
8633                                           && !(sum.defd.fp & sum.used.fp)));
8634
8635                           goto close_shadow;
8636                         }
8637                       break;
8638
8639                     case JUMP_INSN:
8640                     case CALL_INSN:
8641                     case CODE_LABEL:
8642                       goto close_shadow;
8643
8644                     default:
8645                       gcc_unreachable ();
8646                     }
8647                 }
8648               else
8649                 {
8650                 close_shadow:
8651                   n = emit_insn_before (gen_trapb (), i);
8652                   PUT_MODE (n, TImode);
8653                   PUT_MODE (i, TImode);
8654                   trap_pending = 0;
8655                   shadow.used.i = 0;
8656                   shadow.used.fp = 0;
8657                   shadow.used.mem = 0;
8658                   shadow.defd = shadow.used;
8659                 }
8660             }
8661         }
8662
8663       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
8664           && NONJUMP_INSN_P (i)
8665           && GET_CODE (PATTERN (i)) != USE
8666           && GET_CODE (PATTERN (i)) != CLOBBER
8667           && get_attr_trap (i) == TRAP_YES)
8668         {
8669           if (optimize && !trap_pending)
8670             summarize_insn (PATTERN (i), &shadow, 0);
8671           trap_pending = 1;
8672         }
8673     }
8674 }
8675 \f
8676 /* Alpha can only issue instruction groups simultaneously if they are
8677    suitably aligned.  This is very processor-specific.  */
8678 /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
8679    that are marked "fake".  These instructions do not exist on that target,
8680    but it is possible to see these insns with deranged combinations of 
8681    command-line options, such as "-mtune=ev4 -mmax".  Instead of aborting,
8682    choose a result at random.  */
8683
8684 enum alphaev4_pipe {
8685   EV4_STOP = 0,
8686   EV4_IB0 = 1,
8687   EV4_IB1 = 2,
8688   EV4_IBX = 4
8689 };
8690
8691 enum alphaev5_pipe {
8692   EV5_STOP = 0,
8693   EV5_NONE = 1,
8694   EV5_E01 = 2,
8695   EV5_E0 = 4,
8696   EV5_E1 = 8,
8697   EV5_FAM = 16,
8698   EV5_FA = 32,
8699   EV5_FM = 64
8700 };
8701
8702 static enum alphaev4_pipe
8703 alphaev4_insn_pipe (rtx insn)
8704 {
8705   if (recog_memoized (insn) < 0)
8706     return EV4_STOP;
8707   if (get_attr_length (insn) != 4)
8708     return EV4_STOP;
8709
8710   switch (get_attr_type (insn))
8711     {
8712     case TYPE_ILD:
8713     case TYPE_LDSYM:
8714     case TYPE_FLD:
8715     case TYPE_LD_L:
8716       return EV4_IBX;
8717
8718     case TYPE_IADD:
8719     case TYPE_ILOG:
8720     case TYPE_ICMOV:
8721     case TYPE_ICMP:
8722     case TYPE_FST:
8723     case TYPE_SHIFT:
8724     case TYPE_IMUL:
8725     case TYPE_FBR:
8726     case TYPE_MVI:              /* fake */
8727       return EV4_IB0;
8728
8729     case TYPE_IST:
8730     case TYPE_MISC:
8731     case TYPE_IBR:
8732     case TYPE_JSR:
8733     case TYPE_CALLPAL:
8734     case TYPE_FCPYS:
8735     case TYPE_FCMOV:
8736     case TYPE_FADD:
8737     case TYPE_FDIV:
8738     case TYPE_FMUL:
8739     case TYPE_ST_C:
8740     case TYPE_MB:
8741     case TYPE_FSQRT:            /* fake */
8742     case TYPE_FTOI:             /* fake */
8743     case TYPE_ITOF:             /* fake */
8744       return EV4_IB1;
8745
8746     default:
8747       gcc_unreachable ();
8748     }
8749 }
8750
8751 static enum alphaev5_pipe
8752 alphaev5_insn_pipe (rtx insn)
8753 {
8754   if (recog_memoized (insn) < 0)
8755     return EV5_STOP;
8756   if (get_attr_length (insn) != 4)
8757     return EV5_STOP;
8758
8759   switch (get_attr_type (insn))
8760     {
8761     case TYPE_ILD:
8762     case TYPE_FLD:
8763     case TYPE_LDSYM:
8764     case TYPE_IADD:
8765     case TYPE_ILOG:
8766     case TYPE_ICMOV:
8767     case TYPE_ICMP:
8768       return EV5_E01;
8769
8770     case TYPE_IST:
8771     case TYPE_FST:
8772     case TYPE_SHIFT:
8773     case TYPE_IMUL:
8774     case TYPE_MISC:
8775     case TYPE_MVI:
8776     case TYPE_LD_L:
8777     case TYPE_ST_C:
8778     case TYPE_MB:
8779     case TYPE_FTOI:             /* fake */
8780     case TYPE_ITOF:             /* fake */
8781       return EV5_E0;
8782
8783     case TYPE_IBR:
8784     case TYPE_JSR:
8785     case TYPE_CALLPAL:
8786       return EV5_E1;
8787
8788     case TYPE_FCPYS:
8789       return EV5_FAM;
8790
8791     case TYPE_FBR:
8792     case TYPE_FCMOV:
8793     case TYPE_FADD:
8794     case TYPE_FDIV:
8795     case TYPE_FSQRT:            /* fake */
8796       return EV5_FA;
8797
8798     case TYPE_FMUL:
8799       return EV5_FM;
8800
8801     default:
8802       gcc_unreachable ();
8803     }
8804 }
8805
8806 /* IN_USE is a mask of the slots currently filled within the insn group.
8807    The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
8808    the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8809
8810    LEN is, of course, the length of the group in bytes.  */
8811
8812 static rtx
8813 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
8814 {
8815   int len, in_use;
8816
8817   len = in_use = 0;
8818
8819   if (! INSN_P (insn)
8820       || GET_CODE (PATTERN (insn)) == CLOBBER
8821       || GET_CODE (PATTERN (insn)) == USE)
8822     goto next_and_done;
8823
8824   while (1)
8825     {
8826       enum alphaev4_pipe pipe;
8827
8828       pipe = alphaev4_insn_pipe (insn);
8829       switch (pipe)
8830         {
8831         case EV4_STOP:
8832           /* Force complex instructions to start new groups.  */
8833           if (in_use)
8834             goto done;
8835
8836           /* If this is a completely unrecognized insn, it's an asm.
8837              We don't know how long it is, so record length as -1 to
8838              signal a needed realignment.  */
8839           if (recog_memoized (insn) < 0)
8840             len = -1;
8841           else
8842             len = get_attr_length (insn);
8843           goto next_and_done;
8844
8845         case EV4_IBX:
8846           if (in_use & EV4_IB0)
8847             {
8848               if (in_use & EV4_IB1)
8849                 goto done;
8850               in_use |= EV4_IB1;
8851             }
8852           else
8853             in_use |= EV4_IB0 | EV4_IBX;
8854           break;
8855
8856         case EV4_IB0:
8857           if (in_use & EV4_IB0)
8858             {
8859               if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
8860                 goto done;
8861               in_use |= EV4_IB1;
8862             }
8863           in_use |= EV4_IB0;
8864           break;
8865
8866         case EV4_IB1:
8867           if (in_use & EV4_IB1)
8868             goto done;
8869           in_use |= EV4_IB1;
8870           break;
8871
8872         default:
8873           gcc_unreachable ();
8874         }
8875       len += 4;
8876
8877       /* Haifa doesn't do well scheduling branches.  */
8878       if (JUMP_P (insn))
8879         goto next_and_done;
8880
8881     next:
8882       insn = next_nonnote_insn (insn);
8883
8884       if (!insn || ! INSN_P (insn))
8885         goto done;
8886
8887       /* Let Haifa tell us where it thinks insn group boundaries are.  */
8888       if (GET_MODE (insn) == TImode)
8889         goto done;
8890
8891       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8892         goto next;
8893     }
8894
8895  next_and_done:
8896   insn = next_nonnote_insn (insn);
8897
8898  done:
8899   *plen = len;
8900   *pin_use = in_use;
8901   return insn;
8902 }
8903
8904 /* IN_USE is a mask of the slots currently filled within the insn group.
8905    The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
8906    the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8907
8908    LEN is, of course, the length of the group in bytes.  */
8909
8910 static rtx
8911 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
8912 {
8913   int len, in_use;
8914
8915   len = in_use = 0;
8916
8917   if (! INSN_P (insn)
8918       || GET_CODE (PATTERN (insn)) == CLOBBER
8919       || GET_CODE (PATTERN (insn)) == USE)
8920     goto next_and_done;
8921
8922   while (1)
8923     {
8924       enum alphaev5_pipe pipe;
8925
8926       pipe = alphaev5_insn_pipe (insn);
8927       switch (pipe)
8928         {
8929         case EV5_STOP:
8930           /* Force complex instructions to start new groups.  */
8931           if (in_use)
8932             goto done;
8933
8934           /* If this is a completely unrecognized insn, it's an asm.
8935              We don't know how long it is, so record length as -1 to
8936              signal a needed realignment.  */
8937           if (recog_memoized (insn) < 0)
8938             len = -1;
8939           else
8940             len = get_attr_length (insn);
8941           goto next_and_done;
8942
8943         /* ??? Most of the places below, we would like to assert never
8944            happen, as it would indicate an error either in Haifa, or
8945            in the scheduling description.  Unfortunately, Haifa never
8946            schedules the last instruction of the BB, so we don't have
8947            an accurate TI bit to go off.  */
8948         case EV5_E01:
8949           if (in_use & EV5_E0)
8950             {
8951               if (in_use & EV5_E1)
8952                 goto done;
8953               in_use |= EV5_E1;
8954             }
8955           else
8956             in_use |= EV5_E0 | EV5_E01;
8957           break;
8958
8959         case EV5_E0:
8960           if (in_use & EV5_E0)
8961             {
8962               if (!(in_use & EV5_E01) || (in_use & EV5_E1))
8963                 goto done;
8964               in_use |= EV5_E1;
8965             }
8966           in_use |= EV5_E0;
8967           break;
8968
8969         case EV5_E1:
8970           if (in_use & EV5_E1)
8971             goto done;
8972           in_use |= EV5_E1;
8973           break;
8974
8975         case EV5_FAM:
8976           if (in_use & EV5_FA)
8977             {
8978               if (in_use & EV5_FM)
8979                 goto done;
8980               in_use |= EV5_FM;
8981             }
8982           else
8983             in_use |= EV5_FA | EV5_FAM;
8984           break;
8985
8986         case EV5_FA:
8987           if (in_use & EV5_FA)
8988             goto done;
8989           in_use |= EV5_FA;
8990           break;
8991
8992         case EV5_FM:
8993           if (in_use & EV5_FM)
8994             goto done;
8995           in_use |= EV5_FM;
8996           break;
8997
8998         case EV5_NONE:
8999           break;
9000
9001         default:
9002           gcc_unreachable ();
9003         }
9004       len += 4;
9005
9006       /* Haifa doesn't do well scheduling branches.  */
9007       /* ??? If this is predicted not-taken, slotting continues, except
9008          that no more IBR, FBR, or JSR insns may be slotted.  */
9009       if (JUMP_P (insn))
9010         goto next_and_done;
9011
9012     next:
9013       insn = next_nonnote_insn (insn);
9014
9015       if (!insn || ! INSN_P (insn))
9016         goto done;
9017
9018       /* Let Haifa tell us where it thinks insn group boundaries are.  */
9019       if (GET_MODE (insn) == TImode)
9020         goto done;
9021
9022       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9023         goto next;
9024     }
9025
9026  next_and_done:
9027   insn = next_nonnote_insn (insn);
9028
9029  done:
9030   *plen = len;
9031   *pin_use = in_use;
9032   return insn;
9033 }
9034
9035 static rtx
9036 alphaev4_next_nop (int *pin_use)
9037 {
9038   int in_use = *pin_use;
9039   rtx nop;
9040
9041   if (!(in_use & EV4_IB0))
9042     {
9043       in_use |= EV4_IB0;
9044       nop = gen_nop ();
9045     }
9046   else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
9047     {
9048       in_use |= EV4_IB1;
9049       nop = gen_nop ();
9050     }
9051   else if (TARGET_FP && !(in_use & EV4_IB1))
9052     {
9053       in_use |= EV4_IB1;
9054       nop = gen_fnop ();
9055     }
9056   else
9057     nop = gen_unop ();
9058
9059   *pin_use = in_use;
9060   return nop;
9061 }
9062
9063 static rtx
9064 alphaev5_next_nop (int *pin_use)
9065 {
9066   int in_use = *pin_use;
9067   rtx nop;
9068
9069   if (!(in_use & EV5_E1))
9070     {
9071       in_use |= EV5_E1;
9072       nop = gen_nop ();
9073     }
9074   else if (TARGET_FP && !(in_use & EV5_FA))
9075     {
9076       in_use |= EV5_FA;
9077       nop = gen_fnop ();
9078     }
9079   else if (TARGET_FP && !(in_use & EV5_FM))
9080     {
9081       in_use |= EV5_FM;
9082       nop = gen_fnop ();
9083     }
9084   else
9085     nop = gen_unop ();
9086
9087   *pin_use = in_use;
9088   return nop;
9089 }
9090
9091 /* The instruction group alignment main loop.  */
9092
9093 static void
9094 alpha_align_insns (unsigned int max_align,
9095                    rtx (*next_group) (rtx, int *, int *),
9096                    rtx (*next_nop) (int *))
9097 {
9098   /* ALIGN is the known alignment for the insn group.  */
9099   unsigned int align;
9100   /* OFS is the offset of the current insn in the insn group.  */
9101   int ofs;
9102   int prev_in_use, in_use, len, ldgp;
9103   rtx i, next;
9104
9105   /* Let shorten branches care for assigning alignments to code labels.  */
9106   shorten_branches (get_insns ());
9107
9108   if (align_functions < 4)
9109     align = 4;
9110   else if ((unsigned int) align_functions < max_align)
9111     align = align_functions;
9112   else
9113     align = max_align;
9114
9115   ofs = prev_in_use = 0;
9116   i = get_insns ();
9117   if (NOTE_P (i))
9118     i = next_nonnote_insn (i);
9119
9120   ldgp = alpha_function_needs_gp ? 8 : 0;
9121
9122   while (i)
9123     {
9124       next = (*next_group) (i, &in_use, &len);
9125
9126       /* When we see a label, resync alignment etc.  */
9127       if (LABEL_P (i))
9128         {
9129           unsigned int new_align = 1 << label_to_alignment (i);
9130
9131           if (new_align >= align)
9132             {
9133               align = new_align < max_align ? new_align : max_align;
9134               ofs = 0;
9135             }
9136
9137           else if (ofs & (new_align-1))
9138             ofs = (ofs | (new_align-1)) + 1;
9139           gcc_assert (!len);
9140         }
9141
9142       /* Handle complex instructions special.  */
9143       else if (in_use == 0)
9144         {
9145           /* Asms will have length < 0.  This is a signal that we have
9146              lost alignment knowledge.  Assume, however, that the asm
9147              will not mis-align instructions.  */
9148           if (len < 0)
9149             {
9150               ofs = 0;
9151               align = 4;
9152               len = 0;
9153             }
9154         }
9155
9156       /* If the known alignment is smaller than the recognized insn group,
9157          realign the output.  */
9158       else if ((int) align < len)
9159         {
9160           unsigned int new_log_align = len > 8 ? 4 : 3;
9161           rtx prev, where;
9162
9163           where = prev = prev_nonnote_insn (i);
9164           if (!where || !LABEL_P (where))
9165             where = i;
9166
9167           /* Can't realign between a call and its gp reload.  */
9168           if (! (TARGET_EXPLICIT_RELOCS
9169                  && prev && CALL_P (prev)))
9170             {
9171               emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
9172               align = 1 << new_log_align;
9173               ofs = 0;
9174             }
9175         }
9176
9177       /* We may not insert padding inside the initial ldgp sequence.  */
9178       else if (ldgp > 0)
9179         ldgp -= len;
9180
9181       /* If the group won't fit in the same INT16 as the previous,
9182          we need to add padding to keep the group together.  Rather
9183          than simply leaving the insn filling to the assembler, we
9184          can make use of the knowledge of what sorts of instructions
9185          were issued in the previous group to make sure that all of
9186          the added nops are really free.  */
9187       else if (ofs + len > (int) align)
9188         {
9189           int nop_count = (align - ofs) / 4;
9190           rtx where;
9191
9192           /* Insert nops before labels, branches, and calls to truly merge
9193              the execution of the nops with the previous instruction group.  */
9194           where = prev_nonnote_insn (i);
9195           if (where)
9196             {
9197               if (LABEL_P (where))
9198                 {
9199                   rtx where2 = prev_nonnote_insn (where);
9200                   if (where2 && JUMP_P (where2))
9201                     where = where2;
9202                 }
9203               else if (NONJUMP_INSN_P (where))
9204                 where = i;
9205             }
9206           else
9207             where = i;
9208
9209           do
9210             emit_insn_before ((*next_nop)(&prev_in_use), where);
9211           while (--nop_count);
9212           ofs = 0;
9213         }
9214
9215       ofs = (ofs + len) & (align - 1);
9216       prev_in_use = in_use;
9217       i = next;
9218     }
9219 }
9220
9221 /* Insert an unop between a noreturn function call and GP load.  */
9222
9223 static void
9224 alpha_pad_noreturn (void)
9225 {
9226   rtx insn, next;
9227
9228   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9229     {
9230       if (! (CALL_P (insn)
9231              && find_reg_note (insn, REG_NORETURN, NULL_RTX)))
9232         continue;
9233
9234       /* Make sure we do not split a call and its corresponding
9235          CALL_ARG_LOCATION note.  */
9236       if (CALL_P (insn))
9237         {
9238           next = NEXT_INSN (insn);
9239           if (next && NOTE_P (next)
9240               && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION)
9241             insn = next;
9242         }
9243
9244       next = next_active_insn (insn);
9245
9246       if (next)
9247         {
9248           rtx pat = PATTERN (next);
9249
9250           if (GET_CODE (pat) == SET
9251               && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
9252               && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
9253             emit_insn_after (gen_unop (), insn);
9254         }
9255     }
9256 }
9257 \f
9258 /* Machine dependent reorg pass.  */
9259
9260 static void
9261 alpha_reorg (void)
9262 {
9263   /* Workaround for a linker error that triggers when an
9264      exception handler immediatelly follows a noreturn function.
9265
9266      The instruction stream from an object file:
9267
9268   54:   00 40 5b 6b     jsr     ra,(t12),58 <__func+0x58>
9269   58:   00 00 ba 27     ldah    gp,0(ra)
9270   5c:   00 00 bd 23     lda     gp,0(gp)
9271   60:   00 00 7d a7     ldq     t12,0(gp)
9272   64:   00 40 5b 6b     jsr     ra,(t12),68 <__func+0x68>
9273
9274      was converted in the final link pass to:
9275
9276    fdb24:       a0 03 40 d3     bsr     ra,fe9a8 <_called_func+0x8>
9277    fdb28:       00 00 fe 2f     unop
9278    fdb2c:       00 00 fe 2f     unop
9279    fdb30:       30 82 7d a7     ldq     t12,-32208(gp)
9280    fdb34:       00 40 5b 6b     jsr     ra,(t12),fdb38 <__func+0x68>
9281
9282      GP load instructions were wrongly cleared by the linker relaxation
9283      pass.  This workaround prevents removal of GP loads by inserting
9284      an unop instruction between a noreturn function call and
9285      exception handler prologue.  */
9286
9287   if (current_function_has_exception_handlers ())
9288     alpha_pad_noreturn ();
9289
9290   if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
9291     alpha_handle_trap_shadows ();
9292
9293   /* Due to the number of extra trapb insns, don't bother fixing up
9294      alignment when trap precision is instruction.  Moreover, we can
9295      only do our job when sched2 is run.  */
9296   if (optimize && !optimize_size
9297       && alpha_tp != ALPHA_TP_INSN
9298       && flag_schedule_insns_after_reload)
9299     {
9300       if (alpha_tune == PROCESSOR_EV4)
9301         alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
9302       else if (alpha_tune == PROCESSOR_EV5)
9303         alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
9304     }
9305 }
9306 \f
9307 #ifdef HAVE_STAMP_H
9308 #include <stamp.h>
9309 #endif
9310
9311 static void
9312 alpha_file_start (void)
9313 {
9314 #ifdef OBJECT_FORMAT_ELF
9315   /* If emitting dwarf2 debug information, we cannot generate a .file
9316      directive to start the file, as it will conflict with dwarf2out
9317      file numbers.  So it's only useful when emitting mdebug output.  */
9318   targetm.asm_file_start_file_directive = (write_symbols == DBX_DEBUG);
9319 #endif
9320
9321   default_file_start ();
9322 #ifdef MS_STAMP
9323   fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
9324 #endif
9325
9326   fputs ("\t.set noreorder\n", asm_out_file);
9327   fputs ("\t.set volatile\n", asm_out_file);
9328   if (TARGET_ABI_OSF)
9329     fputs ("\t.set noat\n", asm_out_file);
9330   if (TARGET_EXPLICIT_RELOCS)
9331     fputs ("\t.set nomacro\n", asm_out_file);
9332   if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
9333     {
9334       const char *arch;
9335
9336       if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
9337         arch = "ev6";
9338       else if (TARGET_MAX)
9339         arch = "pca56";
9340       else if (TARGET_BWX)
9341         arch = "ev56";
9342       else if (alpha_cpu == PROCESSOR_EV5)
9343         arch = "ev5";
9344       else
9345         arch = "ev4";
9346
9347       fprintf (asm_out_file, "\t.arch %s\n", arch);
9348     }
9349 }
9350
9351 #ifdef OBJECT_FORMAT_ELF
9352 /* Since we don't have a .dynbss section, we should not allow global
9353    relocations in the .rodata section.  */
9354
9355 static int
9356 alpha_elf_reloc_rw_mask (void)
9357 {
9358   return flag_pic ? 3 : 2;
9359 }
9360
9361 /* Return a section for X.  The only special thing we do here is to
9362    honor small data.  */
9363
9364 static section *
9365 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
9366                               unsigned HOST_WIDE_INT align)
9367 {
9368   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
9369     /* ??? Consider using mergeable sdata sections.  */
9370     return sdata_section;
9371   else
9372     return default_elf_select_rtx_section (mode, x, align);
9373 }
9374
9375 static unsigned int
9376 alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
9377 {
9378   unsigned int flags = 0;
9379
9380   if (strcmp (name, ".sdata") == 0
9381       || strncmp (name, ".sdata.", 7) == 0
9382       || strncmp (name, ".gnu.linkonce.s.", 16) == 0
9383       || strcmp (name, ".sbss") == 0
9384       || strncmp (name, ".sbss.", 6) == 0
9385       || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
9386     flags = SECTION_SMALL;
9387
9388   flags |= default_section_type_flags (decl, name, reloc);
9389   return flags;
9390 }
9391 #endif /* OBJECT_FORMAT_ELF */
9392 \f
9393 /* Structure to collect function names for final output in link section.  */
9394 /* Note that items marked with GTY can't be ifdef'ed out.  */
9395
9396 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
9397 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
9398
9399 struct GTY(()) alpha_links
9400 {
9401   int num;
9402   const char *target;
9403   rtx linkage;
9404   enum links_kind lkind;
9405   enum reloc_kind rkind;
9406 };
9407
9408 struct GTY(()) alpha_funcs
9409 {
9410   int num;
9411   splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9412     links;
9413 };
9414
9415 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9416   splay_tree alpha_links_tree;
9417 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
9418   splay_tree alpha_funcs_tree;
9419
9420 static GTY(()) int alpha_funcs_num;
9421
9422 #if TARGET_ABI_OPEN_VMS
9423
9424 /* Return the VMS argument type corresponding to MODE.  */
9425
9426 enum avms_arg_type
9427 alpha_arg_type (enum machine_mode mode)
9428 {
9429   switch (mode)
9430     {
9431     case SFmode:
9432       return TARGET_FLOAT_VAX ? FF : FS;
9433     case DFmode:
9434       return TARGET_FLOAT_VAX ? FD : FT;
9435     default:
9436       return I64;
9437     }
9438 }
9439
9440 /* Return an rtx for an integer representing the VMS Argument Information
9441    register value.  */
9442
9443 rtx
9444 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
9445 {
9446   unsigned HOST_WIDE_INT regval = cum.num_args;
9447   int i;
9448
9449   for (i = 0; i < 6; i++)
9450     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
9451
9452   return GEN_INT (regval);
9453 }
9454 \f
9455 /* Register the need for a (fake) .linkage entry for calls to function NAME.
9456    IS_LOCAL is 1 if this is for a definition, 0 if this is for a real call.
9457    Return a SYMBOL_REF suited to the call instruction.  */
9458
9459 rtx
9460 alpha_need_linkage (const char *name, int is_local)
9461 {
9462   splay_tree_node node;
9463   struct alpha_links *al;
9464   const char *target;
9465   tree id;
9466
9467   if (name[0] == '*')
9468     name++;
9469
9470   if (is_local)
9471     {
9472       struct alpha_funcs *cfaf;
9473
9474       if (!alpha_funcs_tree)
9475         alpha_funcs_tree = splay_tree_new_ggc
9476          (splay_tree_compare_pointers,
9477           ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
9478           ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
9479
9480
9481       cfaf = ggc_alloc_alpha_funcs ();
9482
9483       cfaf->links = 0;
9484       cfaf->num = ++alpha_funcs_num;
9485
9486       splay_tree_insert (alpha_funcs_tree,
9487                          (splay_tree_key) current_function_decl,
9488                          (splay_tree_value) cfaf);
9489     }
9490
9491   if (alpha_links_tree)
9492     {
9493       /* Is this name already defined?  */
9494
9495       node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9496       if (node)
9497         {
9498           al = (struct alpha_links *) node->value;
9499           if (is_local)
9500             {
9501               /* Defined here but external assumed.  */
9502               if (al->lkind == KIND_EXTERN)
9503                 al->lkind = KIND_LOCAL;
9504             }
9505           else
9506             {
9507               /* Used here but unused assumed.  */
9508               if (al->lkind == KIND_UNUSED)
9509                 al->lkind = KIND_LOCAL;
9510             }
9511           return al->linkage;
9512         }
9513     }
9514   else
9515     alpha_links_tree = splay_tree_new_ggc
9516          ((splay_tree_compare_fn) strcmp,
9517           ggc_alloc_splay_tree_str_alpha_links_splay_tree_s,
9518           ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s);
9519
9520   al = ggc_alloc_alpha_links ();
9521   name = ggc_strdup (name);
9522
9523   /* Assume external if no definition.  */
9524   al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9525
9526   /* Ensure we have an IDENTIFIER so assemble_name can mark it used
9527      and find the ultimate alias target like assemble_name.  */
9528   id = get_identifier (name);
9529   target = NULL;
9530   while (IDENTIFIER_TRANSPARENT_ALIAS (id))
9531     {
9532       id = TREE_CHAIN (id);
9533       target = IDENTIFIER_POINTER (id);
9534     }
9535
9536   al->target = target ? target : name;
9537   al->linkage = gen_rtx_SYMBOL_REF (Pmode, name);
9538
9539   splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9540                      (splay_tree_value) al);
9541
9542   return al->linkage;
9543 }
9544
9545 /* Return a SYMBOL_REF representing the reference to the .linkage entry
9546    of function FUNC built for calls made from CFUNDECL.  LFLAG is 1 if
9547    this is the reference to the linkage pointer value, 0 if this is the
9548    reference to the function entry value.  RFLAG is 1 if this a reduced
9549    reference (code address only), 0 if this is a full reference.  */
9550
9551 rtx
9552 alpha_use_linkage (rtx func, tree cfundecl, int lflag, int rflag)
9553 {
9554   splay_tree_node cfunnode;
9555   struct alpha_funcs *cfaf;
9556   struct alpha_links *al;
9557   const char *name = XSTR (func, 0);
9558
9559   cfaf = (struct alpha_funcs *) 0;
9560   al = (struct alpha_links *) 0;
9561
9562   cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9563   cfaf = (struct alpha_funcs *) cfunnode->value;
9564
9565   if (cfaf->links)
9566     {
9567       splay_tree_node lnode;
9568
9569       /* Is this name already defined?  */
9570
9571       lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9572       if (lnode)
9573         al = (struct alpha_links *) lnode->value;
9574     }
9575   else
9576     cfaf->links = splay_tree_new_ggc
9577       ((splay_tree_compare_fn) strcmp,
9578        ggc_alloc_splay_tree_str_alpha_links_splay_tree_s,
9579        ggc_alloc_splay_tree_str_alpha_links_splay_tree_node_s);
9580
9581   if (!al)
9582     {
9583       size_t name_len;
9584       size_t buflen;
9585       char *linksym;
9586       splay_tree_node node = 0;
9587       struct alpha_links *anl;
9588
9589       if (name[0] == '*')
9590         name++;
9591
9592       name_len = strlen (name);
9593       linksym = (char *) alloca (name_len + 50);
9594
9595       al = ggc_alloc_alpha_links ();
9596       al->num = cfaf->num;
9597       al->target = NULL;
9598
9599       node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9600       if (node)
9601         {
9602           anl = (struct alpha_links *) node->value;
9603           al->lkind = anl->lkind;
9604           name = anl->target;
9605         }
9606
9607       sprintf (linksym, "$%d..%s..lk", cfaf->num, name);
9608       buflen = strlen (linksym);
9609
9610       al->linkage = gen_rtx_SYMBOL_REF
9611         (Pmode, ggc_alloc_string (linksym, buflen + 1));
9612
9613       splay_tree_insert (cfaf->links, (splay_tree_key) name,
9614                          (splay_tree_value) al);
9615     }
9616
9617   if (rflag)
9618     al->rkind = KIND_CODEADDR;
9619   else
9620     al->rkind = KIND_LINKAGE;
9621
9622   if (lflag)
9623     return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
9624   else
9625     return al->linkage;
9626 }
9627
9628 static int
9629 alpha_write_one_linkage (splay_tree_node node, void *data)
9630 {
9631   const char *const name = (const char *) node->key;
9632   struct alpha_links *link = (struct alpha_links *) node->value;
9633   FILE *stream = (FILE *) data;
9634
9635   fprintf (stream, "$%d..%s..lk:\n", link->num, name);
9636   if (link->rkind == KIND_CODEADDR)
9637     {
9638       if (link->lkind == KIND_LOCAL)
9639         {
9640           /* Local and used */
9641           fprintf (stream, "\t.quad %s..en\n", name);
9642         }
9643       else
9644         {
9645           /* External and used, request code address.  */
9646           fprintf (stream, "\t.code_address %s\n", name);
9647         }
9648     }
9649   else
9650     {
9651       if (link->lkind == KIND_LOCAL)
9652         {
9653           /* Local and used, build linkage pair.  */
9654           fprintf (stream, "\t.quad %s..en\n", name);
9655           fprintf (stream, "\t.quad %s\n", name);
9656         }
9657       else
9658         {
9659           /* External and used, request linkage pair.  */
9660           fprintf (stream, "\t.linkage %s\n", name);
9661         }
9662     }
9663
9664   return 0;
9665 }
9666
9667 static void
9668 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
9669 {
9670   splay_tree_node node;
9671   struct alpha_funcs *func;
9672
9673   fprintf (stream, "\t.link\n");
9674   fprintf (stream, "\t.align 3\n");
9675   in_section = NULL;
9676
9677   node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
9678   func = (struct alpha_funcs *) node->value;
9679
9680   fputs ("\t.name ", stream);
9681   assemble_name (stream, funname);
9682   fputs ("..na\n", stream);
9683   ASM_OUTPUT_LABEL (stream, funname);
9684   fprintf (stream, "\t.pdesc ");
9685   assemble_name (stream, funname);
9686   fprintf (stream, "..en,%s\n",
9687            alpha_procedure_type == PT_STACK ? "stack"
9688            : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
9689
9690   if (func->links)
9691     {
9692       splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
9693       /* splay_tree_delete (func->links); */
9694     }
9695 }
9696
9697 /* Switch to an arbitrary section NAME with attributes as specified
9698    by FLAGS.  ALIGN specifies any known alignment requirements for
9699    the section; 0 if the default should be used.  */
9700
9701 static void
9702 vms_asm_named_section (const char *name, unsigned int flags, 
9703                        tree decl ATTRIBUTE_UNUSED)
9704 {
9705   fputc ('\n', asm_out_file);
9706   fprintf (asm_out_file, ".section\t%s", name);
9707
9708   if (flags & SECTION_DEBUG)
9709     fprintf (asm_out_file, ",NOWRT");
9710
9711   fputc ('\n', asm_out_file);
9712 }
9713
9714 /* Record an element in the table of global constructors.  SYMBOL is
9715    a SYMBOL_REF of the function to be called; PRIORITY is a number
9716    between 0 and MAX_INIT_PRIORITY.
9717
9718    Differs from default_ctors_section_asm_out_constructor in that the
9719    width of the .ctors entry is always 64 bits, rather than the 32 bits
9720    used by a normal pointer.  */
9721
9722 static void
9723 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9724 {
9725   switch_to_section (ctors_section);
9726   assemble_align (BITS_PER_WORD);
9727   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9728 }
9729
9730 static void
9731 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9732 {
9733   switch_to_section (dtors_section);
9734   assemble_align (BITS_PER_WORD);
9735   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9736 }
9737 #else
9738
9739 rtx
9740 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
9741                     int is_local ATTRIBUTE_UNUSED)
9742 {
9743   return NULL_RTX;
9744 }
9745
9746 rtx
9747 alpha_use_linkage (rtx func ATTRIBUTE_UNUSED,
9748                    tree cfundecl ATTRIBUTE_UNUSED,
9749                    int lflag ATTRIBUTE_UNUSED,
9750                    int rflag ATTRIBUTE_UNUSED)
9751 {
9752   return NULL_RTX;
9753 }
9754
9755 #endif /* TARGET_ABI_OPEN_VMS */
9756 \f
9757 static void
9758 alpha_init_libfuncs (void)
9759 {
9760   if (TARGET_ABI_OPEN_VMS)
9761     {
9762       /* Use the VMS runtime library functions for division and
9763          remainder.  */
9764       set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
9765       set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
9766       set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
9767       set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
9768       set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
9769       set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
9770       set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
9771       set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
9772       abort_libfunc = init_one_libfunc ("decc$abort");
9773       memcmp_libfunc = init_one_libfunc ("decc$memcmp");
9774 #ifdef MEM_LIBFUNCS_INIT
9775       MEM_LIBFUNCS_INIT;
9776 #endif
9777     }
9778 }
9779
9780 /* On the Alpha, we use this to disable the floating-point registers
9781    when they don't exist.  */
9782
9783 static void
9784 alpha_conditional_register_usage (void)
9785 {
9786   int i;
9787   if (! TARGET_FPREGS)
9788     for (i = 32; i < 63; i++)
9789       fixed_regs[i] = call_used_regs[i] = 1;
9790 }
9791 \f
9792 /* Initialize the GCC target structure.  */
9793 #if TARGET_ABI_OPEN_VMS
9794 # undef TARGET_ATTRIBUTE_TABLE
9795 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
9796 # undef TARGET_CAN_ELIMINATE
9797 # define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate
9798 #endif
9799
9800 #undef TARGET_IN_SMALL_DATA_P
9801 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
9802
9803 #undef TARGET_ASM_ALIGNED_HI_OP
9804 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
9805 #undef TARGET_ASM_ALIGNED_DI_OP
9806 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
9807
9808 /* Default unaligned ops are provided for ELF systems.  To get unaligned
9809    data for non-ELF systems, we have to turn off auto alignment.  */
9810 #if !defined (OBJECT_FORMAT_ELF) || TARGET_ABI_OPEN_VMS
9811 #undef TARGET_ASM_UNALIGNED_HI_OP
9812 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
9813 #undef TARGET_ASM_UNALIGNED_SI_OP
9814 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
9815 #undef TARGET_ASM_UNALIGNED_DI_OP
9816 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
9817 #endif
9818
9819 #ifdef OBJECT_FORMAT_ELF
9820 #undef  TARGET_ASM_RELOC_RW_MASK
9821 #define TARGET_ASM_RELOC_RW_MASK  alpha_elf_reloc_rw_mask
9822 #undef  TARGET_ASM_SELECT_RTX_SECTION
9823 #define TARGET_ASM_SELECT_RTX_SECTION  alpha_elf_select_rtx_section
9824 #undef  TARGET_SECTION_TYPE_FLAGS
9825 #define TARGET_SECTION_TYPE_FLAGS  alpha_elf_section_type_flags
9826 #endif
9827
9828 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
9829 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
9830
9831 #undef TARGET_INIT_LIBFUNCS
9832 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
9833
9834 #undef TARGET_LEGITIMIZE_ADDRESS
9835 #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
9836
9837 #undef TARGET_ASM_FILE_START
9838 #define TARGET_ASM_FILE_START alpha_file_start
9839 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
9840 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
9841
9842 #undef TARGET_SCHED_ADJUST_COST
9843 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
9844 #undef TARGET_SCHED_ISSUE_RATE
9845 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
9846 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
9847 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
9848   alpha_multipass_dfa_lookahead
9849
9850 #undef TARGET_HAVE_TLS
9851 #define TARGET_HAVE_TLS HAVE_AS_TLS
9852
9853 #undef  TARGET_BUILTIN_DECL
9854 #define TARGET_BUILTIN_DECL  alpha_builtin_decl
9855 #undef  TARGET_INIT_BUILTINS
9856 #define TARGET_INIT_BUILTINS alpha_init_builtins
9857 #undef  TARGET_EXPAND_BUILTIN
9858 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
9859 #undef  TARGET_FOLD_BUILTIN
9860 #define TARGET_FOLD_BUILTIN alpha_fold_builtin
9861
9862 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
9863 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
9864 #undef TARGET_CANNOT_COPY_INSN_P
9865 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
9866 #undef TARGET_LEGITIMATE_CONSTANT_P
9867 #define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
9868 #undef TARGET_CANNOT_FORCE_CONST_MEM
9869 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
9870
9871 #if TARGET_ABI_OSF
9872 #undef TARGET_ASM_OUTPUT_MI_THUNK
9873 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
9874 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
9875 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
9876 #undef TARGET_STDARG_OPTIMIZE_HOOK
9877 #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
9878 #endif
9879
9880 #undef TARGET_RTX_COSTS
9881 #define TARGET_RTX_COSTS alpha_rtx_costs
9882 #undef TARGET_ADDRESS_COST
9883 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
9884
9885 #undef TARGET_MACHINE_DEPENDENT_REORG
9886 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
9887
9888 #undef TARGET_PROMOTE_FUNCTION_MODE
9889 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
9890 #undef TARGET_PROMOTE_PROTOTYPES
9891 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
9892 #undef TARGET_RETURN_IN_MEMORY
9893 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
9894 #undef TARGET_PASS_BY_REFERENCE
9895 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
9896 #undef TARGET_SETUP_INCOMING_VARARGS
9897 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
9898 #undef TARGET_STRICT_ARGUMENT_NAMING
9899 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
9900 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
9901 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
9902 #undef TARGET_SPLIT_COMPLEX_ARG
9903 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
9904 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
9905 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
9906 #undef TARGET_ARG_PARTIAL_BYTES
9907 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
9908 #undef TARGET_FUNCTION_ARG
9909 #define TARGET_FUNCTION_ARG alpha_function_arg
9910 #undef TARGET_FUNCTION_ARG_ADVANCE
9911 #define TARGET_FUNCTION_ARG_ADVANCE alpha_function_arg_advance
9912 #undef TARGET_TRAMPOLINE_INIT
9913 #define TARGET_TRAMPOLINE_INIT alpha_trampoline_init
9914
9915 #undef TARGET_SECONDARY_RELOAD
9916 #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
9917
9918 #undef TARGET_SCALAR_MODE_SUPPORTED_P
9919 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
9920 #undef TARGET_VECTOR_MODE_SUPPORTED_P
9921 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
9922
9923 #undef TARGET_BUILD_BUILTIN_VA_LIST
9924 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
9925
9926 #undef TARGET_EXPAND_BUILTIN_VA_START
9927 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
9928
9929 /* The Alpha architecture does not require sequential consistency.  See
9930    http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
9931    for an example of how it can be violated in practice.  */
9932 #undef TARGET_RELAXED_ORDERING
9933 #define TARGET_RELAXED_ORDERING true
9934
9935 #undef TARGET_DEFAULT_TARGET_FLAGS
9936 #define TARGET_DEFAULT_TARGET_FLAGS \
9937   (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
9938 #undef TARGET_HANDLE_OPTION
9939 #define TARGET_HANDLE_OPTION alpha_handle_option
9940
9941 #undef TARGET_OPTION_OVERRIDE
9942 #define TARGET_OPTION_OVERRIDE alpha_option_override
9943
9944 #undef TARGET_OPTION_OPTIMIZATION_TABLE
9945 #define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table
9946
9947 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
9948 #undef TARGET_MANGLE_TYPE
9949 #define TARGET_MANGLE_TYPE alpha_mangle_type
9950 #endif
9951
9952 #undef TARGET_LEGITIMATE_ADDRESS_P
9953 #define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
9954
9955 #undef TARGET_CONDITIONAL_REGISTER_USAGE
9956 #define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage
9957
9958 struct gcc_target targetm = TARGET_INITIALIZER;
9959
9960 \f
9961 #include "gt-alpha.h"