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