OSDN Git Service

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