OSDN Git Service

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