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