OSDN Git Service

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