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