OSDN Git Service

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