OSDN Git Service

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