OSDN Git Service

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