OSDN Git Service

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