OSDN Git Service

867bb08dd5ccc37fefdb2b8747bc681755b3feb7
[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 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 "tree-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           CONST_OR_PURE_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           CONST_OR_PURE_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 {
1265   enum machine_mode mode = GET_MODE (x);
1266   bool float_mode_p = FLOAT_MODE_P (mode);
1267   const struct alpha_rtx_cost_data *cost_data;
1268
1269   if (optimize_size)
1270     cost_data = &alpha_rtx_cost_size;
1271   else
1272     cost_data = &alpha_rtx_cost_data[alpha_tune];
1273
1274   switch (code)
1275     {
1276     case CONST_INT:
1277       /* If this is an 8-bit constant, return zero since it can be used
1278          nearly anywhere with no cost.  If it is a valid operand for an
1279          ADD or AND, likewise return 0 if we know it will be used in that
1280          context.  Otherwise, return 2 since it might be used there later.
1281          All other constants take at least two insns.  */
1282       if (INTVAL (x) >= 0 && INTVAL (x) < 256)
1283         {
1284           *total = 0;
1285           return true;
1286         }
1287       /* FALLTHRU */
1288
1289     case CONST_DOUBLE:
1290       if (x == CONST0_RTX (mode))
1291         *total = 0;
1292       else if ((outer_code == PLUS && add_operand (x, VOIDmode))
1293                || (outer_code == AND && and_operand (x, VOIDmode)))
1294         *total = 0;
1295       else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
1296         *total = 2;
1297       else
1298         *total = COSTS_N_INSNS (2);
1299       return true;
1300
1301     case CONST:
1302     case SYMBOL_REF:
1303     case LABEL_REF:
1304       if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
1305         *total = COSTS_N_INSNS (outer_code != MEM);
1306       else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
1307         *total = COSTS_N_INSNS (1 + (outer_code != MEM));
1308       else if (tls_symbolic_operand_type (x))
1309         /* Estimate of cost for call_pal rduniq.  */
1310         /* ??? How many insns do we emit here?  More than one...  */
1311         *total = COSTS_N_INSNS (15);
1312       else
1313         /* Otherwise we do a load from the GOT.  */
1314         *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1315       return true;
1316
1317     case HIGH:
1318       /* This is effectively an add_operand.  */
1319       *total = 2;
1320       return true;
1321
1322     case PLUS:
1323     case MINUS:
1324       if (float_mode_p)
1325         *total = cost_data->fp_add;
1326       else if (GET_CODE (XEXP (x, 0)) == MULT
1327                && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
1328         {
1329           *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
1330                     + rtx_cost (XEXP (x, 1), outer_code) + COSTS_N_INSNS (1));
1331           return true;
1332         }
1333       return false;
1334
1335     case MULT:
1336       if (float_mode_p)
1337         *total = cost_data->fp_mult;
1338       else if (mode == DImode)
1339         *total = cost_data->int_mult_di;
1340       else
1341         *total = cost_data->int_mult_si;
1342       return false;
1343
1344     case ASHIFT:
1345       if (GET_CODE (XEXP (x, 1)) == CONST_INT
1346           && INTVAL (XEXP (x, 1)) <= 3)
1347         {
1348           *total = COSTS_N_INSNS (1);
1349           return false;
1350         }
1351       /* FALLTHRU */
1352
1353     case ASHIFTRT:
1354     case LSHIFTRT:
1355       *total = cost_data->int_shift;
1356       return false;
1357
1358     case IF_THEN_ELSE:
1359       if (float_mode_p)
1360         *total = cost_data->fp_add;
1361       else
1362         *total = cost_data->int_cmov;
1363       return false;
1364
1365     case DIV:
1366     case UDIV:
1367     case MOD:
1368     case UMOD:
1369       if (!float_mode_p)
1370         *total = cost_data->int_div;
1371       else if (mode == SFmode)
1372         *total = cost_data->fp_div_sf;
1373       else
1374         *total = cost_data->fp_div_df;
1375       return false;
1376
1377     case MEM:
1378       *total = COSTS_N_INSNS (optimize_size ? 1 : alpha_memory_latency);
1379       return true;
1380
1381     case NEG:
1382       if (! float_mode_p)
1383         {
1384           *total = COSTS_N_INSNS (1);
1385           return false;
1386         }
1387       /* FALLTHRU */
1388
1389     case ABS:
1390       if (! float_mode_p)
1391         {
1392           *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
1393           return false;
1394         }
1395       /* FALLTHRU */
1396
1397     case FLOAT:
1398     case UNSIGNED_FLOAT:
1399     case FIX:
1400     case UNSIGNED_FIX:
1401     case FLOAT_TRUNCATE:
1402       *total = cost_data->fp_add;
1403       return false;
1404
1405     case FLOAT_EXTEND:
1406       if (GET_CODE (XEXP (x, 0)) == MEM)
1407         *total = 0;
1408       else
1409         *total = cost_data->fp_add;
1410       return false;
1411
1412     default:
1413       return false;
1414     }
1415 }
1416 \f
1417 /* REF is an alignable memory location.  Place an aligned SImode
1418    reference into *PALIGNED_MEM and the number of bits to shift into
1419    *PBITNUM.  SCRATCH is a free register for use in reloading out
1420    of range stack slots.  */
1421
1422 void
1423 get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
1424 {
1425   rtx base;
1426   HOST_WIDE_INT disp, offset;
1427
1428   gcc_assert (GET_CODE (ref) == MEM);
1429
1430   if (reload_in_progress
1431       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1432     {
1433       base = find_replacement (&XEXP (ref, 0));
1434       gcc_assert (memory_address_p (GET_MODE (ref), base));
1435     }
1436   else
1437     base = XEXP (ref, 0);
1438
1439   if (GET_CODE (base) == PLUS)
1440     disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1441   else
1442     disp = 0;
1443
1444   /* Find the byte offset within an aligned word.  If the memory itself is
1445      claimed to be aligned, believe it.  Otherwise, aligned_memory_operand
1446      will have examined the base register and determined it is aligned, and
1447      thus displacements from it are naturally alignable.  */
1448   if (MEM_ALIGN (ref) >= 32)
1449     offset = 0;
1450   else
1451     offset = disp & 3;
1452
1453   /* Access the entire aligned word.  */
1454   *paligned_mem = widen_memory_access (ref, SImode, -offset);
1455
1456   /* Convert the byte offset within the word to a bit offset.  */
1457   if (WORDS_BIG_ENDIAN)
1458     offset = 32 - (GET_MODE_BITSIZE (GET_MODE (ref)) + offset * 8);
1459   else
1460     offset *= 8;
1461   *pbitnum = GEN_INT (offset);
1462 }
1463
1464 /* Similar, but just get the address.  Handle the two reload cases.
1465    Add EXTRA_OFFSET to the address we return.  */
1466
1467 rtx
1468 get_unaligned_address (rtx ref)
1469 {
1470   rtx base;
1471   HOST_WIDE_INT offset = 0;
1472
1473   gcc_assert (GET_CODE (ref) == MEM);
1474
1475   if (reload_in_progress
1476       && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
1477     {
1478       base = find_replacement (&XEXP (ref, 0));
1479
1480       gcc_assert (memory_address_p (GET_MODE (ref), base));
1481     }
1482   else
1483     base = XEXP (ref, 0);
1484
1485   if (GET_CODE (base) == PLUS)
1486     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
1487
1488   return plus_constant (base, offset);
1489 }
1490
1491 /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
1492    X is always returned in a register.  */
1493
1494 rtx
1495 get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
1496 {
1497   if (GET_CODE (addr) == PLUS)
1498     {
1499       ofs += INTVAL (XEXP (addr, 1));
1500       addr = XEXP (addr, 0);
1501     }
1502
1503   return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
1504                               NULL_RTX, 1, OPTAB_LIB_WIDEN);
1505 }
1506
1507 /* On the Alpha, all (non-symbolic) constants except zero go into
1508    a floating-point register via memory.  Note that we cannot
1509    return anything that is not a subset of CLASS, and that some
1510    symbolic constants cannot be dropped to memory.  */
1511
1512 enum reg_class
1513 alpha_preferred_reload_class(rtx x, enum reg_class class)
1514 {
1515   /* Zero is present in any register class.  */
1516   if (x == CONST0_RTX (GET_MODE (x)))
1517     return class;
1518
1519   /* These sorts of constants we can easily drop to memory.  */
1520   if (GET_CODE (x) == CONST_INT
1521       || GET_CODE (x) == CONST_DOUBLE
1522       || GET_CODE (x) == CONST_VECTOR)
1523     {
1524       if (class == FLOAT_REGS)
1525         return NO_REGS;
1526       if (class == ALL_REGS)
1527         return GENERAL_REGS;
1528       return class;
1529     }
1530
1531   /* All other kinds of constants should not (and in the case of HIGH
1532      cannot) be dropped to memory -- instead we use a GENERAL_REGS
1533      secondary reload.  */
1534   if (CONSTANT_P (x))
1535     return (class == ALL_REGS ? GENERAL_REGS : class);
1536
1537   return class;
1538 }
1539
1540 /* Inform reload about cases where moving X with a mode MODE to a register in
1541    CLASS requires an extra scratch or immediate register.  Return the class
1542    needed for the immediate register.  */
1543
1544 static enum reg_class
1545 alpha_secondary_reload (bool in_p, rtx x, enum reg_class class,
1546                         enum machine_mode mode, secondary_reload_info *sri)
1547 {
1548   /* Loading and storing HImode or QImode values to and from memory
1549      usually requires a scratch register.  */
1550   if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode))
1551     {
1552       if (any_memory_operand (x, mode))
1553         {
1554           if (in_p)
1555             {
1556               if (!aligned_memory_operand (x, mode))
1557                 sri->icode = reload_in_optab[mode];
1558             }
1559           else
1560             sri->icode = reload_out_optab[mode];
1561           return NO_REGS;
1562         }
1563     }
1564
1565   /* We also cannot do integral arithmetic into FP regs, as might result
1566      from register elimination into a DImode fp register.  */
1567   if (class == FLOAT_REGS)
1568     {
1569       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
1570         return GENERAL_REGS;
1571       if (in_p && INTEGRAL_MODE_P (mode)
1572           && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x))
1573         return GENERAL_REGS;
1574     }
1575
1576   return NO_REGS;
1577 }
1578 \f
1579 /* Subfunction of the following function.  Update the flags of any MEM
1580    found in part of X.  */
1581
1582 static int
1583 alpha_set_memflags_1 (rtx *xp, void *data)
1584 {
1585   rtx x = *xp, orig = (rtx) data;
1586
1587   if (GET_CODE (x) != MEM)
1588     return 0;
1589
1590   MEM_VOLATILE_P (x) = MEM_VOLATILE_P (orig);
1591   MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (orig);
1592   MEM_SCALAR_P (x) = MEM_SCALAR_P (orig);
1593   MEM_NOTRAP_P (x) = MEM_NOTRAP_P (orig);
1594   MEM_READONLY_P (x) = MEM_READONLY_P (orig);
1595
1596   /* Sadly, we cannot use alias sets because the extra aliasing
1597      produced by the AND interferes.  Given that two-byte quantities
1598      are the only thing we would be able to differentiate anyway,
1599      there does not seem to be any point in convoluting the early
1600      out of the alias check.  */
1601
1602   return -1;
1603 }
1604
1605 /* Given INSN, which is an INSN list or the PATTERN of a single insn
1606    generated to perform a memory operation, 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 insn, rtx ref)
1613 {
1614   rtx *base_ptr;
1615
1616   if (GET_CODE (ref) != MEM)
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   if (INSN_P (insn))
1630     base_ptr = &PATTERN (insn);
1631   else
1632     base_ptr = &insn;
1633   for_each_rtx (base_ptr, alpha_set_memflags_1, (void *) ref);
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;
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 = ((c & 0xffff) ^ 0x8000) - 0x8000;
1747       if (new != 0)
1748         {
1749           temp = alpha_emit_set_const (subtarget, mode, c - new, 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),
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 = c >> bits;
1782             temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1783             if (!temp && c < 0)
1784               {
1785                 new = (unsigned HOST_WIDE_INT)c >> bits;
1786                 temp = alpha_emit_set_const (subtarget, mode, new,
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 = c << bits;
1810             temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1811             if (!temp)
1812               {
1813                 new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1814                 temp = alpha_emit_set_const (subtarget, mode, new,
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 = c << bits;
1836             temp = alpha_emit_set_const (subtarget, mode, new, i, no_output);
1837             if (!temp)
1838               {
1839                 new = (c << bits) | (((HOST_WIDE_INT) 1 << bits) - 1);
1840                 temp = alpha_emit_set_const (subtarget, mode, new,
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 = c;
1859   for (i = 0; i < 64; i += 8)
1860     if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
1861       new |= (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 = ((new & 0xffffffff) ^ 0x80000000) - 0x80000000;
1868
1869   if (new != c)
1870     {
1871       temp = alpha_emit_set_const (subtarget, mode, new, 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),
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)
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   CONST_OR_PURE_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     x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
4469   else
4470     x = gen_rtx_fmt_ee (code, mode, before, val);
4471   if (after)
4472     emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
4473   emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
4474
4475   emit_store_conditional (mode, cond, mem, scratch);
4476
4477   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4478   emit_unlikely_jump (x, label);
4479
4480   emit_insn (gen_memory_barrier ());
4481 }
4482
4483 /* Expand a compare and swap operation.  */
4484
4485 void
4486 alpha_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
4487                               rtx scratch)
4488 {
4489   enum machine_mode mode = GET_MODE (mem);
4490   rtx label1, label2, x, cond = gen_lowpart (DImode, scratch);
4491
4492   emit_insn (gen_memory_barrier ());
4493
4494   label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4495   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4496   emit_label (XEXP (label1, 0));
4497
4498   emit_load_locked (mode, retval, mem);
4499
4500   x = gen_lowpart (DImode, retval);
4501   if (oldval == const0_rtx)
4502     x = gen_rtx_NE (DImode, x, const0_rtx);
4503   else
4504     {
4505       x = gen_rtx_EQ (DImode, x, oldval);
4506       emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4507       x = gen_rtx_EQ (DImode, cond, const0_rtx);
4508     }
4509   emit_unlikely_jump (x, label2);
4510
4511   emit_move_insn (scratch, newval);
4512   emit_store_conditional (mode, cond, mem, scratch);
4513
4514   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4515   emit_unlikely_jump (x, label1);
4516
4517   emit_insn (gen_memory_barrier ());
4518   emit_label (XEXP (label2, 0));
4519 }
4520
4521 void
4522 alpha_expand_compare_and_swap_12 (rtx dst, rtx mem, rtx oldval, rtx newval)
4523 {
4524   enum machine_mode mode = GET_MODE (mem);
4525   rtx addr, align, wdst;
4526   rtx (*fn5) (rtx, rtx, rtx, rtx, rtx);
4527
4528   addr = force_reg (DImode, XEXP (mem, 0));
4529   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4530                                NULL_RTX, 1, OPTAB_DIRECT);
4531
4532   oldval = convert_modes (DImode, mode, oldval, 1);
4533   newval = emit_insxl (mode, newval, addr);
4534
4535   wdst = gen_reg_rtx (DImode);
4536   if (mode == QImode)
4537     fn5 = gen_sync_compare_and_swapqi_1;
4538   else
4539     fn5 = gen_sync_compare_and_swaphi_1;
4540   emit_insn (fn5 (wdst, addr, oldval, newval, align));
4541
4542   emit_move_insn (dst, gen_lowpart (mode, wdst));
4543 }
4544
4545 void
4546 alpha_split_compare_and_swap_12 (enum machine_mode mode, rtx dest, rtx addr,
4547                                  rtx oldval, rtx newval, rtx align,
4548                                  rtx scratch, rtx cond)
4549 {
4550   rtx label1, label2, mem, width, mask, x;
4551
4552   mem = gen_rtx_MEM (DImode, align);
4553   MEM_VOLATILE_P (mem) = 1;
4554
4555   emit_insn (gen_memory_barrier ());
4556   label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4557   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4558   emit_label (XEXP (label1, 0));
4559
4560   emit_load_locked (DImode, scratch, mem);
4561   
4562   width = GEN_INT (GET_MODE_BITSIZE (mode));
4563   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4564   if (WORDS_BIG_ENDIAN)
4565     emit_insn (gen_extxl_be (dest, scratch, width, addr));
4566   else
4567     emit_insn (gen_extxl_le (dest, scratch, width, addr));
4568
4569   if (oldval == const0_rtx)
4570     x = gen_rtx_NE (DImode, dest, const0_rtx);
4571   else
4572     {
4573       x = gen_rtx_EQ (DImode, dest, oldval);
4574       emit_insn (gen_rtx_SET (VOIDmode, cond, x));
4575       x = gen_rtx_EQ (DImode, cond, const0_rtx);
4576     }
4577   emit_unlikely_jump (x, label2);
4578
4579   if (WORDS_BIG_ENDIAN)
4580     emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
4581   else
4582     emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
4583   emit_insn (gen_iordi3 (scratch, scratch, newval));
4584
4585   emit_store_conditional (DImode, scratch, mem, scratch);
4586
4587   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4588   emit_unlikely_jump (x, label1);
4589
4590   emit_insn (gen_memory_barrier ());
4591   emit_label (XEXP (label2, 0));
4592 }
4593
4594 /* Expand an atomic exchange operation.  */
4595
4596 void
4597 alpha_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
4598 {
4599   enum machine_mode mode = GET_MODE (mem);
4600   rtx label, x, cond = gen_lowpart (DImode, scratch);
4601
4602   emit_insn (gen_memory_barrier ());
4603
4604   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4605   emit_label (XEXP (label, 0));
4606
4607   emit_load_locked (mode, retval, mem);
4608   emit_move_insn (scratch, val);
4609   emit_store_conditional (mode, cond, mem, scratch);
4610
4611   x = gen_rtx_EQ (DImode, cond, const0_rtx);
4612   emit_unlikely_jump (x, label);
4613 }
4614
4615 void
4616 alpha_expand_lock_test_and_set_12 (rtx dst, rtx mem, rtx val)
4617 {
4618   enum machine_mode mode = GET_MODE (mem);
4619   rtx addr, align, wdst;
4620   rtx (*fn4) (rtx, rtx, rtx, rtx);
4621
4622   /* Force the address into a register.  */
4623   addr = force_reg (DImode, XEXP (mem, 0));
4624
4625   /* Align it to a multiple of 8.  */
4626   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
4627                                NULL_RTX, 1, OPTAB_DIRECT);
4628
4629   /* Insert val into the correct byte location within the word.  */
4630   val = emit_insxl (mode, val, addr);
4631
4632   wdst = gen_reg_rtx (DImode);
4633   if (mode == QImode)
4634     fn4 = gen_sync_lock_test_and_setqi_1;
4635   else
4636     fn4 = gen_sync_lock_test_and_sethi_1;
4637   emit_insn (fn4 (wdst, addr, val, align));
4638
4639   emit_move_insn (dst, gen_lowpart (mode, wdst));
4640 }
4641
4642 void
4643 alpha_split_lock_test_and_set_12 (enum machine_mode mode, rtx dest, rtx addr,
4644                                   rtx val, rtx align, rtx scratch)
4645 {
4646   rtx label, mem, width, mask, x;
4647
4648   mem = gen_rtx_MEM (DImode, align);
4649   MEM_VOLATILE_P (mem) = 1;
4650
4651   emit_insn (gen_memory_barrier ());
4652   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
4653   emit_label (XEXP (label, 0));
4654
4655   emit_load_locked (DImode, scratch, mem);
4656   
4657   width = GEN_INT (GET_MODE_BITSIZE (mode));
4658   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
4659   if (WORDS_BIG_ENDIAN)
4660     {
4661       emit_insn (gen_extxl_be (dest, scratch, width, addr));
4662       emit_insn (gen_mskxl_be (scratch, scratch, mask, addr));
4663     }
4664   else
4665     {
4666       emit_insn (gen_extxl_le (dest, scratch, width, addr));
4667       emit_insn (gen_mskxl_le (scratch, scratch, mask, addr));
4668     }
4669   emit_insn (gen_iordi3 (scratch, scratch, val));
4670
4671   emit_store_conditional (DImode, scratch, mem, scratch);
4672
4673   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
4674   emit_unlikely_jump (x, label);
4675 }
4676 \f
4677 /* Adjust the cost of a scheduling dependency.  Return the new cost of
4678    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
4679
4680 static int
4681 alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
4682 {
4683   enum attr_type insn_type, dep_insn_type;
4684
4685   /* If the dependence is an anti-dependence, there is no cost.  For an
4686      output dependence, there is sometimes a cost, but it doesn't seem
4687      worth handling those few cases.  */
4688   if (REG_NOTE_KIND (link) != 0)
4689     return cost;
4690
4691   /* If we can't recognize the insns, we can't really do anything.  */
4692   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
4693     return cost;
4694
4695   insn_type = get_attr_type (insn);
4696   dep_insn_type = get_attr_type (dep_insn);
4697
4698   /* Bring in the user-defined memory latency.  */
4699   if (dep_insn_type == TYPE_ILD
4700       || dep_insn_type == TYPE_FLD
4701       || dep_insn_type == TYPE_LDSYM)
4702     cost += alpha_memory_latency-1;
4703
4704   /* Everything else handled in DFA bypasses now.  */
4705
4706   return cost;
4707 }
4708
4709 /* The number of instructions that can be issued per cycle.  */
4710
4711 static int
4712 alpha_issue_rate (void)
4713 {
4714   return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
4715 }
4716
4717 /* How many alternative schedules to try.  This should be as wide as the
4718    scheduling freedom in the DFA, but no wider.  Making this value too
4719    large results extra work for the scheduler.
4720
4721    For EV4, loads can be issued to either IB0 or IB1, thus we have 2
4722    alternative schedules.  For EV5, we can choose between E0/E1 and
4723    FA/FM.  For EV6, an arithmetic insn can be issued to U0/U1/L0/L1.  */
4724
4725 static int
4726 alpha_multipass_dfa_lookahead (void)
4727 {
4728   return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
4729 }
4730 \f
4731 /* Machine-specific function data.  */
4732
4733 struct machine_function GTY(())
4734 {
4735   /* For unicosmk.  */
4736   /* List of call information words for calls from this function.  */
4737   struct rtx_def *first_ciw;
4738   struct rtx_def *last_ciw;
4739   int ciw_count;
4740
4741   /* List of deferred case vectors.  */
4742   struct rtx_def *addr_list;
4743
4744   /* For OSF.  */
4745   const char *some_ld_name;
4746
4747   /* For TARGET_LD_BUGGY_LDGP.  */
4748   struct rtx_def *gp_save_rtx;
4749 };
4750
4751 /* How to allocate a 'struct machine_function'.  */
4752
4753 static struct machine_function *
4754 alpha_init_machine_status (void)
4755 {
4756   return ((struct machine_function *)
4757                 ggc_alloc_cleared (sizeof (struct machine_function)));
4758 }
4759
4760 /* Functions to save and restore alpha_return_addr_rtx.  */
4761
4762 /* Start the ball rolling with RETURN_ADDR_RTX.  */
4763
4764 rtx
4765 alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4766 {
4767   if (count != 0)
4768     return const0_rtx;
4769
4770   return get_hard_reg_initial_val (Pmode, REG_RA);
4771 }
4772
4773 /* Return or create a memory slot containing the gp value for the current
4774    function.  Needed only if TARGET_LD_BUGGY_LDGP.  */
4775
4776 rtx
4777 alpha_gp_save_rtx (void)
4778 {
4779   rtx seq, m = cfun->machine->gp_save_rtx;
4780
4781   if (m == NULL)
4782     {
4783       start_sequence ();
4784
4785       m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
4786       m = validize_mem (m);
4787       emit_move_insn (m, pic_offset_table_rtx);
4788
4789       seq = get_insns ();
4790       end_sequence ();
4791
4792       /* We used to simply emit the sequence after entry_of_function.
4793          However this breaks the CFG if the first instruction in the
4794          first block is not the NOTE_INSN_BASIC_BLOCK, for example a
4795          label.  Emit the sequence properly on the edge.  We are only
4796          invoked from dw2_build_landing_pads and finish_eh_generation
4797          will call commit_edge_insertions thanks to a kludge.  */
4798       insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
4799
4800       cfun->machine->gp_save_rtx = m;
4801     }
4802
4803   return m;
4804 }
4805
4806 static int
4807 alpha_ra_ever_killed (void)
4808 {
4809   rtx top;
4810
4811   if (!has_hard_reg_initial_val (Pmode, REG_RA))
4812     return (int)df_regs_ever_live_p (REG_RA);
4813
4814   push_topmost_sequence ();
4815   top = get_insns ();
4816   pop_topmost_sequence ();
4817
4818   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
4819 }
4820
4821 \f
4822 /* Return the trap mode suffix applicable to the current
4823    instruction, or NULL.  */
4824
4825 static const char *
4826 get_trap_mode_suffix (void)
4827 {
4828   enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
4829
4830   switch (s)
4831     {
4832     case TRAP_SUFFIX_NONE:
4833       return NULL;
4834
4835     case TRAP_SUFFIX_SU:
4836       if (alpha_fptm >= ALPHA_FPTM_SU)
4837         return "su";
4838       return NULL;
4839
4840     case TRAP_SUFFIX_SUI:
4841       if (alpha_fptm >= ALPHA_FPTM_SUI)
4842         return "sui";
4843       return NULL;
4844
4845     case TRAP_SUFFIX_V_SV:
4846       switch (alpha_fptm)
4847         {
4848         case ALPHA_FPTM_N:
4849           return NULL;
4850         case ALPHA_FPTM_U:
4851           return "v";
4852         case ALPHA_FPTM_SU:
4853         case ALPHA_FPTM_SUI:
4854           return "sv";
4855         default:
4856           gcc_unreachable ();
4857         }
4858
4859     case TRAP_SUFFIX_V_SV_SVI:
4860       switch (alpha_fptm)
4861         {
4862         case ALPHA_FPTM_N:
4863           return NULL;
4864         case ALPHA_FPTM_U:
4865           return "v";
4866         case ALPHA_FPTM_SU:
4867           return "sv";
4868         case ALPHA_FPTM_SUI:
4869           return "svi";
4870         default:
4871           gcc_unreachable ();
4872         }
4873       break;
4874
4875     case TRAP_SUFFIX_U_SU_SUI:
4876       switch (alpha_fptm)
4877         {
4878         case ALPHA_FPTM_N:
4879           return NULL;
4880         case ALPHA_FPTM_U:
4881           return "u";
4882         case ALPHA_FPTM_SU:
4883           return "su";
4884         case ALPHA_FPTM_SUI:
4885           return "sui";
4886         default:
4887           gcc_unreachable ();
4888         }
4889       break;
4890       
4891     default:
4892       gcc_unreachable ();
4893     }
4894   gcc_unreachable ();
4895 }
4896
4897 /* Return the rounding mode suffix applicable to the current
4898    instruction, or NULL.  */
4899
4900 static const char *
4901 get_round_mode_suffix (void)
4902 {
4903   enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
4904
4905   switch (s)
4906     {
4907     case ROUND_SUFFIX_NONE:
4908       return NULL;
4909     case ROUND_SUFFIX_NORMAL:
4910       switch (alpha_fprm)
4911         {
4912         case ALPHA_FPRM_NORM:
4913           return NULL;
4914         case ALPHA_FPRM_MINF:
4915           return "m";
4916         case ALPHA_FPRM_CHOP:
4917           return "c";
4918         case ALPHA_FPRM_DYN:
4919           return "d";
4920         default:
4921           gcc_unreachable ();
4922         }
4923       break;
4924
4925     case ROUND_SUFFIX_C:
4926       return "c";
4927       
4928     default:
4929       gcc_unreachable ();
4930     }
4931   gcc_unreachable ();
4932 }
4933
4934 /* Locate some local-dynamic symbol still in use by this function
4935    so that we can print its name in some movdi_er_tlsldm pattern.  */
4936
4937 static int
4938 get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
4939 {
4940   rtx x = *px;
4941
4942   if (GET_CODE (x) == SYMBOL_REF
4943       && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
4944     {
4945       cfun->machine->some_ld_name = XSTR (x, 0);
4946       return 1;
4947     }
4948
4949   return 0;
4950 }
4951
4952 static const char *
4953 get_some_local_dynamic_name (void)
4954 {
4955   rtx insn;
4956
4957   if (cfun->machine->some_ld_name)
4958     return cfun->machine->some_ld_name;
4959
4960   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
4961     if (INSN_P (insn)
4962         && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
4963       return cfun->machine->some_ld_name;
4964
4965   gcc_unreachable ();
4966 }
4967
4968 /* Print an operand.  Recognize special options, documented below.  */
4969
4970 void
4971 print_operand (FILE *file, rtx x, int code)
4972 {
4973   int i;
4974
4975   switch (code)
4976     {
4977     case '~':
4978       /* Print the assembler name of the current function.  */
4979       assemble_name (file, alpha_fnname);
4980       break;
4981
4982     case '&':
4983       assemble_name (file, get_some_local_dynamic_name ());
4984       break;
4985
4986     case '/':
4987       {
4988         const char *trap = get_trap_mode_suffix ();
4989         const char *round = get_round_mode_suffix ();
4990
4991         if (trap || round)
4992           fprintf (file, (TARGET_AS_SLASH_BEFORE_SUFFIX ? "/%s%s" : "%s%s"),
4993                    (trap ? trap : ""), (round ? round : ""));
4994         break;
4995       }
4996
4997     case ',':
4998       /* Generates single precision instruction suffix.  */
4999       fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
5000       break;
5001
5002     case '-':
5003       /* Generates double precision instruction suffix.  */
5004       fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
5005       break;
5006
5007     case '#':
5008       if (alpha_this_literal_sequence_number == 0)
5009         alpha_this_literal_sequence_number = alpha_next_sequence_number++;
5010       fprintf (file, "%d", alpha_this_literal_sequence_number);
5011       break;
5012
5013     case '*':
5014       if (alpha_this_gpdisp_sequence_number == 0)
5015         alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
5016       fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
5017       break;
5018
5019     case 'H':
5020       if (GET_CODE (x) == HIGH)
5021         output_addr_const (file, XEXP (x, 0));
5022       else
5023         output_operand_lossage ("invalid %%H value");
5024       break;
5025
5026     case 'J':
5027       {
5028         const char *lituse;
5029
5030         if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
5031           {
5032             x = XVECEXP (x, 0, 0);
5033             lituse = "lituse_tlsgd";
5034           }
5035         else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
5036           {
5037             x = XVECEXP (x, 0, 0);
5038             lituse = "lituse_tlsldm";
5039           }
5040         else if (GET_CODE (x) == CONST_INT)
5041           lituse = "lituse_jsr";
5042         else
5043           {
5044             output_operand_lossage ("invalid %%J value");
5045             break;
5046           }
5047
5048         if (x != const0_rtx)
5049           fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
5050       }
5051       break;
5052
5053     case 'j':
5054       {
5055         const char *lituse;
5056
5057 #ifdef HAVE_AS_JSRDIRECT_RELOCS
5058         lituse = "lituse_jsrdirect";
5059 #else
5060         lituse = "lituse_jsr";
5061 #endif
5062
5063         gcc_assert (INTVAL (x) != 0);
5064         fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
5065       }
5066       break;
5067     case 'r':
5068       /* If this operand is the constant zero, write it as "$31".  */
5069       if (GET_CODE (x) == REG)
5070         fprintf (file, "%s", reg_names[REGNO (x)]);
5071       else if (x == CONST0_RTX (GET_MODE (x)))
5072         fprintf (file, "$31");
5073       else
5074         output_operand_lossage ("invalid %%r value");
5075       break;
5076
5077     case 'R':
5078       /* Similar, but for floating-point.  */
5079       if (GET_CODE (x) == REG)
5080         fprintf (file, "%s", reg_names[REGNO (x)]);
5081       else if (x == CONST0_RTX (GET_MODE (x)))
5082         fprintf (file, "$f31");
5083       else
5084         output_operand_lossage ("invalid %%R value");
5085       break;
5086
5087     case 'N':
5088       /* Write the 1's complement of a constant.  */
5089       if (GET_CODE (x) != CONST_INT)
5090         output_operand_lossage ("invalid %%N value");
5091
5092       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
5093       break;
5094
5095     case 'P':
5096       /* Write 1 << C, for a constant C.  */
5097       if (GET_CODE (x) != CONST_INT)
5098         output_operand_lossage ("invalid %%P value");
5099
5100       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) 1 << INTVAL (x));
5101       break;
5102
5103     case 'h':
5104       /* Write the high-order 16 bits of a constant, sign-extended.  */
5105       if (GET_CODE (x) != CONST_INT)
5106         output_operand_lossage ("invalid %%h value");
5107
5108       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
5109       break;
5110
5111     case 'L':
5112       /* Write the low-order 16 bits of a constant, sign-extended.  */
5113       if (GET_CODE (x) != CONST_INT)
5114         output_operand_lossage ("invalid %%L value");
5115
5116       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5117                (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
5118       break;
5119
5120     case 'm':
5121       /* Write mask for ZAP insn.  */
5122       if (GET_CODE (x) == CONST_DOUBLE)
5123         {
5124           HOST_WIDE_INT mask = 0;
5125           HOST_WIDE_INT value;
5126
5127           value = CONST_DOUBLE_LOW (x);
5128           for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
5129                i++, value >>= 8)
5130             if (value & 0xff)
5131               mask |= (1 << i);
5132
5133           value = CONST_DOUBLE_HIGH (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 + sizeof (int)));
5138
5139           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask & 0xff);
5140         }
5141
5142       else if (GET_CODE (x) == CONST_INT)
5143         {
5144           HOST_WIDE_INT mask = 0, value = INTVAL (x);
5145
5146           for (i = 0; i < 8; i++, value >>= 8)
5147             if (value & 0xff)
5148               mask |= (1 << i);
5149
5150           fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
5151         }
5152       else
5153         output_operand_lossage ("invalid %%m value");
5154       break;
5155
5156     case 'M':
5157       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
5158       if (GET_CODE (x) != CONST_INT
5159           || (INTVAL (x) != 8 && INTVAL (x) != 16
5160               && INTVAL (x) != 32 && INTVAL (x) != 64))
5161         output_operand_lossage ("invalid %%M value");
5162
5163       fprintf (file, "%s",
5164                (INTVAL (x) == 8 ? "b"
5165                 : INTVAL (x) == 16 ? "w"
5166                 : INTVAL (x) == 32 ? "l"
5167                 : "q"));
5168       break;
5169
5170     case 'U':
5171       /* Similar, except do it from the mask.  */
5172       if (GET_CODE (x) == CONST_INT)
5173         {
5174           HOST_WIDE_INT value = INTVAL (x);
5175
5176           if (value == 0xff)
5177             {
5178               fputc ('b', file);
5179               break;
5180             }
5181           if (value == 0xffff)
5182             {
5183               fputc ('w', file);
5184               break;
5185             }
5186           if (value == 0xffffffff)
5187             {
5188               fputc ('l', file);
5189               break;
5190             }
5191           if (value == -1)
5192             {
5193               fputc ('q', file);
5194               break;
5195             }
5196         }
5197       else if (HOST_BITS_PER_WIDE_INT == 32
5198                && GET_CODE (x) == CONST_DOUBLE
5199                && CONST_DOUBLE_LOW (x) == 0xffffffff
5200                && CONST_DOUBLE_HIGH (x) == 0)
5201         {
5202           fputc ('l', file);
5203           break;
5204         }
5205       output_operand_lossage ("invalid %%U value");
5206       break;
5207
5208     case 's':
5209       /* Write the constant value divided by 8 for little-endian mode or
5210          (56 - value) / 8 for big-endian mode.  */
5211
5212       if (GET_CODE (x) != CONST_INT
5213           || (unsigned HOST_WIDE_INT) INTVAL (x) >= (WORDS_BIG_ENDIAN
5214                                                      ? 56
5215                                                      : 64)
5216           || (INTVAL (x) & 7) != 0)
5217         output_operand_lossage ("invalid %%s value");
5218
5219       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5220                WORDS_BIG_ENDIAN
5221                ? (56 - INTVAL (x)) / 8
5222                : INTVAL (x) / 8);
5223       break;
5224
5225     case 'S':
5226       /* Same, except compute (64 - c) / 8 */
5227
5228       if (GET_CODE (x) != CONST_INT
5229           && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
5230           && (INTVAL (x) & 7) != 8)
5231         output_operand_lossage ("invalid %%s value");
5232
5233       fprintf (file, HOST_WIDE_INT_PRINT_DEC, (64 - INTVAL (x)) / 8);
5234       break;
5235
5236     case 't':
5237       {
5238         /* On Unicos/Mk systems: use a DEX expression if the symbol
5239            clashes with a register name.  */
5240         int dex = unicosmk_need_dex (x);
5241         if (dex)
5242           fprintf (file, "DEX(%d)", dex);
5243         else
5244           output_addr_const (file, x);
5245       }
5246       break;
5247
5248     case 'C': case 'D': case 'c': case 'd':
5249       /* Write out comparison name.  */
5250       {
5251         enum rtx_code c = GET_CODE (x);
5252
5253         if (!COMPARISON_P (x))
5254           output_operand_lossage ("invalid %%C value");
5255
5256         else if (code == 'D')
5257           c = reverse_condition (c);
5258         else if (code == 'c')
5259           c = swap_condition (c);
5260         else if (code == 'd')
5261           c = swap_condition (reverse_condition (c));
5262
5263         if (c == LEU)
5264           fprintf (file, "ule");
5265         else if (c == LTU)
5266           fprintf (file, "ult");
5267         else if (c == UNORDERED)
5268           fprintf (file, "un");
5269         else
5270           fprintf (file, "%s", GET_RTX_NAME (c));
5271       }
5272       break;
5273
5274     case 'E':
5275       /* Write the divide or modulus operator.  */
5276       switch (GET_CODE (x))
5277         {
5278         case DIV:
5279           fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
5280           break;
5281         case UDIV:
5282           fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
5283           break;
5284         case MOD:
5285           fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
5286           break;
5287         case UMOD:
5288           fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
5289           break;
5290         default:
5291           output_operand_lossage ("invalid %%E value");
5292           break;
5293         }
5294       break;
5295
5296     case 'A':
5297       /* Write "_u" for unaligned access.  */
5298       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
5299         fprintf (file, "_u");
5300       break;
5301
5302     case 0:
5303       if (GET_CODE (x) == REG)
5304         fprintf (file, "%s", reg_names[REGNO (x)]);
5305       else if (GET_CODE (x) == MEM)
5306         output_address (XEXP (x, 0));
5307       else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
5308         {
5309           switch (XINT (XEXP (x, 0), 1))
5310             {
5311             case UNSPEC_DTPREL:
5312             case UNSPEC_TPREL:
5313               output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
5314               break;
5315             default:
5316               output_operand_lossage ("unknown relocation unspec");
5317               break;
5318             }
5319         }
5320       else
5321         output_addr_const (file, x);
5322       break;
5323
5324     default:
5325       output_operand_lossage ("invalid %%xn code");
5326     }
5327 }
5328
5329 void
5330 print_operand_address (FILE *file, rtx addr)
5331 {
5332   int basereg = 31;
5333   HOST_WIDE_INT offset = 0;
5334
5335   if (GET_CODE (addr) == AND)
5336     addr = XEXP (addr, 0);
5337
5338   if (GET_CODE (addr) == PLUS
5339       && GET_CODE (XEXP (addr, 1)) == CONST_INT)
5340     {
5341       offset = INTVAL (XEXP (addr, 1));
5342       addr = XEXP (addr, 0);
5343     }
5344
5345   if (GET_CODE (addr) == LO_SUM)
5346     {
5347       const char *reloc16, *reloclo;
5348       rtx op1 = XEXP (addr, 1);
5349
5350       if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
5351         {
5352           op1 = XEXP (op1, 0);
5353           switch (XINT (op1, 1))
5354             {
5355             case UNSPEC_DTPREL:
5356               reloc16 = NULL;
5357               reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
5358               break;
5359             case UNSPEC_TPREL:
5360               reloc16 = NULL;
5361               reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
5362               break;
5363             default:
5364               output_operand_lossage ("unknown relocation unspec");
5365               return;
5366             }
5367
5368           output_addr_const (file, XVECEXP (op1, 0, 0));
5369         }
5370       else
5371         {
5372           reloc16 = "gprel";
5373           reloclo = "gprellow";
5374           output_addr_const (file, op1);
5375         }
5376
5377       if (offset)
5378         fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
5379
5380       addr = XEXP (addr, 0);
5381       switch (GET_CODE (addr))
5382         {
5383         case REG:
5384           basereg = REGNO (addr);
5385           break;
5386
5387         case SUBREG:
5388           basereg = subreg_regno (addr);
5389           break;
5390
5391         default:
5392           gcc_unreachable ();
5393         }
5394
5395       fprintf (file, "($%d)\t\t!%s", basereg,
5396                (basereg == 29 ? reloc16 : reloclo));
5397       return;
5398     }
5399
5400   switch (GET_CODE (addr))
5401     {
5402     case REG:
5403       basereg = REGNO (addr);
5404       break;
5405
5406     case SUBREG:
5407       basereg = subreg_regno (addr);
5408       break;
5409
5410     case CONST_INT:
5411       offset = INTVAL (addr);
5412       break;
5413
5414 #if TARGET_ABI_OPEN_VMS
5415     case SYMBOL_REF:
5416       fprintf (file, "%s", XSTR (addr, 0));
5417       return;
5418
5419     case CONST:
5420       gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS
5421                   && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF);
5422       fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
5423                XSTR (XEXP (XEXP (addr, 0), 0), 0),
5424                INTVAL (XEXP (XEXP (addr, 0), 1)));
5425       return;
5426     
5427 #endif
5428     default:
5429       gcc_unreachable ();
5430     }
5431
5432   fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
5433 }
5434 \f
5435 /* Emit RTL insns to initialize the variable parts of a trampoline at
5436    TRAMP. FNADDR is an RTX for the address of the function's pure
5437    code.  CXT is an RTX for the static chain value for the function.
5438
5439    The three offset parameters are for the individual template's
5440    layout.  A JMPOFS < 0 indicates that the trampoline does not
5441    contain instructions at all.
5442
5443    We assume here that a function will be called many more times than
5444    its address is taken (e.g., it might be passed to qsort), so we
5445    take the trouble to initialize the "hint" field in the JMP insn.
5446    Note that the hint field is PC (new) + 4 * bits 13:0.  */
5447
5448 void
5449 alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
5450                              int fnofs, int cxtofs, int jmpofs)
5451 {
5452   rtx addr;
5453   /* VMS really uses DImode pointers in memory at this point.  */
5454   enum machine_mode mode = TARGET_ABI_OPEN_VMS ? Pmode : ptr_mode;
5455
5456 #ifdef POINTERS_EXTEND_UNSIGNED
5457   fnaddr = convert_memory_address (mode, fnaddr);
5458   cxt = convert_memory_address (mode, cxt);
5459 #endif
5460
5461   /* Store function address and CXT.  */
5462   addr = memory_address (mode, plus_constant (tramp, fnofs));
5463   emit_move_insn (gen_rtx_MEM (mode, addr), fnaddr);
5464   addr = memory_address (mode, plus_constant (tramp, cxtofs));
5465   emit_move_insn (gen_rtx_MEM (mode, addr), cxt);
5466
5467 #ifdef ENABLE_EXECUTE_STACK
5468   emit_library_call (init_one_libfunc ("__enable_execute_stack"),
5469                      0, VOIDmode, 1, tramp, Pmode);
5470 #endif
5471
5472   if (jmpofs >= 0)
5473     emit_insn (gen_imb ());
5474 }
5475 \f
5476 /* Determine where to put an argument to a function.
5477    Value is zero to push the argument on the stack,
5478    or a hard register in which to store the argument.
5479
5480    MODE is the argument's machine mode.
5481    TYPE is the data type of the argument (as a tree).
5482     This is null for libcalls where that information may
5483     not be available.
5484    CUM is a variable of type CUMULATIVE_ARGS which gives info about
5485     the preceding args and about the function being called.
5486    NAMED is nonzero if this argument is a named parameter
5487     (otherwise it is an extra parameter matching an ellipsis).
5488
5489    On Alpha the first 6 words of args are normally in registers
5490    and the rest are pushed.  */
5491
5492 rtx
5493 function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
5494               int named ATTRIBUTE_UNUSED)
5495 {
5496   int basereg;
5497   int num_args;
5498
5499   /* Don't get confused and pass small structures in FP registers.  */
5500   if (type && AGGREGATE_TYPE_P (type))
5501     basereg = 16;
5502   else
5503     {
5504 #ifdef ENABLE_CHECKING
5505       /* With alpha_split_complex_arg, we shouldn't see any raw complex
5506          values here.  */
5507       gcc_assert (!COMPLEX_MODE_P (mode));
5508 #endif
5509
5510       /* Set up defaults for FP operands passed in FP registers, and
5511          integral operands passed in integer registers.  */
5512       if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
5513         basereg = 32 + 16;
5514       else
5515         basereg = 16;
5516     }
5517
5518   /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
5519      the three platforms, so we can't avoid conditional compilation.  */
5520 #if TARGET_ABI_OPEN_VMS
5521     {
5522       if (mode == VOIDmode)
5523         return alpha_arg_info_reg_val (cum);
5524
5525       num_args = cum.num_args;
5526       if (num_args >= 6
5527           || targetm.calls.must_pass_in_stack (mode, type))
5528         return NULL_RTX;
5529     }
5530 #elif TARGET_ABI_UNICOSMK
5531     {
5532       int size;
5533
5534       /* If this is the last argument, generate the call info word (CIW).  */
5535       /* ??? We don't include the caller's line number in the CIW because
5536          I don't know how to determine it if debug infos are turned off.  */
5537       if (mode == VOIDmode)
5538         {
5539           int i;
5540           HOST_WIDE_INT lo;
5541           HOST_WIDE_INT hi;
5542           rtx ciw;
5543
5544           lo = 0;
5545
5546           for (i = 0; i < cum.num_reg_words && i < 5; i++)
5547             if (cum.reg_args_type[i])
5548               lo |= (1 << (7 - i));
5549
5550           if (cum.num_reg_words == 6 && cum.reg_args_type[5])
5551             lo |= 7;
5552           else
5553             lo |= cum.num_reg_words;
5554
5555 #if HOST_BITS_PER_WIDE_INT == 32
5556           hi = (cum.num_args << 20) | cum.num_arg_words;
5557 #else
5558           lo = lo | ((HOST_WIDE_INT) cum.num_args << 52)
5559             | ((HOST_WIDE_INT) cum.num_arg_words << 32);
5560           hi = 0;
5561 #endif
5562           ciw = immed_double_const (lo, hi, DImode);
5563
5564           return gen_rtx_UNSPEC (DImode, gen_rtvec (1, ciw),
5565                                  UNSPEC_UMK_LOAD_CIW);
5566         }
5567
5568       size = ALPHA_ARG_SIZE (mode, type, named);
5569       num_args = cum.num_reg_words;
5570       if (cum.force_stack
5571           || cum.num_reg_words + size > 6
5572           || targetm.calls.must_pass_in_stack (mode, type))
5573         return NULL_RTX;
5574       else if (type && TYPE_MODE (type) == BLKmode)
5575         {
5576           rtx reg1, reg2;
5577
5578           reg1 = gen_rtx_REG (DImode, num_args + 16);
5579           reg1 = gen_rtx_EXPR_LIST (DImode, reg1, const0_rtx);
5580
5581           /* The argument fits in two registers. Note that we still need to
5582              reserve a register for empty structures.  */
5583           if (size == 0)
5584             return NULL_RTX;
5585           else if (size == 1)
5586             return gen_rtx_PARALLEL (mode, gen_rtvec (1, reg1));
5587           else
5588             {
5589               reg2 = gen_rtx_REG (DImode, num_args + 17);
5590               reg2 = gen_rtx_EXPR_LIST (DImode, reg2, GEN_INT (8));
5591               return gen_rtx_PARALLEL (mode, gen_rtvec (2, reg1, reg2));
5592             }
5593         }
5594     }
5595 #elif TARGET_ABI_OSF
5596     {
5597       if (cum >= 6)
5598         return NULL_RTX;
5599       num_args = cum;
5600
5601       /* VOID is passed as a special flag for "last argument".  */
5602       if (type == void_type_node)
5603         basereg = 16;
5604       else if (targetm.calls.must_pass_in_stack (mode, type))
5605         return NULL_RTX;
5606     }
5607 #else
5608 #error Unhandled ABI
5609 #endif
5610
5611   return gen_rtx_REG (mode, num_args + basereg);
5612 }
5613
5614 static int
5615 alpha_arg_partial_bytes (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
5616                          enum machine_mode mode ATTRIBUTE_UNUSED,
5617                          tree type ATTRIBUTE_UNUSED,
5618                          bool named ATTRIBUTE_UNUSED)
5619 {
5620   int words = 0;
5621
5622 #if TARGET_ABI_OPEN_VMS
5623   if (cum->num_args < 6
5624       && 6 < cum->num_args + ALPHA_ARG_SIZE (mode, type, named))
5625     words = 6 - cum->num_args;
5626 #elif TARGET_ABI_UNICOSMK
5627   /* Never any split arguments.  */
5628 #elif TARGET_ABI_OSF
5629   if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (mode, type, named))
5630     words = 6 - *cum;
5631 #else
5632 #error Unhandled ABI
5633 #endif
5634
5635   return words * UNITS_PER_WORD;
5636 }
5637
5638
5639 /* Return true if TYPE must be returned in memory, instead of in registers.  */
5640
5641 static bool
5642 alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
5643 {
5644   enum machine_mode mode = VOIDmode;
5645   int size;
5646
5647   if (type)
5648     {
5649       mode = TYPE_MODE (type);
5650
5651       /* All aggregates are returned in memory.  */
5652       if (AGGREGATE_TYPE_P (type))
5653         return true;
5654     }
5655
5656   size = GET_MODE_SIZE (mode);
5657   switch (GET_MODE_CLASS (mode))
5658     {
5659     case MODE_VECTOR_FLOAT:
5660       /* Pass all float vectors in memory, like an aggregate.  */
5661       return true;
5662
5663     case MODE_COMPLEX_FLOAT:
5664       /* We judge complex floats on the size of their element,
5665          not the size of the whole type.  */
5666       size = GET_MODE_UNIT_SIZE (mode);
5667       break;
5668
5669     case MODE_INT:
5670     case MODE_FLOAT:
5671     case MODE_COMPLEX_INT:
5672     case MODE_VECTOR_INT:
5673       break;
5674
5675     default:
5676       /* ??? We get called on all sorts of random stuff from
5677          aggregate_value_p.  We must return something, but it's not
5678          clear what's safe to return.  Pretend it's a struct I
5679          guess.  */
5680       return true;
5681     }
5682
5683   /* Otherwise types must fit in one register.  */
5684   return size > UNITS_PER_WORD;
5685 }
5686
5687 /* Return true if TYPE should be passed by invisible reference.  */
5688
5689 static bool
5690 alpha_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
5691                          enum machine_mode mode,
5692                          const_tree type ATTRIBUTE_UNUSED,
5693                          bool named ATTRIBUTE_UNUSED)
5694 {
5695   return mode == TFmode || mode == TCmode;
5696 }
5697
5698 /* Define how to find the value returned by a function.  VALTYPE is the
5699    data type of the value (as a tree).  If the precise function being
5700    called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
5701    MODE is set instead of VALTYPE for libcalls.
5702
5703    On Alpha the value is found in $0 for integer functions and
5704    $f0 for floating-point functions.  */
5705
5706 rtx
5707 function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
5708                 enum machine_mode mode)
5709 {
5710   unsigned int regnum, dummy;
5711   enum mode_class class;
5712
5713   gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));
5714
5715   if (valtype)
5716     mode = TYPE_MODE (valtype);
5717
5718   class = GET_MODE_CLASS (mode);
5719   switch (class)
5720     {
5721     case MODE_INT:
5722       PROMOTE_MODE (mode, dummy, valtype);
5723       /* FALLTHRU */
5724
5725     case MODE_COMPLEX_INT:
5726     case MODE_VECTOR_INT:
5727       regnum = 0;
5728       break;
5729
5730     case MODE_FLOAT:
5731       regnum = 32;
5732       break;
5733
5734     case MODE_COMPLEX_FLOAT:
5735       {
5736         enum machine_mode cmode = GET_MODE_INNER (mode);
5737
5738         return gen_rtx_PARALLEL
5739           (VOIDmode,
5740            gen_rtvec (2,
5741                       gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
5742                                          const0_rtx),
5743                       gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
5744                                          GEN_INT (GET_MODE_SIZE (cmode)))));
5745       }
5746
5747     default:
5748       gcc_unreachable ();
5749     }
5750
5751   return gen_rtx_REG (mode, regnum);
5752 }
5753
5754 /* TCmode complex values are passed by invisible reference.  We
5755    should not split these values.  */
5756
5757 static bool
5758 alpha_split_complex_arg (const_tree type)
5759 {
5760   return TYPE_MODE (type) != TCmode;
5761 }
5762
5763 static tree
5764 alpha_build_builtin_va_list (void)
5765 {
5766   tree base, ofs, space, record, type_decl;
5767
5768   if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
5769     return ptr_type_node;
5770
5771   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
5772   type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
5773   TREE_CHAIN (record) = type_decl;
5774   TYPE_NAME (record) = type_decl;
5775
5776   /* C++? SET_IS_AGGR_TYPE (record, 1); */
5777
5778   /* Dummy field to prevent alignment warnings.  */
5779   space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
5780   DECL_FIELD_CONTEXT (space) = record;
5781   DECL_ARTIFICIAL (space) = 1;
5782   DECL_IGNORED_P (space) = 1;
5783
5784   ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
5785                     integer_type_node);
5786   DECL_FIELD_CONTEXT (ofs) = record;
5787   TREE_CHAIN (ofs) = space;
5788
5789   base = build_decl (FIELD_DECL, get_identifier ("__base"),
5790                      ptr_type_node);
5791   DECL_FIELD_CONTEXT (base) = record;
5792   TREE_CHAIN (base) = ofs;
5793
5794   TYPE_FIELDS (record) = base;
5795   layout_type (record);
5796
5797   va_list_gpr_counter_field = ofs;
5798   return record;
5799 }
5800
5801 #if TARGET_ABI_OSF
5802 /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
5803    and constant additions.  */
5804
5805 static tree
5806 va_list_skip_additions (tree lhs)
5807 {
5808   tree rhs, stmt;
5809
5810   if (TREE_CODE (lhs) != SSA_NAME)
5811     return lhs;
5812
5813   for (;;)
5814     {
5815       stmt = SSA_NAME_DEF_STMT (lhs);
5816
5817       if (TREE_CODE (stmt) == PHI_NODE)
5818         return stmt;
5819
5820       if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
5821           || GIMPLE_STMT_OPERAND (stmt, 0) != lhs)
5822         return lhs;
5823
5824       rhs = GIMPLE_STMT_OPERAND (stmt, 1);
5825       if (TREE_CODE (rhs) == WITH_SIZE_EXPR)
5826         rhs = TREE_OPERAND (rhs, 0);
5827
5828       if ((TREE_CODE (rhs) != NOP_EXPR
5829            && TREE_CODE (rhs) != CONVERT_EXPR
5830            && ((TREE_CODE (rhs) != PLUS_EXPR
5831                 && TREE_CODE (rhs) != POINTER_PLUS_EXPR)
5832                || TREE_CODE (TREE_OPERAND (rhs, 1)) != INTEGER_CST
5833                || !host_integerp (TREE_OPERAND (rhs, 1), 1)))
5834           || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
5835         return rhs;
5836
5837       lhs = TREE_OPERAND (rhs, 0);
5838     }
5839 }
5840
5841 /* Check if LHS = RHS statement is
5842    LHS = *(ap.__base + ap.__offset + cst)
5843    or
5844    LHS = *(ap.__base
5845            + ((ap.__offset + cst <= 47)
5846               ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
5847    If the former, indicate that GPR registers are needed,
5848    if the latter, indicate that FPR registers are needed.
5849
5850    Also look for LHS = (*ptr).field, where ptr is one of the forms
5851    listed above.
5852
5853    On alpha, cfun->va_list_gpr_size is used as size of the needed
5854    regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
5855    registers are needed and bit 1 set if FPR registers are needed.
5856    Return true if va_list references should not be scanned for the
5857    current statement.  */
5858
5859 static bool
5860 alpha_stdarg_optimize_hook (struct stdarg_info *si, const_tree lhs, const_tree rhs)
5861 {
5862   tree base, offset, arg1, arg2;
5863   int offset_arg = 1;
5864
5865   while (handled_component_p (rhs))
5866     rhs = TREE_OPERAND (rhs, 0);
5867   if (TREE_CODE (rhs) != INDIRECT_REF
5868       || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
5869     return false;
5870
5871   lhs = va_list_skip_additions (TREE_OPERAND (rhs, 0));
5872   if (lhs == NULL_TREE
5873       || TREE_CODE (lhs) != POINTER_PLUS_EXPR)
5874     return false;
5875
5876   base = TREE_OPERAND (lhs, 0);
5877   if (TREE_CODE (base) == SSA_NAME)
5878     base = va_list_skip_additions (base);
5879
5880   if (TREE_CODE (base) != COMPONENT_REF
5881       || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5882     {
5883       base = TREE_OPERAND (lhs, 0);
5884       if (TREE_CODE (base) == SSA_NAME)
5885         base = va_list_skip_additions (base);
5886
5887       if (TREE_CODE (base) != COMPONENT_REF
5888           || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
5889         return false;
5890
5891       offset_arg = 0;
5892     }
5893
5894   base = get_base_address (base);
5895   if (TREE_CODE (base) != VAR_DECL
5896       || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
5897     return false;
5898
5899   offset = TREE_OPERAND (lhs, offset_arg);
5900   if (TREE_CODE (offset) == SSA_NAME)
5901     offset = va_list_skip_additions (offset);
5902
5903   if (TREE_CODE (offset) == PHI_NODE)
5904     {
5905       HOST_WIDE_INT sub;
5906
5907       if (PHI_NUM_ARGS (offset) != 2)
5908         goto escapes;
5909
5910       arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0));
5911       arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1));
5912       if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
5913         {
5914           tree tem = arg1;
5915           arg1 = arg2;
5916           arg2 = tem;
5917
5918           if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR)
5919             goto escapes;
5920         }
5921       if (!host_integerp (TREE_OPERAND (arg2, 1), 0))
5922         goto escapes;
5923
5924       sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0);
5925       if (TREE_CODE (arg2) == MINUS_EXPR)
5926         sub = -sub;
5927       if (sub < -48 || sub > -32)
5928         goto escapes;
5929
5930       arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0));
5931       if (arg1 != arg2)
5932         goto escapes;
5933
5934       if (TREE_CODE (arg1) == SSA_NAME)
5935         arg1 = va_list_skip_additions (arg1);
5936
5937       if (TREE_CODE (arg1) != COMPONENT_REF
5938           || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
5939           || get_base_address (arg1) != base)
5940         goto escapes;
5941
5942       /* Need floating point regs.  */
5943       cfun->va_list_fpr_size |= 2;
5944     }
5945   else if (TREE_CODE (offset) != COMPONENT_REF
5946            || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
5947            || get_base_address (offset) != base)
5948     goto escapes;
5949   else
5950     /* Need general regs.  */
5951     cfun->va_list_fpr_size |= 1;
5952   return false;
5953
5954 escapes:
5955   si->va_list_escapes = true;
5956   return false;
5957 }
5958 #endif
5959
5960 /* Perform any needed actions needed for a function that is receiving a
5961    variable number of arguments.  */
5962
5963 static void
5964 alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
5965                               tree type, int *pretend_size, int no_rtl)
5966 {
5967   CUMULATIVE_ARGS cum = *pcum;
5968
5969   /* Skip the current argument.  */
5970   FUNCTION_ARG_ADVANCE (cum, mode, type, 1);
5971
5972 #if TARGET_ABI_UNICOSMK
5973   /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
5974      arguments on the stack. Unfortunately, it doesn't always store the first
5975      one (i.e. the one that arrives in $16 or $f16). This is not a problem
5976      with stdargs as we always have at least one named argument there.  */
5977   if (cum.num_reg_words < 6)
5978     {
5979       if (!no_rtl)
5980         {
5981           emit_insn (gen_umk_mismatch_args (GEN_INT (cum.num_reg_words)));
5982           emit_insn (gen_arg_home_umk ());
5983         }
5984       *pretend_size = 0;
5985     }
5986 #elif TARGET_ABI_OPEN_VMS
5987   /* For VMS, we allocate space for all 6 arg registers plus a count.
5988
5989      However, if NO registers need to be saved, don't allocate any space.
5990      This is not only because we won't need the space, but because AP
5991      includes the current_pretend_args_size and we don't want to mess up
5992      any ap-relative addresses already made.  */
5993   if (cum.num_args < 6)
5994     {
5995       if (!no_rtl)
5996         {
5997           emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
5998           emit_insn (gen_arg_home ());
5999         }
6000       *pretend_size = 7 * UNITS_PER_WORD;
6001     }
6002 #else
6003   /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
6004      only push those that are remaining.  However, if NO registers need to
6005      be saved, don't allocate any space.  This is not only because we won't
6006      need the space, but because AP includes the current_pretend_args_size
6007      and we don't want to mess up any ap-relative addresses already made.
6008
6009      If we are not to use the floating-point registers, save the integer
6010      registers where we would put the floating-point registers.  This is
6011      not the most efficient way to implement varargs with just one register
6012      class, but it isn't worth doing anything more efficient in this rare
6013      case.  */
6014   if (cum >= 6)
6015     return;
6016
6017   if (!no_rtl)
6018     {
6019       int count;
6020       alias_set_type set = get_varargs_alias_set ();
6021       rtx tmp;
6022
6023       count = cfun->va_list_gpr_size / UNITS_PER_WORD;
6024       if (count > 6 - cum)
6025         count = 6 - cum;
6026
6027       /* Detect whether integer registers or floating-point registers
6028          are needed by the detected va_arg statements.  See above for
6029          how these values are computed.  Note that the "escape" value
6030          is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of 
6031          these bits set.  */
6032       gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
6033
6034       if (cfun->va_list_fpr_size & 1)
6035         {
6036           tmp = gen_rtx_MEM (BLKmode,
6037                              plus_constant (virtual_incoming_args_rtx,
6038                                             (cum + 6) * UNITS_PER_WORD));
6039           MEM_NOTRAP_P (tmp) = 1;
6040           set_mem_alias_set (tmp, set);
6041           move_block_from_reg (16 + cum, tmp, count);
6042         }
6043
6044       if (cfun->va_list_fpr_size & 2)
6045         {
6046           tmp = gen_rtx_MEM (BLKmode,
6047                              plus_constant (virtual_incoming_args_rtx,
6048                                             cum * UNITS_PER_WORD));
6049           MEM_NOTRAP_P (tmp) = 1;
6050           set_mem_alias_set (tmp, set);
6051           move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
6052         }
6053      }
6054   *pretend_size = 12 * UNITS_PER_WORD;
6055 #endif
6056 }
6057
6058 static void
6059 alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6060 {
6061   HOST_WIDE_INT offset;
6062   tree t, offset_field, base_field;
6063
6064   if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
6065     return;
6066
6067   if (TARGET_ABI_UNICOSMK)
6068     std_expand_builtin_va_start (valist, nextarg);
6069
6070   /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6071      up by 48, storing fp arg registers in the first 48 bytes, and the
6072      integer arg registers in the next 48 bytes.  This is only done,
6073      however, if any integer registers need to be stored.
6074
6075      If no integer registers need be stored, then we must subtract 48
6076      in order to account for the integer arg registers which are counted
6077      in argsize above, but which are not actually stored on the stack.
6078      Must further be careful here about structures straddling the last
6079      integer argument register; that futzes with pretend_args_size,
6080      which changes the meaning of AP.  */
6081
6082   if (NUM_ARGS < 6)
6083     offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
6084   else
6085     offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
6086
6087   if (TARGET_ABI_OPEN_VMS)
6088     {
6089       nextarg = plus_constant (nextarg, offset);
6090       nextarg = plus_constant (nextarg, NUM_ARGS * UNITS_PER_WORD);
6091       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (valist), valist,
6092                   make_tree (ptr_type_node, nextarg));
6093       TREE_SIDE_EFFECTS (t) = 1;
6094
6095       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6096     }
6097   else
6098     {
6099       base_field = TYPE_FIELDS (TREE_TYPE (valist));
6100       offset_field = TREE_CHAIN (base_field);
6101
6102       base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6103                            valist, base_field, NULL_TREE);
6104       offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6105                              valist, offset_field, NULL_TREE);
6106
6107       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6108       t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6109                   size_int (offset));
6110       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base_field), base_field, t);
6111       TREE_SIDE_EFFECTS (t) = 1;
6112       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6113
6114       t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
6115       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset_field),
6116                   offset_field, t);
6117       TREE_SIDE_EFFECTS (t) = 1;
6118       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6119     }
6120 }
6121
6122 static tree
6123 alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
6124 {
6125   tree type_size, ptr_type, addend, t, addr, internal_post;
6126
6127   /* If the type could not be passed in registers, skip the block
6128      reserved for the registers.  */
6129   if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
6130     {
6131       t = build_int_cst (TREE_TYPE (offset), 6*8);
6132       t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (offset), offset,
6133                   build2 (MAX_EXPR, TREE_TYPE (offset), offset, t));
6134       gimplify_and_add (t, pre_p);
6135     }
6136
6137   addend = offset;
6138   ptr_type = build_pointer_type (type);
6139
6140   if (TREE_CODE (type) == COMPLEX_TYPE)
6141     {
6142       tree real_part, imag_part, real_temp;
6143
6144       real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6145                                            offset, pre_p);
6146
6147       /* Copy the value into a new temporary, lest the formal temporary
6148          be reused out from under us.  */
6149       real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
6150
6151       imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6152                                            offset, pre_p);
6153
6154       return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
6155     }
6156   else if (TREE_CODE (type) == REAL_TYPE)
6157     {
6158       tree fpaddend, cond, fourtyeight;
6159
6160       fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
6161       fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
6162                               addend, fourtyeight);
6163       cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
6164       addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
6165                             fpaddend, addend);
6166     }
6167
6168   /* Build the final address and force that value into a temporary.  */
6169   addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
6170                  fold_convert (sizetype, addend));
6171   internal_post = NULL;
6172   gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
6173   append_to_statement_list (internal_post, pre_p);
6174
6175   /* Update the offset field.  */
6176   type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
6177   if (type_size == NULL || TREE_OVERFLOW (type_size))
6178     t = size_zero_node;
6179   else
6180     {
6181       t = size_binop (PLUS_EXPR, type_size, size_int (7));
6182       t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
6183       t = size_binop (MULT_EXPR, t, size_int (8));
6184     }
6185   t = fold_convert (TREE_TYPE (offset), t);
6186   t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset,
6187               build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t));
6188   gimplify_and_add (t, pre_p);
6189
6190   return build_va_arg_indirect_ref (addr);
6191 }
6192
6193 static tree
6194 alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
6195 {
6196   tree offset_field, base_field, offset, base, t, r;
6197   bool indirect;
6198
6199   if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
6200     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6201
6202   base_field = TYPE_FIELDS (va_list_type_node);
6203   offset_field = TREE_CHAIN (base_field);
6204   base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6205                        valist, base_field, NULL_TREE);
6206   offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6207                          valist, offset_field, NULL_TREE);
6208
6209   /* Pull the fields of the structure out into temporaries.  Since we never
6210      modify the base field, we can use a formal temporary.  Sign-extend the
6211      offset field so that it's the proper width for pointer arithmetic.  */
6212   base = get_formal_tmp_var (base_field, pre_p);
6213
6214   t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
6215   offset = get_initialized_tmp_var (t, pre_p, NULL);
6216
6217   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
6218   if (indirect)
6219     type = build_pointer_type (type);
6220
6221   /* Find the value.  Note that this will be a stable indirection, or
6222      a composite of stable indirections in the case of complex.  */
6223   r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
6224
6225   /* Stuff the offset temporary back into its field.  */
6226   t = build2 (GIMPLE_MODIFY_STMT, void_type_node, offset_field,
6227               fold_convert (TREE_TYPE (offset_field), offset));
6228   gimplify_and_add (t, pre_p);
6229
6230   if (indirect)
6231     r = build_va_arg_indirect_ref (r);
6232
6233   return r;
6234 }
6235 \f
6236 /* Builtins.  */
6237
6238 enum alpha_builtin
6239 {
6240   ALPHA_BUILTIN_CMPBGE,
6241   ALPHA_BUILTIN_EXTBL,
6242   ALPHA_BUILTIN_EXTWL,
6243   ALPHA_BUILTIN_EXTLL,
6244   ALPHA_BUILTIN_EXTQL,
6245   ALPHA_BUILTIN_EXTWH,
6246   ALPHA_BUILTIN_EXTLH,
6247   ALPHA_BUILTIN_EXTQH,
6248   ALPHA_BUILTIN_INSBL,
6249   ALPHA_BUILTIN_INSWL,
6250   ALPHA_BUILTIN_INSLL,
6251   ALPHA_BUILTIN_INSQL,
6252   ALPHA_BUILTIN_INSWH,
6253   ALPHA_BUILTIN_INSLH,
6254   ALPHA_BUILTIN_INSQH,
6255   ALPHA_BUILTIN_MSKBL,
6256   ALPHA_BUILTIN_MSKWL,
6257   ALPHA_BUILTIN_MSKLL,
6258   ALPHA_BUILTIN_MSKQL,
6259   ALPHA_BUILTIN_MSKWH,
6260   ALPHA_BUILTIN_MSKLH,
6261   ALPHA_BUILTIN_MSKQH,
6262   ALPHA_BUILTIN_UMULH,
6263   ALPHA_BUILTIN_ZAP,
6264   ALPHA_BUILTIN_ZAPNOT,
6265   ALPHA_BUILTIN_AMASK,
6266   ALPHA_BUILTIN_IMPLVER,
6267   ALPHA_BUILTIN_RPCC,
6268   ALPHA_BUILTIN_THREAD_POINTER,
6269   ALPHA_BUILTIN_SET_THREAD_POINTER,
6270
6271   /* TARGET_MAX */
6272   ALPHA_BUILTIN_MINUB8,
6273   ALPHA_BUILTIN_MINSB8,
6274   ALPHA_BUILTIN_MINUW4,
6275   ALPHA_BUILTIN_MINSW4,
6276   ALPHA_BUILTIN_MAXUB8,
6277   ALPHA_BUILTIN_MAXSB8,
6278   ALPHA_BUILTIN_MAXUW4,
6279   ALPHA_BUILTIN_MAXSW4,
6280   ALPHA_BUILTIN_PERR,
6281   ALPHA_BUILTIN_PKLB,
6282   ALPHA_BUILTIN_PKWB,
6283   ALPHA_BUILTIN_UNPKBL,
6284   ALPHA_BUILTIN_UNPKBW,
6285
6286   /* TARGET_CIX */
6287   ALPHA_BUILTIN_CTTZ,
6288   ALPHA_BUILTIN_CTLZ,
6289   ALPHA_BUILTIN_CTPOP,
6290
6291   ALPHA_BUILTIN_max
6292 };
6293
6294 static unsigned int const code_for_builtin[ALPHA_BUILTIN_max] = {
6295   CODE_FOR_builtin_cmpbge,
6296   CODE_FOR_builtin_extbl,
6297   CODE_FOR_builtin_extwl,
6298   CODE_FOR_builtin_extll,
6299   CODE_FOR_builtin_extql,
6300   CODE_FOR_builtin_extwh,
6301   CODE_FOR_builtin_extlh,
6302   CODE_FOR_builtin_extqh,
6303   CODE_FOR_builtin_insbl,
6304   CODE_FOR_builtin_inswl,
6305   CODE_FOR_builtin_insll,
6306   CODE_FOR_builtin_insql,
6307   CODE_FOR_builtin_inswh,
6308   CODE_FOR_builtin_inslh,
6309   CODE_FOR_builtin_insqh,
6310   CODE_FOR_builtin_mskbl,
6311   CODE_FOR_builtin_mskwl,
6312   CODE_FOR_builtin_mskll,
6313   CODE_FOR_builtin_mskql,
6314   CODE_FOR_builtin_mskwh,
6315   CODE_FOR_builtin_msklh,
6316   CODE_FOR_builtin_mskqh,
6317   CODE_FOR_umuldi3_highpart,
6318   CODE_FOR_builtin_zap,
6319   CODE_FOR_builtin_zapnot,
6320   CODE_FOR_builtin_amask,
6321   CODE_FOR_builtin_implver,
6322   CODE_FOR_builtin_rpcc,
6323   CODE_FOR_load_tp,
6324   CODE_FOR_set_tp,
6325
6326   /* TARGET_MAX */
6327   CODE_FOR_builtin_minub8,
6328   CODE_FOR_builtin_minsb8,
6329   CODE_FOR_builtin_minuw4,
6330   CODE_FOR_builtin_minsw4,
6331   CODE_FOR_builtin_maxub8,
6332   CODE_FOR_builtin_maxsb8,
6333   CODE_FOR_builtin_maxuw4,
6334   CODE_FOR_builtin_maxsw4,
6335   CODE_FOR_builtin_perr,
6336   CODE_FOR_builtin_pklb,
6337   CODE_FOR_builtin_pkwb,
6338   CODE_FOR_builtin_unpkbl,
6339   CODE_FOR_builtin_unpkbw,
6340
6341   /* TARGET_CIX */
6342   CODE_FOR_ctzdi2,
6343   CODE_FOR_clzdi2,
6344   CODE_FOR_popcountdi2
6345 };
6346
6347 struct alpha_builtin_def
6348 {
6349   const char *name;
6350   enum alpha_builtin code;
6351   unsigned int target_mask;
6352   bool is_const;
6353 };
6354
6355 static struct alpha_builtin_def const zero_arg_builtins[] = {
6356   { "__builtin_alpha_implver",  ALPHA_BUILTIN_IMPLVER,  0, true },
6357   { "__builtin_alpha_rpcc",     ALPHA_BUILTIN_RPCC,     0, false }
6358 };
6359
6360 static struct alpha_builtin_def const one_arg_builtins[] = {
6361   { "__builtin_alpha_amask",    ALPHA_BUILTIN_AMASK,    0, true },
6362   { "__builtin_alpha_pklb",     ALPHA_BUILTIN_PKLB,     MASK_MAX, true },
6363   { "__builtin_alpha_pkwb",     ALPHA_BUILTIN_PKWB,     MASK_MAX, true },
6364   { "__builtin_alpha_unpkbl",   ALPHA_BUILTIN_UNPKBL,   MASK_MAX, true },
6365   { "__builtin_alpha_unpkbw",   ALPHA_BUILTIN_UNPKBW,   MASK_MAX, true },
6366   { "__builtin_alpha_cttz",     ALPHA_BUILTIN_CTTZ,     MASK_CIX, true },
6367   { "__builtin_alpha_ctlz",     ALPHA_BUILTIN_CTLZ,     MASK_CIX, true },
6368   { "__builtin_alpha_ctpop",    ALPHA_BUILTIN_CTPOP,    MASK_CIX, true }
6369 };
6370
6371 static struct alpha_builtin_def const two_arg_builtins[] = {
6372   { "__builtin_alpha_cmpbge",   ALPHA_BUILTIN_CMPBGE,   0, true },
6373   { "__builtin_alpha_extbl",    ALPHA_BUILTIN_EXTBL,    0, true },
6374   { "__builtin_alpha_extwl",    ALPHA_BUILTIN_EXTWL,    0, true },
6375   { "__builtin_alpha_extll",    ALPHA_BUILTIN_EXTLL,    0, true },
6376   { "__builtin_alpha_extql",    ALPHA_BUILTIN_EXTQL,    0, true },
6377   { "__builtin_alpha_extwh",    ALPHA_BUILTIN_EXTWH,    0, true },
6378   { "__builtin_alpha_extlh",    ALPHA_BUILTIN_EXTLH,    0, true },
6379   { "__builtin_alpha_extqh",    ALPHA_BUILTIN_EXTQH,    0, true },
6380   { "__builtin_alpha_insbl",    ALPHA_BUILTIN_INSBL,    0, true },
6381   { "__builtin_alpha_inswl",    ALPHA_BUILTIN_INSWL,    0, true },
6382   { "__builtin_alpha_insll",    ALPHA_BUILTIN_INSLL,    0, true },
6383   { "__builtin_alpha_insql",    ALPHA_BUILTIN_INSQL,    0, true },
6384   { "__builtin_alpha_inswh",    ALPHA_BUILTIN_INSWH,    0, true },
6385   { "__builtin_alpha_inslh",    ALPHA_BUILTIN_INSLH,    0, true },
6386   { "__builtin_alpha_insqh",    ALPHA_BUILTIN_INSQH,    0, true },
6387   { "__builtin_alpha_mskbl",    ALPHA_BUILTIN_MSKBL,    0, true },
6388   { "__builtin_alpha_mskwl",    ALPHA_BUILTIN_MSKWL,    0, true },
6389   { "__builtin_alpha_mskll",    ALPHA_BUILTIN_MSKLL,    0, true },
6390   { "__builtin_alpha_mskql",    ALPHA_BUILTIN_MSKQL,    0, true },
6391   { "__builtin_alpha_mskwh",    ALPHA_BUILTIN_MSKWH,    0, true },
6392   { "__builtin_alpha_msklh",    ALPHA_BUILTIN_MSKLH,    0, true },
6393   { "__builtin_alpha_mskqh",    ALPHA_BUILTIN_MSKQH,    0, true },
6394   { "__builtin_alpha_umulh",    ALPHA_BUILTIN_UMULH,    0, true },
6395   { "__builtin_alpha_zap",      ALPHA_BUILTIN_ZAP,      0, true },
6396   { "__builtin_alpha_zapnot",   ALPHA_BUILTIN_ZAPNOT,   0, true },
6397   { "__builtin_alpha_minub8",   ALPHA_BUILTIN_MINUB8,   MASK_MAX, true },
6398   { "__builtin_alpha_minsb8",   ALPHA_BUILTIN_MINSB8,   MASK_MAX, true },
6399   { "__builtin_alpha_minuw4",   ALPHA_BUILTIN_MINUW4,   MASK_MAX, true },
6400   { "__builtin_alpha_minsw4",   ALPHA_BUILTIN_MINSW4,   MASK_MAX, true },
6401   { "__builtin_alpha_maxub8",   ALPHA_BUILTIN_MAXUB8,   MASK_MAX, true },
6402   { "__builtin_alpha_maxsb8",   ALPHA_BUILTIN_MAXSB8,   MASK_MAX, true },
6403   { "__builtin_alpha_maxuw4",   ALPHA_BUILTIN_MAXUW4,   MASK_MAX, true },
6404   { "__builtin_alpha_maxsw4",   ALPHA_BUILTIN_MAXSW4,   MASK_MAX, true },
6405   { "__builtin_alpha_perr",     ALPHA_BUILTIN_PERR,     MASK_MAX, true }
6406 };
6407
6408 static GTY(()) tree alpha_v8qi_u;
6409 static GTY(()) tree alpha_v8qi_s;
6410 static GTY(()) tree alpha_v4hi_u;
6411 static GTY(()) tree alpha_v4hi_s;
6412
6413 /* Helper function of alpha_init_builtins.  Add the COUNT built-in
6414    functions pointed to by P, with function type FTYPE.  */
6415
6416 static void
6417 alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
6418                     tree ftype)
6419 {
6420   tree decl;
6421   size_t i;
6422
6423   for (i = 0; i < count; ++i, ++p)
6424     if ((target_flags & p->target_mask) == p->target_mask)
6425       {
6426         decl = add_builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6427                                      NULL, NULL);
6428         if (p->is_const)
6429           TREE_READONLY (decl) = 1;
6430         TREE_NOTHROW (decl) = 1;
6431       }
6432 }
6433
6434
6435 static void
6436 alpha_init_builtins (void)
6437 {
6438   tree dimode_integer_type_node;
6439   tree ftype, decl;
6440
6441   dimode_integer_type_node = lang_hooks.types.type_for_mode (DImode, 0);
6442
6443   ftype = build_function_type (dimode_integer_type_node, void_list_node);
6444   alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
6445                       ftype);
6446
6447   ftype = build_function_type_list (dimode_integer_type_node,
6448                                     dimode_integer_type_node, NULL_TREE);
6449   alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins),
6450                       ftype);
6451
6452   ftype = build_function_type_list (dimode_integer_type_node,
6453                                     dimode_integer_type_node,
6454                                     dimode_integer_type_node, NULL_TREE);
6455   alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
6456                       ftype);
6457
6458   ftype = build_function_type (ptr_type_node, void_list_node);
6459   decl = add_builtin_function ("__builtin_thread_pointer", ftype,
6460                                ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6461                                NULL, NULL);
6462   TREE_NOTHROW (decl) = 1;
6463
6464   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6465   decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
6466                                ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6467                                NULL, NULL);
6468   TREE_NOTHROW (decl) = 1;
6469
6470   alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
6471   alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
6472   alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
6473   alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
6474 }
6475
6476 /* Expand an expression EXP that calls a built-in function,
6477    with result going to TARGET if that's convenient
6478    (and in mode MODE if that's convenient).
6479    SUBTARGET may be used as the target for computing one of EXP's operands.
6480    IGNORE is nonzero if the value is to be ignored.  */
6481
6482 static rtx
6483 alpha_expand_builtin (tree exp, rtx target,
6484                       rtx subtarget ATTRIBUTE_UNUSED,
6485                       enum machine_mode mode ATTRIBUTE_UNUSED,
6486                       int ignore ATTRIBUTE_UNUSED)
6487 {
6488 #define MAX_ARGS 2
6489
6490   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6491   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6492   tree arg;
6493   call_expr_arg_iterator iter;
6494   enum insn_code icode;
6495   rtx op[MAX_ARGS], pat;
6496   int arity;
6497   bool nonvoid;
6498
6499   if (fcode >= ALPHA_BUILTIN_max)
6500     internal_error ("bad builtin fcode");
6501   icode = code_for_builtin[fcode];
6502   if (icode == 0)
6503     internal_error ("bad builtin fcode");
6504
6505   nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6506
6507   arity = 0;
6508   FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6509     {
6510       const struct insn_operand_data *insn_op;
6511
6512       if (arg == error_mark_node)
6513         return NULL_RTX;
6514       if (arity > MAX_ARGS)
6515         return NULL_RTX;
6516
6517       insn_op = &insn_data[icode].operand[arity + nonvoid];
6518
6519       op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
6520
6521       if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6522         op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6523       arity++;
6524     }
6525
6526   if (nonvoid)
6527     {
6528       enum machine_mode tmode = insn_data[icode].operand[0].mode;
6529       if (!target
6530           || GET_MODE (target) != tmode
6531           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6532         target = gen_reg_rtx (tmode);
6533     }
6534
6535   switch (arity)
6536     {
6537     case 0:
6538       pat = GEN_FCN (icode) (target);
6539       break;
6540     case 1:
6541       if (nonvoid)
6542         pat = GEN_FCN (icode) (target, op[0]);
6543       else
6544         pat = GEN_FCN (icode) (op[0]);
6545       break;
6546     case 2:
6547       pat = GEN_FCN (icode) (target, op[0], op[1]);
6548       break;
6549     default:
6550       gcc_unreachable ();
6551     }
6552   if (!pat)
6553     return NULL_RTX;
6554   emit_insn (pat);
6555
6556   if (nonvoid)
6557     return target;
6558   else
6559     return const0_rtx;
6560 }
6561
6562
6563 /* Several bits below assume HWI >= 64 bits.  This should be enforced
6564    by config.gcc.  */
6565 #if HOST_BITS_PER_WIDE_INT < 64
6566 # error "HOST_WIDE_INT too small"
6567 #endif
6568
6569 /* Fold the builtin for the CMPBGE instruction.  This is a vector comparison
6570    with an 8-bit output vector.  OPINT contains the integer operands; bit N
6571    of OP_CONST is set if OPINT[N] is valid.  */
6572
6573 static tree
6574 alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
6575 {
6576   if (op_const == 3)
6577     {
6578       int i, val;
6579       for (i = 0, val = 0; i < 8; ++i)
6580         {
6581           unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
6582           unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
6583           if (c0 >= c1)
6584             val |= 1 << i;
6585         }
6586       return build_int_cst (long_integer_type_node, val);
6587     }
6588   else if (op_const == 2 && opint[1] == 0)
6589     return build_int_cst (long_integer_type_node, 0xff);
6590   return NULL;
6591 }
6592
6593 /* Fold the builtin for the ZAPNOT instruction.  This is essentially a 
6594    specialized form of an AND operation.  Other byte manipulation instructions
6595    are defined in terms of this instruction, so this is also used as a
6596    subroutine for other builtins.
6597
6598    OP contains the tree operands; OPINT contains the extracted integer values.
6599    Bit N of OP_CONST it set if OPINT[N] is valid.  OP may be null if only
6600    OPINT may be considered.  */
6601
6602 static tree
6603 alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
6604                            long op_const)
6605 {
6606   if (op_const & 2)
6607     {
6608       unsigned HOST_WIDE_INT mask = 0;
6609       int i;
6610
6611       for (i = 0; i < 8; ++i)
6612         if ((opint[1] >> i) & 1)
6613           mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
6614
6615       if (op_const & 1)
6616         return build_int_cst (long_integer_type_node, opint[0] & mask);
6617
6618       if (op)
6619         return fold_build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
6620                             build_int_cst (long_integer_type_node, mask));
6621     }
6622   else if ((op_const & 1) && opint[0] == 0)
6623     return build_int_cst (long_integer_type_node, 0);
6624   return NULL;
6625 }
6626
6627 /* Fold the builtins for the EXT family of instructions.  */
6628
6629 static tree
6630 alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
6631                           long op_const, unsigned HOST_WIDE_INT bytemask,
6632                           bool is_high)
6633 {
6634   long zap_const = 2;
6635   tree *zap_op = NULL;
6636
6637   if (op_const & 2)
6638     {
6639       unsigned HOST_WIDE_INT loc;
6640
6641       loc = opint[1] & 7;
6642       if (BYTES_BIG_ENDIAN)
6643         loc ^= 7;
6644       loc *= 8;
6645
6646       if (loc != 0)
6647         {
6648           if (op_const & 1)
6649             {
6650               unsigned HOST_WIDE_INT temp = opint[0];
6651               if (is_high)
6652                 temp <<= loc;
6653               else
6654                 temp >>= loc;
6655               opint[0] = temp;
6656               zap_const = 3;
6657             }
6658         }
6659       else
6660         zap_op = op;
6661     }
6662   
6663   opint[1] = bytemask;
6664   return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
6665 }
6666
6667 /* Fold the builtins for the INS family of instructions.  */
6668
6669 static tree
6670 alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
6671                           long op_const, unsigned HOST_WIDE_INT bytemask,
6672                           bool is_high)
6673 {
6674   if ((op_const & 1) && opint[0] == 0)
6675     return build_int_cst (long_integer_type_node, 0);
6676
6677   if (op_const & 2)
6678     {
6679       unsigned HOST_WIDE_INT temp, loc, byteloc;
6680       tree *zap_op = NULL;
6681
6682       loc = opint[1] & 7;
6683       if (BYTES_BIG_ENDIAN)
6684         loc ^= 7;
6685       bytemask <<= loc;
6686
6687       temp = opint[0];
6688       if (is_high)
6689         {
6690           byteloc = (64 - (loc * 8)) & 0x3f;
6691           if (byteloc == 0)
6692             zap_op = op;
6693           else
6694             temp >>= byteloc;
6695           bytemask >>= 8;
6696         }
6697       else
6698         {
6699           byteloc = loc * 8;
6700           if (byteloc == 0)
6701             zap_op = op;
6702           else
6703             temp <<= byteloc;
6704         }
6705
6706       opint[0] = temp;
6707       opint[1] = bytemask;
6708       return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
6709     }
6710
6711   return NULL;
6712 }
6713
6714 static tree
6715 alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
6716                           long op_const, unsigned HOST_WIDE_INT bytemask,
6717                           bool is_high)
6718 {
6719   if (op_const & 2)
6720     {
6721       unsigned HOST_WIDE_INT loc;
6722
6723       loc = opint[1] & 7;
6724       if (BYTES_BIG_ENDIAN)
6725         loc ^= 7;
6726       bytemask <<= loc;
6727
6728       if (is_high)
6729         bytemask >>= 8;
6730
6731       opint[1] = bytemask ^ 0xff;
6732     }
6733
6734   return alpha_fold_builtin_zapnot (op, opint, op_const);
6735 }
6736
6737 static tree
6738 alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
6739 {
6740   switch (op_const)
6741     {
6742     case 3:
6743       {
6744         unsigned HOST_WIDE_INT l;
6745         HOST_WIDE_INT h;
6746
6747         mul_double (opint[0], 0, opint[1], 0, &l, &h);
6748
6749 #if HOST_BITS_PER_WIDE_INT > 64
6750 # error fixme
6751 #endif
6752
6753         return build_int_cst (long_integer_type_node, h);
6754       }
6755
6756     case 1:
6757       opint[1] = opint[0];
6758       /* FALLTHRU */
6759     case 2:
6760       /* Note that (X*1) >> 64 == 0.  */
6761       if (opint[1] == 0 || opint[1] == 1)
6762         return build_int_cst (long_integer_type_node, 0);
6763       break;
6764     }
6765   return NULL;
6766 }
6767
6768 static tree
6769 alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
6770 {
6771   tree op0 = fold_convert (vtype, op[0]);
6772   tree op1 = fold_convert (vtype, op[1]);
6773   tree val = fold_build2 (code, vtype, op0, op1);
6774   return fold_convert (long_integer_type_node, val);
6775 }
6776
6777 static tree
6778 alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
6779 {
6780   unsigned HOST_WIDE_INT temp = 0;
6781   int i;
6782
6783   if (op_const != 3)
6784     return NULL;
6785
6786   for (i = 0; i < 8; ++i)
6787     {
6788       unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
6789       unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
6790       if (a >= b)
6791         temp += a - b;
6792       else
6793         temp += b - a;
6794     }
6795
6796   return build_int_cst (long_integer_type_node, temp);
6797 }
6798
6799 static tree
6800 alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
6801 {
6802   unsigned HOST_WIDE_INT temp;
6803
6804   if (op_const == 0)
6805     return NULL;
6806
6807   temp = opint[0] & 0xff;
6808   temp |= (opint[0] >> 24) & 0xff00;
6809
6810   return build_int_cst (long_integer_type_node, temp);
6811 }
6812
6813 static tree
6814 alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
6815 {
6816   unsigned HOST_WIDE_INT temp;
6817
6818   if (op_const == 0)
6819     return NULL;
6820
6821   temp = opint[0] & 0xff;
6822   temp |= (opint[0] >>  8) & 0xff00;
6823   temp |= (opint[0] >> 16) & 0xff0000;
6824   temp |= (opint[0] >> 24) & 0xff000000;
6825
6826   return build_int_cst (long_integer_type_node, temp);
6827 }
6828
6829 static tree
6830 alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
6831 {
6832   unsigned HOST_WIDE_INT temp;
6833
6834   if (op_const == 0)
6835     return NULL;
6836
6837   temp = opint[0] & 0xff;
6838   temp |= (opint[0] & 0xff00) << 24;
6839
6840   return build_int_cst (long_integer_type_node, temp);
6841 }
6842
6843 static tree
6844 alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
6845 {
6846   unsigned HOST_WIDE_INT temp;
6847
6848   if (op_const == 0)
6849     return NULL;
6850
6851   temp = opint[0] & 0xff;
6852   temp |= (opint[0] & 0x0000ff00) << 8;
6853   temp |= (opint[0] & 0x00ff0000) << 16;
6854   temp |= (opint[0] & 0xff000000) << 24;
6855
6856   return build_int_cst (long_integer_type_node, temp);
6857 }
6858
6859 static tree
6860 alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
6861 {
6862   unsigned HOST_WIDE_INT temp;
6863
6864   if (op_const == 0)
6865     return NULL;
6866
6867   if (opint[0] == 0)
6868     temp = 64;
6869   else
6870     temp = exact_log2 (opint[0] & -opint[0]);
6871
6872   return build_int_cst (long_integer_type_node, temp);
6873 }
6874
6875 static tree
6876 alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
6877 {
6878   unsigned HOST_WIDE_INT temp;
6879
6880   if (op_const == 0)
6881     return NULL;
6882
6883   if (opint[0] == 0)
6884     temp = 64;
6885   else
6886     temp = 64 - floor_log2 (opint[0]) - 1;
6887
6888   return build_int_cst (long_integer_type_node, temp);
6889 }
6890
6891 static tree
6892 alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
6893 {
6894   unsigned HOST_WIDE_INT temp, op;
6895
6896   if (op_const == 0)
6897     return NULL;
6898
6899   op = opint[0];
6900   temp = 0;
6901   while (op)
6902     temp++, op &= op - 1;
6903
6904   return build_int_cst (long_integer_type_node, temp);
6905 }
6906
6907 /* Fold one of our builtin functions.  */
6908
6909 static tree
6910 alpha_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
6911 {
6912   tree op[MAX_ARGS], t;
6913   unsigned HOST_WIDE_INT opint[MAX_ARGS];
6914   long op_const = 0, arity = 0;
6915
6916   for (t = arglist; t ; t = TREE_CHAIN (t), ++arity)
6917     {
6918       tree arg = TREE_VALUE (t);
6919       if (arg == error_mark_node)
6920         return NULL;
6921       if (arity >= MAX_ARGS)
6922         return NULL;
6923
6924       op[arity] = arg;
6925       opint[arity] = 0;
6926       if (TREE_CODE (arg) == INTEGER_CST)
6927         {
6928           op_const |= 1L << arity;
6929           opint[arity] = int_cst_value (arg);
6930         }
6931     }
6932
6933   switch (DECL_FUNCTION_CODE (fndecl))
6934     {
6935     case ALPHA_BUILTIN_CMPBGE:
6936       return alpha_fold_builtin_cmpbge (opint, op_const);
6937
6938     case ALPHA_BUILTIN_EXTBL:
6939       return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
6940     case ALPHA_BUILTIN_EXTWL:
6941       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
6942     case ALPHA_BUILTIN_EXTLL:
6943       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
6944     case ALPHA_BUILTIN_EXTQL:
6945       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
6946     case ALPHA_BUILTIN_EXTWH:
6947       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
6948     case ALPHA_BUILTIN_EXTLH:
6949       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
6950     case ALPHA_BUILTIN_EXTQH:
6951       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
6952
6953     case ALPHA_BUILTIN_INSBL:
6954       return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
6955     case ALPHA_BUILTIN_INSWL:
6956       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
6957     case ALPHA_BUILTIN_INSLL:
6958       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
6959     case ALPHA_BUILTIN_INSQL:
6960       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
6961     case ALPHA_BUILTIN_INSWH:
6962       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
6963     case ALPHA_BUILTIN_INSLH:
6964       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
6965     case ALPHA_BUILTIN_INSQH:
6966       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
6967
6968     case ALPHA_BUILTIN_MSKBL:
6969       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
6970     case ALPHA_BUILTIN_MSKWL:
6971       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
6972     case ALPHA_BUILTIN_MSKLL:
6973       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
6974     case ALPHA_BUILTIN_MSKQL:
6975       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
6976     case ALPHA_BUILTIN_MSKWH:
6977       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
6978     case ALPHA_BUILTIN_MSKLH:
6979       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
6980     case ALPHA_BUILTIN_MSKQH:
6981       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
6982
6983     case ALPHA_BUILTIN_UMULH:
6984       return alpha_fold_builtin_umulh (opint, op_const);
6985
6986     case ALPHA_BUILTIN_ZAP:
6987       opint[1] ^= 0xff;
6988       /* FALLTHRU */
6989     case ALPHA_BUILTIN_ZAPNOT:
6990       return alpha_fold_builtin_zapnot (op, opint, op_const);
6991
6992     case ALPHA_BUILTIN_MINUB8:
6993       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
6994     case ALPHA_BUILTIN_MINSB8:
6995       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
6996     case ALPHA_BUILTIN_MINUW4:
6997       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
6998     case ALPHA_BUILTIN_MINSW4:
6999       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
7000     case ALPHA_BUILTIN_MAXUB8:
7001       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
7002     case ALPHA_BUILTIN_MAXSB8:
7003       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
7004     case ALPHA_BUILTIN_MAXUW4:
7005       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
7006     case ALPHA_BUILTIN_MAXSW4:
7007       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
7008
7009     case ALPHA_BUILTIN_PERR:
7010       return alpha_fold_builtin_perr (opint, op_const);
7011     case ALPHA_BUILTIN_PKLB:
7012       return alpha_fold_builtin_pklb (opint, op_const);
7013     case ALPHA_BUILTIN_PKWB:
7014       return alpha_fold_builtin_pkwb (opint, op_const);
7015     case ALPHA_BUILTIN_UNPKBL:
7016       return alpha_fold_builtin_unpkbl (opint, op_const);
7017     case ALPHA_BUILTIN_UNPKBW:
7018       return alpha_fold_builtin_unpkbw (opint, op_const);
7019
7020     case ALPHA_BUILTIN_CTTZ:
7021       return alpha_fold_builtin_cttz (opint, op_const);
7022     case ALPHA_BUILTIN_CTLZ:
7023       return alpha_fold_builtin_ctlz (opint, op_const);
7024     case ALPHA_BUILTIN_CTPOP:
7025       return alpha_fold_builtin_ctpop (opint, op_const);
7026
7027     case ALPHA_BUILTIN_AMASK:
7028     case ALPHA_BUILTIN_IMPLVER:
7029     case ALPHA_BUILTIN_RPCC:
7030     case ALPHA_BUILTIN_THREAD_POINTER:
7031     case ALPHA_BUILTIN_SET_THREAD_POINTER:
7032       /* None of these are foldable at compile-time.  */
7033     default:
7034       return NULL;
7035     }
7036 }
7037 \f
7038 /* This page contains routines that are used to determine what the function
7039    prologue and epilogue code will do and write them out.  */
7040
7041 /* Compute the size of the save area in the stack.  */
7042
7043 /* These variables are used for communication between the following functions.
7044    They indicate various things about the current function being compiled
7045    that are used to tell what kind of prologue, epilogue and procedure
7046    descriptor to generate.  */
7047
7048 /* Nonzero if we need a stack procedure.  */
7049 enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
7050 static enum alpha_procedure_types alpha_procedure_type;
7051
7052 /* Register number (either FP or SP) that is used to unwind the frame.  */
7053 static int vms_unwind_regno;
7054
7055 /* Register number used to save FP.  We need not have one for RA since
7056    we don't modify it for register procedures.  This is only defined
7057    for register frame procedures.  */
7058 static int vms_save_fp_regno;
7059
7060 /* Register number used to reference objects off our PV.  */
7061 static int vms_base_regno;
7062
7063 /* Compute register masks for saved registers.  */
7064
7065 static void
7066 alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
7067 {
7068   unsigned long imask = 0;
7069   unsigned long fmask = 0;
7070   unsigned int i;
7071
7072   /* When outputting a thunk, we don't have valid register life info,
7073      but assemble_start_function wants to output .frame and .mask
7074      directives.  */
7075   if (current_function_is_thunk)
7076     {
7077       *imaskP = 0;
7078       *fmaskP = 0;
7079       return;
7080     }
7081
7082   if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7083     imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
7084
7085   /* One for every register we have to save.  */
7086   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7087     if (! fixed_regs[i] && ! call_used_regs[i]
7088         && df_regs_ever_live_p (i) && i != REG_RA
7089         && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
7090       {
7091         if (i < 32)
7092           imask |= (1UL << i);
7093         else
7094           fmask |= (1UL << (i - 32));
7095       }
7096
7097   /* We need to restore these for the handler.  */
7098   if (current_function_calls_eh_return)
7099     {
7100       for (i = 0; ; ++i)
7101         {
7102           unsigned regno = EH_RETURN_DATA_REGNO (i);
7103           if (regno == INVALID_REGNUM)
7104             break;
7105           imask |= 1UL << regno;
7106         }
7107     }
7108
7109   /* If any register spilled, then spill the return address also.  */
7110   /* ??? This is required by the Digital stack unwind specification
7111      and isn't needed if we're doing Dwarf2 unwinding.  */
7112   if (imask || fmask || alpha_ra_ever_killed ())
7113     imask |= (1UL << REG_RA);
7114
7115   *imaskP = imask;
7116   *fmaskP = fmask;
7117 }
7118
7119 int
7120 alpha_sa_size (void)
7121 {
7122   unsigned long mask[2];
7123   int sa_size = 0;
7124   int i, j;
7125
7126   alpha_sa_mask (&mask[0], &mask[1]);
7127
7128   if (TARGET_ABI_UNICOSMK)
7129     {
7130       if (mask[0] || mask[1])
7131         sa_size = 14;
7132     }
7133   else
7134     {
7135       for (j = 0; j < 2; ++j)
7136         for (i = 0; i < 32; ++i)
7137           if ((mask[j] >> i) & 1)
7138             sa_size++;
7139     }
7140
7141   if (TARGET_ABI_UNICOSMK)
7142     {
7143       /* We might not need to generate a frame if we don't make any calls
7144          (including calls to __T3E_MISMATCH if this is a vararg function),
7145          don't have any local variables which require stack slots, don't
7146          use alloca and have not determined that we need a frame for other
7147          reasons.  */
7148
7149       alpha_procedure_type
7150         = (sa_size || get_frame_size() != 0
7151            || crtl->outgoing_args_size
7152            || current_function_stdarg || current_function_calls_alloca
7153            || frame_pointer_needed)
7154           ? PT_STACK : PT_REGISTER;
7155
7156       /* Always reserve space for saving callee-saved registers if we
7157          need a frame as required by the calling convention.  */
7158       if (alpha_procedure_type == PT_STACK)
7159         sa_size = 14;
7160     }
7161   else if (TARGET_ABI_OPEN_VMS)
7162     {
7163       /* Start by assuming we can use a register procedure if we don't
7164          make any calls (REG_RA not used) or need to save any
7165          registers and a stack procedure if we do.  */
7166       if ((mask[0] >> REG_RA) & 1)
7167         alpha_procedure_type = PT_STACK;
7168       else if (get_frame_size() != 0)
7169         alpha_procedure_type = PT_REGISTER;
7170       else
7171         alpha_procedure_type = PT_NULL;
7172
7173       /* Don't reserve space for saving FP & RA yet.  Do that later after we've
7174          made the final decision on stack procedure vs register procedure.  */
7175       if (alpha_procedure_type == PT_STACK)
7176         sa_size -= 2;
7177
7178       /* Decide whether to refer to objects off our PV via FP or PV.
7179          If we need FP for something else or if we receive a nonlocal
7180          goto (which expects PV to contain the value), we must use PV.
7181          Otherwise, start by assuming we can use FP.  */
7182
7183       vms_base_regno
7184         = (frame_pointer_needed
7185            || current_function_has_nonlocal_label
7186            || alpha_procedure_type == PT_STACK
7187            || crtl->outgoing_args_size)
7188           ? REG_PV : HARD_FRAME_POINTER_REGNUM;
7189
7190       /* If we want to copy PV into FP, we need to find some register
7191          in which to save FP.  */
7192
7193       vms_save_fp_regno = -1;
7194       if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
7195         for (i = 0; i < 32; i++)
7196           if (! fixed_regs[i] && call_used_regs[i] && ! df_regs_ever_live_p (i))
7197             vms_save_fp_regno = i;
7198
7199       if (vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
7200         vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
7201       else if (alpha_procedure_type == PT_NULL)
7202         vms_base_regno = REG_PV;
7203
7204       /* Stack unwinding should be done via FP unless we use it for PV.  */
7205       vms_unwind_regno = (vms_base_regno == REG_PV
7206                           ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
7207
7208       /* If this is a stack procedure, allow space for saving FP and RA.  */
7209       if (alpha_procedure_type == PT_STACK)
7210         sa_size += 2;
7211     }
7212   else
7213     {
7214       /* Our size must be even (multiple of 16 bytes).  */
7215       if (sa_size & 1)
7216         sa_size++;
7217     }
7218
7219   return sa_size * 8;
7220 }
7221
7222 /* Define the offset between two registers, one to be eliminated,
7223    and the other its replacement, at the start of a routine.  */
7224
7225 HOST_WIDE_INT
7226 alpha_initial_elimination_offset (unsigned int from,
7227                                   unsigned int to ATTRIBUTE_UNUSED)
7228 {
7229   HOST_WIDE_INT ret;
7230
7231   ret = alpha_sa_size ();
7232   ret += ALPHA_ROUND (crtl->outgoing_args_size);
7233
7234   switch (from)
7235     {
7236     case FRAME_POINTER_REGNUM:
7237       break;
7238
7239     case ARG_POINTER_REGNUM:
7240       ret += (ALPHA_ROUND (get_frame_size ()
7241                            + crtl->args.pretend_args_size)
7242               - crtl->args.pretend_args_size);
7243       break;
7244
7245     default:
7246       gcc_unreachable ();
7247     }
7248
7249   return ret;
7250 }
7251
7252 int
7253 alpha_pv_save_size (void)
7254 {
7255   alpha_sa_size ();
7256   return alpha_procedure_type == PT_STACK ? 8 : 0;
7257 }
7258
7259 int
7260 alpha_using_fp (void)
7261 {
7262   alpha_sa_size ();
7263   return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
7264 }
7265
7266 #if TARGET_ABI_OPEN_VMS
7267
7268 const struct attribute_spec vms_attribute_table[] =
7269 {
7270   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
7271   { "overlaid",   0, 0, true,  false, false, NULL },
7272   { "global",     0, 0, true,  false, false, NULL },
7273   { "initialize", 0, 0, true,  false, false, NULL },
7274   { NULL,         0, 0, false, false, false, NULL }
7275 };
7276
7277 #endif
7278
7279 static int
7280 find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
7281 {
7282   return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
7283 }
7284
7285 int
7286 alpha_find_lo_sum_using_gp (rtx insn)
7287 {
7288   return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
7289 }
7290
7291 static int
7292 alpha_does_function_need_gp (void)
7293 {
7294   rtx insn;
7295
7296   /* The GP being variable is an OSF abi thing.  */
7297   if (! TARGET_ABI_OSF)
7298     return 0;
7299
7300   /* We need the gp to load the address of __mcount.  */
7301   if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
7302     return 1;
7303
7304   /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
7305   if (current_function_is_thunk)
7306     return 1;
7307
7308   /* The nonlocal receiver pattern assumes that the gp is valid for
7309      the nested function.  Reasonable because it's almost always set
7310      correctly already.  For the cases where that's wrong, make sure
7311      the nested function loads its gp on entry.  */
7312   if (current_function_has_nonlocal_goto)
7313     return 1;
7314
7315   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7316      Even if we are a static function, we still need to do this in case
7317      our address is taken and passed to something like qsort.  */
7318
7319   push_topmost_sequence ();
7320   insn = get_insns ();
7321   pop_topmost_sequence ();
7322
7323   for (; insn; insn = NEXT_INSN (insn))
7324     if (INSN_P (insn)
7325         && ! JUMP_TABLE_DATA_P (insn)
7326         && GET_CODE (PATTERN (insn)) != USE
7327         && GET_CODE (PATTERN (insn)) != CLOBBER
7328         && get_attr_usegp (insn))
7329       return 1;
7330
7331   return 0;
7332 }
7333
7334 \f
7335 /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7336    sequences.  */
7337
7338 static rtx
7339 set_frame_related_p (void)
7340 {
7341   rtx seq = get_insns ();
7342   rtx insn;
7343
7344   end_sequence ();
7345
7346   if (!seq)
7347     return NULL_RTX;
7348
7349   if (INSN_P (seq))
7350     {
7351       insn = seq;
7352       while (insn != NULL_RTX)
7353         {
7354           RTX_FRAME_RELATED_P (insn) = 1;
7355           insn = NEXT_INSN (insn);
7356         }
7357       seq = emit_insn (seq);
7358     }
7359   else
7360     {
7361       seq = emit_insn (seq);
7362       RTX_FRAME_RELATED_P (seq) = 1;
7363     }
7364   return seq;
7365 }
7366
7367 #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
7368
7369 /* Generates a store with the proper unwind info attached.  VALUE is
7370    stored at BASE_REG+BASE_OFS.  If FRAME_BIAS is nonzero, then BASE_REG
7371    contains SP+FRAME_BIAS, and that is the unwind info that should be
7372    generated.  If FRAME_REG != VALUE, then VALUE is being stored on
7373    behalf of FRAME_REG, and FRAME_REG should be present in the unwind.  */
7374
7375 static void
7376 emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
7377                     HOST_WIDE_INT base_ofs, rtx frame_reg)
7378 {
7379   rtx addr, mem, insn;
7380
7381   addr = plus_constant (base_reg, base_ofs);
7382   mem = gen_rtx_MEM (DImode, addr);
7383   set_mem_alias_set (mem, alpha_sr_alias_set);
7384
7385   insn = emit_move_insn (mem, value);
7386   RTX_FRAME_RELATED_P (insn) = 1;
7387
7388   if (frame_bias || value != frame_reg)
7389     {
7390       if (frame_bias)
7391         {
7392           addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
7393           mem = gen_rtx_MEM (DImode, addr);
7394         }
7395
7396       REG_NOTES (insn)
7397         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7398                              gen_rtx_SET (VOIDmode, mem, frame_reg),
7399                              REG_NOTES (insn));
7400     }
7401 }
7402
7403 static void
7404 emit_frame_store (unsigned int regno, rtx base_reg,
7405                   HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
7406 {
7407   rtx reg = gen_rtx_REG (DImode, regno);
7408   emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
7409 }
7410
7411 /* Write function prologue.  */
7412
7413 /* On vms we have two kinds of functions:
7414
7415    - stack frame (PROC_STACK)
7416         these are 'normal' functions with local vars and which are
7417         calling other functions
7418    - register frame (PROC_REGISTER)
7419         keeps all data in registers, needs no stack
7420
7421    We must pass this to the assembler so it can generate the
7422    proper pdsc (procedure descriptor)
7423    This is done with the '.pdesc' command.
7424
7425    On not-vms, we don't really differentiate between the two, as we can
7426    simply allocate stack without saving registers.  */
7427
7428 void
7429 alpha_expand_prologue (void)
7430 {
7431   /* Registers to save.  */
7432   unsigned long imask = 0;
7433   unsigned long fmask = 0;
7434   /* Stack space needed for pushing registers clobbered by us.  */
7435   HOST_WIDE_INT sa_size;
7436   /* Complete stack size needed.  */
7437   HOST_WIDE_INT frame_size;
7438   /* Offset from base reg to register save area.  */
7439   HOST_WIDE_INT reg_offset;
7440   rtx sa_reg;
7441   int i;
7442
7443   sa_size = alpha_sa_size ();
7444
7445   frame_size = get_frame_size ();
7446   if (TARGET_ABI_OPEN_VMS)
7447     frame_size = ALPHA_ROUND (sa_size
7448                               + (alpha_procedure_type == PT_STACK ? 8 : 0)
7449                               + frame_size
7450                               + crtl->args.pretend_args_size);
7451   else if (TARGET_ABI_UNICOSMK)
7452     /* We have to allocate space for the DSIB if we generate a frame.  */
7453     frame_size = ALPHA_ROUND (sa_size
7454                               + (alpha_procedure_type == PT_STACK ? 48 : 0))
7455                  + ALPHA_ROUND (frame_size
7456                                 + crtl->outgoing_args_size);
7457   else
7458     frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7459                   + sa_size
7460                   + ALPHA_ROUND (frame_size
7461                                  + crtl->args.pretend_args_size));
7462
7463   if (TARGET_ABI_OPEN_VMS)
7464     reg_offset = 8;
7465   else
7466     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7467
7468   alpha_sa_mask (&imask, &fmask);
7469
7470   /* Emit an insn to reload GP, if needed.  */
7471   if (TARGET_ABI_OSF)
7472     {
7473       alpha_function_needs_gp = alpha_does_function_need_gp ();
7474       if (alpha_function_needs_gp)
7475         emit_insn (gen_prologue_ldgp ());
7476     }
7477
7478   /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7479      the call to mcount ourselves, rather than having the linker do it
7480      magically in response to -pg.  Since _mcount has special linkage,
7481      don't represent the call as a call.  */
7482   if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
7483     emit_insn (gen_prologue_mcount ());
7484
7485   if (TARGET_ABI_UNICOSMK)
7486     unicosmk_gen_dsib (&imask);
7487
7488   /* Adjust the stack by the frame size.  If the frame size is > 4096
7489      bytes, we need to be sure we probe somewhere in the first and last
7490      4096 bytes (we can probably get away without the latter test) and
7491      every 8192 bytes in between.  If the frame size is > 32768, we
7492      do this in a loop.  Otherwise, we generate the explicit probe
7493      instructions.
7494
7495      Note that we are only allowed to adjust sp once in the prologue.  */
7496
7497   if (frame_size <= 32768)
7498     {
7499       if (frame_size > 4096)
7500         {
7501           int probed;
7502
7503           for (probed = 4096; probed < frame_size; probed += 8192)
7504             emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7505                                                  ? -probed + 64
7506                                                  : -probed)));
7507
7508           /* We only have to do this probe if we aren't saving registers.  */
7509           if (sa_size == 0 && frame_size > probed - 4096)
7510             emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
7511         }
7512
7513       if (frame_size != 0)
7514         FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7515                                     GEN_INT (TARGET_ABI_UNICOSMK
7516                                              ? -frame_size + 64
7517                                              : -frame_size))));
7518     }
7519   else
7520     {
7521       /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7522          number of 8192 byte blocks to probe.  We then probe each block
7523          in the loop and then set SP to the proper location.  If the
7524          amount remaining is > 4096, we have to do one more probe if we
7525          are not saving any registers.  */
7526
7527       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
7528       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
7529       rtx ptr = gen_rtx_REG (DImode, 22);
7530       rtx count = gen_rtx_REG (DImode, 23);
7531       rtx seq;
7532
7533       emit_move_insn (count, GEN_INT (blocks));
7534       emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
7535                              GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
7536
7537       /* Because of the difficulty in emitting a new basic block this
7538          late in the compilation, generate the loop as a single insn.  */
7539       emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7540
7541       if (leftover > 4096 && sa_size == 0)
7542         {
7543           rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7544           MEM_VOLATILE_P (last) = 1;
7545           emit_move_insn (last, const0_rtx);
7546         }
7547
7548       if (TARGET_ABI_WINDOWS_NT)
7549         {
7550           /* For NT stack unwind (done by 'reverse execution'), it's
7551              not OK to take the result of a loop, even though the value
7552              is already in ptr, so we reload it via a single operation
7553              and subtract it to sp.
7554
7555              Yes, that's correct -- we have to reload the whole constant
7556              into a temporary via ldah+lda then subtract from sp.  */
7557
7558           HOST_WIDE_INT lo, hi;
7559           lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7560           hi = frame_size - lo;
7561
7562           emit_move_insn (ptr, GEN_INT (hi));
7563           emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
7564           seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7565                                        ptr));
7566         }
7567       else
7568         {
7569           seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7570                                        GEN_INT (-leftover)));
7571         }
7572
7573       /* This alternative is special, because the DWARF code cannot
7574          possibly intuit through the loop above.  So we invent this
7575          note it looks at instead.  */
7576       RTX_FRAME_RELATED_P (seq) = 1;
7577       REG_NOTES (seq)
7578         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
7579                              gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7580                                gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7581                                              GEN_INT (TARGET_ABI_UNICOSMK
7582                                                       ? -frame_size + 64
7583                                                       : -frame_size))),
7584                              REG_NOTES (seq));
7585     }
7586
7587   if (!TARGET_ABI_UNICOSMK)
7588     {
7589       HOST_WIDE_INT sa_bias = 0;
7590
7591       /* Cope with very large offsets to the register save area.  */
7592       sa_reg = stack_pointer_rtx;
7593       if (reg_offset + sa_size > 0x8000)
7594         {
7595           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7596           rtx sa_bias_rtx;
7597
7598           if (low + sa_size <= 0x8000)
7599             sa_bias = reg_offset - low, reg_offset = low;
7600           else
7601             sa_bias = reg_offset, reg_offset = 0;
7602
7603           sa_reg = gen_rtx_REG (DImode, 24);
7604           sa_bias_rtx = GEN_INT (sa_bias);
7605
7606           if (add_operand (sa_bias_rtx, DImode))
7607             emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
7608           else
7609             {
7610               emit_move_insn (sa_reg, sa_bias_rtx);
7611               emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
7612             }
7613         }
7614
7615       /* Save regs in stack order.  Beginning with VMS PV.  */
7616       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7617         emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
7618
7619       /* Save register RA next.  */
7620       if (imask & (1UL << REG_RA))
7621         {
7622           emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
7623           imask &= ~(1UL << REG_RA);
7624           reg_offset += 8;
7625         }
7626
7627       /* Now save any other registers required to be saved.  */
7628       for (i = 0; i < 31; i++)
7629         if (imask & (1UL << i))
7630           {
7631             emit_frame_store (i, sa_reg, sa_bias, reg_offset);
7632             reg_offset += 8;
7633           }
7634
7635       for (i = 0; i < 31; i++)
7636         if (fmask & (1UL << i))
7637           {
7638             emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
7639             reg_offset += 8;
7640           }
7641     }
7642   else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7643     {
7644       /* The standard frame on the T3E includes space for saving registers.
7645          We just have to use it. We don't have to save the return address and
7646          the old frame pointer here - they are saved in the DSIB.  */
7647
7648       reg_offset = -56;
7649       for (i = 9; i < 15; i++)
7650         if (imask & (1UL << i))
7651           {
7652             emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
7653             reg_offset -= 8;
7654           }
7655       for (i = 2; i < 10; i++)
7656         if (fmask & (1UL << i))
7657           {
7658             emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
7659             reg_offset -= 8;
7660           }
7661     }
7662
7663   if (TARGET_ABI_OPEN_VMS)
7664     {
7665       if (alpha_procedure_type == PT_REGISTER)
7666         /* Register frame procedures save the fp.
7667            ?? Ought to have a dwarf2 save for this.  */
7668         emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
7669                         hard_frame_pointer_rtx);
7670
7671       if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
7672         emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
7673                                     gen_rtx_REG (DImode, REG_PV)));
7674
7675       if (alpha_procedure_type != PT_NULL
7676           && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
7677         FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7678
7679       /* If we have to allocate space for outgoing args, do it now.  */
7680       if (crtl->outgoing_args_size != 0)
7681         {
7682           rtx seq
7683             = emit_move_insn (stack_pointer_rtx,
7684                               plus_constant
7685                               (hard_frame_pointer_rtx,
7686                                - (ALPHA_ROUND
7687                                   (crtl->outgoing_args_size))));
7688
7689           /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
7690              if ! frame_pointer_needed. Setting the bit will change the CFA
7691              computation rule to use sp again, which would be wrong if we had
7692              frame_pointer_needed, as this means sp might move unpredictably
7693              later on.
7694
7695              Also, note that
7696                frame_pointer_needed
7697                => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
7698              and
7699                crtl->outgoing_args_size != 0
7700                => alpha_procedure_type != PT_NULL,
7701
7702              so when we are not setting the bit here, we are guaranteed to
7703              have emitted an FRP frame pointer update just before.  */
7704           RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
7705         }
7706     }
7707   else if (!TARGET_ABI_UNICOSMK)
7708     {
7709       /* If we need a frame pointer, set it from the stack pointer.  */
7710       if (frame_pointer_needed)
7711         {
7712           if (TARGET_CAN_FAULT_IN_PROLOGUE)
7713             FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
7714           else
7715             /* This must always be the last instruction in the
7716                prologue, thus we emit a special move + clobber.  */
7717               FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
7718                                            stack_pointer_rtx, sa_reg)));
7719         }
7720     }
7721
7722   /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
7723      the prologue, for exception handling reasons, we cannot do this for
7724      any insn that might fault.  We could prevent this for mems with a
7725      (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
7726      have to prevent all such scheduling with a blockage.
7727
7728      Linux, on the other hand, never bothered to implement OSF/1's
7729      exception handling, and so doesn't care about such things.  Anyone
7730      planning to use dwarf2 frame-unwind info can also omit the blockage.  */
7731
7732   if (! TARGET_CAN_FAULT_IN_PROLOGUE)
7733     emit_insn (gen_blockage ());
7734 }
7735
7736 /* Count the number of .file directives, so that .loc is up to date.  */
7737 int num_source_filenames = 0;
7738
7739 /* Output the textual info surrounding the prologue.  */
7740
7741 void
7742 alpha_start_function (FILE *file, const char *fnname,
7743                       tree decl ATTRIBUTE_UNUSED)
7744 {
7745   unsigned long imask = 0;
7746   unsigned long fmask = 0;
7747   /* Stack space needed for pushing registers clobbered by us.  */
7748   HOST_WIDE_INT sa_size;
7749   /* Complete stack size needed.  */
7750   unsigned HOST_WIDE_INT frame_size;
7751   /* The maximum debuggable frame size (512 Kbytes using Tru64 as).  */
7752   unsigned HOST_WIDE_INT max_frame_size = TARGET_ABI_OSF && !TARGET_GAS
7753                                           ? 524288
7754                                           : 1UL << 31;
7755   /* Offset from base reg to register save area.  */
7756   HOST_WIDE_INT reg_offset;
7757   char *entry_label = (char *) alloca (strlen (fnname) + 6);
7758   int i;
7759
7760   /* Don't emit an extern directive for functions defined in the same file.  */
7761   if (TARGET_ABI_UNICOSMK)
7762     {
7763       tree name_tree;
7764       name_tree = get_identifier (fnname);
7765       TREE_ASM_WRITTEN (name_tree) = 1;
7766     }
7767
7768   alpha_fnname = fnname;
7769   sa_size = alpha_sa_size ();
7770
7771   frame_size = get_frame_size ();
7772   if (TARGET_ABI_OPEN_VMS)
7773     frame_size = ALPHA_ROUND (sa_size
7774                               + (alpha_procedure_type == PT_STACK ? 8 : 0)
7775                               + frame_size
7776                               + crtl->args.pretend_args_size);
7777   else if (TARGET_ABI_UNICOSMK)
7778     frame_size = ALPHA_ROUND (sa_size
7779                               + (alpha_procedure_type == PT_STACK ? 48 : 0))
7780                  + ALPHA_ROUND (frame_size
7781                               + crtl->outgoing_args_size);
7782   else
7783     frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7784                   + sa_size
7785                   + ALPHA_ROUND (frame_size
7786                                  + crtl->args.pretend_args_size));
7787
7788   if (TARGET_ABI_OPEN_VMS)
7789     reg_offset = 8;
7790   else
7791     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7792
7793   alpha_sa_mask (&imask, &fmask);
7794
7795   /* Ecoff can handle multiple .file directives, so put out file and lineno.
7796      We have to do that before the .ent directive as we cannot switch
7797      files within procedures with native ecoff because line numbers are
7798      linked to procedure descriptors.
7799      Outputting the lineno helps debugging of one line functions as they
7800      would otherwise get no line number at all. Please note that we would
7801      like to put out last_linenum from final.c, but it is not accessible.  */
7802
7803   if (write_symbols == SDB_DEBUG)
7804     {
7805 #ifdef ASM_OUTPUT_SOURCE_FILENAME
7806       ASM_OUTPUT_SOURCE_FILENAME (file,
7807                                   DECL_SOURCE_FILE (current_function_decl));
7808 #endif
7809 #ifdef SDB_OUTPUT_SOURCE_LINE
7810       if (debug_info_level != DINFO_LEVEL_TERSE)
7811         SDB_OUTPUT_SOURCE_LINE (file,
7812                                 DECL_SOURCE_LINE (current_function_decl));
7813 #endif
7814     }
7815
7816   /* Issue function start and label.  */
7817   if (TARGET_ABI_OPEN_VMS
7818       || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
7819     {
7820       fputs ("\t.ent ", file);
7821       assemble_name (file, fnname);
7822       putc ('\n', file);
7823
7824       /* If the function needs GP, we'll write the "..ng" label there.
7825          Otherwise, do it here.  */
7826       if (TARGET_ABI_OSF
7827           && ! alpha_function_needs_gp
7828           && ! current_function_is_thunk)
7829         {
7830           putc ('$', file);
7831           assemble_name (file, fnname);
7832           fputs ("..ng:\n", file);
7833         }
7834     }
7835
7836   strcpy (entry_label, fnname);
7837   if (TARGET_ABI_OPEN_VMS)
7838     strcat (entry_label, "..en");
7839
7840   /* For public functions, the label must be globalized by appending an
7841      additional colon.  */
7842   if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
7843     strcat (entry_label, ":");
7844
7845   ASM_OUTPUT_LABEL (file, entry_label);
7846   inside_function = TRUE;
7847
7848   if (TARGET_ABI_OPEN_VMS)
7849     fprintf (file, "\t.base $%d\n", vms_base_regno);
7850
7851   if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
7852       && !flag_inhibit_size_directive)
7853     {
7854       /* Set flags in procedure descriptor to request IEEE-conformant
7855          math-library routines.  The value we set it to is PDSC_EXC_IEEE
7856          (/usr/include/pdsc.h).  */
7857       fputs ("\t.eflag 48\n", file);
7858     }
7859
7860   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
7861   alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
7862   alpha_arg_offset = -frame_size + 48;
7863
7864   /* Describe our frame.  If the frame size is larger than an integer,
7865      print it as zero to avoid an assembler error.  We won't be
7866      properly describing such a frame, but that's the best we can do.  */
7867   if (TARGET_ABI_UNICOSMK)
7868     ;
7869   else if (TARGET_ABI_OPEN_VMS)
7870     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
7871              HOST_WIDE_INT_PRINT_DEC "\n",
7872              vms_unwind_regno,
7873              frame_size >= (1UL << 31) ? 0 : frame_size,
7874              reg_offset);
7875   else if (!flag_inhibit_size_directive)
7876     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
7877              (frame_pointer_needed
7878               ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
7879              frame_size >= max_frame_size ? 0 : frame_size,
7880              crtl->args.pretend_args_size);
7881
7882   /* Describe which registers were spilled.  */
7883   if (TARGET_ABI_UNICOSMK)
7884     ;
7885   else if (TARGET_ABI_OPEN_VMS)
7886     {
7887       if (imask)
7888         /* ??? Does VMS care if mask contains ra?  The old code didn't
7889            set it, so I don't here.  */
7890         fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
7891       if (fmask)
7892         fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
7893       if (alpha_procedure_type == PT_REGISTER)
7894         fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
7895     }
7896   else if (!flag_inhibit_size_directive)
7897     {
7898       if (imask)
7899         {
7900           fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
7901                    frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7902
7903           for (i = 0; i < 32; ++i)
7904             if (imask & (1UL << i))
7905               reg_offset += 8;
7906         }
7907
7908       if (fmask)
7909         fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
7910                  frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
7911     }
7912
7913 #if TARGET_ABI_OPEN_VMS
7914   /* Ifdef'ed cause link_section are only available then.  */
7915   switch_to_section (readonly_data_section);
7916   fprintf (file, "\t.align 3\n");
7917   assemble_name (file, fnname); fputs ("..na:\n", file);
7918   fputs ("\t.ascii \"", file);
7919   assemble_name (file, fnname);
7920   fputs ("\\0\"\n", file);
7921   alpha_need_linkage (fnname, 1);
7922   switch_to_section (text_section);
7923 #endif
7924 }
7925
7926 /* Emit the .prologue note at the scheduled end of the prologue.  */
7927
7928 static void
7929 alpha_output_function_end_prologue (FILE *file)
7930 {
7931   if (TARGET_ABI_UNICOSMK)
7932     ;
7933   else if (TARGET_ABI_OPEN_VMS)
7934     fputs ("\t.prologue\n", file);
7935   else if (TARGET_ABI_WINDOWS_NT)
7936     fputs ("\t.prologue 0\n", file);
7937   else if (!flag_inhibit_size_directive)
7938     fprintf (file, "\t.prologue %d\n",
7939              alpha_function_needs_gp || current_function_is_thunk);
7940 }
7941
7942 /* Write function epilogue.  */
7943
7944 /* ??? At some point we will want to support full unwind, and so will
7945    need to mark the epilogue as well.  At the moment, we just confuse
7946    dwarf2out.  */
7947 #undef FRP
7948 #define FRP(exp) exp
7949
7950 void
7951 alpha_expand_epilogue (void)
7952 {
7953   /* Registers to save.  */
7954   unsigned long imask = 0;
7955   unsigned long fmask = 0;
7956   /* Stack space needed for pushing registers clobbered by us.  */
7957   HOST_WIDE_INT sa_size;
7958   /* Complete stack size needed.  */
7959   HOST_WIDE_INT frame_size;
7960   /* Offset from base reg to register save area.  */
7961   HOST_WIDE_INT reg_offset;
7962   int fp_is_frame_pointer, fp_offset;
7963   rtx sa_reg, sa_reg_exp = NULL;
7964   rtx sp_adj1, sp_adj2, mem;
7965   rtx eh_ofs;
7966   int i;
7967
7968   sa_size = alpha_sa_size ();
7969
7970   frame_size = get_frame_size ();
7971   if (TARGET_ABI_OPEN_VMS)
7972     frame_size = ALPHA_ROUND (sa_size
7973                               + (alpha_procedure_type == PT_STACK ? 8 : 0)
7974                               + frame_size
7975                               + crtl->args.pretend_args_size);
7976   else if (TARGET_ABI_UNICOSMK)
7977     frame_size = ALPHA_ROUND (sa_size
7978                               + (alpha_procedure_type == PT_STACK ? 48 : 0))
7979                  + ALPHA_ROUND (frame_size
7980                               + crtl->outgoing_args_size);
7981   else
7982     frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7983                   + sa_size
7984                   + ALPHA_ROUND (frame_size
7985                                  + crtl->args.pretend_args_size));
7986
7987   if (TARGET_ABI_OPEN_VMS)
7988     {
7989        if (alpha_procedure_type == PT_STACK)
7990           reg_offset = 8;
7991        else
7992           reg_offset = 0;
7993     }
7994   else
7995     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7996
7997   alpha_sa_mask (&imask, &fmask);
7998
7999   fp_is_frame_pointer
8000     = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
8001        || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
8002   fp_offset = 0;
8003   sa_reg = stack_pointer_rtx;
8004
8005   if (current_function_calls_eh_return)
8006     eh_ofs = EH_RETURN_STACKADJ_RTX;
8007   else
8008     eh_ofs = NULL_RTX;
8009
8010   if (!TARGET_ABI_UNICOSMK && sa_size)
8011     {
8012       /* If we have a frame pointer, restore SP from it.  */
8013       if ((TARGET_ABI_OPEN_VMS
8014            && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
8015           || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
8016         FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
8017
8018       /* Cope with very large offsets to the register save area.  */
8019       if (reg_offset + sa_size > 0x8000)
8020         {
8021           int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
8022           HOST_WIDE_INT bias;
8023
8024           if (low + sa_size <= 0x8000)
8025             bias = reg_offset - low, reg_offset = low;
8026           else
8027             bias = reg_offset, reg_offset = 0;
8028
8029           sa_reg = gen_rtx_REG (DImode, 22);
8030           sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
8031
8032           FRP (emit_move_insn (sa_reg, sa_reg_exp));
8033         }
8034
8035       /* Restore registers in order, excepting a true frame pointer.  */
8036
8037       mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
8038       if (! eh_ofs)
8039         set_mem_alias_set (mem, alpha_sr_alias_set);
8040       FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
8041
8042       reg_offset += 8;
8043       imask &= ~(1UL << REG_RA);
8044
8045       for (i = 0; i < 31; ++i)
8046         if (imask & (1UL << i))
8047           {
8048             if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
8049               fp_offset = reg_offset;
8050             else
8051               {
8052                 mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
8053                 set_mem_alias_set (mem, alpha_sr_alias_set);
8054                 FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
8055               }
8056             reg_offset += 8;
8057           }
8058
8059       for (i = 0; i < 31; ++i)
8060         if (fmask & (1UL << i))
8061           {
8062             mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
8063             set_mem_alias_set (mem, alpha_sr_alias_set);
8064             FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
8065             reg_offset += 8;
8066           }
8067     }
8068   else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
8069     {
8070       /* Restore callee-saved general-purpose registers.  */
8071
8072       reg_offset = -56;
8073
8074       for (i = 9; i < 15; i++)
8075         if (imask & (1UL << i))
8076           {
8077             mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
8078                                                      reg_offset));
8079             set_mem_alias_set (mem, alpha_sr_alias_set);
8080             FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
8081             reg_offset -= 8;
8082           }
8083
8084       for (i = 2; i < 10; i++)
8085         if (fmask & (1UL << i))
8086           {
8087             mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
8088                                                      reg_offset));
8089             set_mem_alias_set (mem, alpha_sr_alias_set);
8090             FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
8091             reg_offset -= 8;
8092           }
8093
8094       /* Restore the return address from the DSIB.  */
8095
8096       mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
8097       set_mem_alias_set (mem, alpha_sr_alias_set);
8098       FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
8099     }
8100
8101   if (frame_size || eh_ofs)
8102     {
8103       sp_adj1 = stack_pointer_rtx;
8104
8105       if (eh_ofs)
8106         {
8107           sp_adj1 = gen_rtx_REG (DImode, 23);
8108           emit_move_insn (sp_adj1,
8109                           gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
8110         }
8111
8112       /* If the stack size is large, begin computation into a temporary
8113          register so as not to interfere with a potential fp restore,
8114          which must be consecutive with an SP restore.  */
8115       if (frame_size < 32768
8116           && ! (TARGET_ABI_UNICOSMK && current_function_calls_alloca))
8117         sp_adj2 = GEN_INT (frame_size);
8118       else if (TARGET_ABI_UNICOSMK)
8119         {
8120           sp_adj1 = gen_rtx_REG (DImode, 23);
8121           FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
8122           sp_adj2 = const0_rtx;
8123         }
8124       else if (frame_size < 0x40007fffL)
8125         {
8126           int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
8127
8128           sp_adj2 = plus_constant (sp_adj1, frame_size - low);
8129           if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
8130             sp_adj1 = sa_reg;
8131           else
8132             {
8133               sp_adj1 = gen_rtx_REG (DImode, 23);
8134               FRP (emit_move_insn (sp_adj1, sp_adj2));
8135             }
8136           sp_adj2 = GEN_INT (low);
8137         }
8138       else
8139         {
8140           rtx tmp = gen_rtx_REG (DImode, 23);
8141           FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size,
8142                                                3, false));
8143           if (!sp_adj2)
8144             {
8145               /* We can't drop new things to memory this late, afaik,
8146                  so build it up by pieces.  */
8147               FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
8148                                                         -(frame_size < 0)));
8149               gcc_assert (sp_adj2);
8150             }
8151         }
8152
8153       /* From now on, things must be in order.  So emit blockages.  */
8154
8155       /* Restore the frame pointer.  */
8156       if (TARGET_ABI_UNICOSMK)
8157         {
8158           emit_insn (gen_blockage ());
8159           mem = gen_rtx_MEM (DImode,
8160                              plus_constant (hard_frame_pointer_rtx, -16));
8161           set_mem_alias_set (mem, alpha_sr_alias_set);
8162           FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
8163         }
8164       else if (fp_is_frame_pointer)
8165         {
8166           emit_insn (gen_blockage ());
8167           mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
8168           set_mem_alias_set (mem, alpha_sr_alias_set);
8169           FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
8170         }
8171       else if (TARGET_ABI_OPEN_VMS)
8172         {
8173           emit_insn (gen_blockage ());
8174           FRP (emit_move_insn (hard_frame_pointer_rtx,
8175                                gen_rtx_REG (DImode, vms_save_fp_regno)));
8176         }
8177
8178       /* Restore the stack pointer.  */
8179       emit_insn (gen_blockage ());
8180       if (sp_adj2 == const0_rtx)
8181         FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
8182       else
8183         FRP (emit_move_insn (stack_pointer_rtx,
8184                              gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
8185     }
8186   else
8187     {
8188       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
8189         {
8190           emit_insn (gen_blockage ());
8191           FRP (emit_move_insn (hard_frame_pointer_rtx,
8192                                gen_rtx_REG (DImode, vms_save_fp_regno)));
8193         }
8194       else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
8195         {
8196           /* Decrement the frame pointer if the function does not have a
8197              frame.  */
8198
8199           emit_insn (gen_blockage ());
8200           FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8201                                       hard_frame_pointer_rtx, constm1_rtx)));
8202         }
8203     }
8204 }
8205 \f
8206 /* Output the rest of the textual info surrounding the epilogue.  */
8207
8208 void
8209 alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
8210 {
8211   rtx insn;
8212
8213   /* We output a nop after noreturn calls at the very end of the function to
8214      ensure that the return address always remains in the caller's code range,
8215      as not doing so might confuse unwinding engines.  */
8216   insn = get_last_insn ();
8217   if (!INSN_P (insn))
8218     insn = prev_active_insn (insn);
8219   if (GET_CODE (insn) == CALL_INSN)
8220     output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
8221
8222 #if TARGET_ABI_OPEN_VMS
8223   alpha_write_linkage (file, fnname, decl);
8224 #endif
8225
8226   /* End the function.  */
8227   if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
8228     {
8229       fputs ("\t.end ", file);
8230       assemble_name (file, fnname);
8231       putc ('\n', file);
8232     }
8233   inside_function = FALSE;
8234
8235   /* Output jump tables and the static subroutine information block.  */
8236   if (TARGET_ABI_UNICOSMK)
8237     {
8238       unicosmk_output_ssib (file, fnname);
8239       unicosmk_output_deferred_case_vectors (file);
8240     }
8241 }
8242
8243 #if TARGET_ABI_OSF
8244 /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8245
8246    In order to avoid the hordes of differences between generated code
8247    with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8248    lots of code loading up large constants, generate rtl and emit it
8249    instead of going straight to text.
8250
8251    Not sure why this idea hasn't been explored before...  */
8252
8253 static void
8254 alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
8255                            HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8256                            tree function)
8257 {
8258   HOST_WIDE_INT hi, lo;
8259   rtx this, insn, funexp;
8260
8261   /* We always require a valid GP.  */
8262   emit_insn (gen_prologue_ldgp ());
8263   emit_note (NOTE_INSN_PROLOGUE_END);
8264
8265   /* Find the "this" pointer.  If the function returns a structure,
8266      the structure return pointer is in $16.  */
8267   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8268     this = gen_rtx_REG (Pmode, 17);
8269   else
8270     this = gen_rtx_REG (Pmode, 16);
8271
8272   /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
8273      entire constant for the add.  */
8274   lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
8275   hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8276   if (hi + lo == delta)
8277     {
8278       if (hi)
8279         emit_insn (gen_adddi3 (this, this, GEN_INT (hi)));
8280       if (lo)
8281         emit_insn (gen_adddi3 (this, this, GEN_INT (lo)));
8282     }
8283   else
8284     {
8285       rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
8286                                            delta, -(delta < 0));
8287       emit_insn (gen_adddi3 (this, this, tmp));
8288     }
8289
8290   /* Add a delta stored in the vtable at VCALL_OFFSET.  */
8291   if (vcall_offset)
8292     {
8293       rtx tmp, tmp2;
8294
8295       tmp = gen_rtx_REG (Pmode, 0);
8296       emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
8297
8298       lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
8299       hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8300       if (hi + lo == vcall_offset)
8301         {
8302           if (hi)
8303             emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
8304         }
8305       else
8306         {
8307           tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
8308                                             vcall_offset, -(vcall_offset < 0));
8309           emit_insn (gen_adddi3 (tmp, tmp, tmp2));
8310           lo = 0;
8311         }
8312       if (lo)
8313         tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
8314       else
8315         tmp2 = tmp;
8316       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
8317
8318       emit_insn (gen_adddi3 (this, this, tmp));
8319     }
8320
8321   /* Generate a tail call to the target function.  */
8322   if (! TREE_USED (function))
8323     {
8324       assemble_external (function);
8325       TREE_USED (function) = 1;
8326     }
8327   funexp = XEXP (DECL_RTL (function), 0);
8328   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
8329   insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
8330   SIBLING_CALL_P (insn) = 1;
8331
8332   /* Run just enough of rest_of_compilation to get the insns emitted.
8333      There's not really enough bulk here to make other passes such as
8334      instruction scheduling worth while.  Note that use_thunk calls
8335      assemble_start_function and assemble_end_function.  */
8336   insn = get_insns ();
8337   insn_locators_alloc ();
8338   shorten_branches (insn);
8339   final_start_function (insn, file, 1);
8340   final (insn, file, 1);
8341   final_end_function ();
8342   free_after_compilation (cfun);
8343 }
8344 #endif /* TARGET_ABI_OSF */
8345 \f
8346 /* Debugging support.  */
8347
8348 #include "gstab.h"
8349
8350 /* Count the number of sdb related labels are generated (to find block
8351    start and end boundaries).  */
8352
8353 int sdb_label_count = 0;
8354
8355 /* Name of the file containing the current function.  */
8356
8357 static const char *current_function_file = "";
8358
8359 /* Offsets to alpha virtual arg/local debugging pointers.  */
8360
8361 long alpha_arg_offset;
8362 long alpha_auto_offset;
8363 \f
8364 /* Emit a new filename to a stream.  */
8365
8366 void
8367 alpha_output_filename (FILE *stream, const char *name)
8368 {
8369   static int first_time = TRUE;
8370
8371   if (first_time)
8372     {
8373       first_time = FALSE;
8374       ++num_source_filenames;
8375       current_function_file = name;
8376       fprintf (stream, "\t.file\t%d ", num_source_filenames);
8377       output_quoted_string (stream, name);
8378       fprintf (stream, "\n");
8379       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
8380         fprintf (stream, "\t#@stabs\n");
8381     }
8382
8383   else if (write_symbols == DBX_DEBUG)
8384     /* dbxout.c will emit an appropriate .stabs directive.  */
8385     return;
8386
8387   else if (name != current_function_file
8388            && strcmp (name, current_function_file) != 0)
8389     {
8390       if (inside_function && ! TARGET_GAS)
8391         fprintf (stream, "\t#.file\t%d ", num_source_filenames);
8392       else
8393         {
8394           ++num_source_filenames;
8395           current_function_file = name;
8396           fprintf (stream, "\t.file\t%d ", num_source_filenames);
8397         }
8398
8399       output_quoted_string (stream, name);
8400       fprintf (stream, "\n");
8401     }
8402 }
8403 \f
8404 /* Structure to show the current status of registers and memory.  */
8405
8406 struct shadow_summary
8407 {
8408   struct {
8409     unsigned int i     : 31;    /* Mask of int regs */
8410     unsigned int fp    : 31;    /* Mask of fp regs */
8411     unsigned int mem   :  1;    /* mem == imem | fpmem */
8412   } used, defd;
8413 };
8414
8415 /* Summary the effects of expression X on the machine.  Update SUM, a pointer
8416    to the summary structure.  SET is nonzero if the insn is setting the
8417    object, otherwise zero.  */
8418
8419 static void
8420 summarize_insn (rtx x, struct shadow_summary *sum, int set)
8421 {
8422   const char *format_ptr;
8423   int i, j;
8424
8425   if (x == 0)
8426     return;
8427
8428   switch (GET_CODE (x))
8429     {
8430       /* ??? Note that this case would be incorrect if the Alpha had a
8431          ZERO_EXTRACT in SET_DEST.  */
8432     case SET:
8433       summarize_insn (SET_SRC (x), sum, 0);
8434       summarize_insn (SET_DEST (x), sum, 1);
8435       break;
8436
8437     case CLOBBER:
8438       summarize_insn (XEXP (x, 0), sum, 1);
8439       break;
8440
8441     case USE:
8442       summarize_insn (XEXP (x, 0), sum, 0);
8443       break;
8444
8445     case ASM_OPERANDS:
8446       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8447         summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8448       break;
8449
8450     case PARALLEL:
8451       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8452         summarize_insn (XVECEXP (x, 0, i), sum, 0);
8453       break;
8454
8455     case SUBREG:
8456       summarize_insn (SUBREG_REG (x), sum, 0);
8457       break;
8458
8459     case REG:
8460       {
8461         int regno = REGNO (x);
8462         unsigned long mask = ((unsigned long) 1) << (regno % 32);
8463
8464         if (regno == 31 || regno == 63)
8465           break;
8466
8467         if (set)
8468           {
8469             if (regno < 32)
8470               sum->defd.i |= mask;
8471             else
8472               sum->defd.fp |= mask;
8473           }
8474         else
8475           {
8476             if (regno < 32)
8477               sum->used.i  |= mask;
8478             else
8479               sum->used.fp |= mask;
8480           }
8481         }
8482       break;
8483
8484     case MEM:
8485       if (set)
8486         sum->defd.mem = 1;
8487       else
8488         sum->used.mem = 1;
8489
8490       /* Find the regs used in memory address computation: */
8491       summarize_insn (XEXP (x, 0), sum, 0);
8492       break;
8493
8494     case CONST_INT:   case CONST_DOUBLE:
8495     case SYMBOL_REF:  case LABEL_REF:     case CONST:
8496     case SCRATCH:     case ASM_INPUT:
8497       break;
8498
8499       /* Handle common unary and binary ops for efficiency.  */
8500     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
8501     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
8502     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
8503     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
8504     case NE:       case EQ:      case GE:      case GT:        case LE:
8505     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
8506       summarize_insn (XEXP (x, 0), sum, 0);
8507       summarize_insn (XEXP (x, 1), sum, 0);
8508       break;
8509
8510     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
8511     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
8512     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
8513     case SQRT:  case FFS:
8514       summarize_insn (XEXP (x, 0), sum, 0);
8515       break;
8516
8517     default:
8518       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8519       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8520         switch (format_ptr[i])
8521           {
8522           case 'e':
8523             summarize_insn (XEXP (x, i), sum, 0);
8524             break;
8525
8526           case 'E':
8527             for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8528               summarize_insn (XVECEXP (x, i, j), sum, 0);
8529             break;
8530
8531           case 'i':
8532             break;
8533
8534           default:
8535             gcc_unreachable ();
8536           }
8537     }
8538 }
8539
8540 /* Ensure a sufficient number of `trapb' insns are in the code when
8541    the user requests code with a trap precision of functions or
8542    instructions.
8543
8544    In naive mode, when the user requests a trap-precision of
8545    "instruction", a trapb is needed after every instruction that may
8546    generate a trap.  This ensures that the code is resumption safe but
8547    it is also slow.
8548
8549    When optimizations are turned on, we delay issuing a trapb as long
8550    as possible.  In this context, a trap shadow is the sequence of
8551    instructions that starts with a (potentially) trap generating
8552    instruction and extends to the next trapb or call_pal instruction
8553    (but GCC never generates call_pal by itself).  We can delay (and
8554    therefore sometimes omit) a trapb subject to the following
8555    conditions:
8556
8557    (a) On entry to the trap shadow, if any Alpha register or memory
8558    location contains a value that is used as an operand value by some
8559    instruction in the trap shadow (live on entry), then no instruction
8560    in the trap shadow may modify the register or memory location.
8561
8562    (b) Within the trap shadow, the computation of the base register
8563    for a memory load or store instruction may not involve using the
8564    result of an instruction that might generate an UNPREDICTABLE
8565    result.
8566
8567    (c) Within the trap shadow, no register may be used more than once
8568    as a destination register.  (This is to make life easier for the
8569    trap-handler.)
8570
8571    (d) The trap shadow may not include any branch instructions.  */
8572
8573 static void
8574 alpha_handle_trap_shadows (void)
8575 {
8576   struct shadow_summary shadow;
8577   int trap_pending, exception_nesting;
8578   rtx i, n;
8579
8580   trap_pending = 0;
8581   exception_nesting = 0;
8582   shadow.used.i = 0;
8583   shadow.used.fp = 0;
8584   shadow.used.mem = 0;
8585   shadow.defd = shadow.used;
8586
8587   for (i = get_insns (); i ; i = NEXT_INSN (i))
8588     {
8589       if (GET_CODE (i) == NOTE)
8590         {
8591           switch (NOTE_KIND (i))
8592             {
8593             case NOTE_INSN_EH_REGION_BEG:
8594               exception_nesting++;
8595               if (trap_pending)
8596                 goto close_shadow;
8597               break;
8598
8599             case NOTE_INSN_EH_REGION_END:
8600               exception_nesting--;
8601               if (trap_pending)
8602                 goto close_shadow;
8603               break;
8604
8605             case NOTE_INSN_EPILOGUE_BEG:
8606               if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
8607                 goto close_shadow;
8608               break;
8609             }
8610         }
8611       else if (trap_pending)
8612         {
8613           if (alpha_tp == ALPHA_TP_FUNC)
8614             {
8615               if (GET_CODE (i) == JUMP_INSN
8616                   && GET_CODE (PATTERN (i)) == RETURN)
8617                 goto close_shadow;
8618             }
8619           else if (alpha_tp == ALPHA_TP_INSN)
8620             {
8621               if (optimize > 0)
8622                 {
8623                   struct shadow_summary sum;
8624
8625                   sum.used.i = 0;
8626                   sum.used.fp = 0;
8627                   sum.used.mem = 0;
8628                   sum.defd = sum.used;
8629
8630                   switch (GET_CODE (i))
8631                     {
8632                     case INSN:
8633                       /* Annoyingly, get_attr_trap will die on these.  */
8634                       if (GET_CODE (PATTERN (i)) == USE
8635                           || GET_CODE (PATTERN (i)) == CLOBBER)
8636                         break;
8637
8638                       summarize_insn (PATTERN (i), &sum, 0);
8639
8640                       if ((sum.defd.i & shadow.defd.i)
8641                           || (sum.defd.fp & shadow.defd.fp))
8642                         {
8643                           /* (c) would be violated */
8644                           goto close_shadow;
8645                         }
8646
8647                       /* Combine shadow with summary of current insn: */
8648                       shadow.used.i   |= sum.used.i;
8649                       shadow.used.fp  |= sum.used.fp;
8650                       shadow.used.mem |= sum.used.mem;
8651                       shadow.defd.i   |= sum.defd.i;
8652                       shadow.defd.fp  |= sum.defd.fp;
8653                       shadow.defd.mem |= sum.defd.mem;
8654
8655                       if ((sum.defd.i & shadow.used.i)
8656                           || (sum.defd.fp & shadow.used.fp)
8657                           || (sum.defd.mem & shadow.used.mem))
8658                         {
8659                           /* (a) would be violated (also takes care of (b))  */
8660                           gcc_assert (get_attr_trap (i) != TRAP_YES
8661                                       || (!(sum.defd.i & sum.used.i)
8662                                           && !(sum.defd.fp & sum.used.fp)));
8663
8664                           goto close_shadow;
8665                         }
8666                       break;
8667
8668                     case JUMP_INSN:
8669                     case CALL_INSN:
8670                     case CODE_LABEL:
8671                       goto close_shadow;
8672
8673                     default:
8674                       gcc_unreachable ();
8675                     }
8676                 }
8677               else
8678                 {
8679                 close_shadow:
8680                   n = emit_insn_before (gen_trapb (), i);
8681                   PUT_MODE (n, TImode);
8682                   PUT_MODE (i, TImode);
8683                   trap_pending = 0;
8684                   shadow.used.i = 0;
8685                   shadow.used.fp = 0;
8686                   shadow.used.mem = 0;
8687                   shadow.defd = shadow.used;
8688                 }
8689             }
8690         }
8691
8692       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
8693           && GET_CODE (i) == INSN
8694           && GET_CODE (PATTERN (i)) != USE
8695           && GET_CODE (PATTERN (i)) != CLOBBER
8696           && get_attr_trap (i) == TRAP_YES)
8697         {
8698           if (optimize && !trap_pending)
8699             summarize_insn (PATTERN (i), &shadow, 0);
8700           trap_pending = 1;
8701         }
8702     }
8703 }
8704 \f
8705 /* Alpha can only issue instruction groups simultaneously if they are
8706    suitably aligned.  This is very processor-specific.  */
8707 /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
8708    that are marked "fake".  These instructions do not exist on that target,
8709    but it is possible to see these insns with deranged combinations of 
8710    command-line options, such as "-mtune=ev4 -mmax".  Instead of aborting,
8711    choose a result at random.  */
8712
8713 enum alphaev4_pipe {
8714   EV4_STOP = 0,
8715   EV4_IB0 = 1,
8716   EV4_IB1 = 2,
8717   EV4_IBX = 4
8718 };
8719
8720 enum alphaev5_pipe {
8721   EV5_STOP = 0,
8722   EV5_NONE = 1,
8723   EV5_E01 = 2,
8724   EV5_E0 = 4,
8725   EV5_E1 = 8,
8726   EV5_FAM = 16,
8727   EV5_FA = 32,
8728   EV5_FM = 64
8729 };
8730
8731 static enum alphaev4_pipe
8732 alphaev4_insn_pipe (rtx insn)
8733 {
8734   if (recog_memoized (insn) < 0)
8735     return EV4_STOP;
8736   if (get_attr_length (insn) != 4)
8737     return EV4_STOP;
8738
8739   switch (get_attr_type (insn))
8740     {
8741     case TYPE_ILD:
8742     case TYPE_LDSYM:
8743     case TYPE_FLD:
8744     case TYPE_LD_L:
8745       return EV4_IBX;
8746
8747     case TYPE_IADD:
8748     case TYPE_ILOG:
8749     case TYPE_ICMOV:
8750     case TYPE_ICMP:
8751     case TYPE_FST:
8752     case TYPE_SHIFT:
8753     case TYPE_IMUL:
8754     case TYPE_FBR:
8755     case TYPE_MVI:              /* fake */
8756       return EV4_IB0;
8757
8758     case TYPE_IST:
8759     case TYPE_MISC:
8760     case TYPE_IBR:
8761     case TYPE_JSR:
8762     case TYPE_CALLPAL:
8763     case TYPE_FCPYS:
8764     case TYPE_FCMOV:
8765     case TYPE_FADD:
8766     case TYPE_FDIV:
8767     case TYPE_FMUL:
8768     case TYPE_ST_C:
8769     case TYPE_MB:
8770     case TYPE_FSQRT:            /* fake */
8771     case TYPE_FTOI:             /* fake */
8772     case TYPE_ITOF:             /* fake */
8773       return EV4_IB1;
8774
8775     default:
8776       gcc_unreachable ();
8777     }
8778 }
8779
8780 static enum alphaev5_pipe
8781 alphaev5_insn_pipe (rtx insn)
8782 {
8783   if (recog_memoized (insn) < 0)
8784     return EV5_STOP;
8785   if (get_attr_length (insn) != 4)
8786     return EV5_STOP;
8787
8788   switch (get_attr_type (insn))
8789     {
8790     case TYPE_ILD:
8791     case TYPE_FLD:
8792     case TYPE_LDSYM:
8793     case TYPE_IADD:
8794     case TYPE_ILOG:
8795     case TYPE_ICMOV:
8796     case TYPE_ICMP:
8797       return EV5_E01;
8798
8799     case TYPE_IST:
8800     case TYPE_FST:
8801     case TYPE_SHIFT:
8802     case TYPE_IMUL:
8803     case TYPE_MISC:
8804     case TYPE_MVI:
8805     case TYPE_LD_L:
8806     case TYPE_ST_C:
8807     case TYPE_MB:
8808     case TYPE_FTOI:             /* fake */
8809     case TYPE_ITOF:             /* fake */
8810       return EV5_E0;
8811
8812     case TYPE_IBR:
8813     case TYPE_JSR:
8814     case TYPE_CALLPAL:
8815       return EV5_E1;
8816
8817     case TYPE_FCPYS:
8818       return EV5_FAM;
8819
8820     case TYPE_FBR:
8821     case TYPE_FCMOV:
8822     case TYPE_FADD:
8823     case TYPE_FDIV:
8824     case TYPE_FSQRT:            /* fake */
8825       return EV5_FA;
8826
8827     case TYPE_FMUL:
8828       return EV5_FM;
8829
8830     default:
8831       gcc_unreachable ();
8832     }
8833 }
8834
8835 /* IN_USE is a mask of the slots currently filled within the insn group.
8836    The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
8837    the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
8838
8839    LEN is, of course, the length of the group in bytes.  */
8840
8841 static rtx
8842 alphaev4_next_group (rtx insn, int *pin_use, int *plen)
8843 {
8844   int len, in_use;
8845
8846   len = in_use = 0;
8847
8848   if (! INSN_P (insn)
8849       || GET_CODE (PATTERN (insn)) == CLOBBER
8850       || GET_CODE (PATTERN (insn)) == USE)
8851     goto next_and_done;
8852
8853   while (1)
8854     {
8855       enum alphaev4_pipe pipe;
8856
8857       pipe = alphaev4_insn_pipe (insn);
8858       switch (pipe)
8859         {
8860         case EV4_STOP:
8861           /* Force complex instructions to start new groups.  */
8862           if (in_use)
8863             goto done;
8864
8865           /* If this is a completely unrecognized insn, it's an asm.
8866              We don't know how long it is, so record length as -1 to
8867              signal a needed realignment.  */
8868           if (recog_memoized (insn) < 0)
8869             len = -1;
8870           else
8871             len = get_attr_length (insn);
8872           goto next_and_done;
8873
8874         case EV4_IBX:
8875           if (in_use & EV4_IB0)
8876             {
8877               if (in_use & EV4_IB1)
8878                 goto done;
8879               in_use |= EV4_IB1;
8880             }
8881           else
8882             in_use |= EV4_IB0 | EV4_IBX;
8883           break;
8884
8885         case EV4_IB0:
8886           if (in_use & EV4_IB0)
8887             {
8888               if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
8889                 goto done;
8890               in_use |= EV4_IB1;
8891             }
8892           in_use |= EV4_IB0;
8893           break;
8894
8895         case EV4_IB1:
8896           if (in_use & EV4_IB1)
8897             goto done;
8898           in_use |= EV4_IB1;
8899           break;
8900
8901         default:
8902           gcc_unreachable ();
8903         }
8904       len += 4;
8905
8906       /* Haifa doesn't do well scheduling branches.  */
8907       if (GET_CODE (insn) == JUMP_INSN)
8908         goto next_and_done;
8909
8910     next:
8911       insn = next_nonnote_insn (insn);
8912
8913       if (!insn || ! INSN_P (insn))
8914         goto done;
8915
8916       /* Let Haifa tell us where it thinks insn group boundaries are.  */
8917       if (GET_MODE (insn) == TImode)
8918         goto done;
8919
8920       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
8921         goto next;
8922     }
8923
8924  next_and_done:
8925   insn = next_nonnote_insn (insn);
8926
8927  done:
8928   *plen = len;
8929   *pin_use = in_use;
8930   return insn;
8931 }
8932
8933 /* IN_USE is a mask of the slots currently filled within the insn group.
8934    The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
8935    the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
8936
8937    LEN is, of course, the length of the group in bytes.  */
8938
8939 static rtx
8940 alphaev5_next_group (rtx insn, int *pin_use, int *plen)
8941 {
8942   int len, in_use;
8943
8944   len = in_use = 0;
8945
8946   if (! INSN_P (insn)
8947       || GET_CODE (PATTERN (insn)) == CLOBBER
8948       || GET_CODE (PATTERN (insn)) == USE)
8949     goto next_and_done;
8950
8951   while (1)
8952     {
8953       enum alphaev5_pipe pipe;
8954
8955       pipe = alphaev5_insn_pipe (insn);
8956       switch (pipe)
8957         {
8958         case EV5_STOP:
8959           /* Force complex instructions to start new groups.  */
8960           if (in_use)
8961             goto done;
8962
8963           /* If this is a completely unrecognized insn, it's an asm.
8964              We don't know how long it is, so record length as -1 to
8965              signal a needed realignment.  */
8966           if (recog_memoized (insn) < 0)
8967             len = -1;
8968           else
8969             len = get_attr_length (insn);
8970           goto next_and_done;
8971
8972         /* ??? Most of the places below, we would like to assert never
8973            happen, as it would indicate an error either in Haifa, or
8974            in the scheduling description.  Unfortunately, Haifa never
8975            schedules the last instruction of the BB, so we don't have
8976            an accurate TI bit to go off.  */
8977         case EV5_E01:
8978           if (in_use & EV5_E0)
8979             {
8980               if (in_use & EV5_E1)
8981                 goto done;
8982               in_use |= EV5_E1;
8983             }
8984           else
8985             in_use |= EV5_E0 | EV5_E01;
8986           break;
8987
8988         case EV5_E0:
8989           if (in_use & EV5_E0)
8990             {
8991               if (!(in_use & EV5_E01) || (in_use & EV5_E1))
8992                 goto done;
8993               in_use |= EV5_E1;
8994             }
8995           in_use |= EV5_E0;
8996           break;
8997
8998         case EV5_E1:
8999           if (in_use & EV5_E1)
9000             goto done;
9001           in_use |= EV5_E1;
9002           break;
9003
9004         case EV5_FAM:
9005           if (in_use & EV5_FA)
9006             {
9007               if (in_use & EV5_FM)
9008                 goto done;
9009               in_use |= EV5_FM;
9010             }
9011           else
9012             in_use |= EV5_FA | EV5_FAM;
9013           break;
9014
9015         case EV5_FA:
9016           if (in_use & EV5_FA)
9017             goto done;
9018           in_use |= EV5_FA;
9019           break;
9020
9021         case EV5_FM:
9022           if (in_use & EV5_FM)
9023             goto done;
9024           in_use |= EV5_FM;
9025           break;
9026
9027         case EV5_NONE:
9028           break;
9029
9030         default:
9031           gcc_unreachable ();
9032         }
9033       len += 4;
9034
9035       /* Haifa doesn't do well scheduling branches.  */
9036       /* ??? If this is predicted not-taken, slotting continues, except
9037          that no more IBR, FBR, or JSR insns may be slotted.  */
9038       if (GET_CODE (insn) == JUMP_INSN)
9039         goto next_and_done;
9040
9041     next:
9042       insn = next_nonnote_insn (insn);
9043
9044       if (!insn || ! INSN_P (insn))
9045         goto done;
9046
9047       /* Let Haifa tell us where it thinks insn group boundaries are.  */
9048       if (GET_MODE (insn) == TImode)
9049         goto done;
9050
9051       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9052         goto next;
9053     }
9054
9055  next_and_done:
9056   insn = next_nonnote_insn (insn);
9057
9058  done:
9059   *plen = len;
9060   *pin_use = in_use;
9061   return insn;
9062 }
9063
9064 static rtx
9065 alphaev4_next_nop (int *pin_use)
9066 {
9067   int in_use = *pin_use;
9068   rtx nop;
9069
9070   if (!(in_use & EV4_IB0))
9071     {
9072       in_use |= EV4_IB0;
9073       nop = gen_nop ();
9074     }
9075   else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
9076     {
9077       in_use |= EV4_IB1;
9078       nop = gen_nop ();
9079     }
9080   else if (TARGET_FP && !(in_use & EV4_IB1))
9081     {
9082       in_use |= EV4_IB1;
9083       nop = gen_fnop ();
9084     }
9085   else
9086     nop = gen_unop ();
9087
9088   *pin_use = in_use;
9089   return nop;
9090 }
9091
9092 static rtx
9093 alphaev5_next_nop (int *pin_use)
9094 {
9095   int in_use = *pin_use;
9096   rtx nop;
9097
9098   if (!(in_use & EV5_E1))
9099     {
9100       in_use |= EV5_E1;
9101       nop = gen_nop ();
9102     }
9103   else if (TARGET_FP && !(in_use & EV5_FA))
9104     {
9105       in_use |= EV5_FA;
9106       nop = gen_fnop ();
9107     }
9108   else if (TARGET_FP && !(in_use & EV5_FM))
9109     {
9110       in_use |= EV5_FM;
9111       nop = gen_fnop ();
9112     }
9113   else
9114     nop = gen_unop ();
9115
9116   *pin_use = in_use;
9117   return nop;
9118 }
9119
9120 /* The instruction group alignment main loop.  */
9121
9122 static void
9123 alpha_align_insns (unsigned int max_align,
9124                    rtx (*next_group) (rtx, int *, int *),
9125                    rtx (*next_nop) (int *))
9126 {
9127   /* ALIGN is the known alignment for the insn group.  */
9128   unsigned int align;
9129   /* OFS is the offset of the current insn in the insn group.  */
9130   int ofs;
9131   int prev_in_use, in_use, len, ldgp;
9132   rtx i, next;
9133
9134   /* Let shorten branches care for assigning alignments to code labels.  */
9135   shorten_branches (get_insns ());
9136
9137   if (align_functions < 4)
9138     align = 4;
9139   else if ((unsigned int) align_functions < max_align)
9140     align = align_functions;
9141   else
9142     align = max_align;
9143
9144   ofs = prev_in_use = 0;
9145   i = get_insns ();
9146   if (GET_CODE (i) == NOTE)
9147     i = next_nonnote_insn (i);
9148
9149   ldgp = alpha_function_needs_gp ? 8 : 0;
9150
9151   while (i)
9152     {
9153       next = (*next_group) (i, &in_use, &len);
9154
9155       /* When we see a label, resync alignment etc.  */
9156       if (GET_CODE (i) == CODE_LABEL)
9157         {
9158           unsigned int new_align = 1 << label_to_alignment (i);
9159
9160           if (new_align >= align)
9161             {
9162               align = new_align < max_align ? new_align : max_align;
9163               ofs = 0;
9164             }
9165
9166           else if (ofs & (new_align-1))
9167             ofs = (ofs | (new_align-1)) + 1;
9168           gcc_assert (!len);
9169         }
9170
9171       /* Handle complex instructions special.  */
9172       else if (in_use == 0)
9173         {
9174           /* Asms will have length < 0.  This is a signal that we have
9175              lost alignment knowledge.  Assume, however, that the asm
9176              will not mis-align instructions.  */
9177           if (len < 0)
9178             {
9179               ofs = 0;
9180               align = 4;
9181               len = 0;
9182             }
9183         }
9184
9185       /* If the known alignment is smaller than the recognized insn group,
9186          realign the output.  */
9187       else if ((int) align < len)
9188         {
9189           unsigned int new_log_align = len > 8 ? 4 : 3;
9190           rtx prev, where;
9191
9192           where = prev = prev_nonnote_insn (i);
9193           if (!where || GET_CODE (where) != CODE_LABEL)
9194             where = i;
9195
9196           /* Can't realign between a call and its gp reload.  */
9197           if (! (TARGET_EXPLICIT_RELOCS
9198                  && prev && GET_CODE (prev) == CALL_INSN))
9199             {
9200               emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
9201               align = 1 << new_log_align;
9202               ofs = 0;
9203             }
9204         }
9205
9206       /* We may not insert padding inside the initial ldgp sequence.  */
9207       else if (ldgp > 0)
9208         ldgp -= len;
9209
9210       /* If the group won't fit in the same INT16 as the previous,
9211          we need to add padding to keep the group together.  Rather
9212          than simply leaving the insn filling to the assembler, we
9213          can make use of the knowledge of what sorts of instructions
9214          were issued in the previous group to make sure that all of
9215          the added nops are really free.  */
9216       else if (ofs + len > (int) align)
9217         {
9218           int nop_count = (align - ofs) / 4;
9219           rtx where;
9220
9221           /* Insert nops before labels, branches, and calls to truly merge
9222              the execution of the nops with the previous instruction group.  */
9223           where = prev_nonnote_insn (i);
9224           if (where)
9225             {
9226               if (GET_CODE (where) == CODE_LABEL)
9227                 {
9228                   rtx where2 = prev_nonnote_insn (where);
9229                   if (where2 && GET_CODE (where2) == JUMP_INSN)
9230                     where = where2;
9231                 }
9232               else if (GET_CODE (where) == INSN)
9233                 where = i;
9234             }
9235           else
9236             where = i;
9237
9238           do
9239             emit_insn_before ((*next_nop)(&prev_in_use), where);
9240           while (--nop_count);
9241           ofs = 0;
9242         }
9243
9244       ofs = (ofs + len) & (align - 1);
9245       prev_in_use = in_use;
9246       i = next;
9247     }
9248 }
9249 \f
9250 /* Machine dependent reorg pass.  */
9251
9252 static void
9253 alpha_reorg (void)
9254 {
9255   if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
9256     alpha_handle_trap_shadows ();
9257
9258   /* Due to the number of extra trapb insns, don't bother fixing up
9259      alignment when trap precision is instruction.  Moreover, we can
9260      only do our job when sched2 is run.  */
9261   if (optimize && !optimize_size
9262       && alpha_tp != ALPHA_TP_INSN
9263       && flag_schedule_insns_after_reload)
9264     {
9265       if (alpha_tune == PROCESSOR_EV4)
9266         alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
9267       else if (alpha_tune == PROCESSOR_EV5)
9268         alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
9269     }
9270 }
9271 \f
9272 #if !TARGET_ABI_UNICOSMK
9273
9274 #ifdef HAVE_STAMP_H
9275 #include <stamp.h>
9276 #endif
9277
9278 static void
9279 alpha_file_start (void)
9280 {
9281 #ifdef OBJECT_FORMAT_ELF
9282   /* If emitting dwarf2 debug information, we cannot generate a .file
9283      directive to start the file, as it will conflict with dwarf2out
9284      file numbers.  So it's only useful when emitting mdebug output.  */
9285   targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
9286 #endif
9287
9288   default_file_start ();
9289 #ifdef MS_STAMP
9290   fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
9291 #endif
9292
9293   fputs ("\t.set noreorder\n", asm_out_file);
9294   fputs ("\t.set volatile\n", asm_out_file);
9295   if (!TARGET_ABI_OPEN_VMS)
9296     fputs ("\t.set noat\n", asm_out_file);
9297   if (TARGET_EXPLICIT_RELOCS)
9298     fputs ("\t.set nomacro\n", asm_out_file);
9299   if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
9300     {
9301       const char *arch;
9302
9303       if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
9304         arch = "ev6";
9305       else if (TARGET_MAX)
9306         arch = "pca56";
9307       else if (TARGET_BWX)
9308         arch = "ev56";
9309       else if (alpha_cpu == PROCESSOR_EV5)
9310         arch = "ev5";
9311       else
9312         arch = "ev4";
9313
9314       fprintf (asm_out_file, "\t.arch %s\n", arch);
9315     }
9316 }
9317 #endif
9318
9319 #ifdef OBJECT_FORMAT_ELF
9320 /* Since we don't have a .dynbss section, we should not allow global
9321    relocations in the .rodata section.  */
9322
9323 static int
9324 alpha_elf_reloc_rw_mask (void)
9325 {
9326   return flag_pic ? 3 : 2;
9327 }
9328
9329 /* Return a section for X.  The only special thing we do here is to
9330    honor small data.  */
9331
9332 static section *
9333 alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
9334                               unsigned HOST_WIDE_INT align)
9335 {
9336   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
9337     /* ??? Consider using mergeable sdata sections.  */
9338     return sdata_section;
9339   else
9340     return default_elf_select_rtx_section (mode, x, align);
9341 }
9342
9343 static unsigned int
9344 alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
9345 {
9346   unsigned int flags = 0;
9347
9348   if (strcmp (name, ".sdata") == 0
9349       || strncmp (name, ".sdata.", 7) == 0
9350       || strncmp (name, ".gnu.linkonce.s.", 16) == 0
9351       || strcmp (name, ".sbss") == 0
9352       || strncmp (name, ".sbss.", 6) == 0
9353       || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
9354     flags = SECTION_SMALL;
9355
9356   flags |= default_section_type_flags (decl, name, reloc);
9357   return flags;
9358 }
9359 #endif /* OBJECT_FORMAT_ELF */
9360 \f
9361 /* Structure to collect function names for final output in link section.  */
9362 /* Note that items marked with GTY can't be ifdef'ed out.  */
9363
9364 enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
9365 enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
9366
9367 struct alpha_links GTY(())
9368 {
9369   int num;
9370   rtx linkage;
9371   enum links_kind lkind;
9372   enum reloc_kind rkind;
9373 };
9374
9375 struct alpha_funcs GTY(())
9376 {
9377   int num;
9378   splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9379     links;
9380 };
9381
9382 static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9383   splay_tree alpha_links_tree;
9384 static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
9385   splay_tree alpha_funcs_tree;
9386
9387 static GTY(()) int alpha_funcs_num;
9388
9389 #if TARGET_ABI_OPEN_VMS
9390
9391 /* Return the VMS argument type corresponding to MODE.  */
9392
9393 enum avms_arg_type
9394 alpha_arg_type (enum machine_mode mode)
9395 {
9396   switch (mode)
9397     {
9398     case SFmode:
9399       return TARGET_FLOAT_VAX ? FF : FS;
9400     case DFmode:
9401       return TARGET_FLOAT_VAX ? FD : FT;
9402     default:
9403       return I64;
9404     }
9405 }
9406
9407 /* Return an rtx for an integer representing the VMS Argument Information
9408    register value.  */
9409
9410 rtx
9411 alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
9412 {
9413   unsigned HOST_WIDE_INT regval = cum.num_args;
9414   int i;
9415
9416   for (i = 0; i < 6; i++)
9417     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
9418
9419   return GEN_INT (regval);
9420 }
9421 \f
9422 /* Make (or fake) .linkage entry for function call.
9423
9424    IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
9425
9426    Return an SYMBOL_REF rtx for the linkage.  */
9427
9428 rtx
9429 alpha_need_linkage (const char *name, int is_local)
9430 {
9431   splay_tree_node node;
9432   struct alpha_links *al;
9433
9434   if (name[0] == '*')
9435     name++;
9436
9437   if (is_local)
9438     {
9439       struct alpha_funcs *cfaf;
9440
9441       if (!alpha_funcs_tree)
9442         alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
9443                                                splay_tree_compare_pointers);
9444
9445       cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
9446
9447       cfaf->links = 0;
9448       cfaf->num = ++alpha_funcs_num;
9449
9450       splay_tree_insert (alpha_funcs_tree,
9451                          (splay_tree_key) current_function_decl,
9452                          (splay_tree_value) cfaf);
9453     }
9454
9455   if (alpha_links_tree)
9456     {
9457       /* Is this name already defined?  */
9458
9459       node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9460       if (node)
9461         {
9462           al = (struct alpha_links *) node->value;
9463           if (is_local)
9464             {
9465               /* Defined here but external assumed.  */
9466               if (al->lkind == KIND_EXTERN)
9467                 al->lkind = KIND_LOCAL;
9468             }
9469           else
9470             {
9471               /* Used here but unused assumed.  */
9472               if (al->lkind == KIND_UNUSED)
9473                 al->lkind = KIND_LOCAL;
9474             }
9475           return al->linkage;
9476         }
9477     }
9478   else
9479     alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9480
9481   al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9482   name = ggc_strdup (name);
9483
9484   /* Assume external if no definition.  */
9485   al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9486
9487   /* Ensure we have an IDENTIFIER so assemble_name can mark it used.  */
9488   get_identifier (name);
9489
9490   /* Construct a SYMBOL_REF for us to call.  */
9491   {
9492     size_t name_len = strlen (name);
9493     char *linksym = alloca (name_len + 6);
9494     linksym[0] = '$';
9495     memcpy (linksym + 1, name, name_len);
9496     memcpy (linksym + 1 + name_len, "..lk", 5);
9497     al->linkage = gen_rtx_SYMBOL_REF (Pmode,
9498                                       ggc_alloc_string (linksym, name_len + 5));
9499   }
9500
9501   splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9502                      (splay_tree_value) al);
9503
9504   return al->linkage;
9505 }
9506
9507 rtx
9508 alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
9509 {
9510   splay_tree_node cfunnode;
9511   struct alpha_funcs *cfaf;
9512   struct alpha_links *al;
9513   const char *name = XSTR (linkage, 0);
9514
9515   cfaf = (struct alpha_funcs *) 0;
9516   al = (struct alpha_links *) 0;
9517
9518   cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9519   cfaf = (struct alpha_funcs *) cfunnode->value;
9520
9521   if (cfaf->links)
9522     {
9523       splay_tree_node lnode;
9524
9525       /* Is this name already defined?  */
9526
9527       lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9528       if (lnode)
9529         al = (struct alpha_links *) lnode->value;
9530     }
9531   else
9532     cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9533
9534   if (!al)
9535     {
9536       size_t name_len;
9537       size_t buflen;
9538       char buf [512];
9539       char *linksym;
9540       splay_tree_node node = 0;
9541       struct alpha_links *anl;
9542
9543       if (name[0] == '*')
9544         name++;
9545
9546       name_len = strlen (name);
9547
9548       al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9549       al->num = cfaf->num;
9550
9551       node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9552       if (node)
9553         {
9554           anl = (struct alpha_links *) node->value;
9555           al->lkind = anl->lkind;
9556         }
9557
9558       sprintf (buf, "$%d..%s..lk", cfaf->num, name);
9559       buflen = strlen (buf);
9560       linksym = alloca (buflen + 1);
9561       memcpy (linksym, buf, buflen + 1);
9562
9563       al->linkage = gen_rtx_SYMBOL_REF
9564         (Pmode, ggc_alloc_string (linksym, buflen + 1));
9565
9566       splay_tree_insert (cfaf->links, (splay_tree_key) name,
9567                          (splay_tree_value) al);
9568     }
9569
9570   if (rflag)
9571     al->rkind = KIND_CODEADDR;
9572   else
9573     al->rkind = KIND_LINKAGE;
9574
9575   if (lflag)
9576     return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
9577   else
9578     return al->linkage;
9579 }
9580
9581 static int
9582 alpha_write_one_linkage (splay_tree_node node, void *data)
9583 {
9584   const char *const name = (const char *) node->key;
9585   struct alpha_links *link = (struct alpha_links *) node->value;
9586   FILE *stream = (FILE *) data;
9587
9588   fprintf (stream, "$%d..%s..lk:\n", link->num, name);
9589   if (link->rkind == KIND_CODEADDR)
9590     {
9591       if (link->lkind == KIND_LOCAL)
9592         {
9593           /* Local and used */
9594           fprintf (stream, "\t.quad %s..en\n", name);
9595         }
9596       else
9597         {
9598           /* External and used, request code address.  */
9599           fprintf (stream, "\t.code_address %s\n", name);
9600         }
9601     }
9602   else
9603     {
9604       if (link->lkind == KIND_LOCAL)
9605         {
9606           /* Local and used, build linkage pair.  */
9607           fprintf (stream, "\t.quad %s..en\n", name);
9608           fprintf (stream, "\t.quad %s\n", name);
9609         }
9610       else
9611         {
9612           /* External and used, request linkage pair.  */
9613           fprintf (stream, "\t.linkage %s\n", name);
9614         }
9615     }
9616
9617   return 0;
9618 }
9619
9620 static void
9621 alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
9622 {
9623   splay_tree_node node;
9624   struct alpha_funcs *func;
9625
9626   fprintf (stream, "\t.link\n");
9627   fprintf (stream, "\t.align 3\n");
9628   in_section = NULL;
9629
9630   node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
9631   func = (struct alpha_funcs *) node->value;
9632
9633   fputs ("\t.name ", stream);
9634   assemble_name (stream, funname);
9635   fputs ("..na\n", stream);
9636   ASM_OUTPUT_LABEL (stream, funname);
9637   fprintf (stream, "\t.pdesc ");
9638   assemble_name (stream, funname);
9639   fprintf (stream, "..en,%s\n",
9640            alpha_procedure_type == PT_STACK ? "stack"
9641            : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
9642
9643   if (func->links)
9644     {
9645       splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
9646       /* splay_tree_delete (func->links); */
9647     }
9648 }
9649
9650 /* Given a decl, a section name, and whether the decl initializer
9651    has relocs, choose attributes for the section.  */
9652
9653 #define SECTION_VMS_OVERLAY     SECTION_FORGET
9654 #define SECTION_VMS_GLOBAL SECTION_MACH_DEP
9655 #define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
9656
9657 static unsigned int
9658 vms_section_type_flags (tree decl, const char *name, int reloc)
9659 {
9660   unsigned int flags = default_section_type_flags (decl, name, reloc);
9661
9662   if (decl && DECL_ATTRIBUTES (decl)
9663       && lookup_attribute ("overlaid", DECL_ATTRIBUTES (decl)))
9664     flags |= SECTION_VMS_OVERLAY;
9665   if (decl && DECL_ATTRIBUTES (decl)
9666       && lookup_attribute ("global", DECL_ATTRIBUTES (decl)))
9667     flags |= SECTION_VMS_GLOBAL;
9668   if (decl && DECL_ATTRIBUTES (decl)
9669       && lookup_attribute ("initialize", DECL_ATTRIBUTES (decl)))
9670     flags |= SECTION_VMS_INITIALIZE;
9671
9672   return flags;
9673 }
9674
9675 /* Switch to an arbitrary section NAME with attributes as specified
9676    by FLAGS.  ALIGN specifies any known alignment requirements for
9677    the section; 0 if the default should be used.  */
9678
9679 static void
9680 vms_asm_named_section (const char *name, unsigned int flags, 
9681                        tree decl ATTRIBUTE_UNUSED)
9682 {
9683   fputc ('\n', asm_out_file);
9684   fprintf (asm_out_file, ".section\t%s", name);
9685
9686   if (flags & SECTION_VMS_OVERLAY)
9687     fprintf (asm_out_file, ",OVR");
9688   if (flags & SECTION_VMS_GLOBAL)
9689     fprintf (asm_out_file, ",GBL");
9690   if (flags & SECTION_VMS_INITIALIZE)
9691     fprintf (asm_out_file, ",NOMOD");
9692   if (flags & SECTION_DEBUG)
9693     fprintf (asm_out_file, ",NOWRT");
9694
9695   fputc ('\n', asm_out_file);
9696 }
9697
9698 /* Record an element in the table of global constructors.  SYMBOL is
9699    a SYMBOL_REF of the function to be called; PRIORITY is a number
9700    between 0 and MAX_INIT_PRIORITY.
9701
9702    Differs from default_ctors_section_asm_out_constructor in that the
9703    width of the .ctors entry is always 64 bits, rather than the 32 bits
9704    used by a normal pointer.  */
9705
9706 static void
9707 vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9708 {
9709   switch_to_section (ctors_section);
9710   assemble_align (BITS_PER_WORD);
9711   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9712 }
9713
9714 static void
9715 vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
9716 {
9717   switch_to_section (dtors_section);
9718   assemble_align (BITS_PER_WORD);
9719   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
9720 }
9721 #else
9722
9723 rtx
9724 alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
9725                     int is_local ATTRIBUTE_UNUSED)
9726 {
9727   return NULL_RTX;
9728 }
9729
9730 rtx
9731 alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
9732                    tree cfundecl ATTRIBUTE_UNUSED,
9733                    int lflag ATTRIBUTE_UNUSED,
9734                    int rflag ATTRIBUTE_UNUSED)
9735 {
9736   return NULL_RTX;
9737 }
9738
9739 #endif /* TARGET_ABI_OPEN_VMS */
9740 \f
9741 #if TARGET_ABI_UNICOSMK
9742
9743 /* This evaluates to true if we do not know how to pass TYPE solely in
9744    registers.  This is the case for all arguments that do not fit in two
9745    registers.  */
9746
9747 static bool
9748 unicosmk_must_pass_in_stack (enum machine_mode mode, const_tree type)
9749 {
9750   if (type == NULL)
9751     return false;
9752
9753   if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
9754     return true;
9755   if (TREE_ADDRESSABLE (type))
9756     return true;
9757
9758   return ALPHA_ARG_SIZE (mode, type, 0) > 2;
9759 }
9760
9761 /* Define the offset between two registers, one to be eliminated, and the
9762    other its replacement, at the start of a routine.  */
9763
9764 int
9765 unicosmk_initial_elimination_offset (int from, int to)
9766 {
9767   int fixed_size;
9768
9769   fixed_size = alpha_sa_size();
9770   if (fixed_size != 0)
9771     fixed_size += 48;
9772
9773   if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9774     return -fixed_size;
9775   else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
9776     return 0;
9777   else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9778     return (ALPHA_ROUND (crtl->outgoing_args_size)
9779             + ALPHA_ROUND (get_frame_size()));
9780   else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
9781     return (ALPHA_ROUND (fixed_size)
9782             + ALPHA_ROUND (get_frame_size()
9783                            + crtl->outgoing_args_size));
9784   else
9785     gcc_unreachable ();
9786 }
9787
9788 /* Output the module name for .ident and .end directives. We have to strip
9789    directories and add make sure that the module name starts with a letter
9790    or '$'.  */
9791
9792 static void
9793 unicosmk_output_module_name (FILE *file)
9794 {
9795   const char *name = lbasename (main_input_filename);
9796   unsigned len = strlen (name);
9797   char *clean_name = alloca (len + 2);
9798   char *ptr = clean_name;
9799
9800   /* CAM only accepts module names that start with a letter or '$'. We
9801      prefix the module name with a '$' if necessary.  */
9802
9803   if (!ISALPHA (*name))
9804     *ptr++ = '$';
9805   memcpy (ptr, name, len + 1);
9806   clean_symbol_name (clean_name);
9807   fputs (clean_name, file);
9808 }
9809
9810 /* Output the definition of a common variable.  */
9811
9812 void
9813 unicosmk_output_common (FILE *file, const char *name, int size, int align)
9814 {
9815   tree name_tree;
9816   printf ("T3E__: common %s\n", name);
9817
9818   in_section = NULL;
9819   fputs("\t.endp\n\n\t.psect ", file);
9820   assemble_name(file, name);
9821   fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
9822   fprintf(file, "\t.byte\t0:%d\n", size);
9823
9824   /* Mark the symbol as defined in this module.  */
9825   name_tree = get_identifier (name);
9826   TREE_ASM_WRITTEN (name_tree) = 1;
9827 }
9828
9829 #define SECTION_PUBLIC SECTION_MACH_DEP
9830 #define SECTION_MAIN (SECTION_PUBLIC << 1)
9831 static int current_section_align;
9832
9833 /* A get_unnamed_section callback for switching to the text section.  */
9834
9835 static void
9836 unicosmk_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
9837 {
9838   static int count = 0;
9839   fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@text___%d,code\n", count++);
9840 }
9841
9842 /* A get_unnamed_section callback for switching to the data section.  */
9843
9844 static void
9845 unicosmk_output_data_section_asm_op (const void *data ATTRIBUTE_UNUSED)
9846 {
9847   static int count = 1;
9848   fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@data___%d,data\n", count++);
9849 }
9850
9851 /* Implement TARGET_ASM_INIT_SECTIONS.
9852
9853    The Cray assembler is really weird with respect to sections. It has only
9854    named sections and you can't reopen a section once it has been closed.
9855    This means that we have to generate unique names whenever we want to
9856    reenter the text or the data section.  */
9857
9858 static void
9859 unicosmk_init_sections (void)
9860 {
9861   text_section = get_unnamed_section (SECTION_CODE,
9862                                       unicosmk_output_text_section_asm_op,
9863                                       NULL);
9864   data_section = get_unnamed_section (SECTION_WRITE,
9865                                       unicosmk_output_data_section_asm_op,
9866                                       NULL);
9867   readonly_data_section = data_section;
9868 }
9869
9870 static unsigned int
9871 unicosmk_section_type_flags (tree decl, const char *name,
9872                              int reloc ATTRIBUTE_UNUSED)
9873 {
9874   unsigned int flags = default_section_type_flags (decl, name, reloc);
9875
9876   if (!decl)
9877     return flags;
9878
9879   if (TREE_CODE (decl) == FUNCTION_DECL)
9880     {
9881       current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
9882       if (align_functions_log > current_section_align)
9883         current_section_align = align_functions_log;
9884
9885       if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
9886         flags |= SECTION_MAIN;
9887     }
9888   else
9889     current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
9890
9891   if (TREE_PUBLIC (decl))
9892     flags |= SECTION_PUBLIC;
9893
9894   return flags;
9895 }
9896
9897 /* Generate a section name for decl and associate it with the
9898    declaration.  */
9899
9900 static void
9901 unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
9902 {
9903   const char *name;
9904   int len;
9905
9906   gcc_assert (decl);
9907
9908   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
9909   name = default_strip_name_encoding (name);
9910   len = strlen (name);
9911
9912   if (TREE_CODE (decl) == FUNCTION_DECL)
9913     {
9914       char *string;
9915
9916       /* It is essential that we prefix the section name here because
9917          otherwise the section names generated for constructors and
9918          destructors confuse collect2.  */
9919
9920       string = alloca (len + 6);
9921       sprintf (string, "code@%s", name);
9922       DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9923     }
9924   else if (TREE_PUBLIC (decl))
9925     DECL_SECTION_NAME (decl) = build_string (len, name);
9926   else
9927     {
9928       char *string;
9929
9930       string = alloca (len + 6);
9931       sprintf (string, "data@%s", name);
9932       DECL_SECTION_NAME (decl) = build_string (len + 5, string);
9933     }
9934 }
9935
9936 /* Switch to an arbitrary section NAME with attributes as specified
9937    by FLAGS.  ALIGN specifies any known alignment requirements for
9938    the section; 0 if the default should be used.  */
9939
9940 static void
9941 unicosmk_asm_named_section (const char *name, unsigned int flags, 
9942                             tree decl ATTRIBUTE_UNUSED)
9943 {
9944   const char *kind;
9945
9946   /* Close the previous section.  */
9947
9948   fputs ("\t.endp\n\n", asm_out_file);
9949
9950   /* Find out what kind of section we are opening.  */
9951
9952   if (flags & SECTION_MAIN)
9953     fputs ("\t.start\tmain\n", asm_out_file);
9954
9955   if (flags & SECTION_CODE)
9956     kind = "code";
9957   else if (flags & SECTION_PUBLIC)
9958     kind = "common";
9959   else
9960     kind = "data";
9961
9962   if (current_section_align != 0)
9963     fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
9964              current_section_align, kind);
9965   else
9966     fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
9967 }
9968
9969 static void
9970 unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
9971 {
9972   if (DECL_P (decl)
9973       && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
9974     unicosmk_unique_section (decl, 0);
9975 }
9976
9977 /* Output an alignment directive. We have to use the macro 'gcc@code@align'
9978    in code sections because .align fill unused space with zeroes.  */
9979
9980 void
9981 unicosmk_output_align (FILE *file, int align)
9982 {
9983   if (inside_function)
9984     fprintf (file, "\tgcc@code@align\t%d\n", align);
9985   else
9986     fprintf (file, "\t.align\t%d\n", align);
9987 }
9988
9989 /* Add a case vector to the current function's list of deferred case
9990    vectors. Case vectors have to be put into a separate section because CAM
9991    does not allow data definitions in code sections.  */
9992
9993 void
9994 unicosmk_defer_case_vector (rtx lab, rtx vec)
9995 {
9996   struct machine_function *machine = cfun->machine;
9997
9998   vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
9999   machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
10000                                           machine->addr_list);
10001 }
10002
10003 /* Output a case vector.  */
10004
10005 static void
10006 unicosmk_output_addr_vec (FILE *file, rtx vec)
10007 {
10008   rtx lab  = XEXP (vec, 0);
10009   rtx body = XEXP (vec, 1);
10010   int vlen = XVECLEN (body, 0);
10011   int idx;
10012
10013   (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
10014
10015   for (idx = 0; idx < vlen; idx++)
10016     {
10017       ASM_OUTPUT_ADDR_VEC_ELT
10018         (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
10019     }
10020 }
10021
10022 /* Output current function's deferred case vectors.  */
10023
10024 static void
10025 unicosmk_output_deferred_case_vectors (FILE *file)
10026 {
10027   struct machine_function *machine = cfun->machine;
10028   rtx t;
10029
10030   if (machine->addr_list == NULL_RTX)
10031     return;
10032
10033   switch_to_section (data_section);
10034   for (t = machine->addr_list; t; t = XEXP (t, 1))
10035     unicosmk_output_addr_vec (file, XEXP (t, 0));
10036 }
10037
10038 /* Generate the name of the SSIB section for the current function.  */
10039
10040 #define SSIB_PREFIX "__SSIB_"
10041 #define SSIB_PREFIX_LEN 7
10042
10043 static const char *
10044 unicosmk_ssib_name (void)
10045 {
10046   /* This is ok since CAM won't be able to deal with names longer than that
10047      anyway.  */
10048
10049   static char name[256];
10050
10051   rtx x;
10052   const char *fnname;
10053   int len;
10054
10055   x = DECL_RTL (cfun->decl);
10056   gcc_assert (GET_CODE (x) == MEM);
10057   x = XEXP (x, 0);
10058   gcc_assert (GET_CODE (x) == SYMBOL_REF);
10059   fnname = XSTR (x, 0);
10060
10061   len = strlen (fnname);
10062   if (len + SSIB_PREFIX_LEN > 255)
10063     len = 255 - SSIB_PREFIX_LEN;
10064
10065   strcpy (name, SSIB_PREFIX);
10066   strncpy (name + SSIB_PREFIX_LEN, fnname, len);
10067   name[len + SSIB_PREFIX_LEN] = 0;
10068
10069   return name;
10070 }
10071
10072 /* Set up the dynamic subprogram information block (DSIB) and update the
10073    frame pointer register ($15) for subroutines which have a frame. If the
10074    subroutine doesn't have a frame, simply increment $15.  */
10075
10076 static void
10077 unicosmk_gen_dsib (unsigned long *imaskP)
10078 {
10079   if (alpha_procedure_type == PT_STACK)
10080     {
10081       const char *ssib_name;
10082       rtx mem;
10083
10084       /* Allocate 64 bytes for the DSIB.  */
10085
10086       FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
10087                                   GEN_INT (-64))));
10088       emit_insn (gen_blockage ());
10089
10090       /* Save the return address.  */
10091
10092       mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
10093       set_mem_alias_set (mem, alpha_sr_alias_set);
10094       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
10095       (*imaskP) &= ~(1UL << REG_RA);
10096
10097       /* Save the old frame pointer.  */
10098
10099       mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
10100       set_mem_alias_set (mem, alpha_sr_alias_set);
10101       FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
10102       (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
10103
10104       emit_insn (gen_blockage ());
10105
10106       /* Store the SSIB pointer.  */
10107
10108       ssib_name = ggc_strdup (unicosmk_ssib_name ());
10109       mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
10110       set_mem_alias_set (mem, alpha_sr_alias_set);
10111
10112       FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
10113                            gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
10114       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
10115
10116       /* Save the CIW index.  */
10117
10118       mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
10119       set_mem_alias_set (mem, alpha_sr_alias_set);
10120       FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
10121
10122       emit_insn (gen_blockage ());
10123
10124       /* Set the new frame pointer.  */
10125
10126       FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10127                                   stack_pointer_rtx, GEN_INT (64))));
10128
10129     }
10130   else
10131     {
10132       /* Increment the frame pointer register to indicate that we do not
10133          have a frame.  */
10134
10135       FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10136                                   hard_frame_pointer_rtx, const1_rtx)));
10137     }
10138 }
10139
10140 /* Output the static subroutine information block for the current
10141    function.  */
10142
10143 static void
10144 unicosmk_output_ssib (FILE *file, const char *fnname)
10145 {
10146   int len;
10147   int i;
10148   rtx x;
10149   rtx ciw;
10150   struct machine_function *machine = cfun->machine;
10151
10152   in_section = NULL;
10153   fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
10154            unicosmk_ssib_name ());
10155
10156   /* Some required stuff and the function name length.  */
10157
10158   len = strlen (fnname);
10159   fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
10160
10161   /* Saved registers
10162      ??? We don't do that yet.  */
10163
10164   fputs ("\t.quad\t0\n", file);
10165
10166   /* Function address.  */
10167
10168   fputs ("\t.quad\t", file);
10169   assemble_name (file, fnname);
10170   putc ('\n', file);
10171
10172   fputs ("\t.quad\t0\n", file);
10173   fputs ("\t.quad\t0\n", file);
10174
10175   /* Function name.
10176      ??? We do it the same way Cray CC does it but this could be
10177      simplified.  */
10178
10179   for( i = 0; i < len; i++ )
10180     fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
10181   if( (len % 8) == 0 )
10182     fputs ("\t.quad\t0\n", file);
10183   else
10184     fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
10185
10186   /* All call information words used in the function.  */
10187
10188   for (x = machine->first_ciw; x; x = XEXP (x, 1))
10189     {
10190       ciw = XEXP (x, 0);
10191 #if HOST_BITS_PER_WIDE_INT == 32
10192       fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
10193                CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
10194 #else
10195       fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
10196 #endif
10197     }
10198 }
10199
10200 /* Add a call information word (CIW) to the list of the current function's
10201    CIWs and return its index.
10202
10203    X is a CONST_INT or CONST_DOUBLE representing the CIW.  */
10204
10205 rtx
10206 unicosmk_add_call_info_word (rtx x)
10207 {
10208   rtx node;
10209   struct machine_function *machine = cfun->machine;
10210
10211   node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
10212   if (machine->first_ciw == NULL_RTX)
10213     machine->first_ciw = node;
10214   else
10215     XEXP (machine->last_ciw, 1) = node;
10216
10217   machine->last_ciw = node;
10218   ++machine->ciw_count;
10219
10220   return GEN_INT (machine->ciw_count
10221                   + strlen (current_function_name ())/8 + 5);
10222 }
10223
10224 /* The Cray assembler doesn't accept extern declarations for symbols which
10225    are defined in the same file. We have to keep track of all global
10226    symbols which are referenced and/or defined in a source file and output
10227    extern declarations for those which are referenced but not defined at
10228    the end of file.  */
10229
10230 /* List of identifiers for which an extern declaration might have to be
10231    emitted.  */
10232 /* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
10233
10234 struct unicosmk_extern_list
10235 {
10236   struct unicosmk_extern_list *next;
10237   const char *name;
10238 };
10239
10240 static struct unicosmk_extern_list *unicosmk_extern_head = 0;
10241
10242 /* Output extern declarations which are required for every asm file.  */
10243
10244 static void
10245 unicosmk_output_default_externs (FILE *file)
10246 {
10247   static const char *const externs[] =
10248     { "__T3E_MISMATCH" };
10249
10250   int i;
10251   int n;
10252
10253   n = ARRAY_SIZE (externs);
10254
10255   for (i = 0; i < n; i++)
10256     fprintf (file, "\t.extern\t%s\n", externs[i]);
10257 }
10258
10259 /* Output extern declarations for global symbols which are have been
10260    referenced but not defined.  */
10261
10262 static void
10263 unicosmk_output_externs (FILE *file)
10264 {
10265   struct unicosmk_extern_list *p;
10266   const char *real_name;
10267   int len;
10268   tree name_tree;
10269
10270   len = strlen (user_label_prefix);
10271   for (p = unicosmk_extern_head; p != 0; p = p->next)
10272     {
10273       /* We have to strip the encoding and possibly remove user_label_prefix
10274          from the identifier in order to handle -fleading-underscore and
10275          explicit asm names correctly (cf. gcc.dg/asm-names-1.c).  */
10276       real_name = default_strip_name_encoding (p->name);
10277       if (len && p->name[0] == '*'
10278           && !memcmp (real_name, user_label_prefix, len))
10279         real_name += len;
10280
10281       name_tree = get_identifier (real_name);
10282       if (! TREE_ASM_WRITTEN (name_tree))
10283         {
10284           TREE_ASM_WRITTEN (name_tree) = 1;
10285           fputs ("\t.extern\t", file);
10286           assemble_name (file, p->name);
10287           putc ('\n', file);
10288         }
10289     }
10290 }
10291
10292 /* Record an extern.  */
10293
10294 void
10295 unicosmk_add_extern (const char *name)
10296 {
10297   struct unicosmk_extern_list *p;
10298
10299   p = (struct unicosmk_extern_list *)
10300        xmalloc (sizeof (struct unicosmk_extern_list));
10301   p->next = unicosmk_extern_head;
10302   p->name = name;
10303   unicosmk_extern_head = p;
10304 }
10305
10306 /* The Cray assembler generates incorrect code if identifiers which
10307    conflict with register names are used as instruction operands. We have
10308    to replace such identifiers with DEX expressions.  */
10309
10310 /* Structure to collect identifiers which have been replaced by DEX
10311    expressions.  */
10312 /* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
10313
10314 struct unicosmk_dex {
10315   struct unicosmk_dex *next;
10316   const char *name;
10317 };
10318
10319 /* List of identifiers which have been replaced by DEX expressions. The DEX
10320    number is determined by the position in the list.  */
10321
10322 static struct unicosmk_dex *unicosmk_dex_list = NULL;
10323
10324 /* The number of elements in the DEX list.  */
10325
10326 static int unicosmk_dex_count = 0;
10327
10328 /* Check if NAME must be replaced by a DEX expression.  */
10329
10330 static int
10331 unicosmk_special_name (const char *name)
10332 {
10333   if (name[0] == '*')
10334     ++name;
10335
10336   if (name[0] == '$')
10337     ++name;
10338
10339   if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
10340     return 0;
10341
10342   switch (name[1])
10343     {
10344     case '1':  case '2':
10345       return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
10346
10347     case '3':
10348       return (name[2] == '\0'
10349                || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
10350
10351     default:
10352       return (ISDIGIT (name[1]) && name[2] == '\0');
10353     }
10354 }
10355
10356 /* Return the DEX number if X must be replaced by a DEX expression and 0
10357    otherwise.  */
10358
10359 static int
10360 unicosmk_need_dex (rtx x)
10361 {
10362   struct unicosmk_dex *dex;
10363   const char *name;
10364   int i;
10365
10366   if (GET_CODE (x) != SYMBOL_REF)
10367     return 0;
10368
10369   name = XSTR (x,0);
10370   if (! unicosmk_special_name (name))
10371     return 0;
10372
10373   i = unicosmk_dex_count;
10374   for (dex = unicosmk_dex_list; dex; dex = dex->next)
10375     {
10376       if (! strcmp (name, dex->name))
10377         return i;
10378       --i;
10379     }
10380
10381   dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
10382   dex->name = name;
10383   dex->next = unicosmk_dex_list;
10384   unicosmk_dex_list = dex;
10385
10386   ++unicosmk_dex_count;
10387   return unicosmk_dex_count;
10388 }
10389
10390 /* Output the DEX definitions for this file.  */
10391
10392 static void
10393 unicosmk_output_dex (FILE *file)
10394 {
10395   struct unicosmk_dex *dex;
10396   int i;
10397
10398   if (unicosmk_dex_list == NULL)
10399     return;
10400
10401   fprintf (file, "\t.dexstart\n");
10402
10403   i = unicosmk_dex_count;
10404   for (dex = unicosmk_dex_list; dex; dex = dex->next)
10405     {
10406       fprintf (file, "\tDEX (%d) = ", i);
10407       assemble_name (file, dex->name);
10408       putc ('\n', file);
10409       --i;
10410     }
10411
10412   fprintf (file, "\t.dexend\n");
10413 }
10414
10415 /* Output text that to appear at the beginning of an assembler file.  */
10416
10417 static void
10418 unicosmk_file_start (void)
10419 {
10420   int i;
10421
10422   fputs ("\t.ident\t", asm_out_file);
10423   unicosmk_output_module_name (asm_out_file);
10424   fputs ("\n\n", asm_out_file);
10425
10426   /* The Unicos/Mk assembler uses different register names. Instead of trying
10427      to support them, we simply use micro definitions.  */
10428
10429   /* CAM has different register names: rN for the integer register N and fN
10430      for the floating-point register N. Instead of trying to use these in
10431      alpha.md, we define the symbols $N and $fN to refer to the appropriate
10432      register.  */
10433
10434   for (i = 0; i < 32; ++i)
10435     fprintf (asm_out_file, "$%d <- r%d\n", i, i);
10436
10437   for (i = 0; i < 32; ++i)
10438     fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
10439
10440   putc ('\n', asm_out_file);
10441
10442   /* The .align directive fill unused space with zeroes which does not work
10443      in code sections. We define the macro 'gcc@code@align' which uses nops
10444      instead. Note that it assumes that code sections always have the
10445      biggest possible alignment since . refers to the current offset from
10446      the beginning of the section.  */
10447
10448   fputs ("\t.macro gcc@code@align n\n", asm_out_file);
10449   fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
10450   fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
10451   fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
10452   fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
10453   fputs ("\tbis r31,r31,r31\n", asm_out_file);
10454   fputs ("\t.endr\n", asm_out_file);
10455   fputs ("\t.endif\n", asm_out_file);
10456   fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
10457
10458   /* Output extern declarations which should always be visible.  */
10459   unicosmk_output_default_externs (asm_out_file);
10460
10461   /* Open a dummy section. We always need to be inside a section for the
10462      section-switching code to work correctly.
10463      ??? This should be a module id or something like that. I still have to
10464      figure out what the rules for those are.  */
10465   fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
10466 }
10467
10468 /* Output text to appear at the end of an assembler file. This includes all
10469    pending extern declarations and DEX expressions.  */
10470
10471 static void
10472 unicosmk_file_end (void)
10473 {
10474   fputs ("\t.endp\n\n", asm_out_file);
10475
10476   /* Output all pending externs.  */
10477
10478   unicosmk_output_externs (asm_out_file);
10479
10480   /* Output dex definitions used for functions whose names conflict with
10481      register names.  */
10482
10483   unicosmk_output_dex (asm_out_file);
10484
10485   fputs ("\t.end\t", asm_out_file);
10486   unicosmk_output_module_name (asm_out_file);
10487   putc ('\n', asm_out_file);
10488 }
10489
10490 #else
10491
10492 static void
10493 unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
10494 {}
10495
10496 static void
10497 unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
10498 {}
10499
10500 static void
10501 unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
10502                       const char * fnname ATTRIBUTE_UNUSED)
10503 {}
10504
10505 rtx
10506 unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
10507 {
10508   return NULL_RTX;
10509 }
10510
10511 static int
10512 unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
10513 {
10514   return 0;
10515 }
10516
10517 #endif /* TARGET_ABI_UNICOSMK */
10518
10519 static void
10520 alpha_init_libfuncs (void)
10521 {
10522   if (TARGET_ABI_UNICOSMK)
10523     {
10524       /* Prevent gcc from generating calls to __divsi3.  */
10525       set_optab_libfunc (sdiv_optab, SImode, 0);
10526       set_optab_libfunc (udiv_optab, SImode, 0);
10527
10528       /* Use the functions provided by the system library
10529          for DImode integer division.  */
10530       set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
10531       set_optab_libfunc (udiv_optab, DImode, "$uldiv");
10532     }
10533   else if (TARGET_ABI_OPEN_VMS)
10534     {
10535       /* Use the VMS runtime library functions for division and
10536          remainder.  */
10537       set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
10538       set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
10539       set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
10540       set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
10541       set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
10542       set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
10543       set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
10544       set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
10545     }
10546 }
10547
10548 \f
10549 /* Initialize the GCC target structure.  */
10550 #if TARGET_ABI_OPEN_VMS
10551 # undef TARGET_ATTRIBUTE_TABLE
10552 # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
10553 # undef TARGET_SECTION_TYPE_FLAGS
10554 # define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
10555 #endif
10556
10557 #undef TARGET_IN_SMALL_DATA_P
10558 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
10559
10560 #if TARGET_ABI_UNICOSMK
10561 # undef TARGET_INSERT_ATTRIBUTES
10562 # define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
10563 # undef TARGET_SECTION_TYPE_FLAGS
10564 # define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
10565 # undef TARGET_ASM_UNIQUE_SECTION
10566 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
10567 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
10568 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
10569 # undef TARGET_ASM_GLOBALIZE_LABEL
10570 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
10571 # undef TARGET_MUST_PASS_IN_STACK
10572 # define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
10573 #endif
10574
10575 #undef TARGET_ASM_ALIGNED_HI_OP
10576 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
10577 #undef TARGET_ASM_ALIGNED_DI_OP
10578 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
10579
10580 /* Default unaligned ops are provided for ELF systems.  To get unaligned
10581    data for non-ELF systems, we have to turn off auto alignment.  */
10582 #ifndef OBJECT_FORMAT_ELF
10583 #undef TARGET_ASM_UNALIGNED_HI_OP
10584 #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
10585 #undef TARGET_ASM_UNALIGNED_SI_OP
10586 #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
10587 #undef TARGET_ASM_UNALIGNED_DI_OP
10588 #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
10589 #endif
10590
10591 #ifdef OBJECT_FORMAT_ELF
10592 #undef  TARGET_ASM_RELOC_RW_MASK
10593 #define TARGET_ASM_RELOC_RW_MASK  alpha_elf_reloc_rw_mask
10594 #undef  TARGET_ASM_SELECT_RTX_SECTION
10595 #define TARGET_ASM_SELECT_RTX_SECTION  alpha_elf_select_rtx_section
10596 #undef  TARGET_SECTION_TYPE_FLAGS
10597 #define TARGET_SECTION_TYPE_FLAGS  alpha_elf_section_type_flags
10598 #endif
10599
10600 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
10601 #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
10602
10603 #undef TARGET_INIT_LIBFUNCS
10604 #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
10605
10606 #if TARGET_ABI_UNICOSMK
10607 #undef TARGET_ASM_FILE_START
10608 #define TARGET_ASM_FILE_START unicosmk_file_start
10609 #undef TARGET_ASM_FILE_END
10610 #define TARGET_ASM_FILE_END unicosmk_file_end
10611 #else
10612 #undef TARGET_ASM_FILE_START
10613 #define TARGET_ASM_FILE_START alpha_file_start
10614 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
10615 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
10616 #endif
10617
10618 #undef TARGET_SCHED_ADJUST_COST
10619 #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
10620 #undef TARGET_SCHED_ISSUE_RATE
10621 #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
10622 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
10623 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
10624   alpha_multipass_dfa_lookahead
10625
10626 #undef TARGET_HAVE_TLS
10627 #define TARGET_HAVE_TLS HAVE_AS_TLS
10628
10629 #undef  TARGET_INIT_BUILTINS
10630 #define TARGET_INIT_BUILTINS alpha_init_builtins
10631 #undef  TARGET_EXPAND_BUILTIN
10632 #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
10633 #undef  TARGET_FOLD_BUILTIN
10634 #define TARGET_FOLD_BUILTIN alpha_fold_builtin
10635
10636 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
10637 #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
10638 #undef TARGET_CANNOT_COPY_INSN_P
10639 #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
10640 #undef TARGET_CANNOT_FORCE_CONST_MEM
10641 #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
10642
10643 #if TARGET_ABI_OSF
10644 #undef TARGET_ASM_OUTPUT_MI_THUNK
10645 #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
10646 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
10647 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
10648 #undef TARGET_STDARG_OPTIMIZE_HOOK
10649 #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
10650 #endif
10651
10652 #undef TARGET_RTX_COSTS
10653 #define TARGET_RTX_COSTS alpha_rtx_costs
10654 #undef TARGET_ADDRESS_COST
10655 #define TARGET_ADDRESS_COST hook_int_rtx_0
10656
10657 #undef TARGET_MACHINE_DEPENDENT_REORG
10658 #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
10659
10660 #undef TARGET_PROMOTE_FUNCTION_ARGS
10661 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
10662 #undef TARGET_PROMOTE_FUNCTION_RETURN
10663 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
10664 #undef TARGET_PROMOTE_PROTOTYPES
10665 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
10666 #undef TARGET_RETURN_IN_MEMORY
10667 #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
10668 #undef TARGET_PASS_BY_REFERENCE
10669 #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
10670 #undef TARGET_SETUP_INCOMING_VARARGS
10671 #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
10672 #undef TARGET_STRICT_ARGUMENT_NAMING
10673 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
10674 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
10675 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
10676 #undef TARGET_SPLIT_COMPLEX_ARG
10677 #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
10678 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
10679 #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
10680 #undef TARGET_ARG_PARTIAL_BYTES
10681 #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
10682
10683 #undef TARGET_SECONDARY_RELOAD
10684 #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
10685
10686 #undef TARGET_SCALAR_MODE_SUPPORTED_P
10687 #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
10688 #undef TARGET_VECTOR_MODE_SUPPORTED_P
10689 #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
10690
10691 #undef TARGET_BUILD_BUILTIN_VA_LIST
10692 #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
10693
10694 #undef TARGET_EXPAND_BUILTIN_VA_START
10695 #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
10696
10697 /* The Alpha architecture does not require sequential consistency.  See
10698    http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
10699    for an example of how it can be violated in practice.  */
10700 #undef TARGET_RELAXED_ORDERING
10701 #define TARGET_RELAXED_ORDERING true
10702
10703 #undef TARGET_DEFAULT_TARGET_FLAGS
10704 #define TARGET_DEFAULT_TARGET_FLAGS \
10705   (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
10706 #undef TARGET_HANDLE_OPTION
10707 #define TARGET_HANDLE_OPTION alpha_handle_option
10708
10709 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
10710 #undef TARGET_MANGLE_TYPE
10711 #define TARGET_MANGLE_TYPE alpha_mangle_type
10712 #endif
10713
10714 struct gcc_target targetm = TARGET_INITIALIZER;
10715
10716 \f
10717 #include "gt-alpha.h"