OSDN Git Service

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