OSDN Git Service

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